From 23ed937afc8dd1828a032822888783acd62e675d Mon Sep 17 00:00:00 2001 From: Arnob kumar saha Date: Tue, 7 Jul 2026 19:44:29 +0600 Subject: [PATCH] docs: separate $-prompt commands from their output in bash code blocks Commands now render alone in a ```bash block; command output moves outside the fence as plain text, matching the rest of the docs. Signed-off-by: Arnob kumar saha --- .../autoscaler/compute/compute-autoscale.md | 52 ++--- .../autoscaler/storage/storage-autoscale.md | 58 +++--- .../backup/kubestash/logical/index.md | 109 +++++----- docs/guides/cassandra/concepts/cassandra.md | 4 +- .../configuration/using-config-file.md | 32 +-- docs/guides/cassandra/monitoring/overview.md | 4 +- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 48 ++--- .../cassandra/quickstart/guide/quickstart.md | 52 +++-- .../cassandra/reconfigure-tls/cassandra.md | 116 ++++++----- .../reconfigure/cassandra-topology.md | 65 +++--- docs/guides/cassandra/restart/restart.md | 24 ++- .../guides/cassandra/rotate-auth/cassandra.md | 94 +++++---- .../scaling/horizontal-scaling/topology.md | 49 +++-- .../scaling/vertical-scaling/topology.md | 32 +-- docs/guides/cassandra/tls/topology.md | 24 +-- .../update-version/update-version.md | 38 ++-- .../cassandra/volume-expansion/topology.md | 48 ++--- .../autoscaler/compute/compute-autoscale.md | 20 +- .../autoscaler/storage/storage-autoscale.md | 16 +- docs/guides/clickhouse/concepts/clickhouse.md | 4 +- .../configuration/using-config-file.md | 8 +- .../initialization/script_source.md | 48 +++-- docs/guides/clickhouse/monitoring/overview.md | 4 +- .../monitoring/using-builtin-prometheus.md | 32 +-- .../monitoring/using-prometheus-operator.md | 28 +-- .../clickhouse/quickstart/guide/quickstart.md | 8 +- .../clickhouse/reconfigure-tls/clickhouse.md | 40 ++-- .../clickhouse/reconfigure/reconfigure.md | 28 +-- docs/guides/clickhouse/restart/restart.md | 14 +- .../clickhouse/rotate-auth/rotateauth.md | 141 +++++++------ .../scaling/horizontal-scaling/cluster.md | 16 +- .../scaling/vertical-scaling/cluster.md | 12 +- .../scaling/vertical-scaling/standalone.md | 12 +- docs/guides/clickhouse/tls/cluster.md | 12 +- .../update-version/update-version.md | 12 +- .../clickhouse/volume-expansion/cluster.md | 12 +- .../documentdb/autoscaler/compute/index.md | 57 +++--- .../documentdb/autoscaler/storage/index.md | 65 +++--- .../configuration/using-config-file.md | 46 +++-- .../failure-and-disaster-recovery/failover.md | 41 ++-- .../documentdb/reconfigure/reconfigure.md | 26 ++- docs/guides/documentdb/restart/restart.md | 37 ++-- .../rotate-authentication.md | 52 +++-- .../horizontal-scaling/horizontal-scaling.md | 49 +++-- .../vertical-scaling/vertical-scaling.md | 33 +-- .../storage-migration/storage-migration.md | 37 ++-- .../volume-expansion/volume-expansion.md | 33 +-- docs/guides/druid/autoscaler/compute/guide.md | 91 +++++---- docs/guides/druid/autoscaler/storage/guide.md | 101 ++++++---- .../druid/backup/application-level/index.md | 150 +++++++------- docs/guides/druid/backup/auto-backup/index.md | 113 ++++++----- .../backup/cross-ns-dependencies/index.md | 184 ++++++++++------- docs/guides/druid/backup/logical/index.md | 146 ++++++++------ docs/guides/druid/clustering/guide/index.md | 81 +++++--- docs/guides/druid/concepts/druid.md | 4 +- .../druid/configuration/config-file/index.md | 74 ++++--- .../configuration/podtemplating/index.md | 119 ++++++----- docs/guides/druid/failover/guide.md | 103 +++++----- docs/guides/druid/monitoring/overview.md | 24 ++- .../monitoring/using-builtin-prometheus.md | 40 ++-- .../monitoring/using-prometheus-operator.md | 48 ++--- docs/guides/druid/quickstart/guide/index.md | 81 ++++---- docs/guides/druid/reconfigure-tls/guide.md | 150 +++++++------- docs/guides/druid/reconfigure/guide.md | 88 ++++---- docs/guides/druid/restart/guide.md | 44 ++-- docs/guides/druid/rotate-auth/guide.md | 151 ++++++++------ .../druid/scaling/horizontal-scaling/guide.md | 116 ++++++----- .../druid/scaling/vertical-scaling/guide.md | 61 +++--- docs/guides/druid/tls/guide.md | 57 +++--- docs/guides/druid/update-version/guide.md | 68 ++++--- docs/guides/druid/volume-expansion/guide.md | 57 +++--- .../autoscaler/compute/combined/index.md | 49 +++-- .../autoscaler/compute/topology/index.md | 73 ++++--- .../autoscaler/storage/combined/index.md | 67 ++++--- .../autoscaler/storage/topology/index.md | 73 ++++--- .../backup/kubestash/auto-backup/index.md | 78 ++++---- .../backup/kubestash/customization/index.md | 4 +- .../backup/kubestash/logical/index.md | 148 ++++++++------ .../backup/stash/kubedb/index.md | 43 ++-- docs/guides/elasticsearch/cli/cli.md | 65 +++--- .../clustering/combined-cluster/index.md | 97 +++++---- .../hot-warm-cold-cluster/index.md | 72 ++++--- .../simple-dedicated-cluster/index.md | 76 +++---- .../concepts/elasticsearch/index.md | 8 +- .../configuration/combined-cluster/index.md | 51 ++--- .../configuration/jvm-options/index.md | 8 +- .../configuration/overview/index.md | 4 +- .../configuration/topology-cluster/index.md | 50 +++-- .../custom-rbac/using-custom-rbac.md | 41 ++-- .../elasticsearch-dashboard/kibana/index.md | 74 ++++--- .../opensearch-dashboards/index.md | 73 ++++--- docs/guides/elasticsearch/gitops/gitops.md | 99 ++++----- .../monitoring/using-builtin-prometheus.md | 73 ++++--- .../monitoring/using-prometheus-operator.md | 36 ++-- .../plugins-backup/overview/index.md | 4 +- .../plugins-backup/s3-repository/index.md | 85 ++++---- .../plugins/search-guard/configuration.md | 50 +++-- .../search-guard/disable-searchguard.md | 33 +-- .../plugins/search-guard/issue-certificate.md | 112 +++++++---- .../plugins/search-guard/use-tls.md | 45 +++-- .../plugins/search-guard/x-pack-monitoring.md | 76 ++++--- .../plugins/x-pack/configuration.md | 37 ++-- .../plugins/x-pack/disable-xpack.md | 24 ++- .../plugins/x-pack/issue-certificate.md | 91 +++++---- .../elasticsearch/plugins/x-pack/use-tls.md | 34 ++-- .../using-private-registry.md | 50 +++-- .../overview/elasticsearch/index.md | 79 ++++---- .../quickstart/overview/opensearch/index.md | 90 +++++---- .../reconfigure/elasticsearch-combined.md | 52 ++--- .../reconfigure/elasticsearch-topology.md | 76 +++---- .../reconfigure_tls/elasticsearch.md | 119 +++++------ docs/guides/elasticsearch/restart/index.md | 57 +++--- .../elasticsearch/rotateauth/rotateauth.md | 141 +++++++------ .../scaling/horizontal/combined.md | 66 +++--- .../scaling/horizontal/topology.md | 83 +++++--- .../scaling/vertical/combined.md | 35 ++-- .../scaling/vertical/topology.md | 56 +++--- .../tls/elasticsearch-combined.md | 32 +-- .../tls/elasticsearch-topology.md | 28 +-- .../update-version/elasticsearch.md | 39 ++-- .../volume-expansion/combined.md | 48 ++--- .../volume-expansion/topology.md | 72 ++++--- .../hanadb/clustering/system-replication.md | 40 ++-- .../hanadb/configuration/using-config-file.md | 36 ++-- .../monitoring/using-builtin-prometheus.md | 31 +-- .../monitoring/using-prometheus-operator.md | 23 ++- docs/guides/hanadb/quickstart/quickstart.md | 58 +++--- docs/guides/hanadb/reconfigure/reconfigure.md | 44 ++-- docs/guides/hanadb/restart/restart.md | 44 ++-- .../rotate-authentication.md | 70 ++++--- .../vertical-scaling/vertical-scaling.md | 36 ++-- .../storage-migration/storage-migration.md | 47 +++-- docs/guides/hanadb/tls/overview.md | 73 ++++--- .../volume-expansion/volume-expansion.md | 40 ++-- .../autoscaler/compute/hazelcast-compute.md | 52 +++-- .../autoscaler/storage/hazelcast-storage.md | 56 +++--- docs/guides/hazelcast/concepts/hazelcast.md | 4 +- .../configuration/hazelcast-config.md | 40 ++-- .../monitoring/prometheus-builtin.md | 73 ++++--- .../monitoring/prometheus-operator.md | 52 ++--- .../hazelcast/quickstart/overview/index.md | 78 ++++---- .../hazelcast/reconfigure-tls/hazelcast.md | 88 ++++---- docs/guides/hazelcast/restart/hazelcast.md | 14 +- .../guides/hazelcast/rotate-auth/hazelcast.md | 110 +++++----- .../horizontal-scaling/horizontal-scaling.md | 68 ++++--- .../vertical-scaling/vertical-scaling.md | 35 ++-- docs/guides/hazelcast/tls/hazelcast.md | 20 +- .../hazelcast/update-version/hazelcast.md | 40 ++-- .../volume-expansion/volume-expansion.md | 40 ++-- .../autoscaler/compute/compute-autoscale.md | 52 ++--- .../autoscaler/storage/storage-autoscale.md | 57 +++--- .../custom-configuration/using-config-file.md | 28 +-- .../custom-configuration/using-podtemplate.md | 116 ++++++----- .../ignite/custom-rbac/using-custom-rbac.md | 65 +++--- .../monitoring/using-builtin-prometheus.md | 73 ++++--- .../monitoring/using-prometheus-operator.md | 37 ++-- .../using-private-registry.md | 40 ++-- docs/guides/ignite/quickstart/quickstart.md | 64 +++--- .../ignite/reconfigure-tls/reconfigure-tls.md | 104 +++++----- docs/guides/ignite/reconfigure/reconfigure.md | 44 ++-- docs/guides/ignite/restart/restart.md | 24 ++- docs/guides/ignite/rotate-auth/rotateauth.md | 126 +++++++----- .../horizontal-scaling/horizontal-scaling.md | 60 +++--- .../vertical-scaling/vertical-scaling.md | 33 ++- .../ignite/update-version/update-version.md | 36 ++-- .../volume-expansion/volume-expansion.md | 44 ++-- .../kafka/autoscaler/compute/combined.md | 49 ++--- .../kafka/autoscaler/compute/topology.md | 91 +++++---- .../autoscaler/storage/kafka-combined.md | 55 ++--- .../autoscaler/storage/kafka-topology.md | 80 ++++---- docs/guides/kafka/cli/cli.md | 69 ++++--- .../clustering/combined-cluster/index.md | 62 +++--- .../clustering/topology-cluster/index.md | 54 +++-- docs/guides/kafka/concepts/connectcluster.md | 4 +- docs/guides/kafka/concepts/kafka.md | 4 +- .../kafka/configuration/kafka-combined.md | 40 ++-- .../kafka/configuration/kafka-topology.md | 42 ++-- .../kafka/connectcluster/connectcluster.md | 54 ++--- .../guides/kafka/connectcluster/quickstart.md | 69 ++++--- docs/guides/kafka/gitops/topology.md | 111 ++++++----- docs/guides/kafka/migration/migration.md | 101 ++++++---- docs/guides/kafka/monitoring/overview.md | 4 +- .../monitoring/using-builtin-prometheus.md | 40 ++-- .../monitoring/using-prometheus-operator.md | 44 ++-- docs/guides/kafka/quickstart/kafka/index.md | 55 ++--- docs/guides/kafka/reconfigure-tls/kafka.md | 108 +++++----- .../kafka/reconfigure/kafka-combined.md | 56 +++--- .../kafka/reconfigure/kafka-topology.md | 56 +++--- docs/guides/kafka/restart/restart.md | 24 ++- docs/guides/kafka/restproxy/overview.md | 69 ++++--- .../kafka/restproxy/with-schema-registry.md | 104 +++++----- docs/guides/kafka/rotate-auth/kafka.md | 103 ++++++---- .../scaling/horizontal-scaling/combined.md | 72 ++++--- .../scaling/horizontal-scaling/topology.md | 100 +++++----- .../scaling/vertical-scaling/combined.md | 32 +-- .../scaling/vertical-scaling/topology.md | 41 ++-- docs/guides/kafka/schemaregistry/overview.md | 62 +++--- .../kafka/tiered-storage/tiered-storage.md | 40 ++-- docs/guides/kafka/tls/combined.md | 30 ++- docs/guides/kafka/tls/connectcluster.md | 26 ++- docs/guides/kafka/tls/topology.md | 30 ++- .../kafka/update-version/update-version.md | 36 ++-- .../guides/kafka/volume-expansion/combined.md | 44 ++-- .../guides/kafka/volume-expansion/topology.md | 52 +++-- .../autoscaler/compute/cluster/index.md | 53 ++--- .../autoscaler/storage/cluster/index.md | 61 +++--- .../kubestash/application-level/index.md | 122 ++++++------ .../backup/kubestash/auto-backup/index.md | 89 +++++---- .../backup/kubestash/customization/index.md | 4 +- .../mariadb/backup/kubestash/logical/index.md | 125 ++++++------ .../backup/stash/logical/cluster/index.md | 125 ++++++------ .../backup/stash/logical/standalone/index.md | 125 ++++++------ .../clustering/galera-cluster/index.md | 50 +++-- .../clustering/mariadb-replication/index.md | 66 +++--- .../configuration/using-config-file/index.md | 41 ++-- .../configuration/using-pod-template/index.md | 29 +-- .../custom-rbac/using-custom-rbac/index.md | 69 ++++--- .../autoscaler/compute/cluster/index.md | 65 +++--- .../autoscaler/storage/cluster/index.md | 77 +++---- .../opsrequest/horizontal_scale.md | 81 ++++---- .../mariadb/distributed/overview/index.md | 140 ++++++++----- docs/guides/mariadb/failover/guide.md | 118 ++++++----- docs/guides/mariadb/gitops/gitops.md | 102 +++++----- .../guides/mariadb/initialization/git-sync.md | 26 ++- .../initialization/using-script/index.md | 30 +-- .../mariadb/migration/databaseMigration.md | 24 +-- .../monitoring/builtin-prometheus/index.md | 44 ++-- .../monitoring/prometheus-operator/index.md | 36 ++-- docs/guides/mariadb/pitr/nfs/index.md | 104 +++++----- docs/guides/mariadb/pitr/overview/index.md | 110 +++++----- .../private-registry/quickstart/index.md | 29 +-- .../mariadb/quickstart/overview/index.md | 9 +- .../mariadb/reconfigure-tls/cluster/index.md | 104 +++++----- .../mariadb/reconfigure/cluster/index.md | 93 +++++---- .../mariadb/reconfigure/standalone/index.md | 92 +++++---- docs/guides/mariadb/restart/restart.md | 26 +-- docs/guides/mariadb/rotate-auth/rotateauth.md | 136 +++++++------ .../horizontal-scaling/cluster/index.md | 83 ++++---- .../scaling/horizontal-scaling/maxscale.md | 67 ++++--- .../scaling/vertical-scaling/cluster/index.md | 35 ++-- .../scaling/vertical-scaling/maxscale.md | 41 ++-- docs/guides/mariadb/tls/configure/index.md | 74 ++++--- .../mariadb/update-version/cluster/index.md | 39 ++-- .../mariadb/volume-expansion/maxscale.md | 59 +++--- .../volume-expansion/index.md | 53 ++--- .../autoscaler/compute/compute-autoscale.md | 62 +++--- docs/guides/memcached/cli/cli.md | 54 ++--- .../custom-configuration/using-config-file.md | 32 +-- .../custom-configuration/using-podtemplate.md | 106 +++++----- .../custom-rbac/using-custom-rbac.md | 65 +++--- .../monitoring/using-builtin-prometheus.md | 73 ++++--- .../monitoring/using-prometheus-operator.md | 37 ++-- .../using-private-registry.md | 40 ++-- .../guides/memcached/quickstart/quickstart.md | 80 +++++--- .../reconfigure-tls/reconfigure-tls.md | 154 +++++++------- .../memcached/reconfigure/reconfigure.md | 74 ++++--- docs/guides/memcached/restart/restart.md | 24 ++- .../memcached/rotate-auth/rotateauth.md | 143 +++++++------ .../horizontal-scaling/horizontal-scaling.md | 43 ++-- .../vertical-scaling/vertical-scaling.md | 43 ++-- docs/guides/memcached/tls/tls.md | 48 +++-- .../update-version/update-version.md | 44 ++-- .../guides/milvus/autoscaler/compute/guide.md | 36 ++-- .../guides/milvus/autoscaler/storage/guide.md | 24 ++- .../monitoring/using-prometheus-operator.md | 27 ++- docs/guides/milvus/quickstart/distributed.md | 48 +++-- docs/guides/milvus/quickstart/standalone.md | 64 +++--- docs/guides/milvus/recommendation/guide.md | 30 +-- docs/guides/milvus/reconfigure-tls/guide.md | 119 +++++++---- docs/guides/milvus/reconfigure/guide.md | 63 +++--- docs/guides/milvus/restart/guide.md | 44 ++-- docs/guides/milvus/rotate-auth/guide.md | 61 ++++-- .../scaling/horizontal-scaling/guide.md | 36 ++-- .../milvus/scaling/vertical-scaling/guide.md | 52 +++-- docs/guides/milvus/storage-migration/guide.md | 56 ++++-- docs/guides/milvus/tls/configure/index.md | 71 ++++--- docs/guides/milvus/update-version/guide.md | 40 ++-- docs/guides/milvus/volume-expansion/guide.md | 58 ++++-- docs/guides/mongodb/arbiter/replicaset.md | 93 +++++---- docs/guides/mongodb/arbiter/sharding.md | 75 +++---- .../mongodb/autoscaler/compute/replicaset.md | 53 ++--- .../mongodb/autoscaler/compute/sharding.md | 55 ++--- .../mongodb/autoscaler/compute/standalone.md | 53 ++--- .../mongodb/autoscaler/storage/replicaset.md | 61 +++--- .../mongodb/autoscaler/storage/sharding.md | 61 +++--- .../mongodb/autoscaler/storage/standalone.md | 61 +++--- .../kubestash/application-level/index.md | 137 +++++++------ .../backup/kubestash/auto-backup/index.md | 30 +-- .../kubestash/logical/replicaset/index.md | 130 ++++++------ .../kubestash/logical/sharding/index.md | 130 ++++++------ .../kubestash/logical/standalone/index.md | 129 ++++++------ .../backup/stash/logical/replicaset/index.md | 159 ++++++++------- .../backup/stash/logical/sharding/index.md | 160 ++++++++------- .../backup/stash/logical/standalone/index.md | 115 ++++++----- docs/guides/mongodb/cli/cli.md | 57 +++--- docs/guides/mongodb/clustering/replicaset.md | 89 +++++---- docs/guides/mongodb/clustering/sharding.md | 76 +++---- docs/guides/mongodb/clustering/standalone.md | 59 +++--- docs/guides/mongodb/concepts/mongodb.md | 4 +- .../configuration/using-config-file.md | 29 +-- .../configuration/using-podtemplate.md | 25 ++- .../mongodb/custom-rbac/using-custom-rbac.md | 41 ++-- .../mongodb/external-connection/horizon.md | 64 +++--- .../failure-and-disaster-recovery/overview.md | 88 ++++---- docs/guides/mongodb/gitops/gitops.md | 96 ++++----- docs/guides/mongodb/hidden-node/replicaset.md | 67 ++++--- docs/guides/mongodb/hidden-node/sharding.md | 30 +-- docs/guides/mongodb/initialization/gitsync.md | 35 ++-- .../mongodb/initialization/using-script.md | 49 +++-- .../mongodb/migration/databaseMigration.md | 26 +-- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 36 ++-- docs/guides/mongodb/pitr/pitr.md | 54 ++--- .../using-private-registry.md | 25 +-- docs/guides/mongodb/quickstart/quickstart.md | 111 ++++++----- .../reconfigure-tls/reconfigure-tls.md | 120 +++++------ docs/guides/mongodb/reconfigure/replicaset.md | 64 +++--- docs/guides/mongodb/reconfigure/sharding.md | 87 ++++---- docs/guides/mongodb/reconfigure/standalone.md | 64 +++--- .../guides/mongodb/reprovision/reprovision.md | 25 +-- docs/guides/mongodb/restart/restart.md | 24 ++- docs/guides/mongodb/rotate-auth/rotateauth.md | 143 +++++++------ .../scaling/horizontal-scaling/replicaset.md | 80 ++++---- .../scaling/horizontal-scaling/sharding.md | 188 ++++++++++-------- .../scaling/vertical-scaling/replicaset.md | 33 ++- .../scaling/vertical-scaling/sharding.md | 48 +++-- .../scaling/vertical-scaling/standalone.md | 33 ++- .../deploy-mongodbdatabase/index.md | 53 ++--- .../initializing-with-script/index.md | 55 ++--- .../initializing-with-snapshot/index.md | 70 ++++--- docs/guides/mongodb/tls/replicaset.md | 28 +-- docs/guides/mongodb/tls/sharding.md | 28 +-- docs/guides/mongodb/tls/standalone.md | 28 +-- .../mongodb/update-version/replicaset.md | 36 ++-- .../guides/mongodb/update-version/sharding.md | 53 +++-- .../mongodb/update-version/standalone.md | 37 ++-- .../kmip-encryption/index.md | 91 ++++++--- .../mongodb/volume-expansion/replicaset.md | 44 ++-- .../mongodb/volume-expansion/sharding.md | 52 +++-- .../mongodb/volume-expansion/standalone.md | 44 ++-- .../mssqlserver/autoscaler/compute/cluster.md | 70 ++++--- .../mssqlserver/autoscaler/storage/cluster.md | 70 ++++--- .../backup/application-level/index.md | 146 +++++++------- .../mssqlserver/backup/auto-backup/index.md | 92 +++++---- .../mssqlserver/backup/customization/index.md | 4 +- .../mssqlserver/backup/logical/index.md | 140 +++++++------ .../mssqlserver/clustering/ag_cluster.md | 121 +++++------ docs/guides/mssqlserver/clustering/arbiter.md | 37 ++-- .../mssqlserver/clustering/dag_cluster.md | 30 +-- .../mssqlserver/clustering/standalone.md | 85 ++++---- .../mssqlserver/concepts/mssqlserver.md | 12 +- .../configuration/using-config-file.md | 50 +++-- .../configuration/using-podtemplate.md | 37 ++-- docs/guides/mssqlserver/failover/guide.md | 145 +++++++------- docs/guides/mssqlserver/gitops/gitops.md | 93 +++++---- .../mssqlserver/initialization/index.md | 38 ++-- .../monitoring/using-prometheus-operator.md | 50 ++--- docs/guides/mssqlserver/pitr/archiver.md | 109 +++++----- .../mssqlserver/quickstart/quickstart.md | 85 ++++---- .../mssqlserver/reconfigure-tls/ag_cluster.md | 112 ++++++----- .../mssqlserver/reconfigure-tls/standalone.md | 117 +++++------ .../mssqlserver/reconfigure/ag_cluster.md | 72 +++---- .../mssqlserver/reconfigure/standalone.md | 72 +++---- docs/guides/mssqlserver/restart/restart.md | 40 ++-- .../mssqlserver/rotate-auth/rotateauth.md | 152 ++++++++------ .../scaling/horizontal-scaling/mssqlserver.md | 76 +++---- .../scaling/vertical-scaling/ag_cluster.md | 60 +++--- .../scaling/vertical-scaling/standalone.md | 40 ++-- docs/guides/mssqlserver/tls/ag_cluster.md | 45 +++-- docs/guides/mssqlserver/tls/standalone.md | 44 ++-- .../mssqlserver/update-version/ag_cluster.md | 44 ++-- .../mssqlserver/update-version/standalone.md | 44 ++-- .../volume-expansion/ag_cluster.md | 60 +++--- .../volume-expansion/standalone.md | 64 +++--- .../mysql/autoscaler/compute/cluster/index.md | 53 ++--- .../mysql/autoscaler/storage/cluster/index.md | 61 +++--- .../kubestash/application-level/index.md | 140 +++++++------ .../backup/kubestash/auto-backup/index.md | 93 +++++---- .../mysql/backup/kubestash/logical/index.md | 140 +++++++------ .../mysql/backup/stash/standalone/index.md | 141 +++++++------ docs/guides/mysql/cli/index.md | 54 ++--- docs/guides/mysql/clients/index.md | 121 ++++++----- .../clustering/group-replication/index.md | 149 ++++++++------ .../mysql/clustering/innodb-cluster/index.md | 144 ++++++++------ .../mysql/clustering/remote-replica/index.md | 108 +++++----- .../mysql/clustering/semi-sync/index.md | 167 ++++++++++------ docs/guides/mysql/concepts/database/index.md | 4 +- .../mysql/configuration/config-file/index.md | 52 +++-- .../configuration/podtemplating/index.md | 40 ++-- docs/guides/mysql/custom-rbac/index.md | 38 ++-- .../failure-and-disaster-recovery/overview.md | 122 ++++++------ docs/guides/mysql/gitops/gitops.md | 107 +++++----- docs/guides/mysql/initialization/gitsync.md | 34 ++-- .../mysql/initialization/using_script.md | 85 +++++--- .../mysql/migration/databaseMigration.md | 24 +-- .../mysql/migration/storageMigration.md | 48 +++-- .../monitoring/builtin-prometheus/index.md | 44 ++-- .../monitoring/prometheus-operator/index.md | 36 ++-- docs/guides/mysql/pitr/restic/archiver.md | 115 ++++++----- .../mysql/pitr/volumesnapshot/archiver.md | 120 +++++------ docs/guides/mysql/private-registry/index.md | 21 +- docs/guides/mysql/quickstart/index.md | 132 ++++++------ .../reconfigure-tls/reconfigure/index.md | 138 +++++++------ .../reconfigure/reconfigure-steps/index.md | 89 +++++---- .../replication-mode-transform/index.md | 111 ++++++----- docs/guides/mysql/restart/restart.md | 25 +-- docs/guides/mysql/rotate-auth/guide.md | 162 ++++++++------- .../horizontal-scaling/cluster/index.md | 89 +++++---- .../scaling/vertical-scaling/cluster/index.md | 52 ++--- .../vertical-scaling/standalone/index.md | 45 +++-- .../deploy-mysqldatabase/index.md | 63 +++--- .../initializing-with-script/index.md | 56 +++--- docs/guides/mysql/tls/configure/index.md | 31 +-- .../majorversion/group-replication/index.md | 94 +++++---- .../majorversion/standalone/index.md | 68 ++++--- .../minorversion/group-replication/index.md | 97 +++++---- .../minorversion/standalone/index.md | 69 ++++--- .../volume-expansion/index.md | 65 +++--- .../backup/kubestash/customization/index.md | 4 +- .../neo4j/backup/kubestash/logical/index.md | 135 +++++++------ .../neo4j/clustering/architecture-overview.md | 22 +- docs/guides/neo4j/concepts/appbinding.md | 2 +- docs/guides/neo4j/concepts/catalog.md | 4 +- docs/guides/neo4j/concepts/neo4j.md | 6 +- .../neo4j/configuration/using-config-file.md | 32 +-- .../neo4j/custom-rbac/using-custom-rbac.md | 24 +-- .../neo4j/migration/storageMigration.md | 48 +++-- .../monitoring/using-builtin-prometheus.md | 76 ++++--- .../monitoring/using-prometheus-operator.md | 40 ++-- .../using-private-registry.md | 24 +-- docs/guides/neo4j/quickstart/quickstart.md | 60 +++--- .../neo4j/reconfigure-tls/reconfigure-tls.md | 124 ++++++++---- docs/guides/neo4j/reconfigure/reconfigure.md | 62 ++++-- docs/guides/neo4j/restart/restart.md | 22 +- docs/guides/neo4j/rotate-auth/rotateauth.md | 45 +++-- .../scale-horizontally/index.md | 117 +++++++---- .../scale-vertically/index.md | 36 ++-- docs/guides/neo4j/tls/configure/index.md | 52 +++-- docs/guides/oracle/concepts/oracle.md | 7 +- .../oracle/configuration/using-config-file.md | 25 +-- docs/guides/oracle/failover/overview.md | 43 ++-- .../oracle/initialization/script_source.md | 21 +- .../monitoring/using-prometheus-operator.md | 36 ++-- docs/guides/oracle/quickstart/index.md | 61 +++--- docs/guides/oracle/reconfigure/reconfigure.md | 33 +-- docs/guides/oracle/restart/restart.md | 52 ++--- .../rotate-authentication/rotateauth.md | 50 ++--- .../vertical-scaling/vertical-scaling.md | 28 +-- docs/guides/oracle/tls/configure/index.md | 49 ++--- .../volume-expansion/volume-expansion.md | 32 +-- .../autoscaler/compute/cluster/index.md | 53 ++--- .../autoscaler/storage/cluster/index.md | 61 +++--- .../clustering/galera-cluster/index.md | 68 ++++--- .../concepts/perconaxtradb/index.md | 5 +- .../configuration/using-config-file/index.md | 43 ++-- .../configuration/using-pod-template/index.md | 29 +-- .../custom-rbac/using-custom-rbac/index.md | 70 ++++--- .../percona-xtradb/failover/overview.md | 75 ++++--- .../initialization/script_source.md | 53 +++-- .../monitoring/builtin-prometheus/index.md | 44 ++-- .../monitoring/prometheus-operator/index.md | 44 ++-- .../private-registry/quickstart/index.md | 29 +-- .../quickstart/overview/index.md | 85 ++++---- .../reconfigure-tls/cluster/index.md | 104 +++++----- .../reconfigure/cluster/index.md | 93 +++++---- docs/guides/percona-xtradb/restart/index.md | 37 ++-- .../percona-xtradb/rotateauth/rotateauth.md | 140 +++++++------ .../horizontal-scaling/cluster/index.md | 83 ++++---- .../scaling/vertical-scaling/cluster/index.md | 35 ++-- .../percona-xtradb/tls/configure/index.md | 46 +++-- .../update-version/cluster/index.md | 39 ++-- .../volume-expansion/index.md | 53 ++--- .../autoscaler/compute/compute-autoscale.md | 52 ++--- docs/guides/pgbouncer/cli/cli.md | 59 +++--- .../pgbouncer/initialization/gitsync.md | 52 ++--- .../pgbouncer/initialization/script_source.md | 48 +++-- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 42 ++-- .../using-private-registry.md | 24 +-- .../guides/pgbouncer/quickstart/quickstart.md | 87 ++++---- .../reconfigure-tls/reconfigure-tls.md | 16 +- .../reconfigure/reconfigure-pgbouncer.md | 56 +++--- docs/guides/pgbouncer/restart/restart.md | 24 ++- .../guides/pgbouncer/rotateauth/rotateauth.md | 140 +++++++------ .../horizontal-scaling/horizontal-ops.md | 60 +++--- .../scaling/vertical-scaling/vertical-ops.md | 32 +-- .../sync-users/sync-users-pgbouncer.md | 46 +++-- docs/guides/pgbouncer/tls/configure_ssl.md | 51 +++-- .../update-version/update_version.md | 36 ++-- docs/guides/pgbouncer/virtual_secret/guide.md | 158 +++++++++------ .../autoscaler/compute/compute-autoscale.md | 52 ++--- docs/guides/pgpool/concepts/pgpool.md | 4 +- .../pgpool/configuration/using-config-file.md | 32 +-- .../pgpool/configuration/using-init-config.md | 24 ++- .../pgpool/configuration/using-podtemplate.md | 139 +++++++------ .../pgpool/custom-rbac/using-custom-rbac.md | 49 +++-- docs/guides/pgpool/initializing/git-sync.md | 50 ++--- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 42 ++-- docs/guides/pgpool/quickstart/quickstart.md | 132 +++++++----- .../pgpool/reconfigure-tls/reconfigure-tls.md | 123 ++++++------ .../pgpool/reconfigure/reconfigure-pgpool.md | 72 +++---- docs/guides/pgpool/restart/restart.md | 24 ++- docs/guides/pgpool/rotateauth/rotateauth.md | 113 ++++++----- .../horizontal-scaling/horizontal-ops.md | 60 +++--- .../scaling/vertical-scaling/vertical-ops.md | 32 +-- .../pgpool/sync-users/sync-users-pgpool.md | 46 +++-- docs/guides/pgpool/tls/configure_ssl.md | 51 +++-- .../pgpool/update-version/update_version.md | 36 ++-- docs/guides/pgpool/virtual_secret/guide.md | 159 +++++++++------ .../postgres/autoscaler/compute/cluster.md | 53 ++--- .../postgres/autoscaler/storage/cluster.md | 61 +++--- .../kubestash/application-level/index.md | 124 ++++++------ .../backup/kubestash/auto-backup/index.md | 91 +++++---- .../backup/kubestash/customization/index.md | 4 +- .../backup/kubestash/logical/index.md | 124 ++++++------ .../postgres/backup/stash/standalone/index.md | 47 +++-- docs/guides/postgres/cli/cli.md | 58 +++--- docs/guides/postgres/clustering/arbiter.md | 4 +- .../clustering/streaming_replication.md | 59 +++--- .../postgres/concepts/postgres-gitops.md | 8 +- docs/guides/postgres/concepts/postgres.md | 12 +- docs/guides/postgres/configuration/pgtune.md | 28 +-- .../configuration/using-config-file.md | 27 ++- .../postgres/custom-rbac/using-custom-rbac.md | 50 +++-- .../postgres/distributed/overview/index.md | 140 ++++++++----- docs/guides/postgres/gitops/gitops.md | 109 +++++----- .../postgres/initialization/script_source.md | 50 +++-- .../postgres/migration/databaseMigration.md | 24 +-- .../postgres/migration/storageMigration.md | 58 +++--- .../monitoring/using-builtin-prometheus.md | 73 ++++--- .../monitoring/using-prometheus-operator.md | 36 ++-- docs/guides/postgres/pitr/archiver.md | 105 +++++----- .../using-private-registry.md | 24 +-- docs/guides/postgres/quickstart/quickstart.md | 72 ++++--- docs/guides/postgres/quickstart/rbac.md | 8 +- .../reconfigure-tls/reconfigure-tls.md | 132 ++++++------ docs/guides/postgres/reconfigure/cluster.md | 77 +++---- .../postgres/remote-replica/remotereplica.md | 71 ++++--- docs/guides/postgres/restart/restart.md | 26 +-- .../rotate-authentication/rotateauth.md | 142 +++++++------ .../scale-horizontally/index.md | 70 +++---- .../scale-vertically/index.md | 50 +++-- docs/guides/postgres/synchronous/index.md | 18 +- docs/guides/postgres/tls/configure/index.md | 42 ++-- .../update-version/versionupgrading/index.md | 70 ++++--- docs/guides/postgres/virtual_secret/guide.md | 166 ++++++++++------ .../volume-expansion/ha-cluster/HA Cluster.md | 52 ++--- .../volume-expansion/standalone/standalone.md | 52 ++--- .../autoscaler/compute/cluster/index.md | 61 +++--- .../proxysql/backends/mariadb-galera/index.md | 36 ++-- .../proxysql/backends/mysqlgrp/index.md | 36 ++-- .../backends/xtradb-galera/external/index.md | 40 ++-- .../backends/xtradb-galera/kubedb/index.md | 36 ++-- .../clustering/proxysql-cluster/index.md | 105 +++++----- .../proxysql/concepts/proxysql/index.md | 8 +- docs/guides/proxysql/custom-rbac/index.md | 34 ++-- .../proxysql/initialization/script_source.md | 106 ++++++---- .../monitoring/builtin-prometheus/index.md | 48 ++--- .../monitoring/prometheus-operator/index.md | 40 ++-- .../proxysql/quickstart/mysqlgrp/index.md | 48 ++--- .../proxysql/quickstart/xtradbext/index.md | 40 ++-- .../proxysql/reconfigure-tls/cluster/index.md | 105 +++++----- .../proxysql/reconfigure/cluster/index.md | 101 +++++----- docs/guides/proxysql/restart/index.md | 31 +-- .../horizontal-scaling/cluster/index.md | 80 ++++---- .../scaling/vertical-scaling/cluster/index.md | 39 ++-- docs/guides/proxysql/tls/configure/index.md | 62 +++--- .../proxysql/update-version/cluster/index.md | 44 ++-- .../autoscaler/compute/compute-autoscale.md | 36 ++-- .../autoscaler/storage/storage-autoscale.md | 52 ++--- docs/guides/qdrant/backup/logical/index.md | 134 +++++++------ .../qdrant/backup/volume-snapshot/index.md | 119 ++++++----- docs/guides/qdrant/concepts/catalog.md | 4 +- docs/guides/qdrant/concepts/qdrant.md | 4 +- .../qdrant/configuration/using-config-file.md | 24 +-- .../qdrant/distributed-deployment/overview.md | 50 ++--- .../qdrant/migration/storageMigration.md | 79 +++++--- .../monitoring/using-prometheus-operator.md | 42 ++-- docs/guides/qdrant/quickstart/quickstart.md | 99 +++++---- .../qdrant/reconfigure-tls/reconfigure-tls.md | 70 +++---- docs/guides/qdrant/reconfigure/reconfigure.md | 58 +++--- docs/guides/qdrant/restart/restart.md | 36 ++-- docs/guides/qdrant/rotate-auth/rotate-auth.md | 54 ++--- .../horizontal-scaling/horizontal-scaling.md | 58 +++--- .../vertical-scaling/vertical-scaling.md | 36 ++-- docs/guides/qdrant/tls/configure-tls.md | 52 ++--- .../qdrant/update-version/update-version.md | 41 ++-- .../volume-expansion/volume-expansion.md | 54 ++--- .../autoscaler/compute/compute-autoscale.md | 52 ++--- .../autoscaler/storage/storage-autoscale.md | 61 +++--- docs/guides/rabbitmq/concepts/catalog.md | 2 +- docs/guides/rabbitmq/concepts/rabbitmq.md | 4 +- .../configuration/using-config-file.md | 32 +-- .../configuration/using-podtemplate.md | 108 +++++----- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 36 ++-- docs/guides/rabbitmq/quickstart/quickstart.md | 80 ++++---- .../reconfigure-tls/reconfigure-tls.md | 98 +++++---- .../rabbitmq/reconfigure/reconfigure.md | 54 ++--- docs/guides/rabbitmq/restart/restart.md | 24 ++- docs/guides/rabbitmq/rotate-auth/guide.md | 165 ++++++++------- .../horizontal-scaling/horizontal-scaling.md | 60 +++--- .../vertical-scaling/vertical-scaling.md | 33 ++- docs/guides/rabbitmq/tls/tls.md | 16 +- .../rabbitmq/update-version/update-version.md | 36 ++-- .../volume-expansion/volume-expansion.md | 44 ++-- docs/guides/redis/autoscaler/compute/redis.md | 63 +++--- .../redis/autoscaler/compute/sentinel.md | 62 +++--- docs/guides/redis/autoscaler/storage/redis.md | 69 ++++--- .../kubestash/application-level/index.md | 121 ++++++----- .../backup/kubestash/auto-backup/index.md | 89 +++++---- .../backup/kubestash/customization/index.md | 4 +- .../redis/backup/kubestash/logical/index.md | 132 ++++++------ .../redis/backup/stash/standalone/index.md | 51 +++-- docs/guides/redis/cli/cli.md | 53 ++--- docs/guides/redis/clustering/overview.md | 6 +- docs/guides/redis/clustering/redis-cluster.md | 78 +++++--- docs/guides/redis/concepts/redis.md | 4 +- docs/guides/redis/concepts/redissentinel.md | 4 +- docs/guides/redis/configuration/acl.md | 8 +- docs/guides/redis/configuration/redis.md | 53 +++-- docs/guides/redis/configuration/valkey.md | 52 +++-- .../redis/custom-rbac/using-custom-rbac.md | 77 ++++--- .../redis/external-connections/exposure.md | 58 +++--- .../external-connections/initialization.md | 24 +-- docs/guides/redis/gitops/gitops.md | 88 ++++---- docs/guides/redis/initialization/gitsync.md | 42 ++-- .../redis/initialization/using-script.md | 56 +++--- .../monitoring/using-builtin-prometheus.md | 73 ++++--- .../monitoring/using-prometheus-operator.md | 38 ++-- .../using-private-registry.md | 41 ++-- .../guides/redis/quickstart/overview/redis.md | 101 +++++----- .../redis/quickstart/overview/valkey.md | 78 ++++---- docs/guides/redis/reconfigure-tls/sentinel.md | 119 +++++------ .../redis/reconfigure-tls/standalone.md | 106 +++++----- docs/guides/redis/reconfigure/redis.md | 65 +++--- docs/guides/redis/reconfigure/valkey.md | 65 +++--- docs/guides/redis/restart/restart.md | 37 ++-- docs/guides/redis/rotateauth/rotateauth.md | 136 +++++++------ .../scaling/horizontal-scaling/cluster.md | 69 ++++--- .../horizontal-scaling/external-connection.md | 61 +++--- .../scaling/horizontal-scaling/sentinel.md | 86 ++++---- .../redis/scaling/vertical-scaling/cluster.md | 52 +++-- .../scaling/vertical-scaling/sentinel.md | 78 ++++---- .../scaling/vertical-scaling/standalone.md | 44 ++-- docs/guides/redis/sentinel/redis-sentinel.md | 112 ++++++----- .../replacesentinel/replace-sentinel.md | 68 ++++--- docs/guides/redis/tls/cluster.md | 36 ++-- docs/guides/redis/tls/sentinel.md | 59 +++--- docs/guides/redis/tls/standalone.md | 37 ++-- docs/guides/redis/update-version/cluster.md | 44 ++-- docs/guides/redis/update-version/sentinel.md | 86 ++++---- .../guides/redis/update-version/standalone.md | 44 ++-- docs/guides/redis/virtual_secret/guide.md | 149 +++++++++----- .../volume-expansion/volume-expansion.md | 64 +++--- .../singlestore/autoscaler/compute/cluster.md | 32 +-- .../singlestore/autoscaler/storage/cluster.md | 66 +++--- .../kubestash/application-level/index.md | 137 +++++++------ .../backup/kubestash/auto-backup/index.md | 97 ++++----- .../backup/kubestash/logical/index.md | 137 +++++++------ .../singlestore-clustering/index.md | 40 ++-- .../singlestore/concepts/singlestore.md | 4 +- .../configuration/config-file/index.md | 38 ++-- .../configuration/podtemplating/index.md | 111 ++++++----- .../initialization/using-script/index.md | 33 +-- .../monitoring/builtin-prometheus/index.md | 47 +++-- .../monitoring/prometheus-operator/index.md | 44 ++-- .../singlestore/quickstart/quickstart.md | 91 +++++---- .../reconfigure-tls/cluster/index.md | 109 +++++----- .../reconfigure/reconfigure-steps/index.md | 17 +- docs/guides/singlestore/restart/restart.md | 28 +-- .../horizontal-scaling/cluster/index.md | 88 ++++---- .../scaling/vertical-scaling/cluster/index.md | 41 ++-- .../guides/singlestore/tls/configure/index.md | 45 +++-- .../sdb update-version opsrequest/index.md | 51 +++-- .../sdb volume-expansion opsrequest/index.md | 70 ++++--- .../solr/autoscaler/compute/combined.md | 67 ++++--- .../solr/autoscaler/compute/topology.md | 66 +++--- .../solr/autoscaler/storage/combined.md | 71 ++++--- .../solr/autoscaler/storage/topology.md | 83 ++++---- .../solr/clustering/combined_cluster.md | 70 ++++--- .../solr/clustering/topology_cluster.md | 79 ++++---- docs/guides/solr/concepts/solr.md | 4 +- docs/guides/solr/configuration/config-file.md | 21 +- .../solr/configuration/custom-pod-template.md | 125 +++++++----- docs/guides/solr/failover/overview.md | 63 +++--- .../solr/monitoring/prometheus-builtin.md | 73 ++++--- .../solr/monitoring/prometheus-operator.md | 50 ++--- docs/guides/solr/quickstart/overview/index.md | 85 ++++---- docs/guides/solr/reconfigure-tls/solr.md | 112 +++++------ docs/guides/solr/reconfigure/solr.md | 57 +++--- docs/guides/solr/restart/restart.md | 24 +-- docs/guides/solr/rotateauth/rotateauth.md | 154 ++++++++------ .../scaling/horizontal-scaling/combined.md | 62 +++--- .../scaling/horizontal-scaling/topology.md | 113 ++++++----- .../solr/scaling/vertical-scaling/combined.md | 42 ++-- .../solr/scaling/vertical-scaling/topology.md | 51 ++--- docs/guides/solr/tls/combined.md | 25 ++- docs/guides/solr/tls/topology.md | 25 ++- .../solr/update-version/update-version.md | 29 ++- docs/guides/solr/volume-expansion/combined.md | 45 +++-- docs/guides/solr/volume-expansion/topology.md | 67 ++++--- .../autoscaler/compute/compute-autoscale.md | 40 ++-- .../autoscaler/storage/storage-autoscale.md | 42 ++-- docs/guides/weaviate/concepts/catalog.md | 4 +- .../configuration/using-config-file.md | 48 +++-- docs/guides/weaviate/quickstart/quickstart.md | 86 ++++---- .../reconfigure-tls/reconfigure-tls.md | 144 +++++++++----- .../weaviate/reconfigure/reconfigure.md | 40 ++-- docs/guides/weaviate/restart/restart.md | 36 ++-- .../weaviate/rotate-auth/rotate-auth.md | 66 +++--- .../horizontal-scaling/horizontal-scaling.md | 64 +++--- .../vertical-scaling/vertical-scaling.md | 48 +++-- .../storage-migration/storage-migration.md | 44 ++-- docs/guides/weaviate/tls/configure-tls.md | 100 ++++++---- .../volume-expansion/volume-expansion.md | 44 ++-- .../backup/kubestash/auto-backup/index.md | 89 +++++---- .../backup/kubestash/logical/index.md | 145 ++++++++------ docs/guides/zookeeper/concepts/zookeeper.md | 4 +- .../monitoring/using-builtin-prometheus.md | 44 ++-- .../monitoring/using-prometheus-operator.md | 36 ++-- .../guides/zookeeper/quickstart/quickstart.md | 85 ++++---- .../reconfigure-tls/reconfigure-tls.md | 108 +++++----- .../zookeeper/reconfigure/reconfigure.md | 64 +++--- docs/guides/zookeeper/restart/restart.md | 25 +-- .../horizontal-scaling/horizontal-scaling.md | 60 +++--- .../vertical-scaling/vertical-scaling.md | 33 ++- docs/guides/zookeeper/tls/configure-ssl.md | 24 +-- .../update-version/update-version.md | 36 ++-- .../volume-expansion/volume-expansion.md | 44 ++-- .../recommendation/configuration.md | 7 +- .../recommendation/recommendation-spec.md | 6 +- .../rotate-auth-recommendation.md | 18 +- .../rotate-tls-recommendation.md | 26 +-- .../version-update-recommendation.md | 36 ++-- docs/setup/install/kubedb/configuration.md | 13 +- docs/setup/install/kubedb/fluxcd.md | 13 +- docs/setup/install/kubedb/helm.md | 16 +- docs/setup/install/kubedb/openshift.md | 17 +- docs/setup/install/kubedb/yaml.md | 4 +- docs/setup/install/troubleshoting.md | 15 +- docs/setup/monitoring/builtin-prometheus.md | 32 +-- docs/setup/monitoring/overview.md | 4 +- docs/setup/monitoring/prometheus-operator.md | 32 +-- docs/setup/uninstall/kubedb.md | 6 +- 747 files changed, 24946 insertions(+), 20109 deletions(-) diff --git a/docs/guides/cassandra/autoscaler/compute/compute-autoscale.md b/docs/guides/cassandra/autoscaler/compute/compute-autoscale.md index f86dbdfe69..5afa01f1b5 100644 --- a/docs/guides/cassandra/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/cassandra/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscaling compute resources i. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/cassandra](/docs/examples/cassandra) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -78,22 +78,23 @@ spec: Let's create the `Cassandra` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/compute/cassandra-autoscale.yaml -cassandra.kubedb.com/cassandra-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/compute/cassandra-autoscale.yaml ``` +cassandra.kubedb.com/cassandra-autoscale created Now, wait until `cassandra-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo +kubectl get cas -n demo +``` NAME TYPE VERSION STATUS AGE cassandra-autoscale kubedb.com/v1alpha2 5.0.3 Ready 22s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -104,11 +105,11 @@ $ kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.cont "memory": "600Mi" } } -``` Let's check the Cassandra resources, ```bash -$ kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topology.rack[0].podTemplate.spec.containers[0].resources' +kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topology.rack[0].podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -119,7 +120,6 @@ $ kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topology "memory": "600Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the cassandra. @@ -173,20 +173,23 @@ Here, Let's create the `CassandraAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/compute/cassandra-autoscaler-ops.yaml -cassandraautoscaler.autoscaling.kubedb.com/cassandra-autoscaler-ops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/compute/cassandra-autoscaler-ops.yaml ``` +cassandraautoscaler.autoscaling.kubedb.com/cassandra-autoscaler-ops created #### Verify Autoscaling is set up successfully Let's check that the `cassandraautoscaler` resource is created successfully, ```bash -$ kubectl get cassandraautoscaler -n demo +kubectl get cassandraautoscaler -n demo +``` NAME AGE cassandra-autoscale-ops 6m55s -$ kubectl describe cassandraautoscaler cassandra-autoscale-ops -n demo +```bash +kubectl describe cassandraautoscaler cassandra-autoscale-ops -n demo +``` Name: cassandra-autoscale-ops Namespace: demo Labels: @@ -276,7 +279,6 @@ Status: Memory: 3Gi Vpa Name: cassandra-autoscale-rack-r0 Events: -``` So, the `Cassandraautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our Cassandra. Our autoscaler operator continuously watches the recommendation generated and creates an `cassandraopsrequest` based on the recommendations, if the cassandra pods are needed to scaled up or down. @@ -284,25 +286,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `cassandraopsrequest` in the demo namespace to see if any `cassandraopsrequest` object is created. After some time you'll see that a `cassandraopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get cassandraopsrequest -n demo +watch kubectl get cassandraopsrequest -n demo +``` Every 2.0s: kubectl get cassandraopsrequest -n demo NAME TYPE STATUS AGE casops-cassandra-autoscale-rack-r0-kefyuq VerticalScaling Progressing 1m28s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get cassandraopsrequest -n demo +watch kubectl get cassandraopsrequest -n demo +``` Every 2.0s: kubectl get cassandraopsrequest -n demo NAME TYPE STATUS AGE casops-cassandra-autoscale-rack-r0-kefyuq VerticalScaling Successful 3m34s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to scale the Cassandra. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-cassandra-autoscale-rack-r0-kefyuq +kubectl describe cassandraopsrequest -n demo casops-cassandra-autoscale-rack-r0-kefyuq +``` Name: casops-cassandra-autoscale-rack-r0-kefyuq Namespace: demo Labels: app.kubernetes.io/component=database @@ -410,12 +413,12 @@ Events: Normal RestartPods 89s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 89s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-autoscale Normal Successful 89s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-autoscale for CassandraOpsRequest: casops-cassandra-autoscale-rack-r0-kefyuq -``` Now, we are going to verify from the Pod, and the Cassandra yaml whether the resources of the Cassandra has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.containers[].resources' + kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1600m", @@ -427,7 +430,9 @@ $ kubectl get pod -n demo cassandra-autoscale-rack-r0-0 -o json | jq '.spec.con } } -$ kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topology.rack[0].podTemplate.spec.containers[0].resources' +```bash + kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topology.rack[0].podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -438,7 +443,6 @@ $ kubectl get cassandra -n demo cassandra-autoscale -o json | jq '.spec.topolog "memory": "600Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the cassandra. diff --git a/docs/guides/cassandra/autoscaler/storage/storage-autoscale.md b/docs/guides/cassandra/autoscaler/storage/storage-autoscale.md index 466d267c11..857c0c211f 100644 --- a/docs/guides/cassandra/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/cassandra/autoscaler/storage/storage-autoscale.md @@ -37,21 +37,21 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Cassa To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h2m longhorn (default) driver.longhorn.io Delete Immediate true 9m41s longhorn-static driver.longhorn.io Delete Immediate true 9m24s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -103,26 +103,28 @@ spec: Let's create the `Cassandra` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/storage/cassandra-autoscale.yaml -cassandra.kubedb.com/cassandra-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/storage/cassandra-autoscale.yaml ``` +cassandra.kubedb.com/cassandra-autoscale created Now, wait until `cassandra-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get cassandra -n demo +kubectl get cassandra -n demo +``` NAME TYPE VERSION STATUS AGE cassandra-autoscale kubedb.com/v1alpha2 5.0.3 Ready 16m -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo cassandra-autoscale-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +kubectl get petset -n demo cassandra-autoscale-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +``` "600Mi" - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-394fefad-d4ad-4dfa-ba11-df96e015da30 600Mi RWO Delete Bound demo/cassandra-autoscale-main-config-volume-cassandra-autoscale-rack-r0-1 longhorn 21m pvc-86ece3c8-520a-4d41-834e-66108867ca36 600Mi RWO Delete Bound demo/cassandra-autoscale-data-cassandra-autoscale-rack-r0-1 longhorn 21m @@ -130,7 +132,6 @@ pvc-c35bb138-9f13-4098-b2b0-cc151f013f6d 600Mi RWO Delete pvc-cc932132-de53-425f-bd31-91af255a47e8 600Mi RWO Delete Bound demo/cassandra-autoscale-data-cassandra-autoscale-rack-r0-0 longhorn 21m pvc-cd57fb5f-b2f3-48de-b9d2-03059b05113f 600Mi RWO Delete Bound demo/cassandra-autoscale-nodetool-cassandra-autoscale-rack-r0-1 longhorn 21m pvc-e550c573-60c7-4ec0-9e01-cf22683c502c 600Mi RWO Delete Bound demo/cassandra-autoscale-nodetool-cassandra-autoscale-rack-r0-0 longhorn 21m -``` You can see the petset has 600Mi storage, and the capacity of all the persistent volume is also 600Mi. @@ -172,20 +173,23 @@ Here, Let's create the `cassandraAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/storage/cassandra-autoscaler-ops.yaml -cassandraautoscaler.autoscaling.kubedb.com/cassandra-storage-autosclaer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/autoscaling/storage/cassandra-autoscaler-ops.yaml ``` +cassandraautoscaler.autoscaling.kubedb.com/cassandra-storage-autosclaer created #### Storage Autoscaling is set up successfully Let's check that the `cassandraautoscaler` resource is created successfully, ```bash -$ kubectl get cassandraautoscaler -n demo +kubectl get cassandraautoscaler -n demo +``` NAME AGE cassandra-storage-autoscaler 1m25s -$ kubectl describe cassandraautoscaler cassandra-storage-autoscaler -n demo +```bash +kubectl describe cassandraautoscaler cassandra-storage-autoscaler -n demo +``` Name: cassandra-storage-autoscaler Namespace: demo Labels: @@ -219,29 +223,29 @@ Spec: Trigger: On Usage Threshold: 2 Events: -``` So, the `cassandraautoscaler` resource is created successfully. Let's watch the `cassandraopsrequest` in the demo namespace to see if any `cassandraopsrequest` object is created. After some time you'll see that a `cassandraopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-cassandra-autoscale-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-cassandra-autoscale-9ah2rp VolumeExpansion Successful 10m -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$kubectl describe cassandraopsrequest -n demo casops-cassandra-autoscale-9ah2rp +kubectl describe cassandraopsrequest -n demo casops-cassandra-autoscale-9ah2rp +``` Name: casops-cassandra-autoscale-9ah2rp Namespace: demo Labels: app.kubernetes.io/component=database @@ -549,15 +553,17 @@ Events: Normal ReadyPetSets 63s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 63s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-autoscale Normal Successful 63s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-autoscale for CassandraOpsRequest: casops-cassandra-autoscale-9ah2rp -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo cassandra-autoscale-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +kubectl get petset -n demo cassandra-autoscale-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +``` "1203126272" -$ kubectl get pv -n demo +```bash + kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-394fefad-d4ad-4dfa-ba11-df96e015da30 600Mi RWO Delete Bound demo/cassandra-autoscale-main-config-volume-cassandra-autoscale-rack-r0-1 longhorn 45m pvc-86ece3c8-520a-4d41-834e-66108867ca36 1148Mi RWO Delete Bound demo/cassandra-autoscale-data-cassandra-autoscale-rack-r0-1 longhorn 45m @@ -566,8 +572,6 @@ pvc-cc932132-de53-425f-bd31-91af255a47e8 1148Mi RWO Delete pvc-cd57fb5f-b2f3-48de-b9d2-03059b05113f 600Mi RWO Delete Bound demo/cassandra-autoscale-nodetool-cassandra-autoscale-rack-r0-1 longhorn 45m pvc-e550c573-60c7-4ec0-9e01-cf22683c502c 600Mi RWO Delete Bound demo/cassandra-autoscale-nodetool-cassandra-autoscale-rack-r0-0 longhorn 45m -``` - The above output verifies that we have successfully autoscaled the volume related to data of the cassandra cluster. ## Cleaning Up diff --git a/docs/guides/cassandra/backup/kubestash/logical/index.md b/docs/guides/cassandra/backup/kubestash/logical/index.md index b1d763b28d..32614e508d 100644 --- a/docs/guides/cassandra/backup/kubestash/logical/index.md +++ b/docs/guides/cassandra/backup/kubestash/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/cassandra/backup/kubestash/logical/examples](https://github.com/kubedb/docs/tree/master/docs/guides/cassandra/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -108,33 +108,35 @@ Here, Create the above `Cassandra` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/cas-sample.yaml -cassandra.kubedb.com/cas-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/cas-sample.yaml ``` +cassandra.kubedb.com/cas-sample created KubeDB will deploy a Cassandra database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get cassandras.kubedb.com -n demo +kubectl get cassandras.kubedb.com -n demo +``` NAME TYPE VERSION STATUS AGE cas-sample kubedb.com/v1alpha2 5.0.3 Ready 3m6s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=cas-sample + kubectl get secret -n demo -l=app.kubernetes.io/instance=cas-sample +``` NAME TYPE DATA AGE cas-sample-auth kubernetes.io/basic-auth 2 3m33s cas-sample-config Opaque 1 3m33s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=cas-sample +```bash + kubectl get service -n demo -l=app.kubernetes.io/instance=cas-sample +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cas-sample ClusterIP 10.96.77.149 9042/TCP,7000/TCP,7199/TCP,7001/TCP 3m57s cas-sample-rack-r0-pods ClusterIP None 9042/TCP,7000/TCP,7199/TCP,7001/TCP 3m57s -``` Here, we have to use service `cas-sample` and secret `cas-sample-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/cassandra/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -143,15 +145,16 @@ Here, we have to use service `cas-sample` and secret `cas-sample-auth` to connec Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo + kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE cas-sample kubedb.com/cassandra 5.0.3 4m23s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo cas-sample -o yaml +kubectl get appbindings -n demo cas-sample -o yaml +``` apiVersion: appcatalog.appscode.com/v1alpha1 kind: AppBinding metadata: @@ -191,7 +194,6 @@ spec: name: cas-sample-auth type: kubedb.com/cassandra version: 5.0.7 -``` KubeStash uses the `AppBinding` CR to connect with the target database. It requires the following two fields to set in AppBinding's `.spec` section. @@ -204,25 +206,26 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, we are going to exec into the any pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=cas-sample" + kubectl get pods -n demo --selector="app.kubernetes.io/instance=cas-sample" +``` NAME READY STATUS RESTARTS AGE cas-sample-rack-r0-0 1/1 Running 0 5m28s cas-sample-rack-r0-1 1/1 Running 0 4m28s -``` And copy the username and password of the database to access into `cqlsh` shell. ```bash -$ kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.username}'| base64 -d + kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.username}'| base64 -d +``` admin⏎ kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.password}'| base64 -d gkebeP3HJbxubvCM⏎ -``` Now, Lets exec into any `Pod` to enter into `cqlsh` shell to create a keyspace and a table, ```bash -$ kubectl exec -it -n demo cas-sample-rack-r0-0 -- cqlsh -u admin -p gkebeP3HJbxubvCM +kubectl exec -it -n demo cas-sample-rack-r0-0 -- cqlsh -u admin -p gkebeP3HJbxubvCM +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -253,7 +256,6 @@ admin@cqlsh:kubedb> SELECT * FROM kubedb.users; (2 rows) admin@cqlsh:kubedb> exit ⏎ -``` Now, we are ready to backup the database. @@ -266,13 +268,11 @@ We are going to store our backed up data into a S3 bucket. We have to create a S Let's create a secret called `medusa-cred` with access credentials to our desired S3 bucket, ```bash -$ kubectl create secret generic -n demo medusa-cred \ + kubectl create secret generic -n demo medusa-cred \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/medusa-cred created - - ``` +secret/medusa-cred created **Create BackupStorage:** @@ -302,9 +302,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -335,9 +335,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -390,27 +390,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-cas-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-cas-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-cas-backup Ready 107s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-cassandra-repo 1 0 B Ready 2m15s 2m48s -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the S3 bucket, we will see the `Repository` YAML stored in the `demo/cassandra` directory. @@ -421,20 +421,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo + kubectl get cronjob -n demo +``` NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-cas-backup-frequent-backup */5 * * * * False 0 47s 2m39s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-cas-backup-frequent-backup-1753682588 BackupConfiguration sample-cas-backup Succeeded 2m2s 2m59s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -443,18 +443,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-cas-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-cassandra-repo + kubectl get repository -n demo s3-cassandra-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-cassandra-repo 1 0 B Ready 3m46s 4m19s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-cassandra-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-cassandra-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-cassandra-repo-sample-cas-backup-frequent-backup-1753682588 s3-cassandra-repo frequent-backup 2025-07-28T06:03:08Z Delete Succeeded 4m12s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -467,7 +467,7 @@ s3-cassandra-repo-sample-cas-backup-frequent-backup-1753682588 s3-cassandra-re If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-cassandra-repo-sample-cas-backup-frequent-backup-1753682588 -oyaml +kubectl get snapshots -n demo s3-cassandra-repo-sample-cas-backup-frequent-backup-1753682588 -oyaml ``` ```yaml @@ -583,17 +583,17 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-cassandra-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/cassandra/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-cassandra-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ kubectl get restoresession -n demo + kubectl get restoresession -n demo +``` NAME REPOSITORY PHASE DURATION AGE restore-sample-cassandra s3-cassandra-repo Running 100s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -605,34 +605,35 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get cassandra -n demo cas-sample +kubectl get cassandra -n demo cas-sample +``` NAME TYPE VERSION STATUS AGE cas-sample kubedb.com/v1alpha2 5.0.3 Ready 136m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=cas- +kubectl get pods -n demo --selector="app.kubernetes.io/instance=cas- +``` sample" NAME READY STATUS RESTARTS AGE cas-sample-rack-r0-0 1/1 Running 0 137m cas-sample-rack-r0-1 1/1 Running 0 136m -``` And then copy the user name and password of the `root` user to access into `cqlsh` shell. ```bash -$ kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.username}'| base64 -d + kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.username}'| base64 -d +``` admin⏎ kubectl get secret -n demo cas-sample-auth -o jsonpath='{.data.password}'| base64 -d gkebeP3HJbxubvCM⏎ -``` Now, Lets exec into any `Pod` to enter into `cqlsh` shell and access the previously created table, ```bash -$ kubectl exec -it -n demo cas-sample-rack-r0-0 -- cqlsh -u admin -p gkebeP3HJbxubvCM +kubectl exec -it -n demo cas-sample-rack-r0-0 -- cqlsh -u admin -p gkebeP3HJbxubvCM +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -650,8 +651,6 @@ admin@cqlsh> SELECT * FROM kubedb.users; (2 rows) -``` - So, from the above output, we can see that the `users` table we have created earlier in the original database and now, they are restored successfully. ## Cleanup diff --git a/docs/guides/cassandra/concepts/cassandra.md b/docs/guides/cassandra/concepts/cassandra.md index a09fbac089..5a25d9a306 100644 --- a/docs/guides/cassandra/concepts/cassandra.md +++ b/docs/guides/cassandra/concepts/cassandra.md @@ -128,11 +128,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic cassandra-auth -n demo \ +kubectl create secret generic cassandra-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "cassandra-auth" created ``` +secret "cassandra-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/cassandra/configuration/using-config-file.md b/docs/guides/cassandra/configuration/using-config-file.md index 3b0172cd2f..86bb0123cf 100644 --- a/docs/guides/cassandra/configuration/using-config-file.md +++ b/docs/guides/cassandra/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Cassandra. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,22 +46,23 @@ At first, you have to create a secret with your configuration file contents as t At first, create `cassandra.yaml` file containing required configuration settings. ```bash -$ cat cassandra.yaml +cat cassandra.yaml +``` read_request_timeout: 6000ms write_request_timeout: 2500ms -``` Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo cas-configuration --from-file=./cassandra.yaml -secret/cas-configuration created +kubectl create secret generic -n demo cas-configuration --from-file=./cassandra.yaml ``` +secret/cas-configuration created Verify the secret has the configuration file. ```bash -$ kubectl get secret -n demo cas-configuration -o yaml + kubectl get secret -n demo cas-configuration -o yaml +``` apiVersion: v1 data: cassandra.yaml: cmVhZF9yZXF1ZXN0X3RpbWVvdXQ6IDYwMDBtcwp3cml0ZV9yZXF1ZXN0X3RpbWVvdXQ6IDI1MDBtcwo= @@ -74,10 +75,11 @@ metadata: uid: 135c819c-fba6-4800-9ae0-fac35312fab2 type: Opaque -$ echo cmVhZF9yZXF1ZXN0X3RpbWVvdXQ6IDYwMDBtcwp3cml0ZV9yZXF1ZXN0X3RpbWVvdXQ6IDI1MDBtcwo= | base64 -d +```bash + echo cmVhZF9yZXF1ZXN0X3RpbWVvdXQ6IDYwMDBtcwp3cml0ZV9yZXF1ZXN0X3RpbWVvdXQ6IDI1MDBtcwo= | base64 -d +``` read_request_timeout: 6000ms write_request_timeout: 2500ms -``` Now, create cassandra crd specifying `spec.configuration.secretName` field. @@ -107,26 +109,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/configuration/cassandra-config-file.yaml -cassandra.kubedb.com/cas-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/configuration/cassandra-config-file.yaml ``` +cassandra.kubedb.com/cas-custom-config 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 `cas-custom-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo cas-custom-config-rack-r0-0 +kubectl get pod -n demo cas-custom-config-rack-r0-0 +``` NAME READY STATUS RESTARTS AGE cas-custom-config-rack-r0-0 1/1 Running 0 36s -``` Now, we will check if the cassandra has started with the custom configuration we have provided. Now, you can exec into the cassandra pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo cas-custom-config-rack-r0-0 -- bash +kubectl exec -it -n demo cas-custom-config-rack-r0-0 -- bash +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) [cassandra@cas-custom-config-rack-r0-0 /]$ cat /etc/cassandra/cassandra.yaml | grep request_timeout read_request_timeout: 6000ms @@ -137,7 +140,6 @@ truncate_request_timeout: 60000ms request_timeout: 10000ms [cassandra@cas-custom-config-rack-r0-0 /]$ exit exit -``` As we can see from the configuration of running cassandra, the value of `read_request_timeout` and `write_request_timeout` has been set to our desired value successfully. diff --git a/docs/guides/cassandra/monitoring/overview.md b/docs/guides/cassandra/monitoring/overview.md index ba91d2f79f..8ce857ceff 100644 --- a/docs/guides/cassandra/monitoring/overview.md +++ b/docs/guides/cassandra/monitoring/overview.md @@ -89,9 +89,9 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cas-with-monitoring.yaml -cassandra.kubedb.com/cassandra created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cas-with-monitoring.yaml ``` +cassandra.kubedb.com/cassandra created Here, we have specified that we are going to monitor this server using Prometheus operator through `spec.monitor.agent: prometheus.io/operator`. KubeDB will create a `ServiceMonitor` crd in databases namespace and this `ServiceMonitor` will have `release: prometheus` label. diff --git a/docs/guides/cassandra/monitoring/using-builtin-prometheus.md b/docs/guides/cassandra/monitoring/using-builtin-prometheus.md index 584f0ae2bf..c74e711285 100644 --- a/docs/guides/cassandra/monitoring/using-builtin-prometheus.md +++ b/docs/guides/cassandra/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Cassandra cluster using builtin [Prom - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -90,32 +92,33 @@ Here, Let's create the Cassandra crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cassandra-builtin-prom.yaml -cassandra.kubedb.com/cassandra-builtin-prom created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cassandra-builtin-prom.yaml ``` +cassandra.kubedb.com/cassandra-builtin-prom created Now, wait for the cluster to go into `Ready` state. ```bash -$ kubectl get cas -n demo +kubectl get cas -n demo +``` NAME TYPE VERSION STATUS AGE cassandra-builtin-prom kubedb.com/v1alpha2 5.0.3 Ready 2m45s -``` KubeDB will create a separate stats service with name `{Cassandra crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=cassandra-builtin-prom" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=cassandra-builtin-prom" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cassandra-builtin-prom ClusterIP 10.96.144.17 9042/TCP,7000/TCP,7199/TCP,7001/TCP 3m1s cassandra-builtin-prom-rack-r0-pods ClusterIP None 9042/TCP,7000/TCP,7199/TCP,7001/TCP 3m1s cassandra-builtin-prom-stats ClusterIP 10.96.195.225 56790/TCP 3m1s -``` Here, `cassandra-builtin-prom-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo cassandra-builtin-prom-stats + kubectl describe svc -n demo cassandra-builtin-prom-stats +``` Name: cassandra-builtin-prom-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -139,7 +142,6 @@ Endpoints: 10.244.0.29:8080,10.244.0.33:8080 Session Affinity: None Internal Traffic Policy: Cluster Events: -``` You can see that the service contains following annotations. @@ -304,20 +306,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -328,9 +330,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -339,18 +341,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-547c78fc57-mg6st 1/1 Running 0 48s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-547c78fc57-mg6st 9090 +kubectl port-forward -n monitoring prometheus-547c78fc57-mg6st 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `cassandra-builtin-prom-stats` service as one of the targets. diff --git a/docs/guides/cassandra/monitoring/using-prometheus-operator.md b/docs/guides/cassandra/monitoring/using-prometheus-operator.md index bedee2bb18..09904c0431 100644 --- a/docs/guides/cassandra/monitoring/using-prometheus-operator.md +++ b/docs/guides/cassandra/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. Alternatively, you can use `--create-namespace` flag while deploying prometheus. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,17 +47,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v3.4.2 1 1 True True 7h43m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -180,7 +183,6 @@ status: shards: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.serviceMonitor.labels` field of Cassandra crd. @@ -237,34 +239,35 @@ Here, Let's create the cassandra object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cas-with-monitoring.yaml -cassandras.kubedb.com/cassandra created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/monitoring/cas-with-monitoring.yaml ``` +cassandras.kubedb.com/cassandra created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get cas -n demo cassandra-prod + kubectl get cas -n demo cassandra-prod +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 17h -``` KubeDB will create a separate stats service with name `{Cassandra crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=cassandra-prod" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=cassandra-prod" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cassandra-prod ClusterIP 10.96.232.61 9042/TCP,7000/TCP,7199/TCP,7001/TCP 17h cassandra-prod-rack-r0-pods ClusterIP None 9042/TCP,7000/TCP,7199/TCP,7001/TCP 17h cassandra-prod-stats ClusterIP 10.96.189.65 56790/TCP 17h -``` Here, `cassandra-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo cassandra-prod-stats +kubectl describe svc -n demo cassandra-prod-stats +``` Name: cassandra-prod-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -285,22 +288,22 @@ Endpoints: 10.244.0.19:8080,10.244.0.18:8080 Session Affinity: None Internal Traffic Policy: Cluster Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `cassandra-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo + kubectl get servicemonitor -n demo +``` NAME AGE cassandra-prod-stats 17h -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Cassandra crd. ```bash -$ kubectl get servicemonitor -n demo cassandra-prod-stats -o yaml +kubectl get servicemonitor -n demo cassandra-prod-stats -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -339,7 +342,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: cassandras.kubedb.com kubedb.com/role: stats -``` Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in Cassandra crd. @@ -350,20 +352,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 2 (18m ago) 24h -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-kube-prometheus-prometheus` service which is pointing to the prometheus pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `cassandra-stats` service as one of the targets. diff --git a/docs/guides/cassandra/quickstart/guide/quickstart.md b/docs/guides/cassandra/quickstart/guide/quickstart.md index 01238da7cd..416150db61 100644 --- a/docs/guides/cassandra/quickstart/guide/quickstart.md +++ b/docs/guides/cassandra/quickstart/guide/quickstart.md @@ -29,13 +29,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/cassandra/quickstart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/cassandra/quickstart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,10 +46,10 @@ demo Active 9s We will have to provide `StorageClass` in Cassandra CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -56,11 +58,11 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named [CassandraVersion](/docs/guides/cassandra/concepts/cassandraversion.md). The installation process comes with a set of tested CassandraVersion objects. Let's check available CassandraVersions by, ```bash -$ kubectl get cassandraversion +kubectl get cassandraversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 4.1.8 4.1.8 ghcr.io/appscode-images/cassandra-management:4.1.8 3m50s 5.0.3 5.0.3 ghcr.io/appscode-images/cassandra-management:5.0.3 3m50s -``` In this tutorial, we will use `5.0.7` CassandraVersion CR to create a Cassandra cluster. @@ -100,26 +102,27 @@ Here, Let's create the Cassandra CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/quickstart/cassandra-quickstart.yaml -cassandra.kubedb.com/cassandra-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/quickstart/cassandra-quickstart.yaml ``` +cassandra.kubedb.com/cassandra-quickstart created The Cassandra's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the newly provisioned Cassandra cluster. ```bash -$ kubectl get cassandra -n demo -w +kubectl get cassandra -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Provisioning 17s cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Provisioning 28s . . cassandra-quickstart kubedb.com/v1alpha2 5.0.3 Ready 82s -``` Describe the Cassandra object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe cassandra -n demo cassandra-quickstart +kubectl describe cassandra -n demo cassandra-quickstart +``` Name: cassandra-quickstart Namespace: demo Labels: @@ -225,14 +228,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a Cassandra CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=cassandra-quickstart' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=cassandra-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/cassandra-quickstart-rack-r0-0 1/1 Running 0 108m pod/cassandra-quickstart-rack-r0-1 1/1 Running 0 103m @@ -250,7 +253,6 @@ secret/cassandra-quickstart-config Opaque 1 108m NAME AGE petset.apps.k8s.appscode.com/cassandra-quickstart-rack-r0 108m -``` - `PetSet` - In topology mode, the operator creates 1 PetSet for each rack with name `{Cassandra-Name}-rack-{Rack-Name}`. - `Services` - For topology mode, 1 headless service for each PetSet with name `{PetSet-Name}-{pods}` is created. Other than that, 1 more service with name `{Cassandra-Name}-{Sufix}` is created. @@ -263,12 +265,14 @@ petset.apps.k8s.appscode.com/cassandra-quickstart-rack-r0 108m Now, you can connect to this database using `cqlsh`. You will need `username` and `password` to connect to this database from `kubeclt exec` command. In this example, `cassandra-quickstart-auth` secret holds username and password. ```bash -$ kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\username}' | base64 -d +``` admin -$ kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\password}' | base64 -d -9sPN85ctoRTnWEQV +```bash +kubectl get secrets -n demo cassandra-quickstart-auth -o jsonpath='{.data.\password}' | base64 -d ``` +9sPN85ctoRTnWEQV We will exec into the pod `cassandra-quickstart-rack-r0-0` and connect to the database using `username` and `password`. ```bash @@ -293,15 +297,19 @@ system system_distributed system_traces system_virtual_schema To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo cassandra cassandra-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo cassandra cassandra-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` cassandra.kubedb.com/cassandra-quickstart patched -$ kubectl delete cas cassandra-quickstart -n demo +```bash +kubectl delete cas cassandra-quickstart -n demo +``` cassandra.kubedb.com "cassandra-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/cassandra/reconfigure-tls/cassandra.md b/docs/guides/cassandra/reconfigure-tls/cassandra.md index 6f451c40cd..500e5d72db 100644 --- a/docs/guides/cassandra/reconfigure-tls/cassandra.md +++ b/docs/guides/cassandra/reconfigure-tls/cassandra.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -77,14 +77,15 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 54s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 84s @@ -92,12 +93,11 @@ cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 84s . cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 2m8s -``` - Now, we can try to access cqlsh of one cassandra pod without providing ssl flag and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -107,7 +107,6 @@ Connected to Test Cluster at 127.0.0.1:9042 [cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5] Use HELP for help. admin@cqlsh> -``` We can verify from the above output that TLS is disabled for this cluster. @@ -118,20 +117,20 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=cassandra/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=cassandra/O=kubedb" +``` .....+................+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+...+...+......+......+........+......+....+..+.......+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...............+.............+..+.+.....+...+.......+.....+....+...+........+....+.........+.....+.+.....+....+...........+.+..+...+...+.+...+...........+....+...+..............+..........+.....+...+..........+......+.........+...+..+...........................+.........+....+...........+....+.....+..................+...+.+...+.....+.+..+....+........+.............+...+..+....+...........+.......+......+...........+.+..+.......+........+...+............+.+.....+.+.....+.........+......+.+........+.+.....+.+....................+...+.......+...+......+...........+..........+............+.....+.+.....+.+.....+.+.........+........+...+....+.....+.........+.........+...+.......+.....+.......+........+.......+.....................+.....+....+...+...+...............+.....+...+....+..+...............+....+..+..........+.....+.......+...+.........+.........+..+...+.+...+..+.+.....+...+...........................+....+.....+...+......+.+...+...+............+..+...................+............+..+......+.+.....+......+.......+........+....+........+......+.+...........+...+.+...+............+......+..+..........+..+.+..+............+....+.........+..+.+............+.....+.......+...+...........+.+........................+......+...+.....+...+.......+..+................+.........+...+......+......+...........+.............+..............+.+...........+.+..+.......+.....+.........+......+...+.......+...+...........+....+.....+...+...+......+.+..+......+.......+..+.......+...+........+.......+..+....+.........+......+..+....+...+...........+..........+...........+.+...............+...............+..+......+...................+..+...+.......+...+.....+...+...+.......+...+......+...+.....+.......+.....+...............+.........+......+.........+....+..+...+.+..+.........+...+...+.............+..+...+..........+.....+..........+.........+..+.+.....+....+.........+..+...+....+......+..+.........+......+.......+...+...+..+.......+..+.........+.+.....+......+...+......+..........+.....+...............+..................+.+............+........+....+...+........+.+.....+.........+....+........+...+....+...+..............+.+...+......+...+......+............+.........+...+..+.+..+......+......+......+...+.+..............+.+...+...+........+....+.....+............+...+.+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ........+....+.........+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+....+......+......+..+......+.+........+......+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.....+..................+...+....+...........+...+...................+......+...............+...........+....+......+........+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -``` - Now we are going to create a ca-secret using the certificate files that we have just generated. ```bash -$ kubectl create secret tls cassandra-ca \ +kubectl create secret tls cassandra-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/cassandra-ca created ``` +secret/cassandra-ca created Now, Let's create an `Issuer` using the `cassandra-ca` secret that we have just created. The `YAML` file looks like this: @@ -149,9 +148,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-issuer.yaml -issuer.cert-manager.io/cas-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-issuer.yaml ``` +issuer.cert-manager.io/cas-issuer created ### Create CassandraOpsRequest @@ -193,24 +192,25 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-add-tls.yaml -cassandraopsrequest.ops.kubedb.com/casops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-add-tls.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-add-tls ReconfigureTLS Successful 3m34s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-add-tls + kubectl describe cassandraopsrequest -n demo casops-add-tls +``` Name: casops-add-tls Namespace: demo Labels: @@ -347,12 +347,12 @@ Events: Normal RestartNodes 43s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 43s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 43s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-add-tls -``` Now, Let's try to access cqlsh of a cassandra pod without and with ssl flag and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -361,7 +361,9 @@ Recommendation: use the credentials file to securely provide the password. Connection error: ('Unable to connect to any servers', {'127.0.0.1:9042': ConnectionShutdown('Connection to 127.0.0.1:9042 was closed')}) command terminated with exit code 1 -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 --ssl +```bash +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 --ssl +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -371,7 +373,6 @@ Connected to Test Cluster at 127.0.0.1:9042 [cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5] Use HELP for help. admin@cqlsh> exit -``` We can see from the above output that, cqlsh is only accessable by using ssl flag which means that TLS is enabled. @@ -380,13 +381,13 @@ We can see from the above output that, cqlsh is only accessable by using ssl fla Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep -E 'Valid from|Alias name' +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep -E 'Valid from|Alias name' +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Alias name: ca Valid from: Tue Jul 29 10:40:48 GMT 2025 until: Wed Jul 29 10:40:48 GMT 2026 Alias name: certificate Valid from: Tue Jul 29 10:45:45 GMT 2025 until: Mon Oct 27 10:45:45 GMT 2025 -``` So, the certificate will expire on this time `Wed Jul 29 10:40:48 GMT 2026`. @@ -417,25 +418,25 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/casops-rotate.yaml -cassandraopsrequest.ops.kubedb.com/casops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/casops-rotate.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-rotate ReconfigureTLS Successful 3m22s -``` - We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$kubectl describe cassandraopsrequest -n demo casops-rotate +kubectl describe cassandraopsrequest -n demo casops-rotate +``` Name: casops-rotate Namespace: demo Labels: @@ -561,19 +562,17 @@ Events: Normal RestartNodes 36s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 36s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 36s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep -E 'Valid from|Alias name' - +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep -E 'Valid from|Alias name' +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Alias name: ca Valid from: Tue Jul 29 10:40:48 GMT 2025 until: Wed Jul 29 10:40:48 GMT 2026 Alias name: certificate Valid from: Tue Jul 29 11:09:11 GMT 2025 until: Mon Oct 27 11:09:11 GMT 2025 -``` As we can see from the above output, the certificate has been rotated successfully. @@ -584,21 +583,21 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=cassandra-updated/O=kubedb-updated" + openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=cassandra-updated/O=kubedb-updated" +``` ....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.......+.....+..........+...+...+..+...+....+............+...........+....+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+..........+..+.......+...+.....+......+.......+...+..+....+.....+.............+..+.+.....+.......+..+.+...+....................+.........+...+..........+.......................+.....................+.+........+....+..+...+.......+.........+..+...+.+......+..+.............+........+......+......+.......+...........+.+.....+................+...+......+........+.......+...+........+...+....+.....+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .....+.....+....+.....+...+....+........+.+..+.......+........+...+.......+........+......+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+........+.........+....+......+...+..+....+..+....+........+............+.+...+............+.........+.....+...+...+.........+.+...+..+.......+........+......................+.....+..........+...+..+......+.+.........+......+....................+.+...+.....+......+.+..............+...+.+..+....+.........+......+......+........+......+....+..+....+......+..+............+.+.................+...+....+...+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ----- -``` - Now we are going to create a new ca-secret using the certificate files that we have just generated. ```bash -$ kubectl create secret tls cassandra-new-ca \ +kubectl create secret tls cassandra-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/cassandra-new-ca created ``` +secret/cassandra-new-ca created Now, Let's create a new `Issuer` using the `cassandra-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -616,9 +615,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-new-issuer.yaml -issuer.cert-manager.io/cas-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-new-issuer.yaml ``` +issuer.cert-manager.io/cas-new-issuer created ### Create CassandraOpsRequest @@ -650,24 +649,25 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-update-tls-issuer.yaml -cassandrapsrequest.ops.kubedb.com/casops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/cassandra-update-tls-issuer.yaml ``` +cassandrapsrequest.ops.kubedb.com/casops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequests -n demo casops-update-issuer +kubectl get cassandraopsrequests -n demo casops-update-issuer +``` NAME TYPE STATUS AGE casops-update-issuer ReconfigureTLS Successful 3m44s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-update-issuer + kubectl describe cassandraopsrequest -n demo casops-update-issuer +``` Name: casops-update-issuer Namespace: demo Labels: @@ -796,16 +796,15 @@ Events: Normal RestartNodes 58s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 58s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 58s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-update-issuer -``` Now, Let's exec into a cassandra node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep 'Issuer' +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- keytool -list -v -keystore /opt/cassandra/ssl/keystore.jks -storepass 'Yd33L.bUW(EdUCaV' | grep 'Issuer' +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Issuer: O=kubedb-updated, CN=cassandra-updated Issuer: O=kubedb-updated, CN=cassandra-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. @@ -840,24 +839,25 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/casops-remove.yaml -cassandraopsrequest.ops.kubedb.com/casops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure-tls/casops-remove.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-remove created #### Verify TLS Removed Successfully Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequest -n demo casops-remove + kubectl get cassandraopsrequest -n demo casops-remove +``` NAME TYPE STATUS AGE casops-remove ReconfigureTLS Successful 4m12s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-remove + kubectl describe cassandraopsrequest -n demo casops-remove +``` Name: casops-remove Namespace: demo Labels: @@ -948,12 +948,12 @@ Events: Normal RestartNodes 3m37s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 3m37s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 3m37s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-remove -``` Now, Let's try to access cqlsh of one cassandra pod without providing ssl flag and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 + kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- cqlsh -u admin -p MkyikyIvjFEzzgB6 +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -964,8 +964,6 @@ Connected to Test Cluster at 127.0.0.1:9042 Use HELP for help. admin@cqlsh> -``` - So, we can see from the above that, output that tls is disabled successfully. ## Cleaning up diff --git a/docs/guides/cassandra/reconfigure/cassandra-topology.md b/docs/guides/cassandra/reconfigure/cassandra-topology.md index b869073b8f..4ed9d09646 100644 --- a/docs/guides/cassandra/reconfigure/cassandra-topology.md +++ b/docs/guides/cassandra/reconfigure/cassandra-topology.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/cassandra](/docs/examples/cassandra) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -70,9 +70,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-topology-custom-config-secret.yaml -secret/cas-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-topology-custom-config-secret.yaml ``` +secret/cas-topology-custom-config created In this section, we are going to create a Cassandra object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Cassandra` CR that we are going to create, @@ -115,27 +115,28 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-topology.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-topology.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 48s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 81s . . cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 105s -``` Now, we will check if the cassandra has started with the custom configuration we have provided. Exec into the Cassandra pod and execute the following commands to see the configurations: ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) [cassandra@cassandra-prod-rack-r0-0 /]$ cat /etc/cassandra/cassandra.yaml | grep request_timeout read_request_timeout: 6000ms @@ -144,7 +145,6 @@ write_request_timeout: 2500ms counter_write_request_timeout: 5000ms truncate_request_timeout: 60000ms request_timeout: 10000ms -``` Here, we can see that our given configuration is applied to the Cassandra cluster . `read_request_timeout` is set to `6000ms` from the default value `5000ms`. ### Reconfigure using new config secret @@ -164,21 +164,21 @@ Then, we will create a new secret with this configuration file. At first, create `cassandra.yaml` file containing required configuration settings. ```bash -$ cat cassandra.yaml -read_request_timeout: 6500ms +cat cassandra.yaml ``` +read_request_timeout: 6500ms Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-cas-topology-custom-config --from-file=./cassandra.yaml -secret/new-cas-topology-custom-config created +kubectl create secret generic -n demo new-cas-topology-custom-config --from-file=./cassandra.yaml ``` +secret/new-cas-topology-custom-config created ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/new-cassandra-topology-custom-config-secret.yaml -secret/new-cas-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/new-cassandra-topology-custom-config-secret.yaml ``` +secret/new-cas-topology-custom-config created #### Create CassandraOpsRequest @@ -210,9 +210,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-reconfigure-update-topology-ops.yaml -cassandraopsrequest.ops.kubedb.com/casops-reconfigure-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-reconfigure-update-topology-ops.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-reconfigure-topology created #### Verify the new configuration is working @@ -221,15 +221,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ kubectl get cassandraopsrequests -n demo +kubectl get cassandraopsrequests -n demo +``` NAME TYPE STATUS AGE casops-reconfigure-topology Reconfigure Successful 2m53s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-reconfigure-topology + kubectl describe cassandraopsrequest -n demo casops-reconfigure-topology +``` Name: casops-reconfigure-topology Namespace: demo Labels: @@ -322,12 +323,12 @@ Events: Normal RestartNodes 25s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 25s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 25s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-reconfigure-topology -``` Now let's exec one of the instance to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) [cassandra@cassandra-prod-rack-r0-0 /]$ cat /etc/cassandra/cassandra.yaml | grep request_timeout read_request_timeout: 6500ms @@ -336,7 +337,6 @@ write_request_timeout: 2500ms counter_write_request_timeout: 5000ms truncate_request_timeout: 60000ms request_timeout: 10000ms -``` As we can see from the configuration of ready cassandra, the value of `read_request_timeout` has been changed from `6000ms` to `6500ms`. So the reconfiguration of the cluster is successful. @@ -376,9 +376,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-reconfigure-apply-topology.yaml -cassandraopsrequest.ops.kubedb.com/casops-reconfigure-apply-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/reconfigure/cassandra-reconfigure-apply-topology.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-reconfigure-apply-topology created #### Verify the new configuration is working @@ -387,17 +387,18 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ kubectl get cassandraopsrequests -n demo casops-reconfigure-apply-topology +kubectl get cassandraopsrequests -n demo casops-reconfigure-apply-topology +``` NAME TYPE STATUS AGE casops-reconfigure-apply-topology Reconfigure Successful 55s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to reconfigure the cluster. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-reconfigure-apply-topology +kubectl describe cassandraopsrequest -n demo casops-reconfigure-apply-topology +``` Name: casops-reconfigure-apply-topology Namespace: demo Labels: @@ -496,12 +497,12 @@ Events: Normal RestartNodes 37s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 37s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 37s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-reconfigure-apply-topology -``` Now let's exec into one of the instance to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +kubectl exec -it -n demo cassandra-prod-rack-r0-0 -- bash +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) [cassandra@cassandra-prod-rack-r0-0 /]$ cat /etc/cassandra/cassandra.yaml | grep request_timeout read_request_timeout: 5500ms @@ -517,8 +518,6 @@ As we can see from the configuration of ready cassandra, the value of `read_requ ## Cleaning Up To clean up the Kubernetes resources created by this tutorial, run: - -```bash kubectl delete cas -n demo cassandra-prod kubectl delete cassandraopsrequest -n demo casops-reconfigure-apply-topology casops-reconfigure-topology kubectl delete secret -n demo cas-topology-custom-config new-cas-topology-custom-config diff --git a/docs/guides/cassandra/restart/restart.md b/docs/guides/cassandra/restart/restart.md index 08502de88a..67e85f4ac6 100644 --- a/docs/guides/cassandra/restart/restart.md +++ b/docs/guides/cassandra/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Cassandra database via a CassandraOpsRequest. Res - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,9 +60,9 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/restart/cassandra.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/restart/cassandra.yaml ``` +cassandra.kubedb.com/cassandra-prod created ## Apply Restart opsRequest @@ -89,18 +89,21 @@ spec: Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/restart/ops.yaml -cassandraopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/restart/ops.yaml ``` +cassandraopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the controller pods, then broker of the referenced cassandra. -```shell -$ kubectl get casops -n demo +```bash +kubectl get casops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 119s -$ kubectl get casops -n demo restart -oyaml +```bash +kubectl get casops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: CassandraOpsRequest metadata: @@ -201,7 +204,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/cassandra/rotate-auth/cassandra.md b/docs/guides/cassandra/rotate-auth/cassandra.md index 8c12bc44eb..6e99e0deb9 100644 --- a/docs/guides/cassandra/rotate-auth/cassandra.md +++ b/docs/guides/cassandra/rotate-auth/cassandra.md @@ -29,9 +29,9 @@ This tutorial will show you how to use KubeDB to rotate authentication credentia - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -75,34 +75,38 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-prod.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-prod.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1 5.0.3 Provisioning 3s cassandra-prod kubedb.com/v1 5.0.3 Provisioning 10s . . cassandra-prod kubedb.com/v1 5.0.3 Ready 2m13s -``` We can verify from the above output that authentication is enabled for this cluster. By default, KubeDB operator create default credentials for the Cassandra cluster. The default credentials are stored in a secret named `-auth` in the same namespace as the Cassandra cluster. You can find the secret by running the following command: ```bash -$ kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +``` "cassandra-prod-auth" -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.password}' | base64 -d -UajtzLlDwiizuHoV +```bash +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.password}' | base64 -d ``` +UajtzLlDwiizuHoV ### Create RotateAuth CassandraOpsRequest @@ -132,22 +136,23 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-rotate-auth-generated.yaml -cassandraopsrequest.ops.kubedb.com/casops-rotate-auth-generated created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-rotate-auth-generated.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-rotate-auth-generated created Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-rotate-auth-generated RotateAuth Successful 3m18s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-rotate-auth-generated +kubectl describe cassandraopsrequest -n demo casops-rotate-auth-generated +``` Name: casops-rotate-auth-generated Namespace: demo Labels: @@ -243,31 +248,37 @@ Events: Normal RestartNodes 3m13s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 3m13s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 3m13s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-rotate-auth-generated -``` #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +``` "cassandra-prod-auth" -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.password}' | base64 -d -t0jL7;5CFWhqn~3o +```bash +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath='{.data.password}' | base64 -d ``` +t0jL7;5CFWhqn~3o Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +``` admin -$ kubectl get secret -n demo cassandra-prod-auth -o=jsonpath="{.data.password\.prev}" | base64 -d -UajtzLlDwiizuHoV + +```bash +kubectl get secret -n demo cassandra-prod-auth -o=jsonpath="{.data.password\.prev}" | base64 -d ``` +UajtzLlDwiizuHoV The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. @@ -276,12 +287,12 @@ The above output shows that the password has been changed successfully. The prev At first, we need to create a secret with `kubernetes.io/basic-auth` type using custom `username` and `password`. Below is the command to create a secret with `kubernetes.io/basic-auth` type, ```bash -$ kubectl create secret generic cassandra-user-auth -n demo \ +kubectl create secret generic cassandra-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=cassandra \ --from-literal=password=cassandra-secret -secret/cassandra-user-auth created ``` +secret/cassandra-user-auth created Now create a Cassandra Ops Request with `RotateAuth` type. Below is the YAML of the `CassandraOpsRequest` that we are going to create, @@ -312,23 +323,24 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-rotate-auth-user.yaml -cassandraopsrequest.ops.kubedb.com/casops-rotate-auth-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/rotate-auth/cassandra-rotate-auth-user.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-rotate-auth-user created Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CRO, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE casops-rotate-auth-generated RotateAuth Successful 53m casops-rotate-auth-user RotateAuth Successful 2m58s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe cassandraopsrequest -n demo casops-rotate-auth-user +kubectl describe cassandraopsrequest -n demo casops-rotate-auth-user +``` Name: casops-rotate-auth-user Namespace: demo Labels: @@ -495,31 +507,37 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +kubectl get cas -n demo cassandra-prod -ojson | jq .spec.authSecret.name +``` "cassandra-user-auth" -$ kubectl get secret -n demo cassandra-user-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo cassandra-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` cassandra -$ kubectl get secret -n demo cassandra-user-auth -o=jsonpath='{.data.password}' | base64 -d -cassandra-secret +```bash +kubectl get secret -n demo cassandra-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +cassandra-secret Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo cassandra-user-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +kubectl get secret -n demo cassandra-user-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +``` admin -$ kubectl get secret -n demo cassandra-user-auth -o=jsonpath="{.data.password\.prev}" | base64 -d -rM4OJfqoTzvKMAx8 + +```bash +kubectl get secret -n demo cassandra-user-auth -o=jsonpath="{.data.password\.prev}" | base64 -d ``` +rM4OJfqoTzvKMAx8 The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. diff --git a/docs/guides/cassandra/scaling/horizontal-scaling/topology.md b/docs/guides/cassandra/scaling/horizontal-scaling/topology.md index f852f3f443..b56f8e3f20 100644 --- a/docs/guides/cassandra/scaling/horizontal-scaling/topology.md +++ b/docs/guides/cassandra/scaling/horizontal-scaling/topology.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the C To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/cassandra](/docs/examples/cassandra) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -84,28 +84,28 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/cassandra-topology.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/cassandra-topology.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 27s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 1m27s . . cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 2m27s -``` Let's check the number of replicas has from cassandra object, number of pods the petset have, ```bash -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' -2 +kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' ``` +2 We can see from commands that the cluster has 2 replicas for rack r0 as we have defined in the yaml. @@ -142,9 +142,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/horizontal-scaling/cassandra-hscale-up-topology.yaml -cassandraopsrequest.ops.kubedb.com/casops-hscale-up-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/horizontal-scaling/cassandra-hscale-up-topology.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-hscale-up-topology created #### Verify Topology cluster replicas scaled up successfully @@ -153,15 +153,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ watch kubectl get cassandraopsrequest -n demo +watch kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE cassandra-horizontal-scale-up HorizontalScaling Successful 106s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe cassandraopsrequests -n demo cassandra-horizontal-scale-up +kubectl describe cassandraopsrequests -n demo cassandra-horizontal-scale-up +``` kubectl describe cassandraopsrequests -n demo cassandra-horizontal-scale-up Name: cassandra-horizontal-scale-up Namespace: demo @@ -226,14 +227,13 @@ Events: Normal UpdatePetSets 12s KubeDB Ops-manager Operator successfully reconciled the Cassandra with modified node Normal Starting 12s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 12s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: cassandra-horizontal-scale-up -``` Now, we are going to verify the number of replicas this cluster has from the Cassandra object, number of pods the petset have, ```bash -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' -4 +kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' ``` +4 ### Scale Down Replicas @@ -266,9 +266,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/horizontal-scaling/cassandra-hscale-down-topology.yaml -cassandraopsrequest.ops.kubedb.com/casops-hscale-down-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/horizontal-scaling/cassandra-hscale-down-topology.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-hscale-down-topology created #### Verify Topology cluster replicas scaled down successfully @@ -277,15 +277,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ watch kubectl get cassandraopsrequest -n demo +watch kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE cassandra-horizontal-scale-down HorizontalScaling Successful 62s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe cassandraopsrequests -n demo cassandra-horizontal-scale-down +kubectl describe cassandraopsrequests -n demo cassandra-horizontal-scale-down +``` Name: cassandra-horizontal-scale-down Namespace: demo Labels: @@ -349,17 +350,15 @@ Events: Normal UpdatePetSets 114s KubeDB Ops-manager Operator successfully reconciled the Cassandra with modified node Normal Starting 114s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 114s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: cassandra-horizontal-scale-down -``` Now, we are going to verify the number of replicas this cluster has from the number of pods the petset have, **Broker Replicas** ```bash -$ -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' -2 +kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the topology cluster is `2`. That means we have successfully scaled down the replicas of the Cassandra topology cluster. diff --git a/docs/guides/cassandra/scaling/vertical-scaling/topology.md b/docs/guides/cassandra/scaling/vertical-scaling/topology.md index 091350b74b..cd0df50d2d 100644 --- a/docs/guides/cassandra/scaling/vertical-scaling/topology.md +++ b/docs/guides/cassandra/scaling/vertical-scaling/topology.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/cassandra](/docs/examples/cassandra) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -84,26 +84,27 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/cassandra-topology.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/cassandra-topology.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 22s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 45s . . cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 104s -``` Let's check the Pod containers resources of the Cassandra topology cluster. Run the following command to get the resources of the containers of the Cassandra topology cluster ```bash -$ kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "2", @@ -114,7 +115,6 @@ $ kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.container "memory": "1Gi" } } -``` We are now ready to apply the `CassandraOpsRequest` CR to update the resources of this database. @@ -158,9 +158,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/vertical-scaling/cassandra-vertical-scaling-topology.yaml -cassandraopsrequest.ops.kubedb.com/casops-vscale-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/scaling/vertical-scaling/cassandra-vertical-scaling-topology.yaml ``` +cassandraopsrequest.ops.kubedb.com/casops-vscale-topology created #### Verify Cassandra Topology cluster resources updated successfully @@ -169,15 +169,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE cassandra-vertical-scale VerticalScaling Successful 3m56s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe cassandraopsrequest -n demo cassandra-vertical-scale + kubectl describe cassandraopsrequest -n demo cassandra-vertical-scale +``` Name: cassandra-vertical-scale Namespace: demo Labels: @@ -276,11 +277,11 @@ Events: Normal RestartPods 34m KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 34m KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 34m KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: cassandra-vertical-scale 2m18s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: casops-vscale-topology -``` Now, we are going to verify from one of the Pod yaml whether the resources of the topology cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.containers[].resources' + kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "3", @@ -291,7 +292,6 @@ $ kubectl get pod -n demo cassandra-prod-rack-r0-0 -o json | jq '.spec.containe "memory": "3Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the Cassandra topology cluster. diff --git a/docs/guides/cassandra/tls/topology.md b/docs/guides/cassandra/tls/topology.md index 2ba2e822be..321758cb19 100644 --- a/docs/guides/cassandra/tls/topology.md +++ b/docs/guides/cassandra/tls/topology.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Cassandra. This tutorial will s - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -83,9 +83,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/tls/cas-issuer.yaml -issuer.cert-manager.io/cassandra-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/tls/cas-issuer.yaml ``` +issuer.cert-manager.io/cassandra-ca-issuer created ## TLS/SSL encryption in Cassandra Topology Cluster @@ -130,26 +130,27 @@ spec: ### Deploy Cassandra Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/tls/cassandra-prod-tls.yaml -cassandra.kubedb.com/cassandra-prod-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/tls/cassandra-prod-tls.yaml ``` +cassandra.kubedb.com/cassandra-prod-tls created Now, wait until `cassandra-prod-tls created` has status `Ready`. i.e, ```bash -$ kubectl get cassandra -n demo -w +kubectl get cassandra -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod-tls kubedb.com/v1alpha2 5.0.3 Provisioning 20s cassandra-prod-tls kubedb.com/v1alpha2 5.0.3 Provisioning 81s . . cassandra-prod-tls kubedb.com/v1alpha2 5.0.3 Ready 104s -``` ### Verify TLS/SSL in Cassandra Topology Cluster ```bash -$ kubectl describe secret cassandra-prod-tls-client-cert -n demo + kubectl describe secret cassandra-prod-tls-client-cert -n demo +``` Name: cassandra-prod-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -174,12 +175,12 @@ Data ca.crt: 1159 bytes tls.crt: 1578 bytes tls.key: 1704 bytes -``` Now, Let's exec into a cassandra pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo cassandra-prod-tls-rack-r0-0 -- cqlsh -u admin -p qAbFK0B8gtUgj3Gp + kubectl exec -it -n demo cassandra-prod-tls-rack-r0-0 -- cqlsh -u admin -p qAbFK0B8gtUgj3Gp +``` Defaulted container "cassandra" out of: cassandra, cassandra-init (init), medusa-init (init) Warning: Using a password on the command line interface can be insecure. @@ -197,7 +198,6 @@ Connected to Test Cluster at 127.0.0.1:9042 [cqlsh 6.2.0 | Cassandra 5.0.3 | CQL spec 3.4.7 | Native protocol v5] Use HELP for help. admin@cqlsh> -``` We can see from the above output that, cqlsh can only be accessed through --ssl flag which means that TLS is enabled. diff --git a/docs/guides/cassandra/update-version/update-version.md b/docs/guides/cassandra/update-version/update-version.md index b4aa513b6d..bbb37612ef 100644 --- a/docs/guides/cassandra/update-version/update-version.md +++ b/docs/guides/cassandra/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/cassandra](/docs/examples/cassandra) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -80,14 +80,15 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/update-version/cassandra.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/update-version/cassandra.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` created has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w + kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 45s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 82s @@ -95,8 +96,6 @@ cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 82s . cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 106s -``` - We are now ready to apply the `CassandraOpsRequest` CR to update. ### update Cassandra Version @@ -132,9 +131,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/update-version/update-version.yaml -cassandraopsrequest.ops.kubedb.com/cassandra-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/update-version/update-version.yaml ``` +cassandraopsrequest.ops.kubedb.com/cassandra-update-version created #### Verify Cassandra version updated successfully @@ -143,15 +142,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE cassandra-update-version UpdateVersion Successful 2m6s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe cassandraopsrequest -n demo cassandra-update-version +kubectl describe cassandraopsrequest -n demo cassandra-update-version +``` Name: cassandra-update-version Namespace: demo Labels: @@ -243,21 +243,23 @@ Events: Normal RestartPods 3m58s KubeDB Ops-manager Operator Successfully Restarted Cassandra nodes Normal Starting 3m58s KubeDB Ops-manager Operator Resuming Cassandra database: demo/cassandra-prod Normal Successful 3m58s KubeDB Ops-manager Operator Successfully resumed Cassandra database: demo/cassandra-prod for CassandraOpsRequest: cassandra-update-version -``` Now, we are going to verify whether the `Cassandra` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get cas -n demo cassandra-prod -o=jsonpath='{.spec.version}{"\n"}' +kubectl get cas -n demo cassandra-prod -o=jsonpath='{.spec.version}{"\n"}' +``` 5.0.3 -$ kubectl get petset -n demo cassandra-prod-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo cassandra-prod-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/cassandra-kraft:3.9.0@sha256:e251d3c0ceee0db8400b689e42587985034852a8a6c81b5973c2844e902e6d11 -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/cassandra-management:5.0.3@sha256:ef296c7ce02b438f3af43bd07457ca44881c845c6eeef631989b4ed7351b7243 - +```bash +kubectl get petset -n demo cassandra-prod-rack-r0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/cassandra-management:5.0.3@sha256:ef296c7ce02b438f3af43bd07457ca44881c845c6eeef631989b4ed7351b7243 You can see from above, our `Cassandra` has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/cassandra/volume-expansion/topology.md b/docs/guides/cassandra/volume-expansion/topology.md index c389a71fcc..50eefd73cc 100644 --- a/docs/guides/cassandra/volume-expansion/topology.md +++ b/docs/guides/cassandra/volume-expansion/topology.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/cassandra](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/cassandra) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,14 +47,13 @@ Here, we are going to deploy a `Cassandra` topology using a supported version by At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d22h longhorn (default) driver.longhorn.io Delete Immediate true 6s longhorn-static driver.longhorn.io Delete Immediate true 3s -``` - We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. Now, we are going to deploy a `Cassandra` combined cluster with version `5.0.7`. @@ -101,30 +100,31 @@ spec: Let's create the `Cassandra` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/volume-expansion/cassandra.yaml -cassandra.kubedb.com/cassandra-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/volume-expansion/cassandra.yaml ``` +cassandra.kubedb.com/cassandra-prod created Now, wait until `cassandra-prod` has status `Ready`. i.e, ```bash -$ kubectl get cas -n demo -w +kubectl get cas -n demo -w +``` NAME TYPE VERSION STATUS AGE cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 4s cassandra-prod kubedb.com/v1alpha2 5.0.3 Provisioning 37s .. cassandra-prod kubedb.com/v1alpha2 5.0.3 Ready 2m3s -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +``` "1Gi" - -$ kubectl get pv -n demo +```bash + kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-623e4d80-f508-4bb1-a4cb-4ebdbcbd8495 1Gi RWO Delete Bound demo/data-cassandra-prod-rack-r0-0 longhorn 82s pvc-76b5a0a7-d234-426c-a4cc-ec740d6456ba 1Gi RWO Delete Bound demo/data-cassandra-prod-rack-r0-1 longhorn 64s @@ -132,7 +132,6 @@ pvc-84588238-9fea-4ac3-9cfa-f7b04640697c 1Gi RWO Delete pvc-849d404c-d078-4802-a28f-6834d8c81998 1Gi RWO Delete Bound demo/nodetool-cassandra-prod-rack-r0-1 longhorn 64s pvc-85a6902d-a596-45db-94f9-1ce355600323 1Gi RWO Delete Bound demo/main-config-volume-cassandra-prod-rack-r0-1 longhorn 64s pvc-88d6586e-b502-481d-91fc-dd6381d9b1c0 1Gi RWO Delete Bound demo/main-config-volume-cassandra-prod-rack-r0-0 longhorn 82s -``` You can see the petsets have 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -172,9 +171,9 @@ Here, Let's create the `CassandraOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/volume-expansion/cassandra-volume-expansion-opsreq.yaml -cassandraopsrequest.ops.kubedb.com/cas-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/cassandra/volume-expansion/cassandra-volume-expansion-opsreq.yaml ``` +cassandraopsrequest.ops.kubedb.com/cas-volume-expansion created #### Verify Cassandra Topology volume expanded successfully @@ -183,15 +182,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `CassandraOpsRequest` to be `Successful`. Run the following command to watch `CassandraOpsRequest` CR, ```bash -$ kubectl get cassandraopsrequest -n demo +kubectl get cassandraopsrequest -n demo +``` NAME TYPE STATUS AGE cas-volume-expansion VolumeExpansion Successful 5m49s -``` We can see from the above output that the `CassandraOpsRequest` has succeeded. If we describe the `CassandraOpsRequest` we will get an overview of the steps that were followed to expand the volume of cassandra. ```bash -$ kubectl describe cassandraopsrequest -n demo cas-volume-expansion +kubectl describe cassandraopsrequest -n demo cas-volume-expansion +``` Name: cas-volume-expansion Namespace: demo Labels: @@ -331,16 +331,17 @@ Events: Normal Successful 5m11s KubeDB Ops-manager Operator Successfully paused Cassandra database: demo/cassandra-prod for CassandraOpsRequest: cas-volume-expansion Warning get pet set; ConditionStatus:True 5m6s KubeDB Ops-manager Operator get pet set; ConditionStatus:True Normal ReadyPetSets 5m6s KubeDB Ops-manager Operator PetSet is recreated -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +kubectl get petset -n demo cassandra-prod-rack-r0 -o json | jq '.spec.volumeClaimTemplates[0].spec.resources.requests.storage' +``` "2Gi" - -$ kubectl get pv -n demo +```bash + kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-7efa007f-5fb2-4e64-aea0-233ec456703f 1Gi RWO Delete Bound demo/main-config-volume-cassandra-prod-rack-r0-1 longhorn 11m pvc-88f8ec55-ae5b-48dd-9b3a-0dc113cdaa43 2Gi RWO Delete Bound demo/data-cassandra-prod-rack-r0-1 longhorn 11m @@ -348,7 +349,6 @@ pvc-c455344e-0f17-42d2-8fd9-062fa2f1b0a1 1Gi RWO Delete pvc-d19d62ac-b37b-406e-a7d6-a10f4f74d929 2Gi RWO Delete Bound demo/data-cassandra-prod-rack-r0-0 longhorn 11m pvc-df152a7a-12ea-4690-b64e-ccb2decce8cd 1Gi RWO Delete Bound demo/nodetool-cassandra-prod-rack-r0-1 longhorn 11m pvc-f8420d54-05f8-4ea2-b70c-11a3737e04e4 1Gi RWO Delete Bound demo/nodetool-cassandra-prod-rack-r0-0 longhorn 11m -``` The above output verifies that we have successfully expanded the data related volume of the Cassandra. diff --git a/docs/guides/clickhouse/autoscaler/compute/compute-autoscale.md b/docs/guides/clickhouse/autoscaler/compute/compute-autoscale.md index 90bb4f6494..efe34c0b79 100644 --- a/docs/guides/clickhouse/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/clickhouse/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscaling compute resources i. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -97,9 +97,9 @@ spec: Let's create the `ClickHouse` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/compute/clickhouse-autoscale.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/compute/clickhouse-autoscale.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -196,9 +196,9 @@ Here, Let's create the `ClickHouseAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/compute/clickhouse-autoscaler-ops.yaml -clickhouseautoscaler.autoscaling.kubedb.com/ch-compute-autoscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/compute/clickhouse-autoscaler-ops.yaml ``` +clickhouseautoscaler.autoscaling.kubedb.com/ch-compute-autoscale created #### Verify Autoscaling is set up successfully @@ -355,20 +355,20 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `clickhouseopsrequest` in the demo namespace to see if any `clickhouseopsrequest` object is created. After some time you'll see that a `clickhouseopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get clickhouseopsrequest -n demo +watch kubectl get clickhouseopsrequest -n demo +``` Every 2.0s: kubectl get clickhouseopsrequest -n demo NAME TYPE STATUS AGE chops-clickhouse-prod-appscode-cluster-shard-0-ckc28v VerticalScaling Progressing 1m28s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get clickhouseopsrequest -n demo +watch kubectl get clickhouseopsrequest -n demo +``` Every 2.0s: kubectl get clickhouseopsrequest -n demo NAME TYPE STATUS AGE chops-clickhouse-prod-appscode-cluster-shard-0-ckc28v VerticalScaling Successful 3m34s -``` We can see from the above output that the `ClickHouseOpsRequest` has succeeded. If we describe the `ClickHouseOpsRequest` we will get an overview of the steps that were followed to scale the ClickHouse. diff --git a/docs/guides/clickhouse/autoscaler/storage/storage-autoscale.md b/docs/guides/clickhouse/autoscaler/storage/storage-autoscale.md index c68c5003c3..bb5fb546fd 100644 --- a/docs/guides/clickhouse/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/clickhouse/autoscaler/storage/storage-autoscale.md @@ -37,21 +37,21 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Click To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h2m longhorn (default) driver.longhorn.io Delete Immediate true 9m41s longhorn-static driver.longhorn.io Delete Immediate true 9m24s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -115,9 +115,9 @@ spec: Let's create the `ClickHouse` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/storage/clickhouse-autoscale.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/storage/clickhouse-autoscale.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -185,9 +185,9 @@ Here, Let's create the `clickhouseAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/storage/clickhouse-autoscaler-ops.yaml -clickhouseautoscaler.autoscaling.kubedb.com/ch-storage-autoscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/autoscaling/storage/clickhouse-autoscaler-ops.yaml ``` +clickhouseautoscaler.autoscaling.kubedb.com/ch-storage-autoscale created #### Storage Autoscaling is set up successfully diff --git a/docs/guides/clickhouse/concepts/clickhouse.md b/docs/guides/clickhouse/concepts/clickhouse.md index 5f70961666..193156d171 100644 --- a/docs/guides/clickhouse/concepts/clickhouse.md +++ b/docs/guides/clickhouse/concepts/clickhouse.md @@ -134,11 +134,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic clickhouse-auth -n demo \ +kubectl create secret generic clickhouse-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "clickhouse-auth" created ``` +secret "clickhouse-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/clickhouse/configuration/using-config-file.md b/docs/guides/clickhouse/configuration/using-config-file.md index ef877cf164..01fdd34544 100644 --- a/docs/guides/clickhouse/configuration/using-config-file.md +++ b/docs/guides/clickhouse/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for ClickHouse. This tutorial wil - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -45,11 +45,11 @@ At first, you have to create a secret with your configuration file contents as t At first, create `clickhouse.yaml` file containing required configuration settings. ```bash -$ cat clickhouse-config.yaml +cat clickhouse-config.yaml +``` profiles: default: max_query_size: 200000 -``` Now, create the secret with this configuration file. diff --git a/docs/guides/clickhouse/initialization/script_source.md b/docs/guides/clickhouse/initialization/script_source.md index 5ed93635f3..3632456478 100644 --- a/docs/guides/clickhouse/initialization/script_source.md +++ b/docs/guides/clickhouse/initialization/script_source.md @@ -25,13 +25,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ At first, we will create a ConfigMap from an `init.sql` file. Then, we will prov Let's create a ConfigMap with the initialization script: ```bash -$ kubectl create configmap -n demo ch-init-script \ +kubectl create configmap -n demo ch-init-script \ --from-literal=init.sql="$(curl -fsSL https://raw.githubusercontent.com/Bonusree/init_script/main/clickhouse_init.sql)" -configmap/ch-init-script created ``` +configmap/ch-init-script created ## Create ClickHouse with Script Source @@ -87,14 +89,15 @@ VolumeSource provided in `init.script` will be mounted in the Pod and will be ex Now, let's create the ClickHouse CRD using the YAML shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/initialization/script-clickhouse.yaml -clickhouse.kubedb.com/script-clickhouse created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/initialization/script-clickhouse.yaml ``` +clickhouse.kubedb.com/script-clickhouse created Now, wait until ClickHouse goes in `Ready` state. Verify that the database is in `Ready` state using the following command: ```bash -$ kubectl-dba describe ch -n demo script-clickhouse +kubectl-dba describe ch -n demo script-clickhouse +``` Name: script-clickhouse Namespace: demo Labels: @@ -204,7 +207,6 @@ Status: Type: Provisioned Phase: Ready Events: -``` ## Verify Initialization @@ -221,30 +223,30 @@ Now let's connect to our ClickHouse instance to verify that the database has bee - Username: Run the following command to get the *username*: ```bash - $ kubectl get secret -n demo script-clickhouse-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo script-clickhouse-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: Run the following command to get the *password*: ```bash - $ kubectl get secret -n demo script-clickhouse-auth -o jsonpath='{.data.password}' | base64 -d - NkBpF0IQRCZ2isMb + kubectl get secret -n demo script-clickhouse-auth -o jsonpath='{.data.password}' | base64 -d ``` + NkBpF0IQRCZ2isMb Now, connect to ClickHouse using the `clickhouse-client` and run the following query to confirm initialization: ```bash -$ kubectl exec -it -n demo script-clickhouse-0 -- clickhouse-client --user=admin --password=NkBpF0IQRCZ2isMb --query "SHOW TABLES FROM init_script" -kubedb_table +kubectl exec -it -n demo script-clickhouse-0 -- clickhouse-client --user=admin --password=NkBpF0IQRCZ2isMb --query "SHOW TABLES FROM init_script" ``` +kubedb_table You can also verify that the table was populated correctly: ```bash -$ kubectl exec -it -n demo script-clickhouse-0 -- clickhouse-client --user=admin --password=NkBpF0IQRCZ2isMb --query "SELECT * FROM init_script.kubedb_table" -1 name1 +kubectl exec -it -n demo script-clickhouse-0 -- clickhouse-client --user=admin --password=NkBpF0IQRCZ2isMb --query "SELECT * FROM init_script.kubedb_table" ``` +1 name1 We can see that the table `kubedb_table` in the `init_script` database was created and populated through the initialization script. @@ -253,9 +255,15 @@ We can see that the table `kubedb_table` in the `init_script` database was creat To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo clickhouse/script-clickhouse -$ kubectl delete -n demo configmap/ch-init-script -$ kubectl delete ns demo +kubectl delete -n demo clickhouse/script-clickhouse +``` + +```bash +kubectl delete -n demo configmap/ch-init-script +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/clickhouse/monitoring/overview.md b/docs/guides/clickhouse/monitoring/overview.md index 0fa0b4a475..f82981d2aa 100644 --- a/docs/guides/clickhouse/monitoring/overview.md +++ b/docs/guides/clickhouse/monitoring/overview.md @@ -106,9 +106,9 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/coreos-prom-clickhouse.yaml -clickhouse.kubedb.com/coreos-prom-clickhouse created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/coreos-prom-clickhouse.yaml ``` +clickhouse.kubedb.com/coreos-prom-clickhouse created Here, we have specified that we are going to monitor this server using Prometheus operator through `spec.monitor.agent: prometheus.io/operator`. KubeDB will create a `ServiceMonitor` crd in databases namespace and this `ServiceMonitor` will have `release: prometheus` label. diff --git a/docs/guides/clickhouse/monitoring/using-builtin-prometheus.md b/docs/guides/clickhouse/monitoring/using-builtin-prometheus.md index 24b33b6cf9..fe1e6edee5 100644 --- a/docs/guides/clickhouse/monitoring/using-builtin-prometheus.md +++ b/docs/guides/clickhouse/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor ClickHouse cluster using builtin [Pro - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -101,9 +103,9 @@ Here, Let's create the ClickHouse crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/builtin-prom-clickhouse.yaml -clickhouse.kubedb.com/clickhouse-builtin-prom created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/builtin-prom-clickhouse.yaml ``` +clickhouse.kubedb.com/clickhouse-builtin-prom created Now, wait for the cluster to go into `Ready` state. @@ -318,20 +320,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -342,9 +344,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -353,18 +355,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-547c78fc57-mg6st 1/1 Running 0 48s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-547c78fc57-mg6st 9090 +kubectl port-forward -n monitoring prometheus-547c78fc57-mg6st 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `clickhouse-builtin-prom-stats` service as one of the targets. diff --git a/docs/guides/clickhouse/monitoring/using-prometheus-operator.md b/docs/guides/clickhouse/monitoring/using-prometheus-operator.md index 10b261cab1..81c7656f7f 100644 --- a/docs/guides/clickhouse/monitoring/using-prometheus-operator.md +++ b/docs/guides/clickhouse/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. Alternatively, you can use `--create-namespace` flag while deploying prometheus. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,17 +47,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v3.4.2 1 1 True True 7h43m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -180,7 +183,6 @@ status: shards: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.serviceMonitor.labels` field of ClickHouse crd. @@ -254,9 +256,9 @@ Here, Let's create the clickhouse object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/coreos-prom-clickhouse.yaml -clickhouses.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/monitoring/coreos-prom-clickhouse.yaml ``` +clickhouses.kubedb.com/clickhouse-prod created Now, wait for the database to go into `Running` state. @@ -369,20 +371,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 2 (18m ago) 24h -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-kube-prometheus-prometheus` service which is pointing to the prometheus pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `clickhouse-stats` service as one of the targets. diff --git a/docs/guides/clickhouse/quickstart/guide/quickstart.md b/docs/guides/clickhouse/quickstart/guide/quickstart.md index 2b1cf88671..5cc39c3d02 100644 --- a/docs/guides/clickhouse/quickstart/guide/quickstart.md +++ b/docs/guides/clickhouse/quickstart/guide/quickstart.md @@ -39,9 +39,9 @@ local-path (default) rancher.io/local-path Delete WaitForFirstConsu - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available ClickHouseVersion @@ -77,9 +77,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/clickhouse/quickstart/yamls/quickstart-v1alpha2.yaml -clickhouse.kubedb.com/clickhouse-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/clickhouse/quickstart/yamls/quickstart-v1alpha2.yaml ``` +clickhouse.kubedb.com/clickhouse-quickstart created Here, diff --git a/docs/guides/clickhouse/reconfigure-tls/clickhouse.md b/docs/guides/clickhouse/reconfigure-tls/clickhouse.md index 66c51b092d..4c51181951 100644 --- a/docs/guides/clickhouse/reconfigure-tls/clickhouse.md +++ b/docs/guides/clickhouse/reconfigure-tls/clickhouse.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -94,9 +94,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -165,9 +165,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-issuer.yaml -issuer.cert-manager.io/clickhouse-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-issuer.yaml ``` +issuer.cert-manager.io/clickhouse-ca-issuer created ### Create ClickHouseOpsRequest @@ -212,9 +212,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-add-tls.yaml -clickhouseopsrequest.ops.kubedb.com/chops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-add-tls.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-add-tls created #### Verify TLS Enabled Successfully @@ -458,9 +458,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-rotate-tls.yaml -clickhouseopsrequest.ops.kubedb.com/chops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-rotate-tls.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-rotate created #### Verify Certificate Rotated Successfully @@ -648,21 +648,21 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=clickhouse-updated/O=kubedb-updated" + openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=clickhouse-updated/O=kubedb-updated" +``` ....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.......+.....+..........+...+...+..+...+....+............+...........+....+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+..........+..+.......+...+.....+......+.......+...+..+....+.....+.............+..+.+.....+.......+..+.+...+....................+.........+...+..........+.......................+.....................+.+........+....+..+...+.......+.........+..+...+.+......+..+.............+........+......+......+.......+...........+.+.....+................+...+......+........+.......+...+........+...+....+.....+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .....+.....+....+.....+...+....+........+.+..+.......+........+...+.......+........+......+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+........+.........+....+......+...+..+....+..+....+........+............+.+...+............+.........+.....+...+...+.........+.+...+..+.......+........+......................+.....+..........+...+..+......+.+.........+......+....................+.+...+.....+......+.+..............+...+.+..+....+.........+......+......+........+......+....+..+....+......+..+............+.+.................+...+....+...+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ----- -``` - Now we are going to create a new ca-secret using the certificate files that we have just generated. ```bash -$ kubectl create secret tls clickhouse-new-ca \ +kubectl create secret tls clickhouse-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/clickhouse-new-ca created ``` +secret/clickhouse-new-ca created Now, Let's create a new `Issuer` using the `clickhouse-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -680,9 +680,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-new-issuer.yaml -issuer.cert-manager.io/ch-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-new-issuer.yaml ``` +issuer.cert-manager.io/ch-new-issuer created ### Create ClickHouseOpsRequest @@ -716,9 +716,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-update-issuer.yaml -clickhouseopsrequest.ops.kubedb.com/chops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-update-issuer.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-update-issuer created #### Verify Issuer is changed successfully @@ -937,9 +937,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-remove-tls.yaml -clickhouseopsrequest.ops.kubedb.com/chops-remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure-tls/clickhouse-remove-tls.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-remove-tls created #### Verify TLS Removed Successfully diff --git a/docs/guides/clickhouse/reconfigure/reconfigure.md b/docs/guides/clickhouse/reconfigure/reconfigure.md index 612e8e7851..a218f158b4 100644 --- a/docs/guides/clickhouse/reconfigure/reconfigure.md +++ b/docs/guides/clickhouse/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,9 +73,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-config-secret.yaml -secret/ch-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-config-secret.yaml ``` +secret/ch-custom-config created In this section, we are going to create a ClickHouse object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `ClickHouse` CR that we are going to create, @@ -135,9 +135,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -181,9 +181,9 @@ Then, we will create a new secret with this configuration file. At first, create `clickhouse.yaml` file containing required configuration settings. ```bash -$ cat clickhouse.yaml -read_request_timeout: 6500ms +cat clickhouse.yaml ``` +read_request_timeout: 6500ms Then, we will create a new secret with this configuration file. @@ -203,9 +203,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/new-ch-config-secret.yaml -secret/new-ch-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/new-ch-config-secret.yaml ``` +secret/new-ch-custom-config created #### Create ClickHouseOpsRequest @@ -237,9 +237,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-reconfigure-ops-with-secret.yaml -clickhouseopsrequest.ops.kubedb.com/chops-cluster-reconfigure-with-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-reconfigure-ops-with-secret.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-cluster-reconfigure-with-secret created #### Verify the new configuration is working @@ -430,9 +430,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-reconfigure-ops-with-apply-config.yaml -clickhouseopsrequest.ops.kubedb.com/chops-cluster-reconfigure-with-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/reconfigure/ch-reconfigure-ops-with-apply-config.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-cluster-reconfigure-with-config created #### Verify the new configuration is working diff --git a/docs/guides/clickhouse/restart/restart.md b/docs/guides/clickhouse/restart/restart.md index 2599ff1d0d..e753575728 100644 --- a/docs/guides/clickhouse/restart/restart.md +++ b/docs/guides/clickhouse/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the ClickHouse database via a ClickHouseOpsRequest. R - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -88,9 +88,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/restart/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/restart/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created ## Apply Restart opsRequest @@ -117,9 +117,9 @@ spec: Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/restart/ops.yaml -clickhouseopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/restart/ops.yaml ``` +clickhouseopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the controller pods, then broker of the referenced clickhouse. diff --git a/docs/guides/clickhouse/rotate-auth/rotateauth.md b/docs/guides/clickhouse/rotate-auth/rotateauth.md index 85fad7f658..01f3b3142e 100644 --- a/docs/guides/clickhouse/rotate-auth/rotateauth.md +++ b/docs/guides/clickhouse/rotate-auth/rotateauth.md @@ -29,9 +29,9 @@ This tutorial will show you how to use KubeDB to rotate authentication credentia - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,27 +60,29 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, ```bash -$ kubectl get clickhouse -n demo -w +kubectl get clickhouse -n demo -w +``` NAME TYPE VERSION STATUS AGE clickhouse kubedb.com/v1alpha2 25.7.1 Ready 25h -``` - We can verify from the above output that authentication is enabled for this cluster. By default, KubeDB operator create default credentials for the ClickHouse cluster. The default credentials are stored in a secret named `-auth` in the same namespace as the ClickHouse cluster. You can find the secret by running the following command: ```bash -$ kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\username}' | base64 -d +``` admin -$ kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\password}' | base64 -d -St9402lDFuk9LgDo + +```bash +kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\password}' | base64 -d ``` +St9402lDFuk9LgDo ### Create RotateAuth ClickHouseOpsRequest @@ -110,23 +112,23 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/chops-rotate-auth-generated.yaml -clickhouseopsrequest.ops.kubedb.com/chops-rotate-auth-generated created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/chops-rotate-auth-generated.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-rotate-auth-generated created Let's wait for `ClickHouseOpsRequest` to be `Successful`. Run the following command to watch `ClickHouseOpsRequest` CRO, ```bash -$ kubectl get clickhouseopsrequest -n demo +kubectl get clickhouseopsrequest -n demo +``` NAME TYPE STATUS AGE chops-rotate-auth-generated RotateAuth Successful 5m59s -``` - We can see from the above output that the `ClickHouseOpsRequest` has succeeded. If we describe the `ClickHouseOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe chops -n demo chops-rotate-auth-generated +kubectl describe chops -n demo chops-rotate-auth-generated +``` Name: chops-rotate-auth-generated Namespace: demo Labels: @@ -215,23 +217,28 @@ Events: Normal Starting 6m31s KubeDB Ops-manager Operator Resuming ClickHouse database: demo/clickhouse Normal Successful 6m31s KubeDB Ops-manager Operator Successfully resumed ClickHouse database: demo/clickhouse for ClickHouseOpsRequest: chops-rotate-auth-generated -``` - #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get ch -n demo clickhouse -ojson | jq .spec.authSecret.name +kubectl get ch -n demo clickhouse -ojson | jq .spec.authSecret.name +``` "clickhouse-auth" -$ kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\username}' | base64 -d +``` admin⏎ -$ kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\password}' | base64 -d -sG0OKmIim3ZkfhpE⏎ + +```bash +kubectl get secrets -n demo clickhouse-auth -o jsonpath='{.data.\password}' | base64 -d ``` +sG0OKmIim3ZkfhpE⏎ Now, you can exec into the pod `clickhouse-0` and connect to database using `username` and `password` ```bash -$ kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +``` clickhouse@clickhouse-0:/$ clickhouse-client -uadmin --password="sG0OKmIim3ZkfhpE" ClickHouse client version 25.7.1.3997 (official build). Connecting to localhost:9000 as user admin. @@ -261,28 +268,27 @@ clickhouse-0.clickhouse-pods.demo.svc.cluster.local :) exit Bye. clickhouse@clickhouse-0:/$ exit exit - - -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo clickhouse-auth -o=jsonpath="{.data.password\.prev}" | base64 -d +kubectl get secret -n demo clickhouse-auth -o=jsonpath="{.data.password\.prev}" | base64 -d +``` w5MKkyQ1PMOOC7BO⏎ -$ kubectl get secret -n demo clickhouse-auth -o=jsonpath="{.data.username\.prev}" | base64 -d -admin⏎ + +```bash +kubectl get secret -n demo clickhouse-auth -o=jsonpath="{.data.username\.prev}" | base64 -d ``` +admin⏎ Let's confirm that the previous credentials no longer work. -```shell -$ kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +```bash +kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +``` clickhouse@clickhouse-0:/$ clickhouse-client -uadmin --password="w5MKkyQ1PMOOC7BO" ClickHouse client version 25.7.1.3997 (official build). Connecting to localhost:9000 as user admin. Code: 516. DB::Exception: Received from localhost:9000. DB::Exception: admin: Authentication failed: password is incorrect, or there is no user with such name.. (AUTHENTICATION_FAILED) clickhouse@clickhouse-0:/$ - -``` The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials @@ -290,12 +296,12 @@ The above output shows that the password has been changed successfully. The prev At first, we need to create a secret with `kubernetes.io/basic-auth` type using custom `username` and `password`. Below is the command to create a secret with `kubernetes.io/basic-auth` type, ```bash -$ kubectl create secret generic clickhouse-user-auth -n demo \ +kubectl create secret generic clickhouse-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=clickhouse \ --from-literal=password=clickhouse-secret -secret/clickhouse-user-auth created ``` +secret/clickhouse-user-auth created Now create a ClickHouse Ops Request with `RotateAuth` type. Below is the YAML of the `ClickHouseOpsRequest` that we are going to create, @@ -326,22 +332,23 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/chops-rotate-auth-user.yaml -clickhouseopsrequest.ops.kubedb.com/chops-rotate-auth-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/rotate-auth/chops-rotate-auth-user.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-rotate-auth-user created Let's wait for `ClickHouseOpsRequest` to be `Successful`. Run the following command to watch `ClickHouseOpsRequest` CRO, ```bash -$ kubectl get clickhouseopsrequest -n demo chops-rotate-auth-user +kubectl get clickhouseopsrequest -n demo chops-rotate-auth-user +``` NAME TYPE STATUS AGE chops-rotate-auth-user RotateAuth Successful 4m43s -``` We can see from the above output that the `ClickHouseOpsRequest` has succeeded. If we describe the `ClickHouseOpsRequest` we will get an overview of the steps that were followed. ```bash -$kubectl describe clickhouseopsrequest -n demo chops-rotate-auth-user +kubectl describe clickhouseopsrequest -n demo chops-rotate-auth-user +``` Name: chops-rotate-auth-user Namespace: demo Labels: @@ -433,23 +440,28 @@ Events: Normal Starting 85s KubeDB Ops-manager Operator Resuming ClickHouse database: demo/clickhouse Normal Successful 85s KubeDB Ops-manager Operator Successfully resumed ClickHouse database: demo/clickhouse for ClickHouseOpsRequest: chops-rotate-auth-user -``` - #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get ch -n demo clickhouse -ojson | jq .spec.authSecret.name + kubectl get ch -n demo clickhouse -ojson | jq .spec.authSecret.name +``` "clickhouse-user-auth" -$ kubectl get secret -n demo clickhouse-user-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo clickhouse-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` clickhouse⏎ -$ kubectl get secret -n demo clickhouse-user-auth -o=jsonpath='{.data.password}' | base64 -d -clickhouse-secret⏎ + +```bash +kubectl get secret -n demo clickhouse-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +clickhouse-secret⏎ Now, you can exec into the pod `clickhouse-0` and connect to database using `username` and `password` ```bash -$ kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +``` clickhouse@clickhouse-0:/$ clickhouse-client -uclickhouse --password="clickhouse-secret" ClickHouse client version 25.7.1.3997 (official build). Connecting to localhost:9000 as user clickhouse. @@ -474,27 +486,27 @@ Query id: 2807f810-8375-47b7-80fe-0ebe3df028ad └────────────────────┘ 5 rows in set. Elapsed: 0.001 sec. - -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo clickhouse-user-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +kubectl get secret -n demo clickhouse-user-auth -o=jsonpath="{.data.username\.prev}" | base64 -d +``` admin⏎ -$ kubectl get secret -n demo clickhouse-user-auth -o=jsonpath="{.data.password\.prev}" | base64 -d -sG0OKmIim3ZkfhpE⏎ + +```bash + kubectl get secret -n demo clickhouse-user-auth -o=jsonpath="{.data.password\.prev}" | base64 -d ``` +sG0OKmIim3ZkfhpE⏎ Let's confirm that the previous credentials no longer work. -```shell -$ kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +```bash + kubectl exec -it -n demo clickhouse-0 -c clickhouse -- bash +``` clickhouse@clickhouse-0:/$ clickhouse-client -uadmin --password="sG0OKmIim3ZkfhpE" ClickHouse client version 25.7.1.3997 (official build). Connecting to localhost:9000 as user admin. Code: 516. DB::Exception: Received from localhost:9000. DB::Exception: admin: Authentication failed: password is incorrect, or there is no user with such name.. (AUTHENTICATION_FAILED) clickhouse@clickhouse-0:/$ - -``` The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. ## Cleaning up @@ -502,10 +514,19 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete clickhouseopsrequests -n demo chops-rotate-auth-generated chops-rotate-auth-user -$ kubectl delete clickhouse -n demo clickhouse -$ kubectl delete secret -n demo clickhouse-user-auth -$ kubectl delete ns demo +kubectl delete clickhouseopsrequests -n demo chops-rotate-auth-generated chops-rotate-auth-user +``` + +```bash +kubectl delete clickhouse -n demo clickhouse +``` + +```bash +kubectl delete secret -n demo clickhouse-user-auth +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/clickhouse/scaling/horizontal-scaling/cluster.md b/docs/guides/clickhouse/scaling/horizontal-scaling/cluster.md index 7c70c97a93..73e61d1687 100644 --- a/docs/guides/clickhouse/scaling/horizontal-scaling/cluster.md +++ b/docs/guides/clickhouse/scaling/horizontal-scaling/cluster.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the C To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -101,9 +101,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -159,9 +159,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/horizontal-scaling/chops-horizontal-scaling-up.yaml -clickhouseopsrequest.ops.kubedb.com/chops-scale-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/horizontal-scaling/chops-horizontal-scaling-up.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-scale-horizontal-up created #### Verify cluster replicas scaled up successfully @@ -348,9 +348,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/horizontal-scaling/chops-horizontal-scaling-down.yaml -clickhouseopsrequest.ops.kubedb.com/chops-scale-horizontal-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/horizontal-scaling/chops-horizontal-scaling-down.yaml ``` +clickhouseopsrequest.ops.kubedb.com/chops-scale-horizontal-down created #### Verify clickhouse cluster replicas scaled down successfully diff --git a/docs/guides/clickhouse/scaling/vertical-scaling/cluster.md b/docs/guides/clickhouse/scaling/vertical-scaling/cluster.md index 0e6083013e..b6a88c0037 100644 --- a/docs/guides/clickhouse/scaling/vertical-scaling/cluster.md +++ b/docs/guides/clickhouse/scaling/vertical-scaling/cluster.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -101,9 +101,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -172,9 +172,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/vertical-scaling/ch-vertical-ops-cluster.yaml -clickhouseopsrequest.ops.kubedb.com/ch-scale-vertical-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/vertical-scaling/ch-vertical-ops-cluster.yaml ``` +clickhouseopsrequest.ops.kubedb.com/ch-scale-vertical-cluster created #### Verify ClickHouse cluster resources updated successfully diff --git a/docs/guides/clickhouse/scaling/vertical-scaling/standalone.md b/docs/guides/clickhouse/scaling/vertical-scaling/standalone.md index 0d1d5593fe..100cef3dcd 100644 --- a/docs/guides/clickhouse/scaling/vertical-scaling/standalone.md +++ b/docs/guides/clickhouse/scaling/vertical-scaling/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -69,9 +69,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-standalone.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/clickhouse-standalone.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -140,9 +140,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/vertical-scaling/ch-vertical-ops-standalone.yaml -clickhouseopsrequest.ops.kubedb.com/ch-vertical-scale-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/scaling/vertical-scaling/ch-vertical-ops-standalone.yaml ``` +clickhouseopsrequest.ops.kubedb.com/ch-vertical-scale-standalone created #### Verify ClickHouse standalone resources updated successfully diff --git a/docs/guides/clickhouse/tls/cluster.md b/docs/guides/clickhouse/tls/cluster.md index 15a2ae2c4b..5079faa83f 100644 --- a/docs/guides/clickhouse/tls/cluster.md +++ b/docs/guides/clickhouse/tls/cluster.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for ClickHouse. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -83,9 +83,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/tls/clickhouse-issuer.yaml -issuer.cert-manager.io/clickhouse-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/tls/clickhouse-issuer.yaml ``` +issuer.cert-manager.io/clickhouse-ca-issuer created ## TLS/SSL encryption in ClickHouse Cluster @@ -158,9 +158,9 @@ spec: ### Deploy ClickHouse Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/tls/clickhouse-cluster-tls.yaml -clickhouse.kubedb.com/clickhouse-prod-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/tls/clickhouse-cluster-tls.yaml ``` +clickhouse.kubedb.com/clickhouse-prod-tls created Now, wait until `clickhouse-prod-tls created` has status `Ready`. i.e, diff --git a/docs/guides/clickhouse/update-version/update-version.md b/docs/guides/clickhouse/update-version/update-version.md index 8e11db81d4..0c48044300 100644 --- a/docs/guides/clickhouse/update-version/update-version.md +++ b/docs/guides/clickhouse/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/clickhouse](/docs/examples/clickhouse) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -97,9 +97,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/update-version/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/update-version/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` created has status `Ready`. i.e, @@ -149,9 +149,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/update-version/update-version.yaml -clickhouseopsrequest.ops.kubedb.com/ch-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/update-version/update-version.yaml ``` +clickhouseopsrequest.ops.kubedb.com/ch-update-version created #### Verify ClickHouse version updated successfully diff --git a/docs/guides/clickhouse/volume-expansion/cluster.md b/docs/guides/clickhouse/volume-expansion/cluster.md index dd71582f20..0c7f8d70fd 100644 --- a/docs/guides/clickhouse/volume-expansion/cluster.md +++ b/docs/guides/clickhouse/volume-expansion/cluster.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/clickhouse](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/clickhouse) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -116,9 +116,9 @@ spec: Let's create the `ClickHouse` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/volume-expansion/clickhouse-cluster.yaml -clickhouse.kubedb.com/clickhouse-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/volume-expansion/clickhouse-cluster.yaml ``` +clickhouse.kubedb.com/clickhouse-prod created Now, wait until `clickhouse-prod` has status `Ready`. i.e, @@ -185,9 +185,9 @@ Here, Let's create the `ClickHouseOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/volume-expansion/chops-volume-expansion.yaml -clickhouseopsrequest.ops.kubedb.com/ch-offline-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/clickhouse/volume-expansion/chops-volume-expansion.yaml ``` +clickhouseopsrequest.ops.kubedb.com/ch-offline-volume-expansion created #### Verify ClickHouse Cluster volume expanded successfully diff --git a/docs/guides/documentdb/autoscaler/compute/index.md b/docs/guides/documentdb/autoscaler/compute/index.md index dbff6a5d69..3c92cd22e0 100644 --- a/docs/guides/documentdb/autoscaler/compute/index.md +++ b/docs/guides/documentdb/autoscaler/compute/index.md @@ -29,9 +29,9 @@ This guide will show you how to use `KubeDB` to auto-scale the compute resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > A DocumentDB exposes the MongoDB wire protocol (port `10260`, TLS) backed by an internal PostgreSQL engine. Every pod runs two containers — `documentdb` (the data plane that the autoscaler tunes) and `documentdb-coordinator`. The `DocumentDBAutoscaler` `spec.compute.documentdb` block targets the `documentdb` container. @@ -83,24 +83,24 @@ spec: Let's create the `DocumentDB` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/compute/autoscaling-compute-object.yaml -documentdb.kubedb.com/dcdb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/compute/autoscaling-compute-object.yaml ``` +documentdb.kubedb.com/dcdb created Now, wait until `dcdb` has status `Ready`. i.e, ```bash -$ kubectl get docdb -n demo +kubectl get docdb -n demo +``` NAME NAMESPACE VERSION STATUS AGE dcdb demo pg17-0.109.0 Ready 113s -``` Let's check the `documentdb` container's resources of the pod, ```bash -$ kubectl get pod -n demo dcdb-0 -o jsonpath='{range .spec.containers[?(@.name=="documentdb")]}{.resources}{"\n"}{end}' -{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} +kubectl get pod -n demo dcdb-0 -o jsonpath='{range .spec.containers[?(@.name=="documentdb")]}{.resources}{"\n"}{end}' ``` +{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} You can see from the above output that the resources are the same as the ones we assigned while deploying the DocumentDB. @@ -157,20 +157,23 @@ Here, Let's create the `DocumentDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/compute/autoscaling-compute.yaml -documentdbautoscaler.autoscaling.kubedb.com/dcdb-compute-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/compute/autoscaling-compute.yaml ``` +documentdbautoscaler.autoscaling.kubedb.com/dcdb-compute-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `documentdbautoscaler` resource is created successfully, ```bash -$ kubectl get documentdbautoscaler -n demo +kubectl get documentdbautoscaler -n demo +``` NAME AGE dcdb-compute-autoscaler 11s -$ kubectl describe documentdbautoscaler dcdb-compute-autoscaler -n demo +```bash +kubectl describe documentdbautoscaler dcdb-compute-autoscaler -n demo +``` Name: dcdb-compute-autoscaler Namespace: demo Labels: @@ -270,7 +273,6 @@ Status: Memory: 3Gi Vpa Name: dcdb Events: -``` So, the `documentdbautoscaler` resource is created successfully. @@ -281,23 +283,24 @@ The Autoscaler operator continuously watches the recommendation and creates a `D Let's watch the `documentdbopsrequest` in the demo namespace to see if any `documentdbopsrequest` object is created. ```bash -$ kubectl get documentdbopsrequest -n demo +kubectl get documentdbopsrequest -n demo +``` NAME TYPE STATUS AGE dcops-dcdb-y87ecq VerticalScaling Progressing 13s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get documentdbopsrequest -n demo +kubectl get documentdbopsrequest -n demo +``` NAME TYPE STATUS AGE dcops-dcdb-y87ecq VerticalScaling Successful 2m55s -``` We can see from the above output that the `DocumentDBOpsRequest` has succeeded. If we describe the `DocumentDBOpsRequest` (or print its YAML) we get an overview of the steps that were followed to scale the database. ```bash -$ kubectl get documentdbopsrequest -n demo dcops-dcdb-y87ecq -o yaml +kubectl get documentdbopsrequest -n demo dcops-dcdb-y87ecq -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: DocumentDBOpsRequest metadata: @@ -357,32 +360,36 @@ status: type: UnsetRaftKeyOpsRequestProgressing observedGeneration: 1 phase: Successful -``` Notice that the ops request body carries exactly the floored target (`600m`/`1536Mi`), and the rollout walks the cluster pod by pod (`SetRaftKeyOpsRequestProgressing` → `UpdatePetSets` → per-pod readiness checks → `RestartReadReplicas`) so the DocumentDB cluster stays available throughout. Now, let's verify from the Pod and the DocumentDB object that the resources of the cluster database have been updated to the desired state. ```bash -$ kubectl get pod -n demo dcdb-0 -o jsonpath='{range .spec.containers[?(@.name=="documentdb")]}{.resources}{"\n"}{end}' +kubectl get pod -n demo dcdb-0 -o jsonpath='{range .spec.containers[?(@.name=="documentdb")]}{.resources}{"\n"}{end}' +``` {"limits":{"cpu":"600m","memory":"1536Mi"},"requests":{"cpu":"600m","memory":"1536Mi"}} -$ kubectl get docdb -n demo dcdb -o json | jq -c '.spec.podTemplate.spec.containers[] | {name:.name, resources:.resources}' +```bash +kubectl get docdb -n demo dcdb -o json | jq -c '.spec.podTemplate.spec.containers[] | {name:.name, resources:.resources}' +``` {"name":"documentdb","resources":{"limits":{"cpu":"600m","memory":"1536Mi"},"requests":{"cpu":"600m","memory":"1536Mi"}}} {"name":"documentdb-coordinator","resources":{"limits":{"memory":"256Mi"},"requests":{"cpu":"200m","memory":"256Mi"}}} -``` The above output verifies that we have successfully autoscaled the compute resources of the DocumentDB cluster database from `500m`/`1Gi` to `600m`/`1.5Gi`. Finally, let's confirm the database is healthy over the MongoDB wire protocol: ```bash -$ PASS=$(kubectl get secret -n demo dcdb-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo dcdb-0 -c documentdb -- mongosh \ +PASS=$(kubectl get secret -n demo dcdb-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo dcdb-0 -c documentdb -- mongosh \ "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Cleaning Up diff --git a/docs/guides/documentdb/autoscaler/storage/index.md b/docs/guides/documentdb/autoscaler/storage/index.md index 37bb2e4503..bb613503b2 100644 --- a/docs/guides/documentdb/autoscaler/storage/index.md +++ b/docs/guides/documentdb/autoscaler/storage/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a `Docu To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > A DocumentDB exposes the MongoDB wire protocol (port `10260`, TLS) backed by an internal PostgreSQL engine. Each pod runs the `documentdb` and `documentdb-coordinator` containers, and the data directory (`/var/pv`) lives on the per-pod PVC `data-dcdb-`. @@ -60,11 +60,11 @@ The `DocumentDBAutoscaler` storage loop is **PVC-usage-driven**: At first, verify that your cluster has a storage class that supports volume expansion. ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 22d longhorn driver.longhorn.io Delete Immediate true 18d -``` We can see the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` set to `true`, and it supports online volume expansion, so we will use it. You can install longhorn from [here](https://longhorn.io/docs/). @@ -106,26 +106,26 @@ spec: Let's create the `DocumentDB` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/storage/autoscaling-storage-object.yaml -documentdb.kubedb.com/dcdb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/storage/autoscaling-storage-object.yaml ``` +documentdb.kubedb.com/dcdb created Now, wait until `dcdb` has status `Ready`. i.e, ```bash -$ kubectl get docdb -n demo +kubectl get docdb -n demo +``` NAME NAMESPACE VERSION STATUS AGE dcdb demo pg17-0.109.0 Ready 2m56s -``` Let's check the PVC sizes of the cluster, ```bash -$ kubectl get pvc -n demo | grep dcdb +kubectl get pvc -n demo | grep dcdb +``` data-dcdb-0 Bound pvc-de4bfaa2-ea8e-4db5-b352-72abe3ab5b67 2Gi RWO longhorn 2m47s data-dcdb-1 Bound pvc-ad3b996c-3ffe-460c-8da3-ea14d534d217 2Gi RWO longhorn 2m data-dcdb-2 Bound pvc-e36556ef-80aa-49ff-91ac-ad07f237e203 2Gi RWO longhorn 93s -``` You can see all three PVCs have `2Gi` of storage. We are now ready to apply the `DocumentDBAutoscaler` CR to set up storage autoscaling for this database. @@ -169,20 +169,23 @@ Here, Let's create the `DocumentDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/storage/autoscaling-storage.yaml -documentdbautoscaler.autoscaling.kubedb.com/dcdb-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/documentdb/autoscaler/storage/autoscaling-storage.yaml ``` +documentdbautoscaler.autoscaling.kubedb.com/dcdb-storage-autoscaler created #### Storage Autoscaling is set up successfully Let's check that the `documentdbautoscaler` resource is created successfully, ```bash -$ kubectl get documentdbautoscaler -n demo +kubectl get documentdbautoscaler -n demo +``` NAME AGE dcdb-storage-autoscaler 8s -$ kubectl describe documentdbautoscaler dcdb-storage-autoscaler -n demo +```bash +kubectl describe documentdbautoscaler dcdb-storage-autoscaler -n demo +``` Name: dcdb-storage-autoscaler Namespace: demo API Version: autoscaling.kubedb.com/v1alpha1 @@ -207,21 +210,20 @@ Spec: Upper Bound: 10Gi Usage Threshold: 60 Events: -``` So, the `documentdbautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volumes to exceed the `usageThreshold` using the `dd` command. The DocumentDB data directory is mounted at `/var/pv` (PVC `data-dcdb-`). The autoscaler evaluates usage per PVC, so we fill all three replicas. ```bash -$ for p in dcdb-0 dcdb-1 dcdb-2; do +for p in dcdb-0 dcdb-1 dcdb-2; do +``` kubectl exec -n demo $p -c documentdb -- sh -c 'dd if=/dev/zero of=/var/pv/_fill bs=1M count=1500; sync; df -h /var/pv' done ... /dev/longhorn/pvc-de4bfaa2-ea8e-4db5-b352-72abe3ab5b67 2.0G 1.8G 180M 91% /var/pv /dev/longhorn/pvc-ad3b996c-3ffe-460c-8da3-ea14d534d217 2.0G 1.7G 212M 90% /var/pv /dev/longhorn/pvc-e36556ef-80aa-49ff-91ac-ad07f237e203 2.0G 1.8G 180M 90% /var/pv -``` So, from the above output the storage usage of each PVC is around `90%`, which exceeds the `usageThreshold` of `60%`. @@ -239,23 +241,24 @@ client.go:88] Creating ops.kubedb.com/v1alpha1, Kind=DocumentDBOpsRequest demo/d Let's watch the `documentdbopsrequest` in the demo namespace to see if any `documentdbopsrequest` object is created. After some time you'll see that a `documentdbopsrequest` of type `VolumeExpansion` is created based on the `scalingRules`. ```bash -$ kubectl get documentdbopsrequest -n demo +kubectl get documentdbopsrequest -n demo +``` NAME TYPE STATUS AGE dcops-dcdb-w5q6tl VolumeExpansion Progressing 13s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get documentdbopsrequest -n demo +kubectl get documentdbopsrequest -n demo +``` NAME TYPE STATUS AGE dcops-dcdb-w5q6tl VolumeExpansion Successful 3m43s -``` We can see from the above output that the `DocumentDBOpsRequest` has succeeded. If we print its YAML we get an overview of the steps that were followed to expand the volume. ```bash -$ kubectl get documentdbopsrequest -n demo dcops-dcdb-w5q6tl -o yaml +kubectl get documentdbopsrequest -n demo dcops-dcdb-w5q6tl -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: DocumentDBOpsRequest metadata: @@ -305,34 +308,38 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Notice that the ops request body carries the computed size `3060559872` bytes (≈ `2.85Gi`) — the result of growing the `2Gi` volume by the `50%` `scalingRules` threshold — and `mode: Online`, so the expansion happens while the cluster stays available. Now, let's verify from the PVCs that the volume of the cluster database has expanded. ```bash -$ kubectl get pvc -n demo | grep dcdb +kubectl get pvc -n demo | grep dcdb +``` data-dcdb-0 Bound pvc-de4bfaa2-ea8e-4db5-b352-72abe3ab5b67 2920Mi RWO longhorn 27m data-dcdb-1 Bound pvc-ad3b996c-3ffe-460c-8da3-ea14d534d217 2920Mi RWO longhorn 26m data-dcdb-2 Bound pvc-e36556ef-80aa-49ff-91ac-ad07f237e203 2920Mi RWO longhorn 26m -$ kubectl exec -n demo dcdb-0 -c documentdb -- df -h /var/pv +```bash +kubectl exec -n demo dcdb-0 -c documentdb -- df -h /var/pv +``` Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-de4bfaa2-ea8e-4db5-b352-72abe3ab5b67 2.8G 1.8G 1.1G 63% /var/pv -``` The above output verifies that we have successfully autoscaled the volume of the DocumentDB cluster database from `2Gi` to `2920Mi` (≈ `2.85Gi`). With the larger volume the same data now sits at `63%` usage, below the threshold, so no further expansion is triggered. Finally, let's confirm the database is healthy over the MongoDB wire protocol: ```bash -$ PASS=$(kubectl get secret -n demo dcdb-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo dcdb-0 -c documentdb -- mongosh \ +PASS=$(kubectl get secret -n demo dcdb-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo dcdb-0 -c documentdb -- mongosh \ "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Cleaning Up diff --git a/docs/guides/documentdb/configuration/using-config-file.md b/docs/guides/documentdb/configuration/using-config-file.md index 19cc1d0c0f..f85e825be8 100644 --- a/docs/guides/documentdb/configuration/using-config-file.md +++ b/docs/guides/documentdb/configuration/using-config-file.md @@ -48,9 +48,9 @@ final files into a per-instance config Secret that is mounted into every pod. - To keep things isolated, this tutorial uses a separate namespace called `demo`: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/documentdb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/documentdb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -105,38 +105,41 @@ spec: Apply both: ```bash -$ kubectl apply -f documentdb-custom-config-secret.yaml +kubectl apply -f documentdb-custom-config-secret.yaml +``` secret/documentdb-custom-config created -$ kubectl apply -f cluster-config-secret.yaml -documentdb.kubedb.com/documentdb-cls-sample created + +```bash +kubectl apply -f cluster-config-secret.yaml ``` +documentdb.kubedb.com/documentdb-cls-sample created ### Inspect the rendered configuration The `spec.configuration` block on the object confirms which Secret is wired in: ```bash -$ kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.configuration}' -{"secretName":"documentdb-custom-config"} +kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.configuration}' ``` +{"secretName":"documentdb-custom-config"} The Secret holds the `user.conf` that KubeDB feeds into each replica: ```bash -$ kubectl get secret -n demo documentdb-custom-config -o jsonpath='{.data.user\.conf}' | base64 -d +kubectl get secret -n demo documentdb-custom-config -o jsonpath='{.data.user\.conf}' | base64 -d +``` max_connections=250 work_mem=8MB -``` KubeDB also provisions the cluster's two auth secrets alongside it — `documentdb-cls-sample-auth` (the MongoDB-compatibility `default_user`) and `documentdb-cls-sample-admin-auth` (the backend admin): ```bash -$ kubectl get secret -n demo | grep documentdb-cls-sample +kubectl get secret -n demo | grep documentdb-cls-sample +``` documentdb-cls-sample-admin-auth kubernetes.io/basic-auth 2 34m documentdb-cls-sample-auth kubernetes.io/basic-auth 2 34m -``` ### Verify the database is serving @@ -144,21 +147,24 @@ Connect over the MongoDB wire protocol (TLS, port `10260`) with the `default_use from `-auth` and ping: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } The primary accepts MongoDB-protocol traffic with the custom configuration applied. Tear the instance down before the next example: ```bash -$ kubectl delete docdb -n demo documentdb-cls-sample -documentdb.kubedb.com "documentdb-cls-sample" deleted +kubectl delete docdb -n demo documentdb-cls-sample ``` +documentdb.kubedb.com "documentdb-cls-sample" deleted ## Configuration inline @@ -199,9 +205,9 @@ spec: ``` ```bash -$ kubectl apply -f standalone-config-inline.yaml -documentdb.kubedb.com/documentdb-sa-sample created +kubectl apply -f standalone-config-inline.yaml ``` +documentdb.kubedb.com/documentdb-sa-sample created On a healthy instance the rendered `user.conf` would show `max_connections=300` / `work_mem=16MB`, overriding any Secret-supplied values. @@ -248,9 +254,9 @@ spec: ``` ```bash -$ kubectl apply -f standalone-config-tuning.yaml -documentdb.kubedb.com/documentdb-sa-sample created +kubectl apply -f standalone-config-tuning.yaml ``` +documentdb.kubedb.com/documentdb-sa-sample created On a healthy instance the auto-tuner emits a `pgtune.conf` derived from `profile: oltp`, `storageType: ssd`, and `maxConnections: 200` (tuned `shared_buffers`, `effective_cache_size`, diff --git a/docs/guides/documentdb/failure-and-disaster-recovery/failover.md b/docs/guides/documentdb/failure-and-disaster-recovery/failover.md index b0b0b8adac..1ac4a0f229 100644 --- a/docs/guides/documentdb/failure-and-disaster-recovery/failover.md +++ b/docs/guides/documentdb/failure-and-disaster-recovery/failover.md @@ -40,22 +40,26 @@ that committed data survives it. The leader is the pod labelled `kubedb.com/role=primary`: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 4m4s primary documentdb-cls-sample-1 2/2 Running 0 99s standby documentdb-cls-sample-2 2/2 Running 0 2m48s standby -``` `documentdb-cls-sample-0` is the leader. ## Write a test document on the primary ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval ' +``` db.getSiblingDB("failover").coll.insertOne({k:"before-failover", ts:new Date()}); printjson(db.getSiblingDB("failover").coll.findOne({k:"before-failover"}));' { @@ -63,16 +67,15 @@ $ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ k: 'before-failover', ts: ISODate('2026-06-30T15:46:05.334Z') } -``` ## Force a failover Simulate a node loss by force-deleting the leader pod: ```bash -$ kubectl delete pod -n demo documentdb-cls-sample-0 --grace-period=0 --force -pod "documentdb-cls-sample-0" force deleted from demo namespace +kubectl delete pod -n demo documentdb-cls-sample-0 --grace-period=0 --force ``` +pod "documentdb-cls-sample-0" force deleted from demo namespace ## Watch the re-election @@ -80,29 +83,30 @@ Within a few seconds a new primary is elected. The database briefly reports `Cri lost a quorum member) and returns to `Ready` once a new leader is serving: ```bash -$ # poll: kubectl get pods ... -L kubedb.com/role + kubectl get docdb +# poll: kubectl get pods ... -L kubedb.com/role + kubectl get docdb +``` [t+0s ] db=Critical primary='' sample-0=0/2 (terminating) sample-1=standby sample-2=standby [t+15s] db=Critical primary='documentdb-cls-sample-2' sample-0=2/2 (rejoining) sample-1=standby sample-2=primary [t+45s] db=Ready primary='documentdb-cls-sample-2' sample-0=standby sample-1=standby sample-2=primary -``` Final topology — `documentdb-cls-sample-2` is the new primary and the old leader has rejoined as a standby: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 56s standby documentdb-cls-sample-1 2/2 Running 0 2m37s standby documentdb-cls-sample-2 2/2 Running 0 3m46s primary -``` The coordinator log on the new primary tells the whole story: the Raft leader change is detected, the **healthiest** node (lowest LSN diff) is chosen, the PostgreSQL engine is promoted, and the pod is re-labelled `primary`: ```bash -$ kubectl logs -n demo documentdb-cls-sample-2 -c documentdb-coordinator | grep -iE 'leader|elect|primary|promot' +kubectl logs -n demo documentdb-cls-sample-2 -c documentdb-coordinator | grep -iE 'leader|elect|primary|promot' +``` on_Leader_change.go:71] *** Raft Leader Changed **** Checking if I can run as primary*** My current Role is standby on_Leader_change.go:350] Healthiest node detected documentdb-cls-sample-2 with LSN diff 0 bytes ha_postgres.go:286] Previous primary from this node is : documentdb-cls-sample-0 @@ -112,7 +116,6 @@ ha_postgres.go:760] This pod is now a primary exec_utils.go:159] demo/documentdb-cls-sample-2 is promoted as primary ha_postgres.go:800] Successfully patched pod demo/documentdb-cls-sample-2 to role "primary" on attempt 1 health.go:209] Timeline missmatch identified. proposing new leader timeline = 3 -``` ## Verify data continuity @@ -120,31 +123,33 @@ Reconnect to the **new** primary and read the document written before the failov intact: ```bash -$ kubectl exec -n demo documentdb-cls-sample-2 -c documentdb -- \ +kubectl exec -n demo documentdb-cls-sample-2 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'printjson(db.getSiblingDB("failover").coll.findOne({k:"before-failover"}));' +``` { _id: ObjectId('6a43e4bd2bb67b71d58563b1'), k: 'before-failover', ts: ISODate('2026-06-30T15:46:05.334Z') } -``` The cluster is back to `Ready` with all conditions healthy: ```bash -$ kubectl get docdb -n demo documentdb-cls-sample +kubectl get docdb -n demo documentdb-cls-sample +``` NAME NAMESPACE VERSION STATUS AGE documentdb-cls-sample demo pg17-0.109.0 Ready 13m -$ kubectl get docdb -n demo documentdb-cls-sample \ +```bash +kubectl get docdb -n demo documentdb-cls-sample \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` ProvisioningStarted=True :: The KubeDB operator has started the provisioning of DocumentDB: demo/documentdb-cls-sample ReplicaReady=True :: All replicas are ready for DocumentDB demo/documentdb-cls-sample AcceptingConnection=True :: The DocumentDB: demo/documentdb-cls-sample is accepting client requests. Ready=True :: The DocumentDB: demo/documentdb-cls-sample is ready. Provisioned=True :: The DocumentDB: demo/documentdb-cls-sample is successfully provisioned. -``` ## Summary diff --git a/docs/guides/documentdb/reconfigure/reconfigure.md b/docs/guides/documentdb/reconfigure/reconfigure.md index 1017008358..9d42067db9 100644 --- a/docs/guides/documentdb/reconfigure/reconfigure.md +++ b/docs/guides/documentdb/reconfigure/reconfigure.md @@ -42,12 +42,18 @@ You can read it from the internal PostgreSQL engine (port `9712`, backend-only) credentials from `-admin-auth`: ```bash -$ ADMINU=$(kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.username}' | base64 -d) -$ ADMINP=$(kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +ADMINU=$(kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.username}' | base64 -d) +``` + +```bash +ADMINP=$(kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ bash -lc "PGPASSWORD='$ADMINP' psql -h localhost -p 9712 -U '$ADMINU' -d postgres -tAc 'show max_connections'" -100 ``` +100 ## Apply a custom configuration @@ -68,24 +74,24 @@ spec: ``` ```bash -$ kubectl apply -f cluster-reconfigure.yaml -documentdbopsrequest.ops.kubedb.com/documentdb-cls-reconfigure created +kubectl apply -f cluster-reconfigure.yaml ``` +documentdbopsrequest.ops.kubedb.com/documentdb-cls-reconfigure created The operator performs a careful, leader-aware rollout: it transfers Raft leadership to the first pod, pauses the `documentdb-coordinator` so it does not trigger an automatic failover during the restart, then evicts the pod so it comes back with the new configuration mounted: ```bash -$ kubectl get dcops -n demo documentdb-cls-reconfigure \ +kubectl get dcops -n demo documentdb-cls-reconfigure \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: Reconfiguring DocumentDB Database ReconcileDocumentDBDatabase=True :: Successfully Reconciled DocumentDB Database TransferLeaderShipToFirstNodeBeforeCoordinatorPaused=True :: Successfully Transferred Leadership to first pod before documentdb-coordinator paused PausePgCoordinatorBeforeCustomRestart=True :: Successfully Pause DocumentDB-Coordinator Before Custom Restart EvictPod=True :: evict pod; ConditionStatus:True CheckPodReady--documentdb-cls-sample-0=False :: check pod ready; ConditionStatus:False; PodName:documentdb-cls-sample-0 -``` ## Remove a custom configuration @@ -106,9 +112,9 @@ spec: ``` ```bash -$ kubectl apply -f cluster-reconfigure-remove.yaml -documentdbopsrequest.ops.kubedb.com/documentdb-cls-reconfigure-remove created +kubectl apply -f cluster-reconfigure-remove.yaml ``` +documentdbopsrequest.ops.kubedb.com/documentdb-cls-reconfigure-remove created The operator performs the same leader-aware rolling restart, dropping the custom-config volume from each pod so `max_connections` returns to its default of `100`. diff --git a/docs/guides/documentdb/restart/restart.md b/docs/guides/documentdb/restart/restart.md index 9308883757..6b368edc31 100644 --- a/docs/guides/documentdb/restart/restart.md +++ b/docs/guides/documentdb/restart/restart.md @@ -28,9 +28,9 @@ so the MongoDB wire endpoint (port `10260`) stays serviceable throughout. - This tutorial uses a namespace called `demo`: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/documentdb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/documentdb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -57,21 +57,21 @@ spec: ``` ```bash -$ kubectl apply -f cluster.yaml -documentdb.kubedb.com/documentdb-cls-sample created +kubectl apply -f cluster.yaml ``` +documentdb.kubedb.com/documentdb-cls-sample created The cluster has three pods — one Raft `primary` and two `standby` replicas. Each pod runs `2/2` containers: the `documentdb` engine and the `documentdb-coordinator` (the Raft member that participates in leader election): ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 2m23s primary documentdb-cls-sample-1 2/2 Running 0 2m standby documentdb-cls-sample-2 2/2 Running 0 93s standby -``` ## Create the Restart OpsRequest @@ -91,19 +91,19 @@ spec: - `spec.databaseRef` holds the name of the `DocumentDB` (it must be in the same namespace). ```bash -$ kubectl apply -f cluster-restart.yaml -documentdbopsrequest.ops.kubedb.com/documentdb-cls-restart created +kubectl apply -f cluster-restart.yaml ``` +documentdbopsrequest.ops.kubedb.com/documentdb-cls-restart created Watch the OpsRequest until it reports `Successful` (`dcops` is the short name for `DocumentDBOpsRequest`; `docdb` is the short name for `DocumentDB`): ```bash -$ kubectl get dcops -n demo documentdb-cls-restart -w +kubectl get dcops -n demo documentdb-cls-restart -w +``` NAME TYPE STATUS AGE documentdb-cls-restart Restart Progressing 20s documentdb-cls-restart Restart Successful 3m52s -``` ## What happened @@ -112,8 +112,9 @@ primary (a controlled failover) before restarting it last, so a writable leader present. The status conditions tell the whole story: ```bash -$ kubectl get dcops -n demo documentdb-cls-restart \ +kubectl get dcops -n demo documentdb-cls-restart \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Restart=True :: DocumentDB ops request is restarting pods ResumePGCoordinator=True :: successfully resumed documentdb-coordinator SetRaftKeyOpsRequestProgressing=True :: Successfully Set Raft Key OpsRequestProgressing @@ -126,7 +127,6 @@ FailoverDone=True :: failover is done successfully RestartNodes=True :: Successfully restarted all nodes Successful=True :: Successfully completed the modification process. UnsetRaftKeyOpsRequestProgressing=True :: Successfully Unset Raft Key OpsRequestProgressing -``` ## After the restart @@ -135,22 +135,25 @@ transferred during the rolling restart, the `primary` role has moved to a differ is expected and harmless: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 66s standby documentdb-cls-sample-1 2/2 Running 0 2m51s primary documentdb-cls-sample-2 2/2 Running 0 2m1s standby -``` The database answers the MongoDB wire protocol immediately after the restart: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Standalone diff --git a/docs/guides/documentdb/rotate-authentication/rotate-authentication.md b/docs/guides/documentdb/rotate-authentication/rotate-authentication.md index fc2acb5059..2f32a0dd42 100644 --- a/docs/guides/documentdb/rotate-authentication/rotate-authentication.md +++ b/docs/guides/documentdb/rotate-authentication/rotate-authentication.md @@ -47,18 +47,21 @@ Postgres, which has a single auth secret): ## Credentials before rotation ```bash -$ kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d +``` EY1imAac)vqps)Ez -$ kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d -DQShSsn0Dqq7Uf*F + +```bash +kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d ``` +DQShSsn0Dqq7Uf*F The `-admin-auth` secret has no `password.prev` key yet (nothing has been rotated): ```bash -$ kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password\.prev}' - # (empty) +kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password\.prev}' ``` + # (empty) ## Create the RotateAuth OpsRequest @@ -75,20 +78,23 @@ spec: ``` ```bash -$ kubectl apply -f cluster-rotate-auth.yaml +kubectl apply -f cluster-rotate-auth.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-rotate-auth created -$ kubectl get dcops -n demo documentdb-cls-rotate-auth +```bash +kubectl get dcops -n demo documentdb-cls-rotate-auth +``` NAME TYPE STATUS AGE documentdb-cls-rotate-auth RotateAuth Successful 3m34s -``` The status conditions show the new credential being generated, applied to the primary, written into the PetSet, and then a rolling restart so all replicas pick it up: ```bash -$ kubectl get dcops -n demo documentdb-cls-rotate-auth \ +kubectl get dcops -n demo documentdb-cls-rotate-auth \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` RotateAuth=True :: DocumentDB ops request has started to rotate auth for documentdb UpdateCredential=True :: Successfully generated new credentials ApplyNewCredential=True :: Successfully applied rotated credential to the database primary @@ -99,7 +105,6 @@ RestartNodes=True :: Successfully restarted all the nodes RestartReadReplicas=True :: Successfully Restarted Read Replicas Successful=True :: Successfully Rotated DocumentDB Auth Secret UnsetRaftKeyOpsRequestProgressing=True :: Successfully Unset Raft Key OpsRequestProgressing -``` ## Credentials after rotation @@ -107,32 +112,41 @@ The admin password has changed, and the **old admin password is retained under `password.prev`**: ```bash -$ kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password}' | base64 -d +``` ELKnwAUT.I85QJ4g -$ kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password\.prev}' | base64 -d -EY1imAac)vqps)Ez + +```bash +kubectl get secret -n demo documentdb-cls-sample-admin-auth -o jsonpath='{.data.password\.prev}' | base64 -d ``` +EY1imAac)vqps)Ez The application `-auth` secret is **unchanged** — same password as before, and no `password.prev` was written: ```bash -$ kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d +``` DQShSsn0Dqq7Uf*F # identical to the "before" value -$ kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password\.prev}' - # (empty) + +```bash +kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password\.prev}' ``` + # (empty) Because the application credential did not change, existing MongoDB-wire clients keep working with no reconfiguration: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-1 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-1 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Summary diff --git a/docs/guides/documentdb/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/documentdb/scaling/horizontal-scaling/horizontal-scaling.md index a9eabe3a86..3b2b8bd9f5 100644 --- a/docs/guides/documentdb/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/documentdb/scaling/horizontal-scaling/horizontal-scaling.md @@ -36,15 +36,17 @@ Raft members** so the consensus group always reflects the live set of replicas. ## Starting point: 3 replicas ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 97s standby documentdb-cls-sample-1 2/2 Running 0 3m22s primary documentdb-cls-sample-2 2/2 Running 0 2m32s standby -$ kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.replicas}' -3 +```bash +kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.replicas}' ``` +3 ## Scale up: 3 → 5 @@ -63,20 +65,23 @@ spec: ``` ```bash -$ kubectl apply -f cluster-hscale-up.yaml +kubectl apply -f cluster-hscale-up.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-hscale-up created -$ kubectl get dcops -n demo documentdb-cls-hscale-up +```bash +kubectl get dcops -n demo documentdb-cls-hscale-up +``` NAME TYPE STATUS AGE documentdb-cls-hscale-up HorizontalScaling Successful 3m31s -``` Two new pods are provisioned (`-3`, `-4`) and **joined to the Raft group** as standbys. The status conditions show the new members being added via the coordinator: ```bash -$ kubectl get dcops -n demo documentdb-cls-hscale-up \ +kubectl get dcops -n demo documentdb-cls-hscale-up \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: DocumentDB ops request is horizontally scaling database GetCurrentLeader--documentdb-cls-sample-0=True :: get current leader; ConditionStatus:True AddRaftNode--documentdb-cls-sample-3=True :: add raft node; ConditionStatus:True; PodName:documentdb-cls-sample-3 @@ -84,19 +89,18 @@ PatchPetset=True :: patch petset; ConditionStatus:True AddRaftNode--documentdb-cls-sample-4=True :: add raft node; ConditionStatus:True; PodName:documentdb-cls-sample-4 HorizontalScaleUp=True :: Successfully Horizontally Scaled Up Successful=True :: Successfully Horizontally Scaled DocumentDB -``` The cluster now runs five pods — one primary and four standbys: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 5m7s standby documentdb-cls-sample-1 2/2 Running 0 6m52s primary documentdb-cls-sample-2 2/2 Running 0 6m2s standby documentdb-cls-sample-3 2/2 Running 0 2m56s standby documentdb-cls-sample-4 2/2 Running 0 106s standby -``` ## Scale down: 5 → 3 @@ -115,20 +119,23 @@ spec: ``` ```bash -$ kubectl apply -f cluster-hscale-down.yaml +kubectl apply -f cluster-hscale-down.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-hscale-down created -$ kubectl get dcops -n demo documentdb-cls-hscale-down +```bash +kubectl get dcops -n demo documentdb-cls-hscale-down +``` NAME TYPE STATUS AGE documentdb-cls-hscale-down HorizontalScaling Successful 2m43s -``` On the way down the operator first **removes the surplus Raft members**, then deletes their pods and their PVCs, so no orphaned storage is left behind: ```bash -$ kubectl get dcops -n demo documentdb-cls-hscale-down \ +kubectl get dcops -n demo documentdb-cls-hscale-down \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: DocumentDB ops request is horizontally scaling database GetCurrentRaftLeader--documentdb-cls-sample-0=True :: get current raft leader; ConditionStatus:True RemoveRaftNode--documentdb-cls-sample-4=True :: remove raft node; ConditionStatus:True; PodName:documentdb-cls-sample-4 @@ -138,23 +145,27 @@ RemoveRaftNode--documentdb-cls-sample-3=True :: remove raft node; ConditionStatu DeletePvc--documentdb-cls-sample-3=True :: delete pvc; ConditionStatus:True; PodName:documentdb-cls-sample-3 HorizontalScaleDown=True :: Successfully Horizontally Scaled Down Successful=True :: Successfully Horizontally Scaled DocumentDB -``` Back to the original three-pod topology, still fully serviceable: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=documentdb-cls-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE documentdb-cls-sample-0 2/2 Running 0 8m1s standby documentdb-cls-sample-1 2/2 Running 0 9m46s primary documentdb-cls-sample-2 2/2 Running 0 8m56s standby -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-1 -c documentdb -- \ +```bash +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-1 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Key takeaway diff --git a/docs/guides/documentdb/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/documentdb/scaling/vertical-scaling/vertical-scaling.md index 0f32358015..c3ecb332e7 100644 --- a/docs/guides/documentdb/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/documentdb/scaling/vertical-scaling/vertical-scaling.md @@ -36,11 +36,11 @@ primary last) so the cluster stays available. ## Resources before ```bash -$ kubectl get docdb -n demo documentdb-cls-sample \ +kubectl get docdb -n demo documentdb-cls-sample \ -o jsonpath='{range .spec.podTemplate.spec.containers[*]}{.name}: requests={.resources.requests} limits={.resources.limits}{"\n"}{end}' +``` documentdb: requests={"cpu":"500m","memory":"2Gi"} limits={"memory":"2Gi"} documentdb-coordinator: requests={"cpu":"200m","memory":"256Mi"} limits={"memory":"256Mi"} -``` ## Create the VerticalScaling OpsRequest @@ -74,20 +74,23 @@ spec: ``` ```bash -$ kubectl apply -f cluster-vertical-scaling.yaml +kubectl apply -f cluster-vertical-scaling.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-vscale created -$ kubectl get dcops -n demo documentdb-cls-vscale +```bash +kubectl get dcops -n demo documentdb-cls-vscale +``` NAME TYPE STATUS AGE documentdb-cls-vscale VerticalScaling Successful 3m33s -``` The status conditions show the PetSet being patched and each pod being evicted and re-checked for readiness before the next is touched: ```bash -$ kubectl get dcops -n demo documentdb-cls-vscale \ +kubectl get dcops -n demo documentdb-cls-vscale \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: Vertical Scaling is in progress UpdatePetSets=True :: Successfully updated petsets resources EvictPod=True :: evict pod; ConditionStatus:True @@ -96,7 +99,6 @@ CheckReplicaFunc=True :: check replica func; ConditionStatus:True VerticalScale=True :: VerticalScaleSucceeded RestartReadReplicas=True :: Successfully Restarted Read Replicas Successful=True :: Successfully Vertically Scaled Database -``` ## Resources after @@ -104,30 +106,33 @@ Both containers reflect the new sizing (note `2.5Gi` is normalized to its binary `2560Mi`, and the `documentdb` container now carries a CPU limit of `1`): ```bash -$ kubectl get docdb -n demo documentdb-cls-sample \ +kubectl get docdb -n demo documentdb-cls-sample \ -o jsonpath='{range .spec.podTemplate.spec.containers[*]}{.name}: requests={.resources.requests} limits={.resources.limits}{"\n"}{end}' +``` documentdb: requests={"cpu":"600m","memory":"2560Mi"} limits={"cpu":"1","memory":"2560Mi"} documentdb-coordinator: requests={"cpu":"100m","memory":"256Mi"} limits={"memory":"256Mi"} -``` The live pod spec matches — the change propagated all the way to the running containers: ```bash -$ kubectl get pod -n demo documentdb-cls-sample-0 \ +kubectl get pod -n demo documentdb-cls-sample-0 \ -o jsonpath='{range .spec.containers[*]}{.name}: req={.resources.requests} lim={.resources.limits}{"\n"}{end}' +``` documentdb: req={"cpu":"600m","memory":"2560Mi"} lim={"cpu":"1","memory":"2560Mi"} documentdb-coordinator: req={"cpu":"100m","memory":"256Mi"} lim={"memory":"256Mi"} -``` The cluster remains healthy and accepts MongoDB traffic after the rollout: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Standalone diff --git a/docs/guides/documentdb/storage-migration/storage-migration.md b/docs/guides/documentdb/storage-migration/storage-migration.md index e574343c7e..193952ac2d 100644 --- a/docs/guides/documentdb/storage-migration/storage-migration.md +++ b/docs/guides/documentdb/storage-migration/storage-migration.md @@ -40,16 +40,18 @@ directory is copied verbatim, so the migrated replica does not have to re-stream The cluster is on `longhorn`, `10Gi` per replica: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName,STATUS:.status.phase +``` NAME SIZE SC STATUS data-documentdb-cls-sample-0 10Gi longhorn Bound data-documentdb-cls-sample-1 10Gi longhorn Bound data-documentdb-cls-sample-2 10Gi longhorn Bound -$ kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.storage.storageClassName}' -longhorn +```bash +kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.storage.storageClassName}' ``` +longhorn ## Create the StorageMigration OpsRequest @@ -73,13 +75,15 @@ spec: ``` ```bash -$ kubectl apply -f cluster-storage-migration.yaml +kubectl apply -f cluster-storage-migration.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-storage-migration created -$ kubectl get dcops -n demo documentdb-cls-storage-migration +```bash +kubectl get dcops -n demo documentdb-cls-storage-migration +``` NAME TYPE STATUS AGE documentdb-cls-storage-migration StorageMigration Successful 8m13s -``` ## What happened @@ -90,8 +94,9 @@ old PVC, binds the new one under the original PVC name, recreates the pod, and w be ready. The condition stream (trimmed) captures the loop: ```bash -$ kubectl get dcops -n demo documentdb-cls-storage-migration \ +kubectl get dcops -n demo documentdb-cls-storage-migration \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: StorageClass migration is in progress PetSetDeleted--documentdb-cls-sample=True :: pet set deleted GetStorageClass=True :: get storage class @@ -111,7 +116,6 @@ PodMigrationCompleted-documentdb-cls-sample-2=True :: PVC Migration Completed fo StorageMigration=True :: Successfully migrated StorageClass for DocumentDB Database Successful=True :: Successfully Migrated DocumentDB StorageClass UnsetRaftKeyOpsRequestProgressing=True :: Successfully Unset Raft Key OpsRequestProgressing -``` ## PVCs after @@ -119,27 +123,32 @@ All three data volumes are now backed by `standard-custom`, keeping their `10Gi` original PVC names, and the `DocumentDB` object reflects the new StorageClass: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName,STATUS:.status.phase +``` NAME SIZE SC STATUS data-documentdb-cls-sample-0 10Gi standard-custom Bound data-documentdb-cls-sample-1 10Gi standard-custom Bound data-documentdb-cls-sample-2 10Gi standard-custom Bound -$ kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='sc={.spec.storage.storageClassName} phase={.status.phase}' -sc=standard-custom phase=Ready +```bash +kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='sc={.spec.storage.storageClassName} phase={.status.phase}' ``` +sc=standard-custom phase=Ready The cluster is `Ready`, all pods `2/2`, and previously written data survived the migration intact: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'printjson(db.runCommand({ping:1}));' -{ ok: 1 } ``` +{ ok: 1 } > [!NOTE] > In the test environment, migrating to `standard-custom` (backed by the `local-path` diff --git a/docs/guides/documentdb/volume-expansion/volume-expansion.md b/docs/guides/documentdb/volume-expansion/volume-expansion.md index 5203712a99..bd07ca4b36 100644 --- a/docs/guides/documentdb/volume-expansion/volume-expansion.md +++ b/docs/guides/documentdb/volume-expansion/volume-expansion.md @@ -37,13 +37,13 @@ backup/restore and no manual PVC editing required. This guide expands a 3-node c ## PVCs before ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName,STATUS:.status.phase +``` NAME SIZE SC STATUS data-documentdb-cls-sample-0 5Gi longhorn Bound data-documentdb-cls-sample-1 5Gi longhorn Bound data-documentdb-cls-sample-2 5Gi longhorn Bound -``` ## Create the VolumeExpansion OpsRequest @@ -67,21 +67,24 @@ spec: ``` ```bash -$ kubectl apply -f cluster-volume-expansion.yaml +kubectl apply -f cluster-volume-expansion.yaml +``` documentdbopsrequest.ops.kubedb.com/documentdb-cls-volume-expansion created -$ kubectl get dcops -n demo documentdb-cls-volume-expansion +```bash +kubectl get dcops -n demo documentdb-cls-volume-expansion +``` NAME TYPE STATUS AGE documentdb-cls-volume-expansion VolumeExpansion Successful 4m49s -``` The status conditions walk through the offline-expansion mechanics: the operator deletes the PetSet, then for each replica it deletes the pod, expands the PVC, recreates the pod, and waits for it to become ready, before finally recreating the PetSet: ```bash -$ kubectl get dcops -n demo documentdb-cls-volume-expansion \ +kubectl get dcops -n demo documentdb-cls-volume-expansion \ -o jsonpath='{range .status.conditions[*]}{.type}={.status} :: {.message}{"\n"}{end}' +``` Running=True :: Volume Expansion is in progress DeletePetset=True :: delete petset; ConditionStatus:True IsPvcData-documentdb-cls-sample-0Updated=True :: is pvc data-documentdb-cls-sample-0 updated; ConditionStatus:True @@ -92,7 +95,6 @@ IsPvcData-documentdb-cls-sample-1Updated=True :: is pvc data-documentdb-cls-samp VolumeExpansion=True :: Offline Volume Expansion performed successfully in DocumentDB pods ReadyPetSets=True :: PetSet is recreated Successful=True :: Successfully Expanded Volume. -``` ## PVCs after @@ -100,26 +102,31 @@ All three data volumes are now `10Gi`, and the `DocumentDB` object's storage req to match: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=documentdb-cls-sample \ -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName,STATUS:.status.phase +``` NAME SIZE SC STATUS data-documentdb-cls-sample-0 10Gi longhorn Bound data-documentdb-cls-sample-1 10Gi longhorn Bound data-documentdb-cls-sample-2 10Gi longhorn Bound -$ kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.storage.resources.requests.storage}' -10Gi +```bash +kubectl get docdb -n demo documentdb-cls-sample -o jsonpath='{.spec.storage.resources.requests.storage}' ``` +10Gi The cluster is healthy and serving traffic after the expansion: ```bash -$ PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ +PASS=$(kubectl get secret -n demo documentdb-cls-sample-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -n demo documentdb-cls-sample-0 -c documentdb -- \ mongosh "mongodb://default_user:${PASS}@localhost:10260/?tls=true&tlsAllowInvalidCertificates=true" \ --quiet --eval 'db.runCommand({ ping: 1 })' -{ ok: 1 } ``` +{ ok: 1 } ## Standalone diff --git a/docs/guides/druid/autoscaler/compute/guide.md b/docs/guides/druid/autoscaler/compute/guide.md index 0ebae20334..ce4b854ba6 100644 --- a/docs/guides/druid/autoscaler/compute/guide.md +++ b/docs/guides/druid/autoscaler/compute/guide.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/druid](/docs/examples/druid) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -50,18 +50,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` + +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -87,9 +94,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, we are going to deploy a `Druid` combined cluster with version `36.0.0`. @@ -118,28 +125,29 @@ spec: Let's create the `Druid` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 0s druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 24s . . druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 118s -``` ## Druid Topology Autoscaler Let's check the Druid resources for coordinators and historicals, ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.podTemplate.spec.containers[].resources' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -150,7 +158,9 @@ $ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinat } } -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.podTemplate.spec.containers[].resources' +```bash +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -160,12 +170,12 @@ $ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historica "memory": "1Gi" } } -``` Let's check the coordinators and historicals Pod containers resources, ```bash -$ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -176,7 +186,9 @@ $ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.conta } } -$ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -186,7 +198,6 @@ $ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.contai "memory": "1Gi" } } -``` You can see from the above outputs that the resources for coordinators and historicals are same as the one we have assigned while deploying the druid. @@ -254,16 +265,17 @@ Here, Let's create the `DruidAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/druid-autoscaler.yaml -druidautoscaler.autoscaling.kubedb.com/druid-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/compute/yamls/druid-autoscaler.yaml ``` +druidautoscaler.autoscaling.kubedb.com/druid-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `druidautoscaler` resource is created successfully, ```bash -$ kubectl describe druidautoscaler druid-autoscaler -n demo +kubectl describe druidautoscaler druid-autoscaler -n demo +``` kubectl describe druidautoscaler druid-autoscaler -n demo Name: druid-autoscaler Namespace: demo @@ -482,7 +494,6 @@ Status: Memory: 5Gi Vpa Name: druid-cluster-coordinators Events: -``` So, the `druidautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `druidopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. @@ -490,27 +501,27 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `druidopsrequest` in the demo namespace to see if any `druidopsrequest` object is created. After some time you'll see that a `druidopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get druidopsrequest -n demo +watch kubectl get druidopsrequest -n demo +``` Every 2.0s: kubectl get druidopsrequest -n demo NAME TYPE STATUS AGE drops-druid-cluster-coordinators-g02xtu VerticalScaling Progressing 8m drops-druid-cluster-historicals-g3oqje VerticalScaling Progressing 8m - -``` Progressing Let's wait for the ops request to become successful. ```bash -$ kubectl get druidopsrequest -n demo +kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE drops-druid-cluster-coordinators-g02xtu VerticalScaling Successful 12m drops-druid-cluster-historicals-g3oqje VerticalScaling Successful 13m -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe druidopsrequests -n demo drops-druid-cluster-coordinators-f6qbth +kubectl describe druidopsrequests -n demo drops-druid-cluster-coordinators-f6qbth +``` Name: drops-druid-cluster-coordinators-g02xtu Namespace: demo Labels: app.kubernetes.io/component=database @@ -648,12 +659,12 @@ Events: Normal RestartPods 12m KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 12m KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 12m KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-druid-cluster-coordinators-g02xtu -``` Let's describe the other `DruidOpsRequest` created for scaling of historicals. ```bash -$ kubectl describe druidopsrequests -n demo drops-druid-cluster-historicals-g3oqje +kubectl describe druidopsrequests -n demo drops-druid-cluster-historicals-g3oqje +``` Name: drops-druid-cluster-historicals-g3oqje Namespace: demo Labels: app.kubernetes.io/component=database @@ -792,12 +803,11 @@ Events: Normal Starting 16m KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 16m KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-druid-cluster-historicals-g3oqje -``` - Now, we are going to verify from the Pod, and the Druid yaml whether the resources of the coordinators and historicals node has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -808,7 +818,9 @@ $ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.conta } } -$ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -819,7 +831,9 @@ $ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.contai } } -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.podTemplate.spec.containers[].resources' +```bash +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -830,7 +844,9 @@ $ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinat } } -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.podTemplate.spec.containers[].resources' +```bash +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -840,7 +856,6 @@ $ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historica "memory": "2Gi" } } -``` The above output verifies that we have successfully auto scaled the resources of the Druid topology cluster for coordinators and historicals. diff --git a/docs/guides/druid/autoscaler/storage/guide.md b/docs/guides/druid/autoscaler/storage/guide.md index 7247f7af45..4212300f08 100644 --- a/docs/guides/druid/autoscaler/storage/guide.md +++ b/docs/guides/druid/autoscaler/storage/guide.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Druid To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/druid](/docs/examples/druid) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,12 +48,12 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 28h longhorn (default) driver.longhorn.io Delete Immediate true 28h longhorn-static driver.longhorn.io Delete Immediate true 28h -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -66,18 +66,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` + +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -103,9 +110,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created ### Deploy Druid Cluster @@ -157,34 +164,40 @@ spec: Let's create the `Druid` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 0s druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 24s . . druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 2m20s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-2c0ef2aa-0438-4d75-9cb2-c12a176bae6a 1Gi RWO Delete Bound demo/druid-cluster-base-task-dir-druid-cluster-middlemanagers-0 longhorn 95s pvc-5f4cea5f-e0c8-4339-b67c-9cb8b02ba49d 1Gi RWO Delete Bound demo/druid-cluster-segment-cache-druid-cluster-historicals-0 longhorn 96s -``` You can see the petset for both historicals and middleManagers has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -231,20 +244,23 @@ Here, Let's create the `DruidAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/druid-storage-autoscaler.yaml -druidautoscaler.autoscaling.kubedb.com/druid-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/autoscaler/storage/yamls/druid-storage-autoscaler.yaml ``` +druidautoscaler.autoscaling.kubedb.com/druid-storage-autoscaler created #### Storage Autoscaling is set up successfully Let's check that the `druidautoscaler` resource is created successfully, ```bash -$ kubectl get druidautoscaler -n demo +kubectl get druidautoscaler -n demo +``` NAME AGE druid-storage-autoscaler 34s -$ kubectl describe druidautoscaler -n demo druid-storage-autoscaler +```bash +kubectl describe druidautoscaler -n demo druid-storage-autoscaler +``` Name: druid-storage-autoscaler Namespace: demo Labels: @@ -324,7 +340,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `druidautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -334,7 +349,8 @@ We are autoscaling volume for both historicals and middleManagers. So we need to 1. Lets exec into the historicals pod and fill the cluster volume using the following commands: ```bash -$ kubectl exec -it -n demo druid-cluster-historicals-0 -- bash +kubectl exec -it -n demo druid-cluster-historicals-0 -- bash +``` bash-5.1$ df -h /druid/data/segments Filesystem Size Used Available Use% Mounted on /dev/longhorn/pvc-d4ef15ef-b1af-4a1f-ad25-ad9bc990a2fb 973.4M 92.0K 957.3M 0% /druid/data/segment @@ -347,12 +363,12 @@ bash-5.1$ dd if=/dev/zero of=/druid/data/segments/file.img bs=600M count=1 bash-5.1$ df -h /druid/data/segments Filesystem Size Used Available Use% Mounted on /dev/longhorn/pvc-d4ef15ef-b1af-4a1f-ad25-ad9bc990a2fb 973.4M 600.1M 357.3M 63% /druid/data/segments -``` 2. Let's exec into the middleManagers pod and fill the cluster volume using the following commands: ```bash -$ kubectl exec -it -n demo druid-cluster-middleManagers-0 -- bash +kubectl exec -it -n demo druid-cluster-middleManagers-0 -- bash +``` druid@druid-cluster-middleManagers-0:~$ df -h /var/druid/task Filesystem Size Used Available Use% Mounted on /dev/longhorn/pvc-2c0ef2aa-0438-4d75-9cb2-c12a176bae6a 973.4M 24.0K 957.4M 0% /var/druid/task @@ -363,7 +379,6 @@ druid@druid-cluster-middleManagers-0:~$ dd if=/dev/zero of=/var/druid/task/file. druid@druid-cluster-middleManagers-0:~$ df -h /var/druid/task Filesystem Size Used Available Use% Mounted on /dev/longhorn/pvc-2c0ef2aa-0438-4d75-9cb2-c12a176bae6a 973.4M 600.0M 357.4M 63% /var/druid/task -``` So, from the above output we can see that the storage usage is 63% for both nodes, which exceeded the `usageThreshold` 60%. @@ -371,25 +386,26 @@ There will be two `DruidOpsRequest` created for both historicals and middleManag Let's watch the `druidopsrequest` in the demo namespace to see if any `druidopsrequest` object is created. After some time you'll see that a `druidopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get druidopsrequest -n demo +watch kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druidopsrequest.ops.kubedb.com/drops-druid-cluster-gq9huj VolumeExpansion Progressing 46s druidopsrequest.ops.kubedb.com/drops-druid-cluster-kbw4fd VolumeExpansion Successful 4m46s -``` Once ops request has succeeded. Let's wait for the other one to become successful. ```bash -$ kubectl get druidopsrequest -n demo +kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druidopsrequest.ops.kubedb.com/drops-druid-cluster-gq9huj VolumeExpansion Successful 3m18s druidopsrequest.ops.kubedb.com/drops-druid-cluster-kbw4fd VolumeExpansion Successful 7m18s -``` We can see from the above output that the both `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` one by one we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe druidopsrequest -n demo drops-druid-cluster-kbw4fd +kubectl describe druidopsrequest -n demo drops-druid-cluster-kbw4fd +``` Name: drops-druid-cluster-kbw4fd Namespace: demo Labels: app.kubernetes.io/component=database @@ -624,10 +640,10 @@ Events: Normal UpdatePetSets 5m18s KubeDB Ops-manager Operator successfully reconciled the Druid resources Normal UpdatePetSets 5m8s KubeDB Ops-manager Operator successfully reconciled the Druid resources Normal UpdatePetSets 4m57s KubeDB Ops-manager Operator successfully reconciled the Druid resources -``` ```bash -$ kubectl describe druidopsrequest -n demo drops-druid-cluster-gq9huj +kubectl describe druidopsrequest -n demo drops-druid-cluster-gq9huj +``` Name: drops-druid-cluster-gq9huj Namespace: demo Labels: app.kubernetes.io/component=database @@ -859,20 +875,25 @@ Events: Normal ReadyPetSets 2m35s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 2m35s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 2m35s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-druid-cluster-gq9huj -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the topology cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2041405440" -$ kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2041405440" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-2c0ef2aa-0438-4d75-9cb2-c12a176bae6a 1948Mi RWO Delete Bound demo/druid-cluster-base-task-dir-druid-cluster-middlemanagers-0 longhorn 19m pvc-5f4cea5f-e0c8-4339-b67c-9cb8b02ba49d 1948Mi RWO Delete Bound demo/druid-cluster-segment-cache-druid-cluster-historicals-0 longhorn 19m -``` The above output verifies that we have successfully autoscaled the volume of the Druid topology cluster for both historicals and middleManagers. diff --git a/docs/guides/druid/backup/application-level/index.md b/docs/guides/druid/backup/application-level/index.md index 88fb5d2903..b7d3cd3511 100644 --- a/docs/guides/druid/backup/application-level/index.md +++ b/docs/guides/druid/backup/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/druid/backup/application-level/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -59,19 +59,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -97,9 +103,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created Let's deploy a sample `Druid` database and insert some data into it. @@ -132,35 +138,37 @@ Here, Create the above `Druid` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/sample-druid.yaml -druid.kubedb.com/sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/sample-druid.yaml ``` +druid.kubedb.com/sample-druid created KubeDB will deploy a Druid database according to the above specification. It will also create the necessary Secrets and Services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get druids.kubedb.com -n demo +kubectl get druids.kubedb.com -n demo +``` NAME TYPE VERSION STATUS AGE sample-druid kubedb.com/v1alpha2 36.0.0 Ready 4m14s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE DATA AGE sample-druid-auth kubernetes.io/basic-auth 2 2m34s sample-druid-config Opaque 11 2m34s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-druid-brokers ClusterIP 10.128.135.115 8082/TCP 2m53s sample-druid-coordinators ClusterIP 10.128.16.222 8081/TCP 2m53s sample-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 2m53s sample-druid-routers ClusterIP 10.128.191.186 8888/TCP 2m53s -``` Here, we have to use service `sample-druid-routers` and secret `sample-druid-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/druid/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -181,19 +189,19 @@ We can see that KubeDB has deployed a `MySQL` and a `ZooKeeper` instance as [Ext Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-druid kubedb.com/druid 36.0.0 4m7s sample-druid-mysql-metadata kubedb.com/mysql 9.1.0 6m31s sample-druid-zk kubedb.com/zookeeper 3.7.2 6m34s -``` Here `sample-druid` is the `AppBinding` of Druid, while `sample-druid-mysql-metadata` and `sample-druid-zk` are the `AppBinding` of `MySQL` and `ZooKeeper` instances that `KubeDB` has deployed as the [External dependencies](https://druid.apache.org/docs/latest/design/architecture/#external-dependencies) of `Druid` Let's check the YAML of the `AppBinding` of druid, ```bash -$ kubectl get appbindings -n demo sample-druid -o yaml +kubectl get appbindings -n demo sample-druid -o yaml ``` ```yaml @@ -261,16 +269,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. @@ -311,13 +319,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -346,9 +360,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -379,9 +393,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -394,8 +408,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -456,27 +473,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-druid-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-druid-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-druid-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-druid-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/druid` directory. @@ -487,10 +504,10 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-druid-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** @@ -499,11 +516,10 @@ KubeStash triggers an instant backup as soon as the `BackupConfiguration` is rea Run the following command to watch `BackupSession` CR, ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-druid-backup-frequent-backup-1724065200 BackupConfiguration sample-druid-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -512,18 +528,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-druid-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-druid-repo +kubectl get repository -n demo gcs-druid-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-druid-repo true 4 664.979 KiB Ready 2m55s 4h56m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-druid-repo-sample-druid-backup-frequent-backup-1726830540 gcs-druid-repo frequent-backup 2024-09-20T11:09:00Z Delete Succeeded 3m13s -``` > **Note**: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -536,7 +552,7 @@ gcs-druid-repo-sample-druid-backup-frequent-backup-1726830540 gcs-druid-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1725359100 -oyaml +kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1725359100 -oyaml ``` ```yaml @@ -638,9 +654,9 @@ In this section, we are going to restore the entire database from the backup tha Now, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -687,19 +703,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-druid created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. #### Verify Restored Druid Manifest: @@ -707,22 +723,22 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `Druid` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get druids.kubedb.com -n dev +kubectl get druids.kubedb.com -n dev +``` NAME VERSION STATUS AGE restored-druid 36.0.0 Ready 39m -``` The output confirms that the `Druid` database has been successfully created with the same configuration as it had at the time of backup. Verify the dependencies have been restored: ```bash -$ kubectl get mysql,zk -n dev +kubectl get mysql,zk -n dev +``` NAME VERSION STATUS AGE mysql.kubedb.com/restored-druid-mysql-metadata 9.1.0 Ready 2m52s NAME TYPE VERSION STATUS AGE zookeeper.kubedb.com/restored-druid-zk kubedb.com/v1alpha2 3.7.2 Ready 2m42s -``` The output confirms that the `MySQL` and `ZooKeper` databases have been successfully created with the same configuration as it had at the time of backup. @@ -733,22 +749,22 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get druid -n dev restored-druid +kubectl get druid -n dev restored-druid +``` NAME VERSION STATUS AGE restored-druid 36.0.0 Ready 34m -``` Now, let's verify if our datasource `wikipedia` exists or not. For that, first find out the database `Sevices` by the following command, Now access the [web console](https://druid.apache.org/docs/latest/operations/web-console) of Druid database from any browser by port-forwarding the routers. Let’s port-forward the port `8888` to local machine: ```bash -$ kubectl get svc -n dev --selector="app.kubernetes.io/instance=restored-druid" +kubectl get svc -n dev --selector="app.kubernetes.io/instance=restored-druid" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE restored-druid-brokers ClusterIP 10.128.74.54 8082/TCP 10m restored-druid-coordinators ClusterIP 10.128.30.124 8081/TCP 10m restored-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 10m restored-druid-routers ClusterIP 10.128.228.193 8888/TCP 10m -``` ```bash kubectl port-forward -n dev svc/restored-druid-routers 8888 Forwarding from 127.0.0.1:8888 -> 8888 @@ -760,16 +776,16 @@ Then hit the `http://localhost:8888` from any browser, and you will be prompted - Username: ```bash - $ kubectl get secret -n dev restored-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n dev restored-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n dev restored-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n dev restored-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. Now if you go to the `Datasources` section, you will see that our ingested datasource `wikipedia` exists in the list.

  lifecycle diff --git a/docs/guides/druid/backup/auto-backup/index.md b/docs/guides/druid/backup/auto-backup/index.md index 923796b813..f71a451240 100644 --- a/docs/guides/druid/backup/auto-backup/index.md +++ b/docs/guides/druid/backup/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare Backend @@ -51,13 +51,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -86,9 +92,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created **Create RetentionPolicy:** @@ -117,9 +123,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -128,11 +134,14 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created ## Auto-backup with default configurations @@ -192,9 +201,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/druid-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/druid-default-backup-blueprint created Now, we are ready to backup our `Druid` databases using a few annotations. @@ -208,19 +217,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -246,9 +261,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created Let's deploy a sample `Druid` database and insert some data into it. @@ -284,24 +299,24 @@ Here, Create the above `Druid` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/sample-druid.yaml -druid.kubedb.com/sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/sample-druid.yaml ``` +druid.kubedb.com/sample-druid created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our Druid in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-druid Ready 8m48s -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-druid -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-druid -o yaml ``` ```yaml @@ -380,13 +395,12 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-druid-frequent-backup-1726741846 BackupConfiguration appbinding-sample-druid Succeeded 28s 10m appbinding-sample-druid-frequent-backup-1726742101 BackupConfiguration appbinding-sample-druid Succeeded 35s 6m37s appbinding-sample-druid-frequent-backup-1726742400 BackupConfiguration appbinding-sample-druid Succeeded 29s 98s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -395,20 +409,20 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 3 1.757 MiB Ready 2m23s 11m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-samruid-frequent-backup-1726741846 default-blueprint frequent-backup 2024-09-19T10:30:56Z Delete Succeeded 11m default-blueprint-appbinding-samruid-frequent-backup-1726742101 default-blueprint frequent-backup 2024-09-19T10:35:01Z Delete Succeeded 7m49s default-blueprint-appbinding-samruid-frequent-backup-1726742400 default-blueprint frequent-backup 2024-09-19T10:40:00Z Delete Succeeded 2m50s -``` > **Note**: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -421,7 +435,7 @@ default-blueprint-appbinding-samruid-frequent-backup-1726742400 default-bluepr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-samruid-frequent-backup-1726741846 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-samruid-frequent-backup-1726741846 -oyaml ``` ```yaml @@ -556,9 +570,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/druid-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/druid-customize-backup-blueprint created Now, we are ready to backup our `Druid` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -603,24 +617,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `Druid` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/sample-druid-2.yaml -druid.kubedb.com/sample-druid-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/auto-backup/examples/sample-druid-2.yaml ``` +druid.kubedb.com/sample-druid-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our Druid in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-druid-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-druid-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-druid-2 -o yaml ``` ```yaml @@ -701,11 +715,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-druid-2-frequent-backup-1726743656 BackupConfiguration appbinding-sample-druid-2 Succeeded 30s 2m32s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -714,18 +727,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-sid-2-frequent-backup-1726743656 customize-blueprint frequent-backup 2024-09-19T11:01:06Z Delete Succeeded 2m56s -``` > **Note**: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -738,7 +751,7 @@ customize-blueprint-appbinding-sid-2-frequent-backup-1726743656 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-sid-2-frequent-backup-1726743656 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-sid-2-frequent-backup-1726743656 -oyaml ``` ```yaml diff --git a/docs/guides/druid/backup/cross-ns-dependencies/index.md b/docs/guides/druid/backup/cross-ns-dependencies/index.md index 55dd8dfcf0..075e30154b 100644 --- a/docs/guides/druid/backup/cross-ns-dependencies/index.md +++ b/docs/guides/druid/backup/cross-ns-dependencies/index.md @@ -40,13 +40,19 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo`, `dev` and `dev1` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl create ns dev + +```bash +kubectl create ns dev +``` namespace/dev created -$ kubectl create ns dev1 -namespace/dev1 created + +```bash +kubectl create ns dev1 ``` +namespace/dev1 created > **Note:** YAML files used in this tutorial are stored in [docs/guides/druid/backup/application-level/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/cross-ns-dependencies/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,19 +72,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -104,9 +116,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created Let's deploy a sample `Druid` database and insert some data into it. @@ -147,49 +159,53 @@ Here, Create the above `Druid` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/sample-druid.yaml -druid.kubedb.com/sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/sample-druid.yaml ``` +druid.kubedb.com/sample-druid created KubeDB will deploy a Druid database according to the above specification. It will also create the necessary Secrets and Services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get druids.kubedb.com -n demo +kubectl get druids.kubedb.com -n demo +``` NAME TYPE VERSION STATUS AGE sample-druid kubedb.com/v1alpha2 36.0.0 Ready 4m14s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE DATA AGE sample-druid-auth kubernetes.io/basic-auth 2 2m34s sample-druid-config Opaque 11 2m34s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-druid-brokers ClusterIP 10.128.135.115 8082/TCP 2m53s sample-druid-coordinators ClusterIP 10.128.16.222 8081/TCP 2m53s sample-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 2m53s sample-druid-routers ClusterIP 10.128.191.186 8888/TCP 2m53s -``` Here, we have to use service `sample-druid-routers` and secret `sample-druid-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/druid/concepts/appbinding.md) CR that holds the necessary information to connect with the database. **Verify Internal Dependencies:** ```bash -$ kubectl get mysql -n dev1 +kubectl get mysql -n dev1 +``` NAME VERSION STATUS AGE mysql.kubedb.com/my-dev1 9.1.0 Ready 6m31s -$ kubectl get zk -n dev +```bash +kubectl get zk -n dev +``` NAME TYPE VERSION STATUS AGE zookeeper.kubedb.com/zk-dev kubedb.com/v1alpha2 3.7.2 Ready 6m31s -``` We can see that KubeDB has deployed a `MySQL` and a `ZooKeeper` instance as [External dependencies](https://druid.apache.org/docs/latest/design/architecture/#external-dependencies) of the `Druid` cluster. **Verify AppBinding:** @@ -197,25 +213,29 @@ We can see that KubeDB has deployed a `MySQL` and a `ZooKeeper` instance as [Ext Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-druid kubedb.com/druid 36.0.0 4m7s -$ kubectl get appbindings -n dev1 +```bash +kubectl get appbindings -n dev1 +``` NAME TYPE VERSION AGE my-dev1 kubedb.com/mysql 9.1.0 6m31s -$ kubectl get appbindings -n dev +```bash +kubectl get appbindings -n dev +``` NAME TYPE VERSION AGE zk-dev kubedb.com/zookeeper 3.7.2 6m34s -``` Here `sample-druid` is the `AppBinding` of Druid, while `my-dev1` and `zk-dev` are the `AppBinding` of `MySQL` and `ZooKeeper` instances that `KubeDB` has deployed as the [External dependencies](https://druid.apache.org/docs/latest/design/architecture/#external-dependencies) of `Druid` Let's check the YAML of the `AppBinding` of druid, ```bash -$ kubectl get appbindings -n demo sample-druid -o yaml +kubectl get appbindings -n demo sample-druid -o yaml ``` ```yaml @@ -283,16 +303,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. @@ -333,13 +353,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -368,9 +394,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -401,9 +427,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -416,8 +442,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -484,12 +513,12 @@ roleRef: Let’s create the RBAC resources we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/cross-ns-dependencies/examples/rbac.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/cross-ns-dependencies/examples/rbac.yaml +``` serviceaccount/cluster-resource-reader created clusterrole.rbac.authorization.k8s.io/cluster-resource-reader created rolebinding.rbac.authorization.k8s.io/cluster-resource-reader created rolebinding.rbac.authorization.k8s.io/cluster-resource-reader created -``` **Create BackupConfiguration:** @@ -550,27 +579,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-druid-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-druid-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-druid-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-druid-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/druid` directory. @@ -581,10 +610,10 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-druid-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** @@ -593,11 +622,10 @@ KubeStash triggers an instant backup as soon as the `BackupConfiguration` is rea Run the following command to watch `BackupSession` CR, ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-druid-backup-frequent-backup-1724065200 BackupConfiguration sample-druid-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -606,18 +634,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-druid-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-druid-repo +kubectl get repository -n demo gcs-druid-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-druid-repo true 4 664.979 KiB Ready 2m55s 4h56m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-druid-repo-sample-druid-backup-frequent-backup-1726830540 gcs-druid-repo frequent-backup 2024-09-20T11:09:00Z Delete Succeeded 3m13s -``` > **Note**: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -630,7 +658,7 @@ gcs-druid-repo-sample-druid-backup-frequent-backup-1726830540 gcs-druid-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1725359100 -oyaml +kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1725359100 -oyaml ``` ```yaml @@ -729,9 +757,9 @@ Now, if we navigate to the GCS bucket, we will see the backed up data stored in Now, we are going to delete the `Druid` cluster that we have deployed and took backup earlier. ```bash -$ kubectl delete druid -n demo sample-druid -druid.kubedb.com "sample-druid" deleted +kubectl delete druid -n demo sample-druid ``` +druid.kubedb.com "sample-druid" deleted The dependencies of druid with name `zk-dev` and `my-dev1` will also be deleted from their respective namespaces. ## Restore @@ -786,19 +814,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-druid created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. #### Verify Restored Druid Manifest: @@ -806,23 +834,25 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `Druid` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get druids.kubedb.com -n demo +kubectl get druids.kubedb.com -n demo +``` NAME VERSION STATUS AGE restored-druid 36.0.0 Ready 6m26s -``` The output confirms that the `Druid` database has been successfully created with the same configuration as it had at the time of backup. Verify the dependencies have been restored: ```bash -$ $ kubectl get mysql -n dev1 +kubectl get mysql -n dev1 +``` NAME VERSION STATUS AGE mysql.kubedb.com/my-dev1 9.1.0 Ready 6m30s -$ kubectl get zk -n dev +```bash +kubectl get zk -n dev +``` NAME TYPE VERSION STATUS AGE zookeeper.kubedb.com/zk-dev kubedb.com/v1alpha2 3.7.2 Ready 6m30s -``` The output confirms that the `MySQL` and `ZooKeper` databases have been successfully created with the same configuration as it had at the time of backup. @@ -833,22 +863,22 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get druid -n demo restored-druid +kubectl get druid -n demo restored-druid +``` NAME VERSION STATUS AGE restored-druid 36.0.0 Ready 34m -``` Now, let's verify if our datasource `wikipedia` exists or not. For that, first find out the database `Sevices` by the following command, Now access the [web console](https://druid.apache.org/docs/latest/operations/web-console) of Druid database from any browser by port-forwarding the routers. Let’s port-forward the port `8888` to local machine: ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=restored-druid" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=restored-druid" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE restored-druid-brokers ClusterIP 10.128.74.54 8082/TCP 10m restored-druid-coordinators ClusterIP 10.128.30.124 8081/TCP 10m restored-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 10m restored-druid-routers ClusterIP 10.128.228.193 8888/TCP 10m -``` ```bash kubectl port-forward -n demo svc/restored-druid-routers 8888 Forwarding from 127.0.0.1:8888 -> 8888 @@ -860,16 +890,16 @@ Then hit the `http://localhost:8888` from any browser, and you will be prompted - Username: ```bash - $ kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. Now if you go to the `Datasources` section, you will see that our ingested datasource `wikipedia` exists in the list.

  lifecycle diff --git a/docs/guides/druid/backup/logical/index.md b/docs/guides/druid/backup/logical/index.md index 92bc85572c..f211ccce3b 100644 --- a/docs/guides/druid/backup/logical/index.md +++ b/docs/guides/druid/backup/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/druid/backup/logical/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -60,19 +60,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -98,9 +104,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created Let's deploy a sample `Druid` database and insert some data into it. @@ -129,34 +135,36 @@ spec: Create the above `Druid` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/sample-druid.yaml -druid.kubedb.com/sample-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/sample-druid.yaml ``` +druid.kubedb.com/sample-druid created KubeDB will deploy a Druid database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database along with `MySQL` and `ZooKeeper` instance as druid dependencies. Let's check if the database is ready to use, ```bash -$ kubectl get druids.kubedb.com -n demo +kubectl get druids.kubedb.com -n demo +``` NAME TYPE VERSION STATUS AGE sample-druid kubedb.com/v1alpha2 36.0.0 Ready 113s -``` The database is `Ready`. Verify that KubeDB has created the necessary `Secrets` and `Services` to access the database along with `MySQL` and `ZooKeeper` instance for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE DATA AGE sample-druid-auth kubernetes.io/basic-auth 2 48s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-druid +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-druid-brokers ClusterIP 10.128.189.77 8082/TCP 72s sample-druid-coordinators ClusterIP 10.128.175.228 8081/TCP 72s sample-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 72s sample-druid-routers ClusterIP 10.128.95.51 8888/TCP 72s -``` Here, we have to use service `sample-druid-routers` and secret `sample-druid-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/druid/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -165,17 +173,17 @@ Here, we have to use service `sample-druid-routers` and secret `sample-druid-aut Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-druid kubedb.com/druid 36.0.0 2m26s sample-druid-mysql-metadata kubedb.com/mysql 9.1.0 5m40s sample-druid-zk kubedb.com/zookeeper 3.7.2 5m43s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-druid -o yaml +kubectl get appbindings -n demo sample-druid -o yaml ``` ```yaml @@ -243,16 +251,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n demo sample-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. @@ -293,13 +301,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -328,9 +342,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -361,9 +375,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -376,8 +390,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -432,27 +449,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-druid-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-druid-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-druid-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-druid-repo true 1 712.822 KiB Ready 5m 4m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/druid` directory. @@ -463,21 +480,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-druid-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-druid-backup-frequent-backup-1724065200 BackupConfiguration sample-druid-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -486,18 +502,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-druid-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo sample-druid-backup +kubectl get repository -n demo sample-druid-backup +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE sample-druid-backup true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-druid-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-druid-repo-sample-druid-backup-frequent-backup-1726656835 gcs-druid-repo frequent-backup 2024-09-18T10:54:07Z Delete Succeeded 11m -``` > **Note**: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -510,7 +526,7 @@ gcs-druid-repo-sample-druid-backup-frequent-backup-1726656835 gcs-druid-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1724065200 -oyaml +kubectl get snapshots -n demo gcs-druid-repo-sample-druid-backup-frequent-backup-1724065200 -oyaml ``` ```yaml @@ -614,17 +630,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/restored-druid.yaml -druid.kubedb.com/restored-druid created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/restored-druid.yaml ``` +druid.kubedb.com/restored-druid created If you check the database status, you will see it is stuck in `Provisioning` state. ```bash -$ kubectl get druid -n demo restored-druid +kubectl get druid -n demo restored-druid +``` NAME TYPE VERSION STATUS AGE restored-druid kubedb.com/v1alpha2 36.0.0 Provisioning 22s -``` #### Create RestoreSession: @@ -667,19 +683,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-druid-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-druid-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -691,22 +707,22 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get druid -n demo restored-druid +kubectl get druid -n demo restored-druid +``` NAME VERSION STATUS AGE restored-druid 36.0.0 Ready 34m -``` Now, let's verify if our datasource `wikipedia` exists or not. For that, first find out the database `Sevices` by the following command, Now access the [web console](https://druid.apache.org/docs/latest/operations/web-console) of Druid database from any browser by port-forwarding the routers. Let’s port-forward the port `8888` to local machine: ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=restored-druid" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=restored-druid" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE restored-druid-brokers ClusterIP 10.128.74.54 8082/TCP 10m restored-druid-coordinators ClusterIP 10.128.30.124 8081/TCP 10m restored-druid-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 10m restored-druid-routers ClusterIP 10.128.228.193 8888/TCP 10m -``` ```bash kubectl port-forward -n demo svc/restored-druid-routers 8888 Forwarding from 127.0.0.1:8888 -> 8888 @@ -718,16 +734,16 @@ Then hit the `http://localhost:8888` from any browser, and you will be prompted - Username: ```bash - $ kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.password}' | base64 -d - DqG5E63NtklAkxqC + kubectl get secret -n demo restored-druid-auth -o jsonpath='{.data.password}' | base64 -d ``` + DqG5E63NtklAkxqC After providing the credentials correctly, you should be able to access the web console like shown below. Now if you go to the `Datasources` section, you will see that our ingested datasource `wikipedia` exists in the list.

  lifecycle diff --git a/docs/guides/druid/clustering/guide/index.md b/docs/guides/druid/clustering/guide/index.md index 5042e3fb0a..a0b33166ae 100644 --- a/docs/guides/druid/clustering/guide/index.md +++ b/docs/guides/druid/clustering/guide/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/druid/clustering/topology-cluster-guide/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/druid/clustering/topology-cluster-guide/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,19 +42,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -80,9 +86,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created ## Deploy Druid Cluster @@ -107,14 +113,15 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/clustering/guide/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/clustering/guide/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created KubeDB operator watches for `Druid` objects using Kubernetes API. When a `Druid` object is created, KubeDB operator will create new PetSets and Services with the matching Druid object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl describe druid -n demo druid-cluster +kubectl describe druid -n demo druid-cluster +``` Name: druid-cluster Namespace: demo Labels: @@ -448,7 +455,9 @@ Status: Phase: Provisioning Events: -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME AGE druid-cluster-brokers 13m druid-cluster-coordinators 13m @@ -458,18 +467,23 @@ druid-cluster-mysql-metadata 14m druid-cluster-routers 13m druid-cluster-zk 14m -$ kubectl get pvc -n demo -l app.kubernetes.io/name=druids.kubedb.com +```bash +kubectl get pvc -n demo -l app.kubernetes.io/name=druids.kubedb.com +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE druid-cluster-base-task-dir-druid-cluster-middlemanagers-0 Bound pvc-d288b621-d281-4004-995d-7a25bb4149de 1Gi RWO standard 14m druid-cluster-segment-cache-druid-cluster-historicals-0 Bound pvc-ccca6be2-658a-46af-a270-de1c6a041af7 1Gi RWO standard 14m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-4f8538f6-a6ce-4233-b533-8566852f5b98 1Gi RWO Delete Bound demo/druid-cluster-base-task-dir-druid-cluster-middlemanagers-0 standard 4m39s pvc-8823d3ad-d614-4172-89ac-c2284a17f502 1Gi RWO Delete Bound demo/druid-cluster-segment-cache-druid-cluster-historicals-0 standard 4m35s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE druid-cluster-brokers ClusterIP 10.96.186.168 8082/TCP 17m druid-cluster-coordinators ClusterIP 10.96.122.235 8081/TCP 17m @@ -481,12 +495,12 @@ druid-cluster-routers ClusterIP 10.96.138.237 druid-cluster-zk ClusterIP 10.96.148.251 2181/TCP 18m druid-cluster-zk-admin-server ClusterIP 10.96.2.106 8080/TCP 18m druid-cluster-zk-pods ClusterIP None 2181/TCP,2888/TCP,3888/TCP 18m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified `Druid` object: ```bash -$ kubectl describe druid -n demo druid-cluster +kubectl describe druid -n demo druid-cluster +``` Name: druid-cluster Namespace: demo Labels: @@ -849,7 +863,6 @@ Status: Type: Provisioned Phase: Ready Events: -``` ## Connect with Druid Database @@ -860,17 +873,17 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 8888 +kubectl port-forward -n demo svc/druid-cluster-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now, the Druid cluster is accessible at `localhost:8888`. Let's check the [Service Health](https://druid.apache.org/docs/latest/api-reference/service-status-api/#get-service-health) of Routers of the Druid database. ```bash -$ curl "http://localhost:8888/status/health" -true +curl "http://localhost:8888/status/health" ``` +true From the retrieved health information above, we can see that our Druid cluster’s status is `true`, indicating that the service can receive API calls and is healthy. In the same way it possible to check the health of other druid nodes by port-forwarding the appropriate services. ### Access the web console @@ -884,16 +897,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -908,15 +921,19 @@ You can use this web console for loading data, managing datasources and tasks, a To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo druid druid-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo druid druid-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` druid.kubedb.com/druid-cluster patched -$ kubectl delete dr druid-cluster -n demo +```bash +kubectl delete dr druid-cluster -n demo +``` druid.kubedb.com "druid-cluster" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/druid/concepts/druid.md b/docs/guides/druid/concepts/druid.md index 61114176e7..7c59b19e8c 100644 --- a/docs/guides/druid/concepts/druid.md +++ b/docs/guides/druid/concepts/druid.md @@ -209,11 +209,11 @@ AuthSecret contains a `username` key and a `password` key which contains the `us Example: ```bash -$ kubectl create secret generic druid-auth -n demo \ +kubectl create secret generic druid-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "druid-auth" created ``` +secret "druid-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/druid/configuration/config-file/index.md b/docs/guides/druid/configuration/config-file/index.md index fcd4e036c6..6fdf9d37d3 100644 --- a/docs/guides/druid/configuration/config-file/index.md +++ b/docs/guides/druid/configuration/config-file/index.md @@ -26,13 +26,15 @@ In Druid cluster, there are six nodes available coordinators, overlords, brokers - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/druid/configuration/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Druid CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -57,19 +59,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -95,9 +103,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created ## Use Custom Configuration @@ -133,9 +141,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/config-file/yamls/config-secret.yaml -secret/config-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/config-file/yamls/config-secret.yaml ``` +secret/config-secret created > To provide custom configuration for other nodes add values for the following `key` under `stringData`: > - Use `common.runtime.properties` for common configurations @@ -169,21 +177,21 @@ spec: Now, create the Druid object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/config-file/yamls/druid-with-config.yaml -druid.kubedb.com/druid-with-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/config-file/yamls/druid-with-config.yaml ``` +druid.kubedb.com/druid-with-config created Now, wait for the Druid to become ready: ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-with-config kubedb.com/v1alpha2 36.0.0 Provisioning 5s druid-with-config kubedb.com/v1alpha2 36.0.0 Provisioning 7s . . druid-with-config kubedb.com/v1alpha2 36.0.0 Ready 2m -``` ## Verify Configuration @@ -192,10 +200,10 @@ Lets exec into one of the druid middleManagers pod that we have created and chec Exec into the Druid middleManagers: ```bash -$ kubectl exec -it -n demo druid-with-config-middleManagers-0 -- bash +kubectl exec -it -n demo druid-with-config-middleManagers-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the configurations: ```bash @@ -209,10 +217,10 @@ Now, lets exec into one of the druid historicals pod that we have created and ch Exec into the Druid historicals: ```bash -$ kubectl exec -it -n demo druid-with-config-historicals-0 -- bash +kubectl exec -it -n demo druid-with-config-historicals-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the metadata storage directory: ```bash @@ -228,10 +236,10 @@ You can also see the configuration changes from the druid ui. For that, follow t First port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-with-config-routers 8888 +kubectl port-forward -n demo svc/druid-with-config-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now hit the `http://localhost:8888` from any browser, and you will be prompted to provide the credential of the druid database. By following the steps discussed below, you can get the credential generated by the KubeDB operator for your Druid database. @@ -241,16 +249,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-with-config-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-with-config-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-with-config-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-with-config-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -266,11 +274,15 @@ You can see that there are 5 task slots reflecting with our provided custom conf To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete dr -n demo druid-with-config +kubectl delete dr -n demo druid-with-config +``` -$ kubectl delete secret -n demo config-secret +```bash +kubectl delete secret -n demo config-secret +``` -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/druid/configuration/podtemplating/index.md b/docs/guides/druid/configuration/podtemplating/index.md index bd6c051201..0564cfaac1 100644 --- a/docs/guides/druid/configuration/podtemplating/index.md +++ b/docs/guides/druid/configuration/podtemplating/index.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Druid via [PodTemplate](/docs - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/druid/configuration/podtemplating/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,19 +67,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -105,9 +111,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/backup/application-level/examples/deep-storage-config.yaml ``` +secret/deep-storage-config created ## CRD Configuration @@ -160,33 +166,34 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that `druid-cluster` is in `Ready` state. ```bash -$ kubectl get druid -n demo +kubectl get druid -n demo +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 6m5s -``` Check that the petset's pod is running ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=druid-cluster +kubectl get pods -n demo -l app.kubernetes.io/instance=druid-cluster +``` NAME READY STATUS RESTARTS AGE druid-cluster-brokers-0 1/1 Running 0 7m2s druid-cluster-coordinators-0 1/1 Running 0 7m9s druid-cluster-historicals-0 1/1 Running 0 7m7s druid-cluster-middlemanagers-0 1/1 Running 0 7m5s druid-cluster-routers-0 1/1 Running 0 7m -``` Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -198,7 +205,9 @@ $ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.conta } } -$ kubectl get pod -n demo druid-cluster-brokers-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo druid-cluster-brokers-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -209,7 +218,6 @@ $ kubectl get pod -n demo druid-cluster-brokers-0 -o json | jq '.spec.containers "memory": "2Gi" } } -``` Here we can see the containers of the both `coordinators` and `brokers` have the resources we have specified in the manifest. @@ -218,31 +226,32 @@ Here we can see the containers of the both `coordinators` and `brokers` have the Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our druid 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -258,7 +267,6 @@ Labels: beta.kubernetes.io/arch=amd64 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 druid with this new label as nodeSelector. Below is the yaml we are going to apply: @@ -286,22 +294,22 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-node-selector.yaml -druid.kubedb.com/druid-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-node-selector.yaml ``` +druid.kubedb.com/druid-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 the `druid-node-selector` instance is in `Ready` state. ```bash -$ kubectl get druid -n demo +kubectl get druid -n demo +``` NAME TYPE VERSION STATUS AGE druid-node-selector kubedb.com/v1alpha2 36.0.0 Ready 54m -``` You can verify that by running `kubectl get pods -n demo druid-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo druid-node-selector-coordinators-0 -o wide +kubectl get pods -n demo druid-node-selector-coordinators-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES druid-node-selector-coordinators-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 @@ -309,28 +317,33 @@ We can successfully verify that our pod was scheduled to our desired node. Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our druid 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +```bash +kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +``` node/lke212553-307295-5541798e0000 tainted -$ kubectl taint nodes lke212553-307295-5b53c5520000 key1=node3:NoSchedule -node/lke212553-307295-5b53c5520000 tainted +```bash +kubectl taint nodes lke212553-307295-5b53c5520000 key1=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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -355,7 +368,6 @@ lke212553-307295-5b53c5520000 "value": "node3" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a druid without proper tolerations. Here is the yaml of druid we are going to create. ```yaml apiVersion: kubedb.com/v1alpha2 @@ -375,24 +387,25 @@ spec: deletionPolicy: Delete ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-without-tolerations.yaml -druid.kubedb.com/druid-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-without-tolerations.yaml ``` +druid.kubedb.com/druid-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 `druid-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=druid-without-tolerations +kubectl get pods -n demo -l app.kubernetes.io/instance=druid-without-tolerations +``` NAME READY STATUS RESTARTS AGE druid-without-tolerations-brokers-0 0/1 Pending 0 3m35s druid-without-tolerations-coordinators-0 0/1 Pending 0 3m35s druid-without-tolerations-historicals-0 0/1 Pending 0 3m35s druid-without-tolerations-middlemanager-0 0/1 Pending 0 3m35s druid-without-tolerations-routers-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 druid-without-tolerations-coordinators-0 +kubectl describe pods -n demo druid-without-tolerations-coordinators-0 +``` Name: druid-without-tolerations-coordinators-0 Namespace: demo Priority: 0 @@ -504,7 +517,6 @@ Events: 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 druid. Here is the yaml we are going to apply, @@ -570,29 +582,28 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-with-tolerations.yaml -druid.kubedb.com/druid-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/configuration/podtemplating/yamls/druid-with-tolerations.yaml ``` +druid.kubedb.com/druid-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 `druid-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ $ kubectl get pods -n demo -l app.kubernetes.io/instance=druid-cluster - +kubectl get pods -n demo -l app.kubernetes.io/instance=druid-cluster +``` NAME READY STATUS RESTARTS AGE druid-with-tolerations-brokers-0 1/1 Running 0 164m druid-with-tolerations-coordinators-0 1/1 Running 0 164m druid-with-tolerations-historicals-0 1/1 Running 0 164m druid-with-tolerations-middlemanagers-0 1/1 Running 0 164m druid-with-tolerations-routers-0 1/1 Running 0 164m -``` As we see the pod is running, you can verify that by running `kubectl get pods -n demo druid-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo druid-with-tolerations-coordinators-0 -o wide +kubectl get pods -n demo druid-with-tolerations-coordinators-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES druid-with-tolerations-coordinators-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 diff --git a/docs/guides/druid/failover/guide.md b/docs/guides/druid/failover/guide.md index b6458afea7..230406d72c 100644 --- a/docs/guides/druid/failover/guide.md +++ b/docs/guides/druid/failover/guide.md @@ -45,13 +45,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/druid/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/druid/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,10 +64,10 @@ demo Active 9s We will have to provide `StorageClass` in Druid CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -74,15 +76,14 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named [DruidVersion](/docs/guides/druid/concepts/druidversion.md). The installation process comes with a set of tested DruidVersion objects. Let's check available DruidVersions by, ```bash -$ kubectl get druidversion +kubectl get druidversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 28.0.1 28.0.1 ghcr.io/appscode-images/druid:28.0.1 24h 30.0.1 30.0.1 ghcr.io/appscode-images/druid:30.0.1 24h 31.0.0 31.0.0 ghcr.io/appscode-images/druid:31.0.0 24h 36.0.0 36.0.0 ghcr.io/appscode-images/druid:36.0.0 24h -``` - Notice the `DEPRECATED` column. Here, `true` means that this DruidVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated DruidVersion. You can also use the short from `drversion` to check available DruidVersions. In this tutorial, we will use `36.0.0` DruidVersion CR to create a Druid cluster. @@ -96,19 +97,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` + +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -134,9 +141,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/deep-storage-config.yaml ``` +secret/deep-storage-config created ## Deploy a Highly Available Druid Cluster ## Create a Druid Cluster @@ -180,29 +187,29 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-with-monitoring.yaml -druid.kubedb.com/druid-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-with-monitoring.yaml ``` +druid.kubedb.com/druid-quickstart created The Druid's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the newly provisioned Druid cluster. ```bash -$ kubectl get druid -n demo -w +kubectl get druid -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 4m12s - -``` ## Inspect Druid Pod Roles and Health You can monitor on another terminal the status until all pods are ready: -```shell -$ watch kubectl get druid,petset,pods -n demo +```bash +watch kubectl get druid,petset,pods -n demo ``` See the database is ready. -```shell -$ kubectl get druid,petset,pods -n demo +```bash +kubectl get druid,petset,pods -n demo +``` NAME TYPE VERSION STATUS AGE druid.kubedb.com/druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 15m @@ -237,13 +244,12 @@ pod/druid-cluster-zk-1 1/1 Running 0 15m pod/druid-cluster-zk-2 1/1 Running 0 15m pod/myminio-default-0 2/2 Running 0 3d21h -``` - You can check the roles and status of Druid pods using labels: ```bash -$ kubectl get pods -n demo --show-labels | grep role +kubectl get pods -n demo --show-labels | grep role +``` druid-cluster-brokers-0 1/1 Running 0 2d19h app.kubernetes.io/component=database,app.kubernetes.io/instance=druid-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=druids.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=druid-cluster-brokers-64667d6fbb,kubedb.com/role=brokers,statefulset.kubernetes.io/pod-name=druid-cluster-brokers-0 druid-cluster-brokers-1 1/1 Running 0 2d19h app.kubernetes.io/component=database,app.kubernetes.io/instance=druid-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=druids.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=druid-cluster-brokers-64667d6fbb,kubedb.com/role=brokers,statefulset.kubernetes.io/pod-name=druid-cluster-brokers-1 druid-cluster-coordinators-0 1/1 Running 0 2d19h app.kubernetes.io/component=database,app.kubernetes.io/instance=druid-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=druids.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=druid-cluster-coordinators-955d5f7c4,kubedb.com/role=coordinators,statefulset.kubernetes.io/pod-name=druid-cluster-coordinators-0 @@ -260,8 +266,6 @@ druid-cluster-overlords-1 1/1 Running 0 2d19h app.kubern druid-cluster-routers-0 1/1 Running 0 2d19h app.kubernetes.io/component=database,app.kubernetes.io/instance=druid-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=druids.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=druid-cluster-routers-86f759b75b,kubedb.com/role=routers,statefulset.kubernetes.io/pod-name=druid-cluster-routers-0 druid-cluster-routers-1 1/1 Running 0 2d19h app.kubernetes.io/component=database,app.kubernetes.io/instance=druid-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=druids.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=druid-cluster-routers-86f759b75b,kubedb.com/role=routers,statefulset.kubernetes.io/pod-name=druid-cluster-routers-1 -``` - ## How Failover Works in Druid with KubeDB KubeDB continuously monitors the health of Druid pods. If a Coordinator, Overlord, or any other critical pod fails (due to crash, node failure, or manual deletion), KubeDB: @@ -276,12 +280,12 @@ This process is automatic and typically completes within seconds, ensuring minim For highly-available ZooKeeper, `KubeDB` provides a cluster of 3 `Zookeeper` nodes. You can delete one of the `Zookeeper` pods to see how `KubeDB` handles failover. **Delete a `Zookeeper` pod** ```bash -$ kubectl delete pod -n demo druid-cluster-zk-0 -pod "druid-cluster-zk-0" deleted +kubectl delete pod -n demo druid-cluster-zk-0 ``` +pod "druid-cluster-zk-0" deleted in another terminal you can watch their status -```shell -$ watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" +```bash +watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" ``` ```shell @@ -315,11 +319,10 @@ You can not see that a new `druid-cluster-zk-0` pod is created automatically and Druid uses MySQL for metadata storage. Each of the nods has their role also, you can see the role of each pod. **Delete the `primary` MySQL pod** -```shell -$ kubectl delete pod -n demo druid-cluster-mysql-metadata-0 -pod "druid-cluster-mysql-metadata-0" deleted - +```bash +kubectl delete pod -n demo druid-cluster-mysql-metadata-0 ``` +pod "druid-cluster-mysql-metadata-0" deleted You can delete `druid-cluster-mysql-metadata-0` pods which has `primary` role to see how KubeDB handles failover. ```shell druid-cluster-brokers-0 brokers @@ -370,11 +373,11 @@ myminio-default-0 **Delete two `standby` MySQL pod** You can also delete `druid-cluster-mysql-metadata-1` pods which has `standby` role to see how KubeDB handles failover. -```shell -$ kubectl delete pod -n demo druid-cluster-mysql-metadata-0 druid-cluster-mysql-metadata-1 +```bash +kubectl delete pod -n demo druid-cluster-mysql-metadata-0 druid-cluster-mysql-metadata-1 +``` pod "druid-cluster-mysql-metadata-0" deleted pod "druid-cluster-mysql-metadata-1" deleted -``` For few seconds, you will see that `standby` roles are missing. ```shell @@ -433,10 +436,9 @@ recommend placing them behind a load balancer. **Delete a `Broker` pod and observe failover:** ```bash -$ kubectl delete pod -n demo druid-cluster-brokers-0 -pod "druid-cluster-brokers-0" deleted - +kubectl delete pod -n demo druid-cluster-brokers-0 ``` +pod "druid-cluster-brokers-0" deleted Monitor the pods: @@ -472,9 +474,9 @@ at a time, but inactive servers will redirect to the currently active server. **Delete a Coordinator Pod** ```bash -$ kubectl delete pod -n demo druid-cluster-coordinators-0 +kubectl delete pod -n demo druid-cluster-coordinators-0 +``` pod "druid-cluster-coordinators-0" deleted -``` ```shell druid-cluster-brokers-0 brokers @@ -502,9 +504,9 @@ myminio-default-0 **Delete a Overlord Pod** ```bash -$ kubectl delete pod -n demo druid-cluster-overlords-0 -pod "druid-cluster-overlords-0" deleted +kubectl delete pod -n demo druid-cluster-overlords-0 ``` +pod "druid-cluster-overlords-0" deleted ```shell druid-cluster-brokers-0 brokers @@ -534,8 +536,11 @@ myminio-default-0 To clean up run: ```bash -$ kubectl delete druid -n demo druid-cluster -$ kubectl delete ns demo +kubectl delete druid -n demo druid-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/druid/monitoring/overview.md b/docs/guides/druid/monitoring/overview.md index 0b20440478..b981752d92 100644 --- a/docs/guides/druid/monitoring/overview.md +++ b/docs/guides/druid/monitoring/overview.md @@ -78,19 +78,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -116,16 +122,16 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Let's deploy the above druid example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-with-monitoring.yaml -druid.kubedb.com/druid created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-with-monitoring.yaml ``` +druid.kubedb.com/druid created Here, we have specified that we are going to monitor this server using Prometheus operator through `spec.monitor.agent: prometheus.io/operator`. KubeDB will create a `ServiceMonitor` crd in databases namespace and this `ServiceMonitor` will have `release: prometheus` label. diff --git a/docs/guides/druid/monitoring/using-builtin-prometheus.md b/docs/guides/druid/monitoring/using-builtin-prometheus.md index de452cc5d2..1742139f2d 100644 --- a/docs/guides/druid/monitoring/using-builtin-prometheus.md +++ b/docs/guides/druid/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Druid cluster using builtin [Promethe - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -77,9 +79,9 @@ Here, Let's create the Druid crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-monitoring-builtin.yaml -druid.kubedb.com/druid-with-monitoring created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-monitoring-builtin.yaml ``` +druid.kubedb.com/druid-with-monitoring created Now, wait for the cluster to go into `Ready` state. @@ -91,19 +93,20 @@ druid-with-monitoring kubedb.com/v1alpha2 36.0.0 Ready 31s KubeDB will create a separate stats service with name `{Druid crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=druid-with-monitoring" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=druid-with-monitoring" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE druid-with-monitoring-brokers ClusterIP 10.96.28.252 8082/TCP 2m13s druid-with-monitoring-coordinators ClusterIP 10.96.52.186 8081/TCP 2m13s druid-with-monitoring-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 2m13s druid-with-monitoring-routers ClusterIP 10.96.134.202 8888/TCP 2m13s druid-with-monitoring-stats ClusterIP 10.96.222.96 56790/TCP 2m13s -``` Here, `druid-with-monitoring-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo druid-with-monitoring-stats +kubectl describe svc -n demo druid-with-monitoring-stats +``` Name: druid-with-monitoring-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -126,7 +129,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.31:56790,10.244.0.33:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -290,20 +292,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -314,9 +316,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -325,18 +327,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-7bd56c6865-8dlpv 1/1 Running 0 28s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `druid-with-monitoring-stats` service as one of the targets. diff --git a/docs/guides/druid/monitoring/using-prometheus-operator.md b/docs/guides/druid/monitoring/using-prometheus-operator.md index 5e1a7f2144..2aeb437053 100644 --- a/docs/guides/druid/monitoring/using-prometheus-operator.md +++ b/docs/guides/druid/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. Alternatively, you can use `--create-namespace` flag while deploying prometheus. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,17 +47,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.42.0 1 1 True True 2d23h -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -145,7 +148,6 @@ status: updatedReplicas: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.serviceMonitor.labels` field of Druid crd. @@ -187,36 +189,37 @@ Here, Let's create the druid object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-with-monitoring.yaml -druids.kubedb.com/druid-with-monitoring created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/monitoring/yamls/druid-with-monitoring.yaml ``` +druids.kubedb.com/druid-with-monitoring created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get dr -n demo druid +kubectl get dr -n demo druid +``` NAME TYPE VERSION STATUS AGE druid-with-monitoring kubedb.com/v1alpha2 36.0.0 Ready 2m24s -``` KubeDB will create a separate stats service with name `{Druid crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=druid-with-monitoring" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=druid-with-monitoring" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE druid-with-monitoring-brokers ClusterIP 10.96.28.252 8082/TCP 2m13s druid-with-monitoring-coordinators ClusterIP 10.96.52.186 8081/TCP 2m13s druid-with-monitoring-pods ClusterIP None 8081/TCP,8090/TCP,8083/TCP,8091/TCP,8082/TCP,8888/TCP 2m13s druid-with-monitoring-routers ClusterIP 10.96.134.202 8888/TCP 2m13s druid-with-monitoring-stats ClusterIP 10.96.222.96 56790/TCP 2m13s -``` Here, `druid-with-monitoring-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo druid-with-monitoring-stats +kubectl describe svc -n demo druid-with-monitoring-stats +``` Name: druid-with-monitoring-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -236,22 +239,22 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.68:9104,10.244.0.71:9104,10.244.0.72:9104 + 2 more... Session Affinity: None Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `druid-with-monitoring-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE druid-with-monitoring-stats 4m49s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Druid crd. ```bash -$ kubectl get servicemonitor -n demo druid-with-monitoring-stats -o yaml +kubectl get servicemonitor -n demo druid-with-monitoring-stats -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -290,7 +293,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: druids.kubedb.com kubedb.com/role: stats -``` Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in Druid crd. @@ -301,20 +303,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 8 (4h27m ago) 3d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-kube-prometheus-prometheus` service which is pointing to the prometheus pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `druid-with-monitoring-stats` service as one of the targets. diff --git a/docs/guides/druid/quickstart/guide/index.md b/docs/guides/druid/quickstart/guide/index.md index eaa8a5c096..d6cbe89021 100644 --- a/docs/guides/druid/quickstart/guide/index.md +++ b/docs/guides/druid/quickstart/guide/index.md @@ -29,13 +29,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/druid/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/druid/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ demo Active 9s We will have to provide `StorageClass` in Druid CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -58,10 +60,10 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named [DruidVersion](/docs/guides/druid/concepts/druidversion.md). The installation process comes with a set of tested DruidVersion objects. Let's check available DruidVersions by, ```bash -$ kubectl get druidversion +kubectl get druidversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 36.0.0 36.0.0 ghcr.io/appscode-images/druid:36.0.0 4h47m -``` Notice the `DEPRECATED` column. Here, `true` means that this DruidVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated DruidVersion. You can also use the short from `drversion` to check available DruidVersions. @@ -76,19 +78,25 @@ One of the external dependency of Druid is deep storage where the segments are s In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -114,9 +122,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/deep-storage-config.yaml ``` +secret/deep-storage-config created You can also use options like **Amazon S3**, **Google Cloud Storage**, **Azure Blob Storage** or **HDFS** and create a connection information `Secret` like this, and you are good to go. @@ -194,26 +202,27 @@ Here, Let's create the Druid CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-quickstart.yaml -druid.kubedb.com/druid-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-quickstart.yaml ``` +druid.kubedb.com/druid-quickstart created The Druid's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the newly provisioned Druid cluster. ```bash -$ kubectl get druid -n demo -w +kubectl get druid -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-quickstart kubedb.com/v1alpha2 36.0.0 Provisioning 17s druid-quickstart kubedb.com/v1alpha2 36.0.0 Provisioning 28s . . druid-quickstart kubedb.com/v1alpha2 36.0.0 Ready 82s -``` Describe the Druid object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe druid -n demo druid-quickstart +kubectl describe druid -n demo druid-quickstart +``` Name: druid-quickstart Namespace: demo Labels: @@ -585,14 +594,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a Druid CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=druid-quickstart' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=druid-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/druid-quickstart-brokers-0 1/1 Running 0 2m4s pod/druid-quickstart-coordinators-0 1/1 Running 0 2m10s @@ -619,8 +628,6 @@ petset.apps.k8s.appscode.com/druid-quickstart-historicals 2m8s petset.apps.k8s.appscode.com/druid-quickstart-middlemanagers 2m6s petset.apps.k8s.appscode.com/druid-quickstart-routers 2m1s -``` - - `PetSet` - In topology mode, the operator may create 4 to 6 petSets (depending on the topology you provide as overlords and routers are optional) with name `{Druid-Name}-{Sufix}`. - `Services` - For topology mode, a headless service with name `{Druid-Name}-{pods}`. Other than that, 2 to 4 more services (depending on the specified topology) with name `{Druid-Name}-{Sufix}` can be created. - `{Druid-Name}-{brokers}` - The primary service which is used to connect the brokers with external clients. @@ -639,17 +646,17 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-quickstart-routers 8888 +kubectl port-forward -n demo svc/druid-quickstart-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now, the Druid cluster is accessible at `localhost:8888`. Let's check the [Service Health](https://druid.apache.org/docs/latest/api-reference/service-status-api/#get-service-health) of Routers of the Druid database. ```bash -$ curl "http://localhost:8888/status/health" -true +curl "http://localhost:8888/status/health" ``` +true From the retrieved health information above, we can see that our Druid cluster’s status is `true`, indicating that the service can receive API calls and is healthy. In the same way it is possible to check the health of other druid nodes by port-forwarding the appropriate services. ### Access the web console @@ -663,16 +670,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-quickstart-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-quickstart-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-quickstart-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -687,15 +694,19 @@ You can use this web console for loading data, managing datasources and tasks, a To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo druid druid-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo druid druid-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` kafka.kubedb.com/druid-quickstart patched -$ kubectl delete dr druid-quickstart -n demo +```bash +kubectl delete dr druid-quickstart -n demo +``` druid.kubedb.com "druid-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/druid/reconfigure-tls/guide.md b/docs/guides/druid/reconfigure-tls/guide.md index b9e280edc6..f0b027c610 100644 --- a/docs/guides/druid/reconfigure-tls/guide.md +++ b/docs/guides/druid/reconfigure-tls/guide.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,26 +62,27 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 15s druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 37s . . druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 2m27s -``` Now, we can exec one druid broker pod and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo druid-cluster-coordinators-0 -- bash +kubectl exec -it -n demo druid-cluster-coordinators-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ cat conf/druid/cluster/_common/common.runtime.properties druid.auth.authenticator.basic.authorizerName=basic @@ -135,7 +136,6 @@ druid.zk.paths.base=/druid druid.zk.service.host=druid-cluster-zk.demo.svc:2181 druid.zk.service.pwd={"type": "environment", "variable": "DRUID_ZK_SERVICE_PASSWORD"} druid.zk.service.user=super -``` We can verify from the above output that TLS is disabled for this cluster as there is no TLS/SSL related configs provided for it. @@ -144,10 +144,10 @@ We can verify from the above output that TLS is disabled for this cluster as the First port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 8888 +kubectl port-forward -n demo svc/druid-cluster-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now hit the `http://localhost:8888` from any browser, and you will be prompted to provide the credential of the druid database. By following the steps discussed below, you can get the credential generated by the KubeDB operator for your Druid database. @@ -157,16 +157,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -183,23 +183,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 druid-ca \ +kubectl create secret tls druid-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/druid-ca created ``` +secret/druid-ca created Now, Let's create an `Issuer` using the `druid-ca` secret that we have just created. The `YAML` file looks like this: @@ -217,9 +217,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-ca-issuer.yaml -issuer.cert-manager.io/druid-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-ca-issuer.yaml ``` +issuer.cert-manager.io/druid-ca-issuer created ### Create DruidOpsRequest @@ -261,28 +261,29 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-add-tls.yaml -druidopsrequest.ops.kubedb.com/drops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-add-tls.yaml ``` +druidopsrequest.ops.kubedb.com/drops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CRO, ```bash -$ kubectl get drops -n demo -w + kubectl get drops -n demo -w +``` NAME TYPE STATUS AGE drops-add-tls ReconfigureTLS Progressing 39s drops-add-tls ReconfigureTLS Progressing 44s ... ... drops-add-tls ReconfigureTLS Successful 79s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe druidopsrequest -n demo drops-add-tls +kubectl describe druidopsrequest -n demo drops-add-tls +``` Name: drops-add-tls Namespace: demo Labels: @@ -508,12 +509,12 @@ Events: Normal RestartNodes 24s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 24s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 24s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-add-tls -``` Now, Lets exec into a druid coordinators pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo druid-cluster-coordinators-0 -- bash +kubectl exec -it -n demo druid-cluster-coordinators-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ cat conf/druid/cluster/_common/common.runtime.properties druid.auth.authenticator.basic.authorizerName=basic @@ -578,8 +579,6 @@ druid.zk.service.host=druid-cluster-zk.demo.svc:2181 druid.zk.service.pwd={"type": "environment", "variable": "DRUID_ZK_SERVICE_PASSWORD"} druid.zk.service.user=super -``` - We can see from the output above that all TLS related configs are added in the configuration file of the druid database. #### Verify TLS/SSL using Druid UI @@ -591,10 +590,10 @@ Druid uses separate ports for TLS/SSL. While the plaintext port for `routers` no First port-forward the port `9088` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-tls-routers 9088 +kubectl port-forward -n demo svc/druid-cluster-tls-routers 9088 +``` Forwarding from 127.0.0.1:9088 -> 9088 Forwarding from [::1]:9088 -> 9088 -``` Now hit the `https://localhost:9088/` from any browser. Here you may select `Advance` and then `Proceed to localhost (unsafe)` or you can add the `ca.crt` from the secret `druid-cluster-tls-client-cert` to your browser's Authorities. @@ -606,16 +605,16 @@ After that you will be prompted to provide the credential of the druid database. - Username: ```bash - $ kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -631,15 +630,17 @@ From the above screenshot, we can see that the connection is secure. Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 9088 +kubectl port-forward -n demo svc/druid-cluster-routers 9088 +``` Forwarding from 127.0.0.1:9088 -> 9088 Forwarding from [::1]:9088 -> 9088 Handling connection for 9088 ... -$ openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -enddate -notAfter=Jan 26 09:43:16 2025 GMT +```bash +openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -enddate ``` +notAfter=Jan 26 09:43:16 2025 GMT So, the certificate will expire on this time `Jan 26 09:43:16 2025 GMT`. @@ -670,24 +671,25 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-rotate.yaml -druidopsrequest.ops.kubedb.com/drops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-rotate.yaml ``` +druidopsrequest.ops.kubedb.com/drops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CRO, ```bash -$ kubectl get druidopsrequests -n demo drops-rotate -w +kubectl get druidopsrequests -n demo drops-rotate -w +``` NAME TYPE STATUS AGE drops-rotate ReconfigureTLS Successful 4m4s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe druidopsrequest -n demo drops-rotate +kubectl describe druidopsrequest -n demo drops-rotate +``` Name: drops-rotate Namespace: demo Labels: @@ -900,20 +902,21 @@ Events: Normal RestartNodes 27s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 27s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 27s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 9088 +kubectl port-forward -n demo svc/druid-cluster-routers 9088 +``` Forwarding from 127.0.0.1:9088 -> 9088 Forwarding from [::1]:9088 -> 9088 Handling connection for 9088 ... -$ openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -enddate -notAfter=Jan 26 14:15:46 2025 GMT +```bash +openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -enddate ``` +notAfter=Jan 26 14:15:46 2025 GMT As we can see from the above output, the certificate has been rotated successfully. @@ -924,23 +927,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 druid-new-ca \ +kubectl create secret tls druid-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/druid-new-ca created ``` +secret/druid-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -958,9 +961,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-new-issuer.yaml -issuer.cert-manager.io/dr-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-new-issuer.yaml ``` +issuer.cert-manager.io/dr-new-issuer created ### Create DruidOpsRequest @@ -992,28 +995,29 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-update-tls-issuer.yaml -druidpsrequest.ops.kubedb.com/drops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/druid-update-tls-issuer.yaml ``` +druidpsrequest.ops.kubedb.com/drops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CRO, ```bash -$ kubectl get druidopsrequests -n demo drops-update-issuer -w +kubectl get druidopsrequests -n demo drops-update-issuer -w +``` NAME TYPE STATUS AGE drops-update-issuer ReconfigureTLS Progressing 14s drops-update-issuer ReconfigureTLS Progressing 18s ... ... drops-update-issuer ReconfigureTLS Successful 73s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe druidopsrequest -n demo drops-update-issuer +kubectl describe druidopsrequest -n demo drops-update-issuer +``` Name: drops-update-issuer Namespace: demo Labels: @@ -1229,25 +1233,28 @@ Events: Normal RestartNodes 19s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 19s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 19s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-update-issuer -``` Now, let's exec into a druid node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it druid-cluster-broker-0 -- bash +kubectl exec -it druid-cluster-broker-0 -- bash +``` druid@druid-cluster-broker-0:~$ keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep 'Issuer' Issuer: O=kubedb-updated, CN=ca-updated Issuer: O=kubedb-updated, CN=ca-updated -$ kubectl port-forward -n demo svc/druid-cluster-routers 9088 +```bash +kubectl port-forward -n demo svc/druid-cluster-routers 9088 +``` Forwarding from 127.0.0.1:9088 -> 9088 Forwarding from [::1]:9088 -> 9088 Handling connection for 9088 ... -$ openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -issuer -issuer=CN = ca-updated, O = kubedb-updated +```bash +openssl s_client -connect localhost:9088 2>/dev/null | openssl x509 -noout -issuer ``` +issuer=CN = ca-updated, O = kubedb-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. @@ -1282,16 +1289,17 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-remove.yaml -druidopsrequest.ops.kubedb.com/drops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure-tls/yamls/drops-remove.yaml ``` +druidopsrequest.ops.kubedb.com/drops-remove created #### Verify TLS Removed Successfully Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CRO, ```bash -$ kubectl get druidopsrequest -n demo drops-remove -w +kubectl get druidopsrequest -n demo drops-remove -w +``` NAME TYPE STATUS AGE drops-remove ReconfigureTLS Progressing 25s drops-remove ReconfigureTLS Progressing 29s @@ -1299,12 +1307,11 @@ drops-remove ReconfigureTLS Progressing 29s ... drops-remove ReconfigureTLS Successful 114s -``` - We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe druidopsrequest -n demo drops-remove + kubectl describe druidopsrequest -n demo drops-remove +``` Name: drops-remove Namespace: demo Labels: @@ -1497,12 +1504,12 @@ Events: Normal RestartNodes 18s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 18s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 18s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: drops-remove -``` Now, Lets exec into one of the broker node and find out that TLS is disabled or not. ```bash -$$ kubectl exec -it -n demo druid-cluster-broker-0 -- druid-configs.sh --bootstrap-server localhost:9092 --command-config /opt/druid/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo druid-cluster-broker-0 -- druid-configs.sh --bootstrap-server localhost:9092 --command-config /opt/druid/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=null sensitive=false synonyms={} @@ -1512,7 +1519,6 @@ $$ kubectl exec -it -n demo druid-cluster-broker-0 -- druid-configs.sh --bootstr ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=null sensitive=false synonyms={} ssl.keystore.password=null sensitive=true synonyms={} -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/druid/reconfigure/guide.md b/docs/guides/druid/reconfigure/guide.md index 47d2090592..ce8d715dbe 100644 --- a/docs/guides/druid/reconfigure/guide.md +++ b/docs/guides/druid/reconfigure/guide.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [/docs/guides/druid/reconfigure/yamls](/docs/guides/druid/reconfigure/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -50,19 +50,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -88,9 +94,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, lets go ahead and create a druid database. @@ -115,9 +121,9 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created ### Reconfigure using config secret @@ -151,9 +157,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure/yamls/config-secret.yaml -secret/new-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure/yamls/config-secret.yaml ``` +secret/new-config created ### Check Current Configuration @@ -163,10 +169,10 @@ Lets exec into one of the druid middleManagers pod that we have created and chec Exec into the Druid middleManagers: ```bash -$ kubectl exec -it -n demo druid-cluster-middleManagers-0 -- bash +kubectl exec -it -n demo druid-cluster-middleManagers-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the configurations: ```bash @@ -180,10 +186,10 @@ Now, lets exec into one of the druid historicals pod that we have created and ch Exec into the Druid historicals: ```bash -$ kubectl exec -it -n demo druid-cluster-historicals-0 -- bash +kubectl exec -it -n demo druid-cluster-historicals-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the metadata storage directory: ```bash @@ -200,10 +206,10 @@ You can also see the configuration changes from the druid ui. For that, follow t First port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 8888 +kubectl port-forward -n demo svc/druid-cluster-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now hit the `http://localhost:8888` from any browser, and you will be prompted to provide the credential of the druid database. By following the steps discussed below, you can get the credential generated by the KubeDB operator for your Druid database. @@ -213,16 +219,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -261,9 +267,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure/yamls/reconfigure-druid-ops.yaml -druidopsrequest.ops.kubedb.com/reconfigure-drops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/reconfigure/yamls/reconfigure-druid-ops.yaml ``` +druidopsrequest.ops.kubedb.com/reconfigure-drops created #### Check new configuration @@ -272,15 +278,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ kubectl get druidopsrequests -n demo +kubectl get druidopsrequests -n demo +``` NAME TYPE STATUS AGE reconfigure-drops Reconfigure Successful 4m55s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe druidopsrequest -n demo reconfigure-drops +kubectl describe druidopsrequest -n demo reconfigure-drops +``` Name: reconfigure-drops Namespace: demo Labels: @@ -421,15 +428,14 @@ Events: Normal RestartNodes 7s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-prod Normal Successful 5s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-prod for DruidOpsRequest: reconfigure-drops -``` Now let's exec one of the instance and run a druid-configs.sh command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo druid-prod-middleManagers-0 -- druid-configs.sh --bootstrap-server localhost:9092 --command-config /opt/druid/config/clientauth.properties --describe --entity-type middleManagerss --all | grep 'log.retention.hours' +kubectl exec -it -n demo druid-prod-middleManagers-0 -- druid-configs.sh --bootstrap-server localhost:9092 --command-config /opt/druid/config/clientauth.properties --describe --entity-type middleManagerss --all | grep 'log.retention.hours' +``` log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} -``` As we can see from the configuration of ready druid, the value of `log.retention.hours` has been changed from `100` to `125`. So the reconfiguration of the cluster is successful. @@ -472,9 +478,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/reconfigure/druid-reconfigure-apply-topology.yaml -druidopsrequest.ops.kubedb.com/kfops-reconfigure-apply-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/reconfigure/druid-reconfigure-apply-topology.yaml ``` +druidopsrequest.ops.kubedb.com/kfops-reconfigure-apply-topology created #### Verify new configuration @@ -483,15 +489,16 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ kubectl get druidopsrequests -n demo kfops-reconfigure-apply-topology +kubectl get druidopsrequests -n demo kfops-reconfigure-apply-topology +``` NAME TYPE STATUS AGE kfops-reconfigure-apply-topology Reconfigure Successful 55s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to reconfigure the cluster. ```bash -$ kubectl describe druidopsrequest -n demo kfops-reconfigure-apply-topology +kubectl describe druidopsrequest -n demo kfops-reconfigure-apply-topology +``` Name: kfops-reconfigure-apply-topology Namespace: demo Labels: @@ -634,17 +641,16 @@ Events: Normal RestartNodes 15s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 14s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-prod Normal Successful 14s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-prod for DruidOpsRequest: kfops-reconfigure-apply-topology -``` Lets exec into one of the druid middleManagers pod that have updated and check the new configurations are applied or not: Exec into the Druid middleManagers: ```bash -$ kubectl exec -it -n demo druid-with-config-middleManagers-0 -- bash +kubectl exec -it -n demo druid-with-config-middleManagers-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the configurations: ```bash @@ -658,10 +664,10 @@ Now, lets exec into one of the druid historicals pod that have updated and check Exec into the Druid historicals: ```bash -$ kubectl exec -it -n demo druid-with-config-historicals-0 -- bash +kubectl exec -it -n demo druid-with-config-historicals-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ -``` Now, execute the following commands to see the metadata storage directory: ```bash diff --git a/docs/guides/druid/restart/guide.md b/docs/guides/druid/restart/guide.md index c4175081f7..46420ec7b9 100644 --- a/docs/guides/druid/restart/guide.md +++ b/docs/guides/druid/restart/guide.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Druid database via a DruidOpsRequest. Restarting - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,19 +42,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -80,9 +86,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, lets go ahead and create a druid database. @@ -107,9 +113,9 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created ## Apply Restart opsRequest @@ -134,18 +140,21 @@ spec: Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/restart.yaml -druidopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/restart.yaml ``` +druidopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the controller pods, then broker of the referenced druid. -```shell -$ kubectl get drops -n demo +```bash +kubectl get drops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 2m11s -$ kubectl get drops -n demo restart -oyaml +```bash +kubectl get drops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: DruidOpsRequest metadata: @@ -261,7 +270,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/druid/rotate-auth/guide.md b/docs/guides/druid/rotate-auth/guide.md index 126f51e457..9b14534f0a 100644 --- a/docs/guides/druid/rotate-auth/guide.md +++ b/docs/guides/druid/rotate-auth/guide.md @@ -28,10 +28,10 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo + ```bash + kubectl create ns demo + ``` namespace/demo created -``` > Note: YAML files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,19 +46,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -84,9 +90,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/restart/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, lets go ahead and create a druid database. @@ -111,16 +117,16 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-quickstart.yaml -druid.kubedb.com/druid-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/druid/quickstart/druid-quickstart.yaml ``` +druid.kubedb.com/druid-quickstart created Now, wait until `druid-quickstart` has status Ready. i.e, -```shell -$ kubectl get druid -n demo +```bash +kubectl get druid -n demo +``` NAME TYPE VERSION STATUS AGE druid-quickstart kubedb.com/v1alpha2 36.0.0 Ready 5m3s -``` ## Verify authentication @@ -157,19 +163,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Druid. Let's create the `DruidOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/rotate-auth/yamls/Druid-rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/rotate-auth/yamls/Druid-rotate-auth-generated.yaml + ``` Druidopsrequest.ops.kubedb.com/druidops-rotate-auth-generated created -``` Let's wait for `DruidOpsrequest` to be `Successful`. Run the following command to watch `DruidOpsrequest` CRO -```shell -$ kubectl get Druidopsrequest -n demo +```bash +kubectl get Druidopsrequest -n demo +``` NAME TYPE STATUS AGE druidops-rotate-auth-generated RotateAuth Successful 6m28s -``` If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Druidopsrequest -n demo druidops-rotate-auth-generated +```bash +kubectl describe Druidopsrequest -n demo druidops-rotate-auth-generated +``` Name: druidops-rotate-auth-generated Namespace: demo Labels: @@ -327,38 +334,45 @@ Events: Normal RestartNodes 51m KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 51m KubeDB Ops-manager Operator Resuming Druid database: demo/druid-quickstart Normal Successful 51m KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-quickstart for DruidOpsRequest: druidops-rotate-auth-generated - -``` **Verify Auth is rotated** -```shell -$ kubectl get druid -n demo druid-quickstart -ojson | jq .spec.authSecret.name +```bash + kubectl get druid -n demo druid-quickstart -ojson | jq .spec.authSecret.name +``` "druid-quickstart-auth" -$ kubectl get secret -n demo druid-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo druid-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo druid-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d -gTJJMdgpKy9U(Eqi⏎ + +```bash +kubectl get secret -n demo druid-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d ``` +gTJJMdgpKy9U(Eqi⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo druid-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo druid-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo druid-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -e4qcqnS.tt_zFQDa⏎ + +```bash +kubectl get secret -n demo druid-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +e4qcqnS.tt_zFQDa⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > Note: The database `username` is fixed as `admin` and cannot be changed. However, you can update the `password` while keeping the same `username`. -```shell -$ kubectl create secret generic druid-quickstart-auth-user -n demo \ +```bash +kubectl create secret generic druid-quickstart-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=admin \ --from-literal=password=testpassword -secret/druid-quickstart-auth-user created ``` +secret/druid-quickstart-auth-user created Now create a `DruidOpsRequest` with `RotateAuth` type. Below is the YAML of the `DruidOpsRequest` that we are going to create, ```shell @@ -386,22 +400,22 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/rotate-auth/yamls/Druid-rotate-auth-user.yaml -Druidopsrequest.ops.kubedb.com/drops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/rotate-auth/yamls/Druid-rotate-auth-user.yaml ``` +Druidopsrequest.ops.kubedb.com/drops-rotate-auth-user created Let’s wait for `DruidOpsRequest` to be Successful. Run the following command to watch `DruidOpsRequest` CRO: -```shell -$ kubectl get drops -n demo +```bash +kubectl get drops -n demo +``` NAME TYPE STATUS AGE drops-rotate-auth-user RotateAuth Successful 5m32s druidops-rotate-auth-generated RotateAuth Successful 15m - -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Druidopsrequest -n demo drops-rotate-auth-user +```bash + kubectl describe Druidopsrequest -n demo drops-rotate-auth-user +``` Name: drops-rotate-auth-user Namespace: demo Labels: @@ -560,24 +574,31 @@ Events: Normal RestartNodes 56m KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 56m KubeDB Ops-manager Operator Resuming Druid database: demo/druid-quickstart Normal Successful 56m KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-quickstart for DruidOpsRequest: drops-rotate-auth-user - -``` **Verify auth is rotate** -```shell -$ kubectl get druid -n demo druid-quickstart -ojson | jq .spec.authSecret.name +```bash + kubectl get druid -n demo druid-quickstart -ojson | jq .spec.authSecret.name +``` "druid-quickstart-auth-user" -$ kubectl get secret -n demo druid-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo druid-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo druid-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d -testpassword⏎ + +```bash +kubectl get secret -n demo druid-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d ``` +testpassword⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo druid-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d +```bash +kubectl get secret -n demo druid-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo druid-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d -gTJJMdgpKy9U(Eqi⏎ + +```bash +kubectl get secret -n demo druid-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +gTJJMdgpKy9U(Eqi⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -586,14 +607,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Druidopsrequest druidops-rotate-auth-generated drops-rotate-auth-user -n demo +```bash +kubectl delete Druidopsrequest druidops-rotate-auth-generated drops-rotate-auth-user -n demo +``` Druidopsrequest.ops.kubedb.com "druidops-rotate-auth-generated" "drops-rotate-auth-user" deleted -$ kubectl delete secret -n demo druid-quickstart-auth-user + +```bash +kubectl delete secret -n demo druid-quickstart-auth-user +``` secret "druid-quickstart-auth-user" deleted -$ kubectl delete secret -n demo druid-quickstart-auth -secret "druid-quickstart-auth" deleted + +```bash +kubectl delete secret -n demo druid-quickstart-auth ``` +secret "druid-quickstart-auth" deleted ## Next Steps diff --git a/docs/guides/druid/scaling/horizontal-scaling/guide.md b/docs/guides/druid/scaling/horizontal-scaling/guide.md index 1e6061895a..9f4b36ff39 100644 --- a/docs/guides/druid/scaling/horizontal-scaling/guide.md +++ b/docs/guides/druid/scaling/horizontal-scaling/guide.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the D To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/druid](/docs/examples/druid) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -52,19 +52,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -90,9 +96,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created ### Deploy Druid topology cluster @@ -120,43 +126,47 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1aplha2 36.0.0 Provisioning 0s druid-cluster kubedb.com/v1aplha2 36.0.0 Provisioning 24s . . druid-cluster kubedb.com/v1aplha2 36.0.0 Ready 92s -``` Let's check the number of replicas has from druid object, number of pods the petset have, **Coordinators Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +``` 1 -$ kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' ``` +1 **Historicals Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +``` 1 -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' ``` +1 We can see from commands that the cluster has 1 replicas for both coordinators and historicals. @@ -167,10 +177,10 @@ You can also see the replica count of each node from the druid ui. For that, fol First port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 8888 +kubectl port-forward -n demo svc/druid-cluster-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now hit the `http://localhost:8888` from any browser, and you will be prompted to provide the credential of the druid database. By following the steps discussed below, you can get the credential generated by the KubeDB operator for your Druid database. @@ -180,16 +190,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -242,9 +252,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-hscale-up.yaml -druidopsrequest.ops.kubedb.com/druid-hscale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-hscale-up.yaml ``` +druidopsrequest.ops.kubedb.com/druid-hscale-up created ### Verify Topology cluster replicas scaled up successfully @@ -253,15 +263,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ watch kubectl get druidopsrequest -n demo +watch kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druid-hscale-up HorizontalScaling Successful 106s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe druidopsrequests -n demo druid-hscale-up + kubectl describe druidopsrequests -n demo druid-hscale-up +``` Name: druid-hscale-up Namespace: demo Labels: @@ -375,7 +386,6 @@ Events: Normal ScaleUpHistoricals 24s KubeDB Ops-manager Operator Successfully Scaled Up Broker Normal Starting 24s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 24s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: druid-hscale-up -``` Now, we are going to verify the number of replicas this cluster has from the Druid object, number of pods the petset have, @@ -383,22 +393,26 @@ Now, we are going to verify the number of replicas this cluster has from the Dru **Coordinators Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +``` 2 -$ kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' ``` +2 **Historicals Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +``` 2 -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' ``` +2 Now, we are going to verify the number of replicas this cluster has from the Druid UI. @@ -452,9 +466,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-hscale-down.yaml -druidopsrequest.ops.kubedb.com/druid-hscale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/horizontal-scaling/yamls/druid-hscale-down.yaml ``` +druidopsrequest.ops.kubedb.com/druid-hscale-down created #### Verify Topology cluster replicas scaled down successfully @@ -463,15 +477,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ watch kubectl get druidopsrequest -n demo +watch kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druid-hscale-down HorizontalScaling Successful 2m32s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl get druidopsrequest -n demo druid-hscale-down -oyaml +kubectl get druidopsrequest -n demo druid-hscale-down -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: DruidOpsRequest metadata: @@ -546,29 +561,32 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Now, we are going to verify the number of replicas this cluster has from the Druid object, number of pods the petset have, **Coordinators Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.coordinators.replicas' +``` 1 -$ kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo druid-cluster-coordinators -o json | jq '.spec.replicas' ``` +1 **Historicals Replicas** ```bash -$ kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +kubectl get druid -n demo druid-cluster -o json | jq '.spec.topology.historicals.replicas' +``` 1 -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.replicas' ``` +1 Now, we are going to verify the number of replicas this cluster has from the Druid UI. diff --git a/docs/guides/druid/scaling/vertical-scaling/guide.md b/docs/guides/druid/scaling/vertical-scaling/guide.md index eeaee1d691..49b584b2f7 100644 --- a/docs/guides/druid/scaling/vertical-scaling/guide.md +++ b/docs/guides/druid/scaling/vertical-scaling/guide.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/druid](/docs/examples/druid) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -52,19 +52,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -90,9 +96,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created ### Deploy Druid Cluster @@ -119,26 +125,27 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1aplha2 36.0.0 Provisioning 0s druid-cluster kubedb.com/v1aplha2 36.0.0 Provisioning 24s . . druid-cluster kubedb.com/v1aplha2 36.0.0 Ready 92s -``` Let's check the Pod containers resources for both `coordinators` and `historicals` of the Druid topology cluster. Run the following command to get the resources of the `coordinators` and `historicals` containers of the Druid topology cluster ```bash -$ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -148,10 +155,10 @@ $ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.conta "memory": "1Gi" } } -``` ```bash -$ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -161,7 +168,6 @@ $ kubectl get pod -n demo druid-cluster-historicals-0 -o json | jq '.spec.contai "memory": "1Gi" } } -``` This is the default resources of the Druid topology cluster set by the `KubeDB` operator. We are now ready to apply the `DruidOpsRequest` CR to update the resources of this database. @@ -221,9 +227,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/druid-vscale.yaml -druidopsrequest.ops.kubedb.com/druid-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/scaling/vertical-scaling/yamls/druid-vscale.yaml ``` +druidopsrequest.ops.kubedb.com/druid-vscale created #### Verify Druid cluster resources have been updated successfully @@ -232,15 +238,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ kubectl get druidopsrequest -n demo +kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druid-vscale VerticalScaling Successful 3m56s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe druidopsrequest -n demo druid-vscale +kubectl describe druidopsrequest -n demo druid-vscale +``` Name: druid-vscale Namespace: demo Labels: @@ -404,11 +411,11 @@ Events: Normal RestartPods 39s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 39s KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 39s KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: druid-vscale -``` Now, we are going to verify from one of the Pod yaml whether the resources of the topology cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -419,7 +426,10 @@ $ kubectl get pod -n demo druid-cluster-coordinators-0 -o json | jq '.spec.conta "memory": "1288490188800m" } } -$ kubectl get pod -n demo druid-cluster-historicals-1 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo druid-cluster-historicals-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -430,7 +440,6 @@ $ kubectl get pod -n demo druid-cluster-historicals-1 -o json | jq '.spec.contai "memory": "1181116006400m" } } -``` The above output verifies that we have successfully scaled up the resources of the Druid topology cluster. diff --git a/docs/guides/druid/tls/guide.md b/docs/guides/druid/tls/guide.md index 622fef68e3..3b85b07e58 100644 --- a/docs/guides/druid/tls/guide.md +++ b/docs/guides/druid/tls/guide.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Druid. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/druid-ca-issuer.yaml -issuer.cert-manager.io/druid-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/druid-ca-issuer.yaml ``` +issuer.cert-manager.io/druid-ca-issuer created ## TLS/SSL encryption in Druid Cluster @@ -97,19 +97,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -135,9 +141,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, lets go ahead and create a druid database. @@ -168,15 +174,15 @@ spec: ### Deploy Druid Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/druid-cluster-tls.yaml -druid.kubedb.com/druid-cluster-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/tls/yamls/druid-cluster-tls.yaml ``` +druid.kubedb.com/druid-cluster-tls created Now, wait until `druid-cluster-tls created` has status `Ready`. i.e, ```bash -$ kubectl get druid -n demo -w - +kubectl get druid -n demo -w +``` Every 2.0s: kubectl get druid -n demo aadee: Fri Sep 6 12:34:51 2024 NAME TYPE VERSION STATUS AGE druid-cluster-tls kubedb.com/v1alpha2 36.0.0 Ready 20s @@ -184,12 +190,12 @@ druid-cluster-tls kubedb.com/v1alpha2 36.0.0 Provisioning 1m ... ... druid-cluster-tls kubedb.com/v1alpha2 36.0.0 Ready 38m -``` ### Verify TLS/SSL in Druid Cluster ```bash -$ kubectl describe secret druid-cluster-tls-client-cert -n demo +kubectl describe secret druid-cluster-tls-client-cert -n demo +``` Name: druid-cluster-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -217,12 +223,12 @@ tls-combined.pem: 3835 bytes tls.crt: 2126 bytes tls.key: 1708 bytes truststore.jks: 865 bytes -``` Now, Lets exec into a druid coordinators pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo druid-cluster-tls-coordinators-0 -- bash +kubectl exec -it -n demo druid-cluster-tls-coordinators-0 -- bash +``` Defaulted container "druid" out of: druid, init-druid (init) bash-5.1$ cat conf/druid/cluster/_common/common.runtime.properties druid.client.https.trustStorePassword={"type": "environment", "variable": "DRUID_KEY_STORE_PASSWORD"} @@ -239,7 +245,6 @@ druid.server.https.certAlias=druid druid.server.https.keyStorePassword={"type": "environment", "variable": "DRUID_KEY_STORE_PASSWORD"} druid.server.https.keyStorePath=/opt/druid/ssl/keystore.jks druid.server.https.keyStoreType=jks -``` We can see from the above output that, all the TLS related configuration is added. Here the `MySQL` and `ZooKeeper` deployed with Druid is also TLS secure and their connection configs are added as well. @@ -252,10 +257,10 @@ Druid uses separate ports for TLS/SSL. While the plaintext port for `routers` no First port-forward the port `9088` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-tls-routers 9088 +kubectl port-forward -n demo svc/druid-cluster-tls-routers 9088 +``` Forwarding from 127.0.0.1:9088 -> 9088 Forwarding from [::1]:9088 -> 9088 -``` Now hit the `https://localhost:9088/` from any browser. Here you may select `Advance` and then `Proceed to localhost (unsafe)` or you can add the `ca.crt` from the secret `druid-cluster-tls-client-cert` to your browser's Authorities. @@ -267,16 +272,16 @@ After that you will be prompted to provide the credential of the druid database. - Username: ```bash - $ kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-tls-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. diff --git a/docs/guides/druid/update-version/guide.md b/docs/guides/druid/update-version/guide.md index 5c63085d31..7ff81aa1b6 100644 --- a/docs/guides/druid/update-version/guide.md +++ b/docs/guides/druid/update-version/guide.md @@ -29,9 +29,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/druid](/docs/examples/druid) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -46,19 +46,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash +helm repo add minio https://operator.min.io/ +``` -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -84,9 +90,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created ### Deploy Druid @@ -113,21 +119,21 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` created has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1aplha2 35.0.1 Provisioning 0s druid-cluster kubedb.com/v1aplha2 35.0.1 Provisioning 55s . . druid-cluster kubedb.com/v1aplha2 35.0.1 Ready 119s -``` We are now ready to apply the `DruidOpsRequest` CR to update. @@ -138,10 +144,10 @@ You can also see the version of druid cluster from the druid ui. For that, follo First, port-forward the port `8888` to local machine: ```bash -$ kubectl port-forward -n demo svc/druid-cluster-routers 8888 +kubectl port-forward -n demo svc/druid-cluster-routers 8888 +``` Forwarding from 127.0.0.1:8888 -> 8888 Forwarding from [::1]:8888 -> 8888 -``` Now hit the `http://localhost:8888` from any browser, and you will be prompted to provide the credential of the druid database. By following the steps discussed below, you can get the credential generated by the KubeDB operator for your Druid database. @@ -150,16 +156,16 @@ Now hit the `http://localhost:8888` from any browser, and you will be prompted t - Username: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d - admin + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + admin - Password: ```bash - $ kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d - LzJtVRX5E8MorFaf + kubectl get secret -n demo druid-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + LzJtVRX5E8MorFaf After providing the credentials correctly, you should be able to access the web console like shown below. @@ -203,9 +209,9 @@ Here, Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/update-version-ops.yaml -druidopsrequest.ops.kubedb.com/druid-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/update-version/yamls/update-version-ops.yaml ``` +druidopsrequest.ops.kubedb.com/druid-update-version created #### Verify Druid version updated successfully @@ -214,15 +220,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ watch kubectl get druidopsrequest -n demo +watch kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE druid-update-version UpdateVersion Successful 2m6s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe druidopsrequest -n demo druid-update-version +kubectl describe druidopsrequest -n demo druid-update-version +``` Name: druid-update-version Namespace: demo Labels: @@ -401,20 +408,23 @@ Events: Normal RestartPods 17m KubeDB Ops-manager Operator Successfully Restarted Druid nodes Normal Starting 17m KubeDB Ops-manager Operator Resuming Druid database: demo/druid-cluster Normal Successful 17m KubeDB Ops-manager Operator Successfully resumed Druid database: demo/druid-cluster for DruidOpsRequest: druid-update-version -``` Now, we are going to verify whether the `Druid` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get dr -n demo druid-cluster -o=jsonpath='{.spec.version}{"\n"}' +kubectl get dr -n demo druid-cluster -o=jsonpath='{.spec.version}{"\n"}' +``` 36.0.0 -$ kubectl get petset -n demo druid-cluster-brokers -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo druid-cluster-brokers -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/druid:36.0.0@sha256:4cd60a1dc6a124e27e91ec52ca39e2b9ca6809df915ae2dd712a2dd7462626d7 -$ kubectl get pods -n demo druid-cluster-brokers-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/druid:36.0.0 +```bash +kubectl get pods -n demo druid-cluster-brokers-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/druid:36.0.0 You can see from above, our `Druid` has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/druid/volume-expansion/guide.md b/docs/guides/druid/volume-expansion/guide.md index a3be15e6c9..b709b5c304 100644 --- a/docs/guides/druid/volume-expansion/guide.md +++ b/docs/guides/druid/volume-expansion/guide.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/druid](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/druid) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,12 +48,12 @@ Here, we are going to deploy a `Druid` topology using a supported version by `Ku At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 28h longhorn (default) driver.longhorn.io Delete Immediate true 27h longhorn-static driver.longhorn.io Delete Immediate true 27h -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -64,18 +64,25 @@ Before proceeding further, we need to prepare deep storage, which is one of the In this tutorial, we will run a `minio-server` as deep storage in our local `kind` cluster using `minio-operator` and create a bucket named `druid` in it, which the deployed druid database will use. ```bash -$ helm repo add minio https://operator.min.io/ -$ helm repo update minio -$ helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +helm repo add minio https://operator.min.io/ +``` + +```bash +helm repo update minio +``` -$ helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ +```bash +helm upgrade --install --namespace "minio-operator" --create-namespace "minio-operator" minio/operator --set operator.replicaCount=1 +``` + +```bash +helm upgrade --install --namespace "demo" --create-namespace druid-minio minio/tenant \ --set tenant.pools[0].servers=1 \ --set tenant.pools[0].volumesPerServer=1 \ --set tenant.pools[0].size=1Gi \ --set tenant.certificate.requestAutoCert=false \ --set tenant.buckets[0].name="druid" \ --set tenant.pools[0].name="default" - ``` Now we need to create a `Secret` named `deep-storage-config`. It contains the necessary connection information using which the druid database will connect to the deep storage. @@ -101,9 +108,9 @@ stringData: Let’s create the `deep-storage-config` Secret shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/deep-storage-config.yaml -secret/deep-storage-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/deep-storage-config.yaml ``` +secret/deep-storage-config created Now, we are going to deploy a `Druid` combined cluster with version `36.0.0`. @@ -150,36 +157,40 @@ spec: Let's create the `Druid` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/druid-cluster.yaml -druid.kubedb.com/druid-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/druid-cluster.yaml ``` +druid.kubedb.com/druid-cluster created Now, wait until `druid-cluster` has status `Ready`. i.e, ```bash -$ kubectl get dr -n demo -w +kubectl get dr -n demo -w +``` NAME TYPE VERSION STATUS AGE druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 0s druid-cluster kubedb.com/v1alpha2 36.0.0 Provisioning 9s . . druid-cluster kubedb.com/v1alpha2 36.0.0 Ready 3m26s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo druid-cluster-historicals -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo druid-cluster-middleManagers -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-0bf49077-1c7a-4943-bb17-1dffd1626dcd 1Gi RWO Delete Bound demo/druid-cluster-segment-cache-druid-cluster-historicals-0 longhorn 10m pvc-59ed4914-53b3-4f18-a6aa-7699c2b738e2 1Gi RWO Delete Bound demo/druid-cluster-base-task-dir-druid-cluster-middlemanagers-0 longhorn 10m -``` You can see the petsets have 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -224,9 +235,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `DruidOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/volume-expansion-ops.yaml -druidopsrequest.ops.kubedb.com/dr-volume-exp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/druid/volume-expansion/yamls/volume-expansion-ops.yaml ``` +druidopsrequest.ops.kubedb.com/dr-volume-exp created #### Verify Druid Topology volume expanded successfully @@ -235,10 +246,10 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `DruidOpsRequest` to be `Successful`. Run the following command to watch `DruidOpsRequest` CR, ```bash -$ kubectl get druidopsrequest -n demo +kubectl get druidopsrequest -n demo +``` NAME TYPE STATUS AGE dr-volume-exp VolumeExpansion Successful 3m1s -``` We can see from the above output that the `DruidOpsRequest` has succeeded. If we describe the `DruidOpsRequest` we will get an overview of the steps that were followed to expand the volume of druid. diff --git a/docs/guides/elasticsearch/autoscaler/compute/combined/index.md b/docs/guides/elasticsearch/autoscaler/compute/combined/index.md index 2b1f4d4d33..560d9f3d12 100644 --- a/docs/guides/elasticsearch/autoscaler/compute/combined/index.md +++ b/docs/guides/elasticsearch/autoscaler/compute/combined/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/guides/elasticsearch/autoscaler/compute/combined/yamls) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -81,14 +81,15 @@ spec: Let's create the `Elasticsearch` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/combined/yamls/es-combined.yaml -elasticsearch.kubedb.com/es-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/combined/yamls/es-combined.yaml ``` +elasticsearch.kubedb.com/es-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-combined xpack-9.2.3 Provisioning 4s es-combined xpack-9.2.3 Provisioning 7s @@ -96,8 +97,6 @@ es-combined xpack-9.2.3 Provisioning 7s .... es-combined xpack-9.2.3 Ready 60s -``` - Let's check the Pod containers resources, ```json @@ -182,20 +181,23 @@ Here, Let's create the `ElasticsearchAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/combined/yamls/es-auto-scaler.yaml -elasticsearchautoscaler.autoscaling.kubedb.com/es-combined-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/combined/yamls/es-auto-scaler.yaml ``` +elasticsearchautoscaler.autoscaling.kubedb.com/es-combined-as created #### Verify Autoscaling is set up successfully Let's check that the `elasticsearchautoscaler` resource is created successfully, ```bash -$kubectl get elasticsearchautoscaler -n demo +kubectl get elasticsearchautoscaler -n demo +``` NAME AGE es-combined-as 14s -$ kubectl describe elasticsearchautoscaler -n demo es-combined-as +```bash +kubectl describe elasticsearchautoscaler -n demo es-combined-as +``` Name: es-combined-as Namespace: demo Labels: @@ -335,7 +337,6 @@ Status: Memory: 3Gi Vpa Name: es-combined Events: -``` So, the `elasticsearchautoscaler` resource is created successfully. @@ -344,23 +345,24 @@ you can see in the `Status.VPAs.Recommendation section`, that recommendation has Let's watch the `elasticsearchopsrequest` in the demo namespace to see if any `elasticsearchopsrequest` object is created. After some time you'll see that an `elasticsearchopsrequest` will be created based on the recommendation. ```bash -$ kubectl get elasticsearchopsrequest -n demo + kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-es-combined-ujb5hy VerticalScaling Progessing 1m -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get elasticsearchopsrequest -n demo + kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-es-combined-ujb5hy VerticalScaling Successful 1m -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe elasticsearchopsrequest -n demo esops-es-combined-ujb5hy +kubectl describe elasticsearchopsrequest -n demo esops-es-combined-ujb5hy +``` Name: esops-es-combined-ujb5hy Namespace: demo Labels: @@ -475,7 +477,6 @@ Events: Normal UpdateElasticsearchCR 4m7s KubeDB Ops-manager Operator successfully updated Elasticsearch CR Normal ResumeDatabase 4m7s KubeDB Ops-manager Operator Resuming Elasticsearch demo/es-combined Normal Successful 4m7s KubeDB Ops-manager Operator Successfully Updated Database -``` Now, we are going to verify from the Pod, and the Elasticsearch YAML whether the resources of the standalone database has updated to meet up the desired state, Let's check, @@ -512,7 +513,13 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete es -n demo es-combined -$ kubectl delete elasticsearchautoscaler -n demo es-combined-as -$ kubectl delete ns demo +kubectl delete es -n demo es-combined +``` + +```bash +kubectl delete elasticsearchautoscaler -n demo es-combined-as +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/elasticsearch/autoscaler/compute/topology/index.md b/docs/guides/elasticsearch/autoscaler/compute/topology/index.md index 5278d9fa6c..e22aa5ebff 100644 --- a/docs/guides/elasticsearch/autoscaler/compute/topology/index.md +++ b/docs/guides/elasticsearch/autoscaler/compute/topology/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/guides/elasticsearch/autoscaler/compute/topology/yamls) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -94,23 +94,24 @@ spec: Let's create the `Elasticsearch` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/topology/yamls/es-topology.yaml -elasticsearch.kubedb.com/es-topology created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/topology/yamls/es-topology.yaml ``` +elasticsearch.kubedb.com/es-topology created Now, wait until `es-topology` has status `Ready`. i.e, ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-topology opensearch-3.4.0 Provisioning 113s es-topology opensearch-3.4.0 Ready 115s -``` Let's check an ingest node containers resources, ```bash -$ kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -121,12 +122,12 @@ $ kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[]. "memory": "1Gi" } } -``` Let's check the Elasticsearch CR for the ingest node resources, ```bash -$ kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ingest.resources' +kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ingest.resources' +``` { "limits": { "cpu": "500m", @@ -137,8 +138,6 @@ $ kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ing "memory": "1Gi" } -``` - You can see from the above outputs that the resources are the same as the ones we have assigned while deploying the Elasticsearch. We are now ready to apply the `ElasticsearchAutoscaler` CRO to set up autoscaling for this database. @@ -187,20 +186,23 @@ Here, Let's create the `ElasticsearchAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/topology/yamls/es-topology-auto-scaler.yaml -elasticsearchautoscaler.autoscaling.kubedb.com/es-topology-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/compute/topology/yamls/es-topology-auto-scaler.yaml ``` +elasticsearchautoscaler.autoscaling.kubedb.com/es-topology-as created #### Verify Autoscaling is set up successfully Let's check that the `elasticsearchautoscaler` resource is created successfully, ```bash -$ kubectl get elasticsearchautoscaler -n demo +kubectl get elasticsearchautoscaler -n demo +``` NAME AGE es-topology-as 9s -$ kubectl describe elasticsearchautoscaler -n demo es-topology-as +```bash +kubectl describe elasticsearchautoscaler -n demo es-topology-as +``` Name: es-topology-as Namespace: demo Labels: @@ -230,18 +232,20 @@ Spec: Database Ref: Name: es-topology Events: -``` So, the `elasticsearchautoscaler` resource is created successfully. Now, lets verify that the vertical pod autoscaler (vpa) resource is created successfully, ```bash -$ kubectl get vpa -n demo +kubectl get vpa -n demo +``` NAME MODE CPU MEM PROVIDED AGE vpa-es-topology-ingest Off 400m 1102117711 True 30s -$ kubectl describe vpa -n demo vpa-es-topology-ingest +```bash +kubectl describe vpa -n demo vpa-es-topology-ingest +``` Name: vpa-es-topology-ingest Namespace: demo Labels: @@ -301,31 +305,31 @@ Status: Cpu: 2 Memory: 3Gi Events: -``` As you can see from the output the vpa has generated a recommendation for the ingest node of the Elasticsearch cluster. Our autoscaler operator continuously watches the recommendation generated and creates an `elasticsearchopsrequest` based on the recommendations, if the Elasticsearch nodes are needed to be scaled up or down. Let's watch the `elasticsearchopsrequest` in the demo namespace to see if any `elasticsearchopsrequest` object is created. After some time you'll see that an `elasticsearchopsrequest` will be created based on the recommendation. ```bash -$ kubectl get elasticsearchopsrequest -n demo +kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-vpa-es-topology-ingest-37m2wi VerticalScaling Progressing 44s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get elasticsearchopsrequest -n demo -w + kubectl get elasticsearchopsrequest -n demo -w +``` NAME TYPE STATUS AGE esops-vpa-es-topology-ingest-37m2wi VerticalScaling Progressing 8m2s esops-vpa-es-topology-ingest-37m2wi VerticalScaling Successful 9m20s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ Name: esops-vpa-es-topology-ingest-37m2wi +Name: esops-vpa-es-topology-ingest-37m2wi +``` Namespace: demo Labels: app.kubernetes.io/component=database app.kubernetes.io/instance=es-topology @@ -398,12 +402,12 @@ Events: Normal Updating 56s KubeDB Enterprise Operator Successfully Updated Elasticsearch Normal ResumeDatabase 56s KubeDB Enterprise Operator Resuming Elasticsearch demo/es-topology Normal Successful 56s KubeDB Enterprise Operator Successfully Updated Database -``` Now, we are going to verify from the Pod, and the Elasticsearch YAML whether the resources of the ingest node of the cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -415,7 +419,9 @@ $ kubectl get pod -n demo es-topology-ingest-0 -o json | jq '.spec.containers[]. } } -$ kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ingest.resources' +```bash +kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ingest.resources' +``` { "limits": { "cpu": "400m", @@ -426,7 +432,6 @@ $ kubectl get elasticsearch -n demo es-topology -o json | jq '.spec.topology.ing "memory": "1102117711" } } -``` The above output verifies that we have successfully auto-scaled the resources of the Elasticsearch topology cluster. @@ -435,7 +440,13 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearch -n demo es-topology -$ kubectl delete elasticsearchautoscaler -n demo es-topology-as -$ kubectl delete ns demo +kubectl delete elasticsearch -n demo es-topology +``` + +```bash +kubectl delete elasticsearchautoscaler -n demo es-topology-as +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/elasticsearch/autoscaler/storage/combined/index.md b/docs/guides/elasticsearch/autoscaler/storage/combined/index.md index fe5edeb52b..164c0be38e 100644 --- a/docs/guides/elasticsearch/autoscaler/storage/combined/index.md +++ b/docs/guides/elasticsearch/autoscaler/storage/combined/index.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of an Elas To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/guides/elasticsearch/autoscaler/storage/combined/yamls) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -46,11 +46,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -84,33 +84,35 @@ spec: Let's create the `Elasticsearch` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/combined/yamls/es-combined.yaml -elasticsearch.kubedb.com/es-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/combined/yamls/es-combined.yaml ``` +elasticsearch.kubedb.com/es-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-combined xpack-9.2.3 Provisioning 5s es-combined xpack-9.2.3 Ready 50s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1Gi" } } -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-efe67aee-21bf-4320-9873-5d58d68182ae 1Gi RWO Delete Bound demo/data-es-combined-0 topolvm-provisioner 8m3s -``` You can see the PetSet has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -151,20 +153,23 @@ Here, Let's create the `ElasticsearchAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/combined/yamls/es-combined-storage-as.yaml -elasticsearchautoscaler.autoscaling.kubedb.com/es-combined-storage-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/combined/yamls/es-combined-storage-as.yaml ``` +elasticsearchautoscaler.autoscaling.kubedb.com/es-combined-storage-as created #### Storage Autoscaling is set up successfully Let's check that the `elasticsearchautoscaler` resource is created successfully, ```bash -$ kubectl get elasticsearchautoscaler -n demo +kubectl get elasticsearchautoscaler -n demo +``` NAME AGE es-combined-storage-as 9s -$ kubectl describe elasticsearchautoscaler -n demo es-combined-storage-as +```bash +kubectl describe elasticsearchautoscaler -n demo es-combined-storage-as +``` Name: es-combined-storage-as Namespace: demo Labels: @@ -185,7 +190,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `elasticsearchautoscaler` resource is created successfully. @@ -194,7 +198,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo es-combined-0 -- bash +kubectl exec -it -n demo es-combined-0 -- bash +``` [root@es-combined-0 elasticsearch]# df -h /usr/share/elasticsearch/data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/026b4152-c7d8-47c1-afe2-0a7c7b708857 1014M 40M 975M 4% /usr/share/elasticsearch/data @@ -207,30 +212,30 @@ Filesystem Size Used Avail Use% Mounted [root@es-combined-0 elasticsearch]# df -h /usr/share/elasticsearch/data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/026b4152-c7d8-47c1-afe2-0a7c7b708857 1014M 640M 375M 64% /usr/share/elasticsearch/data -``` So, from the above output, we can see that the storage usage is 64%, which exceeded the `usageThreshold` 60%. Let's watch the `elasticsearchopsrequest` in the demo namespace to see if any `elasticsearchopsrequest` object is created. After some time you'll see that a `elasticsearchopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get esops -n demo -w + kubectl get esops -n demo -w +``` NAME TYPE STATUS AGE esops-es-combined-8ub9ca VolumeExpansion Progressing 30s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get esops -n demo +kubectl get esops -n demo +``` NAME TYPE STATUS AGE esops-es-combined-8ub9ca VolumeExpansion Successful 50s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe esops -n demo esops-es-combined-8ub9ca +kubectl describe esops -n demo esops-es-combined-8ub9ca +``` Name: esops-es-combined-8ub9ca Namespace: demo Labels: app.kubernetes.io/component=database @@ -303,22 +308,23 @@ Events: Normal ReadyPetSets 16m KubeDB Enterprise Operator PetSet is recreated Normal ResumeDatabase 16m KubeDB Enterprise Operator Resuming Elasticsearch demo/es-combined Normal Successful 16m KubeDB Enterprise Operator Successfully Updated Database -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the combined cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1594884096" } } -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-efe67aee-21bf-4320-9873-5d58d68182ae 2Gi RWO Delete Bound demo/data-es-combined-0 topolvm-provisioner 43m -``` The above output verifies that we have successfully autoscaled the volume of the Elasticsearch combined cluster. @@ -327,6 +333,9 @@ The above output verifies that we have successfully autoscaled the volume of the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearch -n demo es-combined -$ kubectl delete elasticsearchautoscaler -n demo es-combined-storage-as +kubectl delete elasticsearch -n demo es-combined +``` + +```bash +kubectl delete elasticsearchautoscaler -n demo es-combined-storage-as ``` diff --git a/docs/guides/elasticsearch/autoscaler/storage/topology/index.md b/docs/guides/elasticsearch/autoscaler/storage/topology/index.md index 2cc0397407..ab24c36eb7 100644 --- a/docs/guides/elasticsearch/autoscaler/storage/topology/index.md +++ b/docs/guides/elasticsearch/autoscaler/storage/topology/index.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of an Elas To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/guides/elasticsearch/autoscaler/storage/topology/yamls) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -46,11 +46,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -107,36 +107,38 @@ spec: Let's create the `Elasticsearch` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/topology/yamls/es-topology.yaml -elasticsearch.kubedb.com/es-topology created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/topology/yamls/es-topology.yaml ``` +elasticsearch.kubedb.com/es-topology created Now, wait until `es-topology` has status `Ready`. i.e, ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-topology xpack-9.2.3 Provisioning 12s es-topology xpack-9.2.3 Ready 1m50s -``` Let's check volume size from the data petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo es-topology-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo es-topology-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1Gi" } } -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-1a22f743-2b03-487b-92db-e75ce14a3994 1Gi RWO Delete Bound demo/data-es-topology-ingest-0 topolvm-provisioner 2m8s pvc-82c60733-22a3-4dbb-bac0-2fcd386650dd 1Gi RWO Delete Bound demo/data-es-topology-data-0 topolvm-provisioner 2m7s pvc-a610cbb8-dece-4d2e-8870-b66a2f1fe458 1Gi RWO Delete Bound demo/data-es-topology-master-0 topolvm-provisioner 2m8s pvc-edb7f4f7-f8ba-4af9-a507-b707462ddc3c 1Gi RWO Delete Bound demo/data-es-topology-data-1 topolvm-provisioner 119s -``` You can see that the data PetSet has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -179,20 +181,23 @@ Here, Let's create the `ElasticsearchAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/topology/yamls/es-topology-storage-as.yaml -elasticsearchautoscaler.autoscaling.kubedb.com/es-topology-storage-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/autoscaler/storage/topology/yamls/es-topology-storage-as.yaml ``` +elasticsearchautoscaler.autoscaling.kubedb.com/es-topology-storage-as created #### Storage Autoscaling is set up successfully Let's check that the `elasticsearchautoscaler` resource is created successfully, ```bash -$ kubectl get elasticsearchautoscaler -n demo +kubectl get elasticsearchautoscaler -n demo +``` NAME AGE es-topology-storage-as 4m16s -$ kubectl describe elasticsearchautoscaler -n demo es-topology-storage-as +```bash +kubectl describe elasticsearchautoscaler -n demo es-topology-storage-as +``` Name: es-topology-storage-as Namespace: demo Labels: @@ -215,8 +220,6 @@ Spec: Usage Threshold: 60 Events: -``` - So, the `elasticsearchautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up one of the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -224,7 +227,8 @@ Now, for this demo, we are going to manually fill up one of the persistent volum Let's exec into the data nodes and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo es-topology-data-0 -- bash +kubectl exec -it -n demo es-topology-data-0 -- bash +``` [root@es-topology-data-0 elasticsearch]# df -h /usr/share/elasticsearch/data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/fb6d30c8-8bf7-4c19-884e-937f150f4763 1014M 40M 975M 4% /usr/share/elasticsearch/data @@ -236,31 +240,30 @@ Filesystem Size Used Avail Use% Mounted Filesystem Size Used Avail Use% Mounted on /dev/topolvm/fb6d30c8-8bf7-4c19-884e-937f150f4763 1014M 690M 325M 69% /usr/share/elasticsearch/data -``` - So, from the above output we can see that the storage usage is 69%, which exceeded the `usageThreshold` 60%. Let's watch the `elasticsearchopsrequest` in the demo namespace to see if any `elasticsearchopsrequest` object is created. After some time you'll see that an `elasticsearchopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get esops -n demo -w +kubectl get esops -n demo -w +``` NAME TYPE STATUS AGE esops-es-topology-79zpaf VolumeExpansion 0s esops-es-topology-79zpaf VolumeExpansion Progressing 0s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get esops -n demo +kubectl get esops -n demo +``` NAME TYPE STATUS AGE esops-es-topology-79zpaf VolumeExpansion Successful 110s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe elasticsearchopsrequest -n demo esops-es-topology-79zpaf +kubectl describe elasticsearchopsrequest -n demo esops-es-topology-79zpaf +``` Name: esops-es-topology-79zpaf Namespace: demo Labels: app.kubernetes.io/component=database @@ -334,32 +337,35 @@ Events: Normal ReadyPetSets 88s KubeDB Enterprise Operator PetSet is recreated Normal ResumeDatabase 88s KubeDB Enterprise Operator Resuming Elasticsearch demo/es-topology Normal Successful 88s KubeDB Enterprise Operator Successfully Updated Database -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the data nodes of the cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo es-topology-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo es-topology-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1594884096" } } -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-es-topology-data-0 Bound pvc-82c60733-22a3-4dbb-bac0-2fcd386650dd 2Gi RWO topolvm-provisioner 11m data-es-topology-data-1 Bound pvc-edb7f4f7-f8ba-4af9-a507-b707462ddc3c 2Gi RWO topolvm-provisioner 11m data-es-topology-ingest-0 Bound pvc-1a22f743-2b03-487b-92db-e75ce14a3994 1Gi RWO topolvm-provisioner 11m data-es-topology-master-0 Bound pvc-a610cbb8-dece-4d2e-8870-b66a2f1fe458 1Gi RWO topolvm-provisioner 11m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-1a22f743-2b03-487b-92db-e75ce14a3994 1Gi RWO Delete Bound demo/data-es-topology-ingest-0 topolvm-provisioner 10m pvc-82c60733-22a3-4dbb-bac0-2fcd386650dd 2Gi RWO Delete Bound demo/data-es-topology-data-0 topolvm-provisioner 10m pvc-a610cbb8-dece-4d2e-8870-b66a2f1fe458 1Gi RWO Delete Bound demo/data-es-topology-master-0 topolvm-provisioner 10m pvc-edb7f4f7-f8ba-4af9-a507-b707462ddc3c 2Gi RWO Delete Bound demo/data-es-topology-data-1 topolvm-provisioner 10m -``` The above output verifies that we have successfully autoscaled the volume of the data nodes of this Elasticsearch topology cluster. @@ -368,6 +374,9 @@ The above output verifies that we have successfully autoscaled the volume of the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearch -n demo es-topology -$ kubectl delete elasticsearchautoscaler -n demo es-topology-storage-as +kubectl delete elasticsearch -n demo es-topology +``` + +```bash +kubectl delete elasticsearchautoscaler -n demo es-topology-storage-as ``` diff --git a/docs/guides/elasticsearch/backup/kubestash/auto-backup/index.md b/docs/guides/elasticsearch/backup/kubestash/auto-backup/index.md index 6cac666316..68f512eb41 100644 --- a/docs/guides/elasticsearch/backup/kubestash/auto-backup/index.md +++ b/docs/guides/elasticsearch/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/elasticsearch/backup/kubestash/auto-backup/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -53,13 +53,19 @@ We are going to store our backed up data into a `S3` bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -90,9 +96,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -123,9 +129,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -134,8 +140,11 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -197,9 +206,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/default-backup-blueprint.yaml -backupblueprint.core.kubestash.com/es-quickstart-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/default-backup-blueprint.yaml ``` +backupblueprint.core.kubestash.com/es-quickstart-backup-blueprint created Now, we are ready to backup our `Elasticsearch` databases using few annotations. @@ -241,24 +250,25 @@ Here, Let's create the `Elasticsearch` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/sample-es.yaml -elasticsearch.kubedb.com/es-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/sample-es.yaml ``` +elasticsearch.kubedb.com/es-quickstart created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our Elasticsearch in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-es-quickstart Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-es-quickstart -oyaml +kubectl get backupconfiguration -n demo appbinding-es-quickstart -oyaml +``` apiVersion: core.kubestash.com/v1alpha1 kind: BackupConfiguration metadata: @@ -353,7 +363,6 @@ status: type: InitialBackupTriggered name: frequent-backup targetFound: true -``` Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStash automatically resolved those info from the `BackupBluePrint` and created above `BackupConfiguration`. @@ -362,10 +371,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-es-quickstart-frequent-backup-1726722240 BackupConfiguration appbinding-es-quickstart Running 12s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -374,10 +383,10 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `s3-elasticsearch-repo` has been updated by the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-elasticsearch-repo true 8 6.836 KiB Ready 64s 15m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. @@ -399,7 +408,8 @@ s3-elasticsearch-repo-appbindingtart-frequent-backup-1726722361 s3-elasticsear If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-elasticsearch-repo-appbindingtart-frequent-backup-1726722361 -oyaml +kubectl get snapshots -n demo s3-elasticsearch-repo-appbindingtart-frequent-backup-1726722361 -oyaml +``` apiVersion: storage.kubestash.com/v1alpha1 kind: Snapshot metadata: @@ -468,7 +478,6 @@ status: size: 7.790 KiB snapshotTime: "2024-09-19T05:06:01Z" totalComponents: 1 -``` > KubeStash uses `multielasticdump` to perform backups of target `Elasticsearch` databases. Therefore, the component name for logical backups is set as `dump`. @@ -541,9 +550,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/custom-backup-blueprint.yaml -backupblueprint.core.kubestash.com/es-quickstart-custom-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/custom-backup-blueprint.yaml ``` +backupblueprint.core.kubestash.com/es-quickstart-custom-backup-blueprint created Now, we are ready to backup our `Elasticsearch` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -586,9 +595,9 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `Elasticsearch` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/sample-es-2.yaml -elasticsearch.kubedb.com/es-quickstart-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/auto-backup/examples/sample-es-2.yaml ``` +elasticsearch.kubedb.com/es-quickstart-2 created **Verify BackupConfiguration** @@ -603,7 +612,8 @@ appbinding-es-quickstart-2 Ready 8s Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get bacupconfiguration -n demo appbinding-es-quickstart-2 -oyaml +kubectl get bacupconfiguration -n demo appbinding-es-quickstart-2 -oyaml +``` apiVersion: core.kubestash.com/v1alpha1 kind: BackupConfiguration metadata: @@ -700,7 +710,6 @@ status: type: InitialBackupTriggered name: frequent-backup targetFound: true -``` Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStash automatically resolved those info from the `BackupBluePrint` and created above `BackupConfiguration`. @@ -709,7 +718,8 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-es-quickstart-2-frequent-backup-1726726553 BackupConfiguration appbinding-es-quickstart-2 Succeeded 19s 2m51s @@ -718,8 +728,6 @@ We can see from the above output that the backup session has succeeded. Now, we **Verify Backup:** Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `s3-elasticsearch-repo` has been updated by the following command, - -```bash $ kubectl get repo -n demo s3-elasticsearch-repo NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-elasticsearch-repo true 10 15.974 KiB Ready 17s 100m diff --git a/docs/guides/elasticsearch/backup/kubestash/customization/index.md b/docs/guides/elasticsearch/backup/kubestash/customization/index.md index 020c0d6e2c..b77b69ee18 100644 --- a/docs/guides/elasticsearch/backup/kubestash/customization/index.md +++ b/docs/guides/elasticsearch/backup/kubestash/customization/index.md @@ -312,10 +312,10 @@ spec: You can also restore a specific snapshot. At first, list the available snapshot as bellow, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=s3-elasticsearch-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=s3-elasticsearch-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-elasticsearch-repo-es-quickstckup-frequent-backup-1726655113 s3-elasticsearch-repo frequent-backup 2024-09-18T10:25:23Z Delete Succeeded 147m -``` The below example shows how you can pass a specific snapshot name in `.spec.dataSource` section. diff --git a/docs/guides/elasticsearch/backup/kubestash/logical/index.md b/docs/guides/elasticsearch/backup/kubestash/logical/index.md index 6b151135f0..771c7c81ad 100644 --- a/docs/guides/elasticsearch/backup/kubestash/logical/index.md +++ b/docs/guides/elasticsearch/backup/kubestash/logical/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/elasticsearch/backup/kubestash/logical/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -84,24 +84,25 @@ spec: Create the above `Elasticsearch` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/sample-es.yaml -elasticsearch.kubedb.com/es-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/sample-es.yaml ``` +elasticsearch.kubedb.com/es-quickstart created KubeDB will deploy a `Elasticsearch` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get es -n demo es-quickstart +kubectl get es -n demo es-quickstart +``` NAME VERSION STATUS AGE es-quickstart xpack-9.2.3 Ready 3h -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE es-quickstart-apm-system-cred kubernetes.io/basic-auth 2 3h35m es-quickstart-beats-system-cred kubernetes.io/basic-auth 2 3h35m @@ -115,12 +116,13 @@ es-quickstart-logstash-system-cred kubernetes.io/basic-auth 2 3h es-quickstart-remote-monitoring-user-cred kubernetes.io/basic-auth 2 3h35m es-quickstart-transport-cert kubernetes.io/tls 3 3h1m -$ kubectl get service -n demo -l=app.kubernetes.io/instance=es-quickstart +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=es-quickstart +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE es-quickstart ClusterIP 10.128.185.239 9200/TCP 3h2m es-quickstart-master ClusterIP None 9300/TCP 3h2m es-quickstart-pods ClusterIP None 9200/TCP 3h2m -``` Here, we have to use service `es-quickstart` and secret `es-quickstart-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/elasticsearch/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. @@ -129,16 +131,16 @@ Here, we have to use service `es-quickstart` and secret `es-quickstart-auth` to Verify that the `AppBinding` has been created successfully using the following command, -```bash - $ kubectl get appbindings -n demo + ```bash + kubectl get appbindings -n demo + ``` NAME TYPE VERSION AGE es-quickstart kubedb.com/elasticsearch 9.2.3 3h6m -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo es-quickstart -o yaml +kubectl get appbindings -n demo es-quickstart -o yaml ``` ```yaml @@ -218,35 +220,37 @@ Here, Now, we are going to insert some data into Elasticsearch. ```bash -$ kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -tS$k!2IBI.ASI7FJ + +```bash +kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +tS$k!2IBI.ASI7FJ ```bash -$ kubectl port-forward -n demo svc/es-quickstart 9200 +kubectl port-forward -n demo svc/es-quickstart 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` ```bash -$ curl -XPOST -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/info/_doc?pretty" -H 'Content-Type: application/json' -d' +curl -XPOST -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/info/_doc?pretty" -H 'Content-Type: application/json' -d' +``` { "Company": "AppsCode Inc", "Product": "KubeDB" } ' - -``` Now, let’s verify that the index have been created successfully. ```bash -$ curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases FsJlvTyRSsuRWTpX8OpkOA 1 1 40 0 76mb 38mb green open info 9Z2Cl5fjQWGBAfjtF9LqBw 1 1 1 0 8.9kb 4.4kb -``` Also, let’s verify the data in the indexes: ```bash @@ -294,13 +298,19 @@ We are going to store our backed up data into a `S3` bucket. We have to create a Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -332,9 +342,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -365,9 +375,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -380,8 +390,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -436,27 +449,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/es-quickstart-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/es-quickstart-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE es-quickstart-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-elasticsearch-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the S3 bucket, we will see the `Repository` YAML stored in the `elastic/es` directory. @@ -467,20 +480,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-es-quickstart-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE es-quickstart-backup-frequent-backup-1726655113 BackupConfiguration es-quickstart-backup Succeeded 22s 2m7s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -489,18 +502,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `es-quickstart-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo +kubectl get repository -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-elasticsearch-repo true 1 1.453 KiB Ready 2m20s 2m30s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-elasticsearch-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-elasticsearch-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-elasticsearch-repo-es-quickstckup-frequent-backup-1726655113 s3-elasticsearch-repo frequent-backup 2024-09-18T10:25:23Z Delete Succeeded 8m -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -513,7 +526,8 @@ s3-elasticsearch-repo-es-quickstckup-frequent-backup-1726655113 s3-elasticsear If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-elasticsearch-repo-es-quickstckup-frequent-backup-1726655113 -oyaml +kubectl get snapshots -n demo s3-elasticsearch-repo-es-quickstckup-frequent-backup-1726655113 -oyaml +``` apiVersion: storage.kubestash.com/v1alpha1 kind: Snapshot metadata: @@ -582,7 +596,6 @@ status: size: 1.454 KiB snapshotTime: "2024-09-18T10:25:23Z" totalComponents: 1 -``` > KubeStash uses `multielasticdump` to perform backups of target `Elasticsearch` databases. Therefore, the component name for logical backups is set as `dump`. @@ -622,17 +635,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/restore-es.yaml -elasticsearch.kubedb.com/es-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/restore-es.yaml ``` +elasticsearch.kubedb.com/es-cluster created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get es -n demo restored-es +kubectl get es -n demo restored-es +``` NAME VERSION STATUS AGE es-cluster 9.2.3 Provisioning 61s -``` #### Create RestoreSession: @@ -673,18 +686,18 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/es-cluster-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/es-cluster-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE es-cluster-restore s3-elasticsearch-repo Succeeded 7s 116s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -695,29 +708,33 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get es -n demo es-cluster +kubectl get es -n demo es-cluster +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 6m14s -``` ```bash -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d -tS$k!2IBI.ASI7FJ + +```bash +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +tS$k!2IBI.ASI7FJ ```bash -$ kubectl port-forward -n demo svc/es-cluster 9200 +kubectl port-forward -n demo svc/es-cluster 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, lets check either data restored in elasticsearch or not. ```bash -$ curl -XGET -k --user 'elastic:vD~b4DMXZ1iwdjnh' "https://localhost:9200/info/_search?pretty" +curl -XGET -k --user 'elastic:vD~b4DMXZ1iwdjnh' "https://localhost:9200/info/_search?pretty" +``` { "took" : 83, "timed_out" : false, @@ -746,7 +763,6 @@ $ curl -XGET -k --user 'elastic:vD~b4DMXZ1iwdjnh' "https://localhost:9200/info/_ ] } } -``` So, from the above output, we can see the `info` database we had created in the original database `es-cluster` has been restored successfully. diff --git a/docs/guides/elasticsearch/backup/stash/kubedb/index.md b/docs/guides/elasticsearch/backup/stash/kubedb/index.md index 382785e278..19fa841879 100644 --- a/docs/guides/elasticsearch/backup/stash/kubedb/index.md +++ b/docs/guides/elasticsearch/backup/stash/kubedb/index.md @@ -34,10 +34,10 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created it yet. -```console -$ kubectl create ns demo -namespace/demo created +```bash +kubectl create ns demo ``` +namespace/demo created ## Prepare Elasticsearch @@ -91,10 +91,10 @@ spec: Let's create the above `Elasticsearch` object, -```console -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/elasticsearch/sample_es.yaml -elasticsearch.kubedb.com/sample-es created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/elasticsearch/sample_es.yaml ``` +elasticsearch.kubedb.com/sample-es created KubeDB will create the necessary resources to deploy the Elasticsearch database according to the above specification. Let's wait until the database to be ready to use, @@ -369,15 +369,24 @@ We are going to store our backed up data into a GCS bucket. So, we need to creat At first, let's create a `Secret` called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created #### Create Repository @@ -400,9 +409,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/backup/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/backup/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to back up our database into our desired backend. @@ -453,19 +462,19 @@ Here, Let's create the `BackupConfiguration` object we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/backup/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-es-backup created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/backup/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-es-backup created ### Verify Backup Setup Successful If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-es-backup elasticsearch-backup-7.3.2 */5 * * * * Ready 11s -``` ### Verify CronJob diff --git a/docs/guides/elasticsearch/cli/cli.md b/docs/guides/elasticsearch/cli/cli.md index b0b7eac219..2c6df5357f 100644 --- a/docs/guides/elasticsearch/cli/cli.md +++ b/docs/guides/elasticsearch/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create an Elasticsearch object as specified in `elasticsearch.yaml`. ```bash -$ kubectl create -f elasticsearch-demo.yaml -elasticsearch.kubedb.com/elasticsearch-demo created +kubectl create -f elasticsearch-demo.yaml ``` +elasticsearch.kubedb.com/elasticsearch-demo created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f elasticsearch-demo.yaml --namespace=kube-system -elasticsearch.kubedb.com/elasticsearch-demo created +kubectl create -f elasticsearch-demo.yaml --namespace=kube-system ``` +elasticsearch.kubedb.com/elasticsearch-demo created `kubectl create` command also considers `stdin` as input. @@ -45,10 +45,10 @@ cat elasticsearch-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all Elasticsearch objects in `default` namespace, run the following command: ```bash -$ kubectl get elasticsearch +kubectl get elasticsearch +``` NAME VERSION STATUS AGE elasticsearch-demo 7.3.2 Running 1m -``` To get YAML of an object, use `--output=yaml` flag. @@ -88,13 +88,14 @@ status: To get JSON of an object, use `--output=json` flag. ```bash -$ kubectl get elasticsearch elasticsearch-demo --output=json +kubectl get elasticsearch elasticsearch-demo --output=json ``` To list all KubeDB objects, use following command: ```bash -$ kubectl get all -o wide +kubectl get all -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE pod/elasticsearch-demo-0 1/1 Running 0 2m 192.168.1.105 4gb-pool-crtbqq @@ -128,7 +129,6 @@ elasticsearch.kubedb.com/elasticsearch-demo 5.6-v1 Running 2m NAME DATABASE BUCKET STATUS AGE snap/elasticsearch-demo-20170605-073557 es/elasticsearch-demo gs:bucket-name Succeeded 9m snap/snapshot-20171212-114700 es/elasticsearch-demo gs:bucket-name Succeeded 1h -``` Flag `--output=wide` is used to print additional information. @@ -141,25 +141,26 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Snapshots with their corresponding labels. ```bash -$ kubectl get snap --show-labels +kubectl get snap --show-labels +``` NAME DATABASE STATUS AGE LABELS elasticsearch-demo-20170605-073557 es/elasticsearch-demo Succeeded 11m app.kubernetes.io/name=elasticsearches.kubedb.com,app.kubernetes.io/instance=elasticsearch-demo snapshot-20171212-114700 es/elasticsearch-demo Succeeded 1h app.kubernetes.io/name=elasticsearches.kubedb.com,app.kubernetes.io/instance=elasticsearch-demo -``` You can also filter list using `--selector` flag. ```bash -$ kubectl get snap --selector='app.kubernetes.io/name=elasticsearches.kubedb.com' --show-labels +kubectl get snap --selector='app.kubernetes.io/name=elasticsearches.kubedb.com' --show-labels +``` NAME DATABASE STATUS AGE LABELS elasticsearch-demo-20171212-073557 es/elasticsearch-demo Succeeded 14m app.kubernetes.io/name=elasticsearches.kubedb.com,app.kubernetes.io/instance=elasticsearch-demo snapshot-20171212-114700 es/elasticsearch-demo Succeeded 2h app.kubernetes.io/name=elasticsearches.kubedb.com,app.kubernetes.io/instance=elasticsearch-demo -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` pod/elasticsearch-demo-0 service/elasticsearch-demo service/elasticsearch-demo-master @@ -181,14 +182,14 @@ elasticsearchversion.catalog.kubedb.com/6.3.0-v1 elasticsearchversion.catalog.kubedb.com/6.4 elasticsearchversion.catalog.kubedb.com/6.4.0 elasticsearch.kubedb.com/elasticsearch-demo -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe Elasticsearch database `elasticsearch-demo` with relevant information. ```bash -$ kubectl dba describe es elasticsearch-demo +kubectl dba describe es elasticsearch-demo +``` Name: elasticsearch-demo Namespace: default CreationTimestamp: Mon, 08 Oct 2018 20:22:19 +0600 @@ -289,7 +290,6 @@ Events: Normal Successful 5m Elasticsearch operator Successfully patched Elasticsearch Normal Successful 5m Elasticsearch operator Successfully patched PetSet Normal Successful 4m Elasticsearch operator Successfully patched Elasticsearch -``` `kubectl dba describe` command provides following basic information about a database. @@ -308,25 +308,25 @@ To hide events on KubeDB object, use flag `--show-events=false` To describe all Elasticsearch objects in `default` namespace, use following command ```bash -$ kubectl dba describe es +kubectl dba describe es ``` To describe all Elasticsearch objects from every namespace, provide `--all-namespaces` flag. ```bash -$ kubectl dba describe es --all-namespaces +kubectl dba describe es --all-namespaces ``` To describe all KubeDB objects from every namespace, use the following command: ```bash -$ kubectl dba describe all --all-namespaces +kubectl dba describe all --all-namespaces ``` You can also describe KubeDb objects with matching labels. The following command will describe all Elasticsearch objects with specified labels from every namespace. ```bash -$ kubectl dba describe es --all-namespaces --selector='group=dev' +kubectl dba describe es --all-namespaces --selector='group=dev' ``` To learn about various options of `describe` command, please visit [here](/docs/reference/cli/kubectl-dba_describe.md). @@ -359,16 +359,16 @@ For DormantDatabase, `spec.origin` can't be edited using `kubectl edit` `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete an Elasticsearch `elasticsearch-dev` in default namespace ```bash -$ kubectl delete elasticsearch elasticsearch-demo -elasticsearch.kubedb.com "elasticsearch-demo" deleted +kubectl delete elasticsearch elasticsearch-demo ``` +elasticsearch.kubedb.com "elasticsearch-demo" deleted You can also use YAML files to delete objects. The following command will delete an Elasticsearch using the type and name specified in `elasticsearch.yaml`. ```bash -$ kubectl delete -f elasticsearch-demo.yaml -elasticsearch.kubedb.com "elasticsearch-demo" deleted +kubectl delete -f elasticsearch-demo.yaml ``` +elasticsearch.kubedb.com "elasticsearch-demo" deleted `kubectl delete` command also takes input from `stdin`. @@ -379,20 +379,25 @@ cat elasticsearch.yaml | kubectl delete -f - To delete database with matching labels, use `--selector` flag. The following command will delete elasticsearch with label `elasticsearch.app.kubernetes.io/instance=elasticsearch-demo`. ```bash -$ kubectl delete elasticsearch -l elasticsearch.app.kubernetes.io/instance=elasticsearch-demo +kubectl delete elasticsearch -l elasticsearch.app.kubernetes.io/instance=elasticsearch-demo ``` ## Using Kubectl You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # List objects -$ kubectl get elasticsearch -$ kubectl get elasticsearch.kubedb.com +```bash +kubectl get elasticsearch +``` + +```bash +kubectl get elasticsearch.kubedb.com +``` # Delete objects -$ kubectl delete elasticsearch +```bash +kubectl delete elasticsearch ``` ## Next Steps diff --git a/docs/guides/elasticsearch/clustering/combined-cluster/index.md b/docs/guides/elasticsearch/clustering/combined-cluster/index.md index 0e1cf5a3c9..ca1a9409a4 100644 --- a/docs/guides/elasticsearch/clustering/combined-cluster/index.md +++ b/docs/guides/elasticsearch/clustering/combined-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/combined-cluster/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -63,27 +65,28 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/combined-cluster/yamls/es-standalone.yaml -elasticsearch.kubedb.com/es-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/combined-cluster/yamls/es-standalone.yaml ``` +elasticsearch.kubedb.com/es-standalone created Watch the bootstrap progress: ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-standalone opensearch-3.4.0 Provisioning 1m32s es-standalone opensearch-3.4.0 Provisioning 2m17s es-standalone opensearch-3.4.0 Provisioning 2m17s es-standalone opensearch-3.4.0 Provisioning 2m20s es-standalone opensearch-3.4.0 Ready 2m20s -``` Hence the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-standalone' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-standalone' +``` NAME READY STATUS RESTARTS AGE pod/es-standalone-0 1/1 Running 0 33m @@ -114,26 +117,31 @@ secret/es-standalone-transport-cert kubernetes.io/tls 3 33 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-es-standalone-0 Bound pvc-a2d3e491-1d66-4b29-bb18-d5f06905336c 1Gi RWO standard 33m -``` Connect to the Cluster: -```bash # Port-forward the service to local machine -$ kubectl port-forward -n demo svc/es-standalone 9200 +```bash +kubectl port-forward -n demo svc/es-standalone 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` -```bash # Get admin username & password from k8s secret -$ kubectl get secret -n demo es-standalone-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo es-standalone-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo es-standalone-auth -o jsonpath='{.data.password}' | base64 -d + +```bash +kubectl get secret -n demo es-standalone-auth -o jsonpath='{.data.password}' | base64 -d +``` V,YY1.qXxoAch9)B # Check cluster health -$ curl -XGET -k -u 'admin:V,YY1.qXxoAch9)B' "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k -u 'admin:V,YY1.qXxoAch9)B' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "es-standalone", "status" : "green", @@ -151,7 +159,6 @@ $ curl -XGET -k -u 'admin:V,YY1.qXxoAch9)B' "https://localhost:9200/_cluster/hea "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` ## Create Multi-Node Combined Elasticsearch Cluster @@ -181,27 +188,28 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/combined-cluster/yamls/es-multinode.yaml -elasticsearch.kubedb.com/es-multinode created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/combined-cluster/yamls/es-multinode.yaml ``` +elasticsearch.kubedb.com/es-multinode created Watch the bootstrap progress: ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-multinode opensearch-3.4.0 Provisioning 18s es-multinode opensearch-3.4.0 Provisioning 78s es-multinode opensearch-3.4.0 Provisioning 78s es-multinode opensearch-3.4.0 Provisioning 81s es-multinode opensearch-3.4.0 Ready 81s -``` Hence the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-multinode' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-multinode' +``` NAME READY STATUS RESTARTS AGE pod/es-multinode-0 1/1 Running 0 6m12s pod/es-multinode-1 1/1 Running 0 6m7s @@ -237,26 +245,30 @@ persistentvolumeclaim/data-es-multinode-0 Bound pvc-c031bd37-2266-4a0b-8d9f persistentvolumeclaim/data-es-multinode-1 Bound pvc-e75bc8a8-15ed-4522-b0b3-252ff6c841a8 1Gi RWO standard 6m7s persistentvolumeclaim/data-es-multinode-2 Bound pvc-6452fa80-91c6-4d71-9b93-5cff973a2625 1Gi RWO standard 6m2s -``` - Connect to the Cluster: -```bash # Port-forward the service to local machine -$ kubectl port-forward -n demo svc/es-multinode 9200 +```bash +kubectl port-forward -n demo svc/es-multinode 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` -```bash # Get admin username & password from k8s secret -$ kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.password}' | base64 -d + +```bash +kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.password}' | base64 -d +``` 9f$A8o2pBpKL~1T8 # Check cluster health -$ curl -XGET -k -u 'admin:9f$A8o2pBpKL~1T8' "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k -u 'admin:9f$A8o2pBpKL~1T8' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "es-multinode", "status" : "green", @@ -274,23 +286,32 @@ $ curl -XGET -k -u 'admin:9f$A8o2pBpKL~1T8' "https://localhost:9200/_cluster/hea "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` ## Cleaning Up TO cleanup the k8s resources created by this tutorial, run: -```bash # standalone cluster -$ kubectl patch -n demo elasticsearch es-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete elasticsearch -n demo es-standalone +```bash +kubectl patch -n demo elasticsearch es-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete elasticsearch -n demo es-standalone +``` # multinode cluster -$ kubectl patch -n demo elasticsearch es-multinode -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete elasticsearch -n demo es-multinode +```bash +kubectl patch -n demo elasticsearch es-multinode -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete elasticsearch -n demo es-multinode +``` # delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/index.md b/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/index.md index ebc3fbcd0b..6677bc1c35 100644 --- a/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/index.md +++ b/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 14s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,12 +42,12 @@ demo Active 14s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 10m linode-block-storage linodebs.csi.linode.com Delete Immediate true 10m linode-block-storage-retain (default) linodebs.csi.linode.com Retain Immediate true 10m -``` Here, we use `linode-block-storage` as StorageClass in this demo. @@ -137,23 +139,24 @@ Here, Let's deploy the above example by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/yamls/es-cluster.yaml -elasticsearch.kubedb.com/es-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/hot-warm-cold-cluster/yamls/es-cluster.yaml ``` +elasticsearch.kubedb.com/es-cluster created KubeDB will create the necessary resources to deploy the Elasticsearch cluster according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ watch kubectl get elasticsearch -n demo +watch kubectl get elasticsearch -n demo +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 2m48s -``` Here, Elasticsearch is in `Ready` state. It means the database is ready to accept connections. Describe the Elasticsearch object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo es-cluster +kubectl describe elasticsearch -n demo es-cluster +``` Name: es-cluster Namespace: demo Labels: @@ -342,7 +345,6 @@ Events: Normal Successful 3m27s KubeDB Operator Successfully created Elasticsearch Normal Successful 3m26s KubeDB Operator Successfully created appbinding Normal Successful 3m26s KubeDB Operator Successfully governing service -``` - Here, in `Status.Conditions` - `Conditions.Status` is `True` for the `Condition.Type:ProvisioningStarted` which means database provisioning has been started successfully. - `Conditions.Status` is `True` for the `Condition.Type:ReplicaReady` which specifies all replicas are ready in the cluster. @@ -355,7 +357,8 @@ Events: Let's check the Kubernetes resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +``` NAME READY STATUS RESTARTS AGE pod/es-cluster-data-cold-0 1/1 Running 0 5m46s pod/es-cluster-data-cold-1 1/1 Running 0 4m51s @@ -408,8 +411,6 @@ persistentvolumeclaim/data-es-cluster-ingest-1 Bound pvc-1bea5a3b5be2 persistentvolumeclaim/data-es-cluster-master-0 Bound pvc-2c49a2ccb4644d6e 10Gi RWO linode-block-storage 5m50s persistentvolumeclaim/data-es-cluster-master-1 Bound pvc-cb1d970febff498f 10Gi RWO linode-block-storage 4m54s -``` - - `PetSet` - 6 PetSets are created for 6 types Elasticsearch nodes. The PetSets are named after the Elasticsearch instance with given suffix: `{Elasticsearch-Name}-{Sufix}`. - `Services` - 3 services are generated for each Elasticsearch database. - `{Elasticsearch-Name}` - the client service which is used to connect to the database. It points to the `ingest` nodes. @@ -430,20 +431,20 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio KubeDB will create few Services to connect with the database. Let’s check the Services by following command, ```bash -$ kubectl get service -n demo +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE es-cluster ClusterIP 10.128.132.28 9200/TCP 10m es-cluster-dashboard ClusterIP 10.128.99.51 5601/TCP 10m es-cluster-master ClusterIP None 9300/TCP 10m es-cluster-pods ClusterIP None 9200/TCP 10m -``` Here, we are going to use `es-cluster` Service to connect with the database. Now, let’s port-forward the `es-cluster` Service to the port `9200` to local machine: ```bash -$ kubectl port-forward -n demo svc/es-cluster 9200 +kubectl port-forward -n demo svc/es-cluster 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, our Elasticsearch cluster is accessible at `localhost:9200`. #### Export the Credentials @@ -451,7 +452,8 @@ Now, our Elasticsearch cluster is accessible at `localhost:9200`. KubeDB also create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `es-cluster`. ```bash -$ kubectl get secret -n demo | grep es-cluster +kubectl get secret -n demo | grep es-cluster +``` es-cluster-archiver-cert kubernetes.io/tls 3 12m es-cluster-ca-cert kubernetes.io/tls 2 12m es-cluster-config Opaque 1 12m @@ -462,7 +464,6 @@ es-cluster-auth kubernetes.io/basic-auth 2 1 es-cluster-http-cert kubernetes.io/tls 3 12m es-cluster-token-v97c7 kubernetes.io/service-account-token 3 12m es-cluster-transport-cert kubernetes.io/tls 3 12m -``` Now, we can connect to the database with `es-cluster-auth` which contains the admin level credentials to connect with the database. ### Accessing Database Through CLI @@ -470,17 +471,21 @@ Now, we can connect to the database with `es-cluster-auth` which contains the ad To access the database through CLI, we have to get the credentials to access. Let’s export the credentials as environment variable to our current shell : ```bash -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d -YQB)~K6M9U)d_yVu + +```bash +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +YQB)~K6M9U)d_yVu Now, let's check the health of our Elasticsearch cluster -```bash # curl -XGET -k -u 'username:password' https://localhost:9200/_cluster/health?pretty" -$ curl -XGET -k -u 'elastic:YQB)~K6M9U)d_yVu' "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k -u 'elastic:YQB)~K6M9U)d_yVu' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "es-cluster", "status" : "green", @@ -499,14 +504,13 @@ $ curl -XGET -k -u 'elastic:YQB)~K6M9U)d_yVu' "https://localhost:9200/_cluster/h "active_shards_percent_as_number" : 100.0 } -``` - ### Verify Node Role As we have assigned a dedicated role to each type of node, let's verify them by following command, ```bash -$ curl -XGET -k -u 'elastic:YQB)~K6M9U)d_yVu' "https://localhost:9200/_cat/nodes?v" +curl -XGET -k -u 'elastic:YQB)~K6M9U)d_yVu' "https://localhost:9200/_cat/nodes?v" +``` ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 10.2.2.30 41 90 3 0.22 0.31 0.34 s - es-cluster-data-content-0 10.2.1.28 70 76 3 0.00 0.03 0.07 h - es-cluster-data-hot-0 @@ -521,8 +525,6 @@ ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master 10.2.3.49 23 85 3 0.02 0.06 0.11 i - es-cluster-ingest-1 10.2.3.51 72 75 3 0.02 0.06 0.11 h - es-cluster-data-hot-2 -``` - - `node.role` field specifies the dedicated role that we have assigned for each type of node. Where `h` refers to the hot node, `w` refers to the warm node, `c` refers to the cold node, `i` refers to the ingest node, `m` refers to the master node, and `s` refers to the content node. - `master` field specifies the acive master node. Here, we can see a `*` in the `es-cluster-master-0` which shows that it is the active master node now. @@ -533,12 +535,16 @@ ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master To cleanup the k8s resources created by this tutorial, run: ```bash -$ kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete elasticsearch -n demo es-cluster +```bash +kubectl delete elasticsearch -n demo es-cluster +``` # Delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md b/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md index a8916875a8..9ca38b460f 100644 --- a/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md +++ b/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/index.md @@ -23,13 +23,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 7s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -38,10 +40,10 @@ demo Active 7s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -108,22 +110,23 @@ Here, Let's deploy the above example by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/yamls/es-cluster.yaml -elasticsearch.kubedb.com/es-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/clustering/topology-cluster/simple-dedicated-cluster/yamls/es-cluster.yaml ``` +elasticsearch.kubedb.com/es-cluster created KubeDB will create the necessary resources to deploy the Elasticsearch cluster according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ watch kubectl get elasticsearch -n demo +watch kubectl get elasticsearch -n demo +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 3m32s -``` Here, Elasticsearch is in `Ready` state. It means the database is ready to accept connections. Describe the Elasticsearch object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo es-cluster +kubectl describe elasticsearch -n demo es-cluster +``` Name: es-cluster Namespace: demo Labels: @@ -276,7 +279,6 @@ Events: Normal Successful 30m KubeDB Operator Successfully created Elasticsearch Normal Successful 30m KubeDB Operator Successfully created appbinding Normal Successful 30m KubeDB Operator Successfully governing service -``` - Here, in `Status.Conditions` - `Conditions.Status` is `True` for the `Condition.Type:ProvisioningStarted` which means database provisioning has been started successfully. - `Conditions.Status` is `True` for the `Condition.Type:ReplicaReady` which specifies all replicas are ready in the cluster. @@ -289,7 +291,8 @@ Events: Let's check the Kubernetes resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +``` NAME READY STATUS RESTARTS AGE pod/es-cluster-data-0 1/1 Running 0 31m pod/es-cluster-data-1 1/1 Running 0 29m @@ -329,8 +332,6 @@ persistentvolumeclaim/data-es-cluster-ingest-1 Bound pvc-18420ed8-8455-4b18 persistentvolumeclaim/data-es-cluster-master-0 Bound pvc-6892422b-e399-44e1-9fdb-884b68fc66b5 1Gi RWO standard 31m persistentvolumeclaim/data-es-cluster-master-1 Bound pvc-ed4a704c-7b13-421e-85e1-d710e556ca4e 1Gi RWO standard 29m -``` - - `PetSet` - 3 PetSets are created for 3 types Elasticsearch nodes. The PetSets are named after the Elasticsearch instance with given suffix: `{Elasticsearch-Name}-{Sufix}`. - `Services` - 3 services are generated for each Elasticsearch database. - `{Elasticsearch-Name}` - the client service which is used to connect to the database. It points to the `ingest` nodes. @@ -351,19 +352,19 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio KubeDB will create few Services to connect with the database. Let’s check the Services by following command, ```bash -$ kubectl get service -n demo +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE es-cluster ClusterIP 10.96.67.225 9200/TCP 11m es-cluster-master ClusterIP None 9300/TCP 11m es-cluster-pods ClusterIP None 9200/TCP 11m -``` Here, we are going to use `es-cluster` Service to connect with the database. Now, let’s port-forward the `es-cluster` Service to the port `9200` to local machine: ```bash -$ kubectl port-forward -n demo svc/es-cluster 9200 +kubectl port-forward -n demo svc/es-cluster 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, our Elasticsearch cluster is accessible at `localhost:9200`. #### Export the Credentials @@ -371,7 +372,8 @@ Now, our Elasticsearch cluster is accessible at `localhost:9200`. KubeDB also create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `es-cluster`. ```bash -$ kubectl get secret -n demo | grep es-cluster +kubectl get secret -n demo | grep es-cluster +``` es-cluster-archiver-cert kubernetes.io/tls 3 12m es-cluster-ca-cert kubernetes.io/tls 2 12m es-cluster-config Opaque 1 12m @@ -379,7 +381,6 @@ es-cluster-auth kubernetes.io/basic-auth 2 12m es-cluster-http-cert kubernetes.io/tls 3 12m es-cluster-token-hx5mn kubernetes.io/service-account-token 3 12m es-cluster-transport-cert kubernetes.io/tls 3 12m -``` Now, we can connect to the database with `es-cluster-auth` which contains the admin level credentials to connect with the database. ### Accessing Database Through CLI @@ -387,17 +388,21 @@ Now, we can connect to the database with `es-cluster-auth` which contains the ad To access the database through CLI, we have to get the credentials to access. Let’s export the credentials as environment variable to our current shell : ```bash -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d -tS$k!2IBI.ASI7FJ + +```bash +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +tS$k!2IBI.ASI7FJ Now, let's check the health of our Elasticsearch cluster -```bash # curl -XGET -k -u 'username:password' https://localhost:9200/_cluster/health?pretty" -$ curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "es-cluster", "status" : "green", @@ -416,29 +421,26 @@ $ curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_clust "active_shards_percent_as_number" : 100.0 } -``` - ## Insert Sample Data Now, we are going to insert some data into Elasticsearch. ```bash -$ curl -XPOST -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/info/_doc?pretty" -H 'Content-Type: application/json' -d' +curl -XPOST -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/info/_doc?pretty" -H 'Content-Type: application/json' -d' +``` { "Company": "AppsCode Inc", "Product": "KubeDB" } ' - -``` Now, let’s verify that the index have been created successfully. ```bash -$ curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases FsJlvTyRSsuRWTpX8OpkOA 1 1 40 0 76mb 38mb green open info 9Z2Cl5fjQWGBAfjtF9LqBw 1 1 1 0 8.9kb 4.4kb -``` Also, let’s verify the data in the indexes: ```bash @@ -481,12 +483,16 @@ curl -XGET -k --user 'elastic:tS$k!2IBI.ASI7FJ' "https://localhost:9200/info/_se To cleanup the k8s resources created by this tutorial, run: ```bash -$ kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete elasticsearch -n demo es-cluster +```bash +kubectl delete elasticsearch -n demo es-cluster +``` # Delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/concepts/elasticsearch/index.md b/docs/guides/elasticsearch/concepts/elasticsearch/index.md index f06445263c..adb23a9b58 100644 --- a/docs/guides/elasticsearch/concepts/elasticsearch/index.md +++ b/docs/guides/elasticsearch/concepts/elasticsearch/index.md @@ -564,11 +564,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic elastic-auth -n demo \ +kubectl create secret generic elastic-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "elastic-auth" created ``` +secret "elastic-auth" created ```yaml apiVersion: v1 @@ -690,13 +690,13 @@ The configuration file names are used as secret keys. - `YML`: The default configuration file pre-stored at config directories is overwritten by the operator-generated configuration file (if any). Then the resultant configuration file is overwritten by the user-provided custom configuration file (if any). The [yq](https://github.com/mikefarah/yq) tool is used to merge two YAML files. ```bash - $ yq merge -i --overwrite file1.yml file2.yml + yq merge -i --overwrite file1.yml file2.yml ``` - `Non-YML`: The default configuration file is replaced by the operator-generated one (if any). Then the resultant configuration file is replaced by the user-provided custom configuration file (if any). ```bash - $ cp -f file2 file1 + cp -f file2 file1 ``` **How to provide node-role specific configurations?** diff --git a/docs/guides/elasticsearch/configuration/combined-cluster/index.md b/docs/guides/elasticsearch/configuration/combined-cluster/index.md index b446f041bd..158e674d84 100644 --- a/docs/guides/elasticsearch/configuration/combined-cluster/index.md +++ b/docs/guides/elasticsearch/configuration/combined-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls ) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -87,9 +89,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls/config-secret.yaml -secret/es-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls/config-secret.yaml ``` +secret/es-custom-config created Now that the config secret is created, it needs to be mention in the [Elasticsearch](/docs/guides/elasticsearch/concepts/elasticsearch/index.md) object's yaml: @@ -120,19 +122,19 @@ spec: Now, create the Elasticsearch object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls/es-combined.yaml -elasticsearch.kubedb.com/es-multinode created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls/es-combined.yaml ``` +elasticsearch.kubedb.com/es-multinode created Now, wait for the Elasticsearch to become ready: ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-multinode xpack-9.2.3 Provisioning 18s es-multinode xpack-9.2.3 Provisioning 2m5s es-multinode xpack-9.2.3 Ready 2m5s -``` ## Verify Configuration @@ -140,12 +142,12 @@ Let's connect to the Elasticsearch cluster that we have created and check the no Connect to the Cluster: -```bash # Port-forward the service to local machine -$ kubectl port-forward -n demo svc/es-multinode 9200 +```bash +kubectl port-forward -n demo svc/es-multinode 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, our Elasticsearch cluster is accessible at `localhost:9200`. @@ -155,22 +157,21 @@ Now, our Elasticsearch cluster is accessible at `localhost:9200`. - Username: ```bash - $ kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.username}' | base64 -d - elastic + kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.username}' | base64 -d ``` + elastic - Password: ```bash - $ kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.password}' | base64 -d - ehG7*7SJZ0o9PA05 + kubectl get secret -n demo es-multinode-auth -o jsonpath='{.data.password}' | base64 -d ``` + ehG7*7SJZ0o9PA05 Now, we will query for settings of all nodes in an Elasticsearch cluster, ```bash -$ curl -XGET -k -u 'elastic:ehG7*7SJZ0o9PA05' "https://localhost:9200/_nodes/_all/settings?pretty" - +curl -XGET -k -u 'elastic:ehG7*7SJZ0o9PA05' "https://localhost:9200/_nodes/_all/settings?pretty" ``` This will return a large JSON with node settings. Here is the prettified JSON response, @@ -504,11 +505,15 @@ Here we can see that our given configuration is merged to the default configurat To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearch -n demo es-multinode +kubectl delete elasticsearch -n demo es-multinode +``` -$ kubectl delete secret -n demo es-custom-config +```bash +kubectl delete secret -n demo es-custom-config +``` -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/configuration/jvm-options/index.md b/docs/guides/elasticsearch/configuration/jvm-options/index.md index 580b4eec77..df258ce1e4 100644 --- a/docs/guides/elasticsearch/configuration/jvm-options/index.md +++ b/docs/guides/elasticsearch/configuration/jvm-options/index.md @@ -124,16 +124,16 @@ spec: Deploy Elasticsearch: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/jvm-options/yamls/elasticsearch.yaml -elasticsearch/es-test created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/jvm-options/yamls/elasticsearch.yaml ``` +elasticsearch/es-test created Wait for the Elasticsearch to become ready: ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-test opensearch-3.4.0 Provisioning 12s es-test opensearch-3.4.0 Provisioning 2m2s es-test opensearch-3.4.0 Ready 2m2s -``` diff --git a/docs/guides/elasticsearch/configuration/overview/index.md b/docs/guides/elasticsearch/configuration/overview/index.md index 4b5d8b3348..bc62b89936 100644 --- a/docs/guides/elasticsearch/configuration/overview/index.md +++ b/docs/guides/elasticsearch/configuration/overview/index.md @@ -82,13 +82,13 @@ stringData: - `YML`: The default configuration file pre-stored at config directories is overwritten by the operator-generated configuration file (if any). Then the resultant configuration file is overwritten by the user-provided custom configuration file (if any). The [yq](https://github.com/mikefarah/yq) tool is used to merge two YAML files. ```bash - $ yq merge -i --overwrite file1.yml file2.yml + yq merge -i --overwrite file1.yml file2.yml ``` - `Non-YML`: The default configuration file is replaced by the operator-generated one (if any). Then the resultant configuration file is replaced by the user-provided custom configuration file (if any). ```bash - $ cp -f file2 file1 + cp -f file2 file1 ``` **How to provide node-role specific configurations?** diff --git a/docs/guides/elasticsearch/configuration/topology-cluster/index.md b/docs/guides/elasticsearch/configuration/topology-cluster/index.md index ce31192305..0e857868e1 100644 --- a/docs/guides/elasticsearch/configuration/topology-cluster/index.md +++ b/docs/guides/elasticsearch/configuration/topology-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/combined-cluster/yamls ) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -126,9 +128,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/topology-cluster/yamls/config-secret.yaml -secret/es-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/topology-cluster/yamls/config-secret.yaml ``` +secret/es-custom-config created Now that the config secret is created, it needs to be mention in the [Elasticsearch](/docs/guides/elasticsearch/concepts/elasticsearch/index.md) object's yaml: @@ -178,19 +180,19 @@ spec: Now, create the Elasticsearch object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/topology-cluster/yamls/es-topology.yaml -elasticsearch.kubedb.com/es-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/configuration/topology-cluster/yamls/es-topology.yaml ``` +elasticsearch.kubedb.com/es-topology created Now, wait for the Elasticsearch to become ready: ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-topology xpack-9.2.3 Provisioning 12s es-topology xpack-9.2.3 Provisioning 2m2s es-topology xpack-9.2.3 Ready 2m2s -``` ## Verify Configuration @@ -198,12 +200,12 @@ Let's connect to the Elasticsearch cluster that we have created and check the no Connect to the Cluster: -```bash # Port-forward the service to local machine -$ kubectl port-forward -n demo svc/es-topology 9200 +```bash +kubectl port-forward -n demo svc/es-topology 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, our Elasticsearch cluster is accessible at `localhost:9200`. @@ -213,21 +215,21 @@ Now, our Elasticsearch cluster is accessible at `localhost:9200`. - Username: ```bash - $ kubectl get secret -n demo es-topology-auth -o jsonpath='{.data.username}' | base64 -d - elastic + kubectl get secret -n demo es-topology-auth -o jsonpath='{.data.username}' | base64 -d ``` + elastic - Password: ```bash - $ kubectl get secret -n demo es-topology-auth -o jsonpath='{.data.password}' | base64 -d - F2sIde1TbZqOR_gF + kubectl get secret -n demo es-topology-auth -o jsonpath='{.data.password}' | base64 -d ``` + F2sIde1TbZqOR_gF Now, we will query for settings of all nodes in an Elasticsearch cluster, ```bash -$ curl -XGET -k -u 'elastic:F2sIde1TbZqOR_gF' "https://localhost:9200/_nodes/_all/settings?pretty" +curl -XGET -k -u 'elastic:F2sIde1TbZqOR_gF' "https://localhost:9200/_nodes/_all/settings?pretty" ``` This will return a large JSON with node settings. Here is the prettified JSON response, @@ -530,11 +532,15 @@ Here we can see that our given configuration is merged to the default configurat To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearch -n demo es-topology +kubectl delete elasticsearch -n demo es-topology +``` -$ kubectl delete secret -n demo es-custom-config +```bash +kubectl delete secret -n demo es-custom-config +``` -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/custom-rbac/using-custom-rbac.md b/docs/guides/elasticsearch/custom-rbac/using-custom-rbac.md index 0d98fcad92..02b4a9ade1 100644 --- a/docs/guides/elasticsearch/custom-rbac/using-custom-rbac.md +++ b/docs/guides/elasticsearch/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the Elasticsearch instance named `quick-elasticsearch`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -98,10 +98,9 @@ This permission is required for Elasticsearch pods running on PSP enabled cluste Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -129,9 +128,9 @@ subjects: Now, create an Elasticsearch crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-db.yaml -elasticsearch.kubedb.com/quick-elasticsearch created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-db.yaml ``` +elasticsearch.kubedb.com/quick-elasticsearch created Below is the YAML for the Elasticsearch crd we just created. @@ -158,20 +157,20 @@ spec: ``` ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE quick-elasticsearch 9.2.3 Running 74s -``` Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we should see that a pod with the name `quick-elasticsearch-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo quick-elasticsearch-0 +kubectl get pod -n demo quick-elasticsearch-0 +``` NAME READY STATUS RESTARTS AGE quick-elasticsearch-0 1/1 Running 0 93s -``` ## Reusing Service Account @@ -180,9 +179,9 @@ An existing service account can be reused in another Elasticsearch Database. No Now, create Elasticsearch crd `minute-elasticsearch` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-db-two.yaml -elasticsearch.kubedb.com/quick-elasticsearch created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/custom-rbac/es-custom-db-two.yaml ``` +elasticsearch.kubedb.com/quick-elasticsearch created Below is the YAML for the Elasticsearch crd we just created. @@ -209,21 +208,21 @@ spec: ``` ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE minute-elasticsearch 9.2.3 Running 59s quick-elasticsearch 9.2.3 Running 3m17s -``` Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we should see that a pod with the name `minute-elasticsearch-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo minute-elasticsearch-0 +kubectl get pod -n demo minute-elasticsearch-0 +``` NAME READY STATUS RESTARTS AGE minute-elasticsearch-0 1/1 Running 0 71s -``` ## Cleaning up diff --git a/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/index.md b/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/index.md index e73c664592..8e672adb42 100644 --- a/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/index.md +++ b/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/index.md @@ -23,13 +23,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 11s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -38,10 +40,10 @@ demo Active 11s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -108,22 +110,23 @@ Here, Let's deploy the above yaml by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch//elasticsearch-dashboard/kibana/yamls/es-cluster.yaml -elasticsearch.kubedb.com/es-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch//elasticsearch-dashboard/kibana/yamls/es-cluster.yaml ``` +elasticsearch.kubedb.com/es-cluster created KubeDB will create the necessary resources to deploy the Elasticsearch cluster according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ watch kubectl get elasticsearch -n demo +watch kubectl get elasticsearch -n demo +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 4m32s -``` Here, Elasticsearch is in `Ready` state. It means the database is ready to accept connections. Describe the Elasticsearch object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo es-cluster +kubectl describe elasticsearch -n demo es-cluster +``` Name: es-cluster Namespace: demo Labels: @@ -309,8 +312,6 @@ Events: Normal Successful 6m25s KubeDB Operator Successfully created appbinding Normal Successful 6m25s KubeDB Operator Successfully governing service Normal Successful 6m22s KubeDB Operator Successfully governing service - -``` - Here, in `Status.Conditions` - `Conditions.Status` is `True` for the `Condition.Type:ProvisioningStarted` which means database provisioning has been started successfully. - `Conditions.Status` is `True` for the `Condition.Type:ReplicaReady` which specifies all replicas are ready in the cluster. @@ -323,7 +324,8 @@ Events: Let's check the Kubernetes resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-cluster' +``` NAME READY STATUS RESTARTS AGE pod/es-cluster-data-0 1/1 Running 0 13m pod/es-cluster-data-1 1/1 Running 0 13m @@ -368,8 +370,6 @@ persistentvolumeclaim/data-es-cluster-ingest-1 Bound pvc-024a1697-7737-4a53 persistentvolumeclaim/data-es-cluster-master-0 Bound pvc-775f89a2-4fcd-4660-b0c3-8c46dd1b0a67 1Gi RWO standard 13m persistentvolumeclaim/data-es-cluster-master-1 Bound pvc-53fd7683-96a6-4737-9c4c-eade942e6743 1Gi RWO standard 13m -``` - - `PetSet` - 3 PetSets are created for 3 types Elasticsearch nodes. The PetSets are named after the Elasticsearch instance with given suffix: `{Elasticsearch-Name}-{Sufix}`. - `Services` - 3 services are generated for each Elasticsearch database. - `{Elasticsearch-Name}` - the client service which is used to connect to the database. It points to the `ingest` nodes. @@ -404,18 +404,18 @@ spec: Let's deploy the above yaml by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/yamls/es-cluster-dashboard.yaml -elasticsearchdashboard.elasticsearch.kubedb.com/es-cluster-dashboard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/yamls/es-cluster-dashboard.yaml ``` +elasticsearchdashboard.elasticsearch.kubedb.com/es-cluster-dashboard created KubeDB will create the necessary resources to deploy the dashboard according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ watch kubectl get elasticsearchdashboard -n demo +watch kubectl get elasticsearchdashboard -n demo +``` NAME TYPE DATABASE STATUS AGE es-cluster-dashboard elasticsearch.kubedb.com/v1alpha1 es-cluster Ready 9m -``` Here, Elasticsearch Dashboard is in `Ready` state. @@ -428,21 +428,20 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio KubeDB will create few Services to connect with the database. Let’s check the Services by following command, ```bash -$ kubectl get service -n demo +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE es-cluster ClusterIP 10.96.103.250 9200/TCP 13m es-cluster-dashboard ClusterIP 10.96.108.252 5601/TCP 11m es-cluster-master ClusterIP None 9300/TCP 13m es-cluster-pods ClusterIP None 9200/TCP 13m - -``` Here, we are going to use `es-cluster-dashboard` Service to connect with the database. Now, let’s port-forward the `es-cluster` Service to the port `5601` to local machine: ```bash -$ kubectl port-forward -n demo service/es-cluster-dashboard 5601 +kubectl port-forward -n demo service/es-cluster-dashboard 5601 +``` Forwarding from 127.0.0.1:5601 -> 5601 Forwarding from [::1]:5601 -> 5601 -``` Now, our Elasticsearch cluster dashboard is accessible at `https://localhost:5601`. #### Export the Credentials @@ -450,7 +449,8 @@ Now, our Elasticsearch cluster dashboard is accessible at `https://localhost:560 KubeDB also create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `es-cluster`. ```bash -$ kubectl get secret -n demo | grep es-cluster +kubectl get secret -n demo | grep es-cluster +``` es-cluster-apm-system-cred kubernetes.io/basic-auth 2 14m es-cluster-beats-system-cred kubernetes.io/basic-auth 2 14m es-cluster-ca-cert kubernetes.io/tls 2 14m @@ -463,7 +463,6 @@ es-cluster-logstash-system-cred kubernetes.io/basic-auth 2 es-cluster-remote-monitoring-user-cred kubernetes.io/basic-auth 2 14m es-cluster-token-8tbg6 kubernetes.io/service-account-token 3 14m es-cluster-transport-cert kubernetes.io/tls 3 14m -``` Now, we can connect to the database with the `es-cluster-auth` secret, which holds the `elastic` superuser credentials used to connect with the database. ### Accessing Database Through Dashboard @@ -471,11 +470,14 @@ Now, we can connect to the database with the `es-cluster-auth` secret, which hol To access the database through Dashboard, we have to get the credentials. We can do that by following command, ```bash -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d -5m2YFv!JO6w5_LrD + +```bash +kubectl get secret -n demo es-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +5m2YFv!JO6w5_LrD Now, let's go to `https://localhost:5601` from our browser and login by using those credentials. @@ -518,14 +520,20 @@ Now, Let's remove that index by using `DELETE` query. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearchdashboard -n demo es-cluster-dashboard +kubectl delete elasticsearchdashboard -n demo es-cluster-dashboard +``` -$ kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo elasticsearch es-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete elasticsearch -n demo es-cluster +```bash +kubectl delete elasticsearch -n demo es-cluster +``` # Delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/index.md b/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/index.md index 253b3f6aec..2274f7925a 100644 --- a/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/index.md +++ b/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/index.md @@ -25,13 +25,15 @@ Elasticsearch has many distributions like `ElasticStack`, `OpenSearch`, `SearchG To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 14s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,10 +42,10 @@ demo Active 14s We will have to provide `StorageClass` in Elasticsearch CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 10m -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -110,22 +112,23 @@ Here, Let's deploy the above yaml by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/yamls/os-cluster.yaml -elasticsearch.kubedb.com/os-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/yamls/os-cluster.yaml ``` +elasticsearch.kubedb.com/os-cluster created KubeDB will create the necessary resources to deploy the OpenSearch cluster according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ watch kubectl get elasticsearch -n demo +watch kubectl get elasticsearch -n demo +``` NAME VERSION STATUS AGE os-cluster opensearch-3.4.0 Ready 3m25s -``` Here, OpenSearch is in `Ready` state. It means the database is ready to accept connections. Describe the object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo os-cluster +kubectl describe elasticsearch -n demo os-cluster +``` Name: os-cluster Namespace: demo Labels: @@ -298,8 +301,6 @@ Events: ---- ------ ---- ---- ------- Normal Successful 12m KubeDB Operator Successfully governing service Normal Successful 12m KubeDB Operator Successfully governing service - -``` - Here, in `Status.Conditions` - `Conditions.Status` is `True` for the `Condition.Type:ProvisioningStarted` which means database provisioning has been started successfully. - `Conditions.Status` is `True` for the `Condition.Type:ReplicaReady` which specifies all replicas are ready in the cluster. @@ -312,7 +313,8 @@ Events: After the deployment, the operator creates the following resources:: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=os-cluster' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=os-cluster' +``` NAME READY STATUS RESTARTS AGE pod/os-cluster-data-0 1/1 Running 0 16m pod/os-cluster-data-1 1/1 Running 0 16m @@ -357,7 +359,6 @@ persistentvolumeclaim/data-os-cluster-ingest-0 Bound pvc-fe3b6633-bd74-465c persistentvolumeclaim/data-os-cluster-ingest-1 Bound pvc-2f60eea0-2bb8-4e42-a8e2-49232163f0a5 1Gi RWO standard 16m persistentvolumeclaim/data-os-cluster-master-0 Bound pvc-59e14a54-6311-4639-9b00-dca6304ed90c 1Gi RWO standard 16m persistentvolumeclaim/data-os-cluster-master-1 Bound pvc-37783550-3c3a-4280-b9ac-9e967ab248af 1Gi RWO standard 16m -``` - `PetSet` - 3 PetSets are created for 3 type of nodes. The PetSets are named after the OpenSearch instance with given suffix: `{OpenSearch-Name}-{Sufix}`. - `Services` - 3 services are generated for each OpenSearch database. @@ -393,17 +394,17 @@ spec: Let's deploy the above yaml by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/yamls/os-cluster-dashboard.yaml -elasticsearchdashboard.elasticsearch.kubedb.com/os-cluster-dashboard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/elasticsearch-dashboard/opensearch-dashboards/yamls/os-cluster-dashboard.yaml ``` +elasticsearchdashboard.elasticsearch.kubedb.com/os-cluster-dashboard created KubeDB will create the necessary resources to deploy the OpenSearch dashboard according to the above specification. Let’s wait until the dashboard to be ready to use, ```bash -$ watch kubectl get elasticsearchdashboard -n demo +watch kubectl get elasticsearchdashboard -n demo +``` NAME TYPE DATABASE STATUS AGE os-cluster-dashboard elasticsearch.kubedb.com/v1alpha1 os-cluster Ready 9m -``` Here, OpenSearch Dashboard is in `Ready` state. @@ -416,21 +417,20 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio KubeDB will create few Services to connect with the database. Let’s check the Services by following command, ```bash -$ kubectl get service -n demo +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE os-cluster ClusterIP 10.96.103.250 9200/TCP 19m os-cluster-dashboard ClusterIP 10.96.108.252 5601/TCP 19m os-cluster-master ClusterIP None 9300/TCP 19m os-cluster-pods ClusterIP None 9200/TCP 19m - -``` Here, we are going to use `os-cluster-dashboard` Service to connect with the database. Now, let’s port-forward the `os-cluster` Service to the port `5601` to local machine: ```bash -$ kubectl port-forward -n demo service/os-cluster-dashboard 5601 +kubectl port-forward -n demo service/os-cluster-dashboard 5601 +``` Forwarding from 127.0.0.1:5601 -> 5601 Forwarding from [::1]:5601 -> 5601 -``` Now, our OpenSearch cluster dashboard is accessible at `https://localhost:5601`. #### Export the Credentials @@ -438,7 +438,8 @@ Now, our OpenSearch cluster dashboard is accessible at `https://localhost:5601`. KubeDB also create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `os-cluster`. ```bash -$ kubectl get secret -n demo | grep es-cluster +kubectl get secret -n demo | grep es-cluster +``` os-cluster-admin-cert kubernetes.io/tls 3 16m os-cluster-auth kubernetes.io/basic-auth 2 16m os-cluster-ca-cert kubernetes.io/tls 2 16m @@ -455,7 +456,6 @@ os-cluster-readall-cred kubernetes.io/basic-auth 2 os-cluster-snapshotrestore-cred kubernetes.io/basic-auth 2 16m os-cluster-token-wq8b9 kubernetes.io/service-account-token 3 16m os-cluster-transport-cert kubernetes.io/tls 3 16m -``` Now, we can connect to the database with `os-cluster-auth` which contains the admin credentials to connect with the database. ### Accessing Database Through Dashboard @@ -463,11 +463,14 @@ Now, we can connect to the database with `os-cluster-auth` which contains the ad To access the database through Dashboard, we have to get the credentials. We can do that by following command, ```bash -$ kubectl get secret -n demo os-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo os-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo os-cluster-auth -o jsonpath='{.data.password}' | base64 -d -Oyj8FdPzA.DZqEyS + +```bash +kubectl get secret -n demo os-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +Oyj8FdPzA.DZqEyS Now, let's go to `https://localhost:5601` from our browser and login by using those credentials. @@ -510,14 +513,20 @@ Now, Let's remove that index by using `DELETE` query. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete elasticsearchdashboard -n demo os-cluster-dashboard +kubectl delete elasticsearchdashboard -n demo os-cluster-dashboard +``` -$ kubectl patch -n demo elasticsearch os-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo elasticsearch os-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete elasticsearch -n demo os-cluster +```bash +kubectl delete elasticsearch -n demo os-cluster +``` # Delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/gitops/gitops.md b/docs/guides/elasticsearch/gitops/gitops.md index fc7cabd225..9b55aac307 100644 --- a/docs/guides/elasticsearch/gitops/gitops.md +++ b/docs/guides/elasticsearch/gitops/gitops.md @@ -31,12 +31,14 @@ process to enable `GitOps` operator. cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -97,11 +99,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── Elasticsearch.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `Elasticsearch` CR is created in your cluster. @@ -109,18 +111,19 @@ Our `gitops` operator will create an actual `Elasticsearch` database CR in the c ```bash -$ kubectl get elasticsearch.gitops.kubedb.com,elasticsearch.kubedb.com -n demo +kubectl get elasticsearch.gitops.kubedb.com,elasticsearch.kubedb.com -n demo +``` NAME AGE elasticsearch.gitops.kubedb.com/es-gitops 20m NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 20m -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` Elasticsearch. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=es-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=es-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/es-gitops 20m @@ -149,7 +152,6 @@ service/es-gitops-pods ClusterIP None 9200/TCP 2 NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/es-gitops kubedb.com/elasticsearch 8.18.8 20m -``` ## Update Elasticsearch Database using GitOps ### Scale Elasticsearch Replicas @@ -180,22 +182,22 @@ Now, `gitops` operator will detect the replica changes and create a `HorizontalS resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,esops -n demo +kubectl get es,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 64m NAME TYPE STATUS AGE elasticsearchopsrequest.ops.kubedb.com/es-gitops-horizontalscaling-32p116 HorizontalScaling Successful 39m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=es-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=es-gitops' +``` NAME READY STATUS RESTARTS AGE es-gitops-0 1/1 Running 0 36m es-gitops-1 1/1 Running 0 16m es-gitops-2 1/1 Running 0 15m -``` We can also scale down the replicas by updating the `replicas` fields. @@ -254,7 +256,8 @@ Resource Requests and Limits are updated to `1000m` CPU and `2Gi` Memory. Commit Now, `gitops` operator will detect the resource changes and create a `ElasticsearchOpsRequest` to update the `Elasticsearch` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,esops -n demo +kubectl get es,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 64m @@ -262,11 +265,10 @@ NAME TYPE elasticsearchopsrequest.ops.kubedb.com/es-gitops-horizontalscaling-injx1l HorizontalScaling Successful 15m elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-x5mfy0 VerticalScaling Successful 39m -``` - After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo es-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo es-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -277,7 +279,6 @@ $ kubectl get pod -n demo es-gitops-0 -o json | jq '.spec.containers[0].resource "memory": "2Gi" } } -``` ### Expand Elasticsearch Volume @@ -320,7 +321,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` ElasticsearchOpsRequest to update the `Elasticsearch` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,esops -n demo + kubectl get es,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 3h1m @@ -328,16 +330,15 @@ NAME TYPE elasticsearchopsrequest.ops.kubedb.com/es-gitops-horizontalscaling-32p116 HorizontalScaling Successful 157m elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-x5mfy0 VerticalScaling Successful 157m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-sata37 VolumeExpansion Successful 38m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=es-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=es-gitops' +``` NAME READY STATUS RESTARTS AGE es-gitops-0 1/1 Running 0 36m es-gitops-1 1/1 Running 0 16m es-gitops-2 1/1 Running 0 15m -``` ## Reconfigure Elasticsearch @@ -357,12 +358,12 @@ stringData: Now, we will add this file to `kubedb/es-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── es-configuration.yaml │ └── Elasticsearch.yaml 1 directories, 2 files -``` Update the `Elasticsearch.yaml` with the following, ```yaml @@ -404,7 +405,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` ElasticsearchOpsRequest to update the `Elasticsearch` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,esops -n demo +kubectl get es,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 3h53m @@ -413,7 +415,6 @@ elasticsearchopsrequest.ops.kubedb.com/es-gitops-horizontalscaling-32p116 Hori elasticsearchopsrequest.ops.kubedb.com/es-gitops-reconfigure-wj5qyx Reconfigure Successful 3m42s elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-lvh38k VerticalScaling Successful 99m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-sata37 VolumeExpansion Successful 90m -``` @@ -439,13 +440,13 @@ stringData: Now, we will add this file to `kubedb/es-rotateauth.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── es-configuration.yaml │ ├── es-rotateauth.yaml │ └── Elasticsearch.yaml 1 directories, 3 files -``` Update the `Elasticsearch.yaml` with the following, ```yaml @@ -490,7 +491,8 @@ Change the `authSecret` field to `es-rotate-auth`. Commit the changes and push t Now, `gitops` operator will detect the auth changes and create a `RotateAuth` ElasticsearchOpsRequest to update the `Elasticsearch` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,esops -n demo +kubectl get es,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-8.18.8 Ready 32m @@ -500,7 +502,6 @@ elasticsearchopsrequest.ops.kubedb.com/es-gitops-reconfigure-x7ou3f Reco elasticsearchopsrequest.ops.kubedb.com/es-gitops-rotate-auth-8cgx3b RotateAuth Successful 2m34s elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-wyjx4l VerticalScaling Successful 21m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-z2e3qb VolumeExpansion Successful 17m -``` ### Update Version List Elasticsearch versions using `kubectl get Elasticsearchversion` and choose desired version that is compatible for upgrade from current version. Check the version constraints and ops request [here](/docs/guides/elasticsearch/update-version/elasticsearch.md). @@ -550,7 +551,8 @@ Update the `version` field to `xpack-9.2.3`. Commit the changes and push to your Now, `gitops` operator will detect the version changes and create a `VersionUpdate` ElasticsearchOpsRequest to update the `Elasticsearch` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,elasticsearch,esops -n demo +kubectl get es,elasticsearch,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-9.2.3 Ready 54m @@ -564,19 +566,24 @@ elasticsearchopsrequest.ops.kubedb.com/es-gitops-rotate-auth-8cgx3b Rota elasticsearchopsrequest.ops.kubedb.com/es-gitops-versionupdate-z92dz0 UpdateVersion Successful 17m elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-wyjx4l VerticalScaling Successful 44m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-z2e3qb VolumeExpansion Successful 39m -``` Now, we are going to verify whether the `Elasticsearch`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get Elasticsearch -n demo es-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get Elasticsearch -n demo es-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` xpack-9.2.3 -$ kubectl get petset -n demo es-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/elastic:9.2.3@sha256:e0b89e3ace47308fa5fa842823bc622add3733e47c1067cd1e6afed2cfd317ca -$ kubectl get pod -n demo es-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get petset -n demo es-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/elastic:9.2.3@sha256:e0b89e3ace47308fa5fa842823bc622add3733e47c1067cd1e6afed2cfd317ca + +```bash +kubectl get pod -n demo es-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/elastic:9.2.3@sha256:e0b89e3ace47308fa5fa842823bc622add3733e47c1067cd1e6afed2cfd317ca @@ -633,7 +640,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` ElasticsearchOpsRequest to add the `Elasticsearch` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,elasticsearch,esops -n demo +kubectl get es,elasticsearch,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-9.2.3 Ready 66m @@ -648,7 +656,6 @@ elasticsearchopsrequest.ops.kubedb.com/es-gitops-rotate-auth-8cgx3b Rota elasticsearchopsrequest.ops.kubedb.com/es-gitops-versionupdate-z92dz0 UpdateVersion Successful 28m elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-wyjx4l VerticalScaling Successful 55m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-z2e3qb VolumeExpansion Successful 50m -``` Verify the monitoring is enabled by checking the prometheus targets. @@ -665,23 +672,23 @@ To add tls, we are going to create an example `Issuer` that will be used to enab - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 es-ca \ +kubectl create secret tls es-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/es-ca created ``` +secret/es-ca created Now, Let's create an `Issuer` using the `elasticsearch-ca` secret that we have just created. The `YAML` file looks like this: @@ -698,7 +705,8 @@ spec: Let's add that to our `kubedb/es-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── es-configuration.yaml │ ├── es-rotateauth.yaml @@ -706,7 +714,6 @@ $ tree . │ ├── es-issuer.yaml │ └── Elasticsearch.yaml 1 directories, 5 files -``` Update the `Elasticsearch.yaml` with the following, ```yaml @@ -771,7 +778,8 @@ Add `enableSSL: true` and `tls` fields in the spec. Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` ElasticsearchOpsRequest to update the `Elasticsearch` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get es,elasticsearch,esops -n demo +kubectl get es,elasticsearch,esops -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-gitops xpack-9.2.3 Ready 66m @@ -787,7 +795,6 @@ elasticsearchopsrequest.ops.kubedb.com/es-gitops-versionupdate-z92dz0 Upda elasticsearchopsrequest.ops.kubedb.com/es-gitops-verticalscaling-wyjx4l VerticalScaling Successful 55m elasticsearchopsrequest.ops.kubedb.com/es-gitops-volumeexpansion-z2e3qb VolumeExpansion Successful 50m elasticsearchopsrequest.ops.kubedb.com/es-gitops-reconfiguretls-r4mx7v ReconfigureTLS Successful 9m18s -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for Elasticsearch. diff --git a/docs/guides/elasticsearch/monitoring/using-builtin-prometheus.md b/docs/guides/elasticsearch/monitoring/using-builtin-prometheus.md index c87b53fb39..1b7ffd743f 100644 --- a/docs/guides/elasticsearch/monitoring/using-builtin-prometheus.md +++ b/docs/guides/elasticsearch/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Elasticsearch database using builtin - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the Elasticsearch crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/monitoring/builtin-prom-es.yaml -elasticsearch.kubedb.com/builtin-prom-es created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/monitoring/builtin-prom-es.yaml ``` +elasticsearch.kubedb.com/builtin-prom-es created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get es -n demo builtin-prom-es +kubectl get es -n demo builtin-prom-es +``` NAME VERSION STATUS AGE builtin-prom-es 7.3.2 Running 4m -``` KubeDB will create a separate stats service with name `{Elasticsearch crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-es" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-es" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-es ClusterIP 10.0.14.79 9200/TCP 4m10s builtin-prom-es-master ClusterIP 10.0.1.39 9300/TCP 4m10s builtin-prom-es-stats ClusterIP 10.0.3.147 56790/TCP 3m14s -``` Here, `builtin-prom-es-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-es-stats +kubectl describe svc -n demo builtin-prom-es-stats +``` Name: builtin-prom-es-stats Namespace: demo Labels: app.kubernetes.io/name=elasticsearches.kubedb.com @@ -112,7 +115,6 @@ TargetPort: prom-http/TCP Endpoints: 10.4.0.49:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -276,20 +278,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -300,9 +302,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -311,18 +313,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-es-stats` service as one of the targets. @@ -339,16 +341,31 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo es/builtin-prom-es +kubectl delete -n demo es/builtin-prom-es +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md b/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md index eb46244d76..5735c9cfea 100644 --- a/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md +++ b/docs/guides/elasticsearch/monitoring/using-prometheus-operator.md @@ -25,12 +25,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME AGE monitoring prometheus 18m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -125,27 +127,27 @@ Here, Let's create the Elasticsearch object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/monitoring/coreos-prom-es.yaml -elasticsearch.kubedb.com/coreos-prom-es created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/monitoring/coreos-prom-es.yaml ``` +elasticsearch.kubedb.com/coreos-prom-es created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get es -n demo coreos-prom-es +kubectl get es -n demo coreos-prom-es +``` NAME VERSION STATUS AGE coreos-prom-es 7.3.2 Running 85s -``` KubeDB will create a separate stats service with name `{Elasticsearch crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-es" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-es" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-es ClusterIP 10.0.1.56 9200/TCP 77s coreos-prom-es-master ClusterIP 10.0.7.18 9300/TCP 77s coreos-prom-es-stats ClusterIP 10.0.5.58 56790/TCP 19s -``` Here, `coreos-prom-es-stats` service has been created for monitoring purpose. @@ -174,10 +176,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `coreos-prom-es-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n monitoring +kubectl get servicemonitor -n monitoring +``` NAME AGE kubedb-demo-coreos-prom-es 6m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Elasticsearch crd. @@ -227,20 +229,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 63m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-es-stats` service as one of the targets. diff --git a/docs/guides/elasticsearch/plugins-backup/overview/index.md b/docs/guides/elasticsearch/plugins-backup/overview/index.md index 6ace4f27cc..6bfd21b6ba 100644 --- a/docs/guides/elasticsearch/plugins-backup/overview/index.md +++ b/docs/guides/elasticsearch/plugins-backup/overview/index.md @@ -31,13 +31,13 @@ sudo bin/elasticsearch-plugin install repository-s3 While running the Elasticsearch cluster in k8s, you don't always have the previliage to run as root user. Moreover, the plugin must be installed on every node in the cluster, and each node must be restarted after installation which bring more operational complexities. Here comes the KubeDB with Elasticsearch docker images (i.e. `Distribution=KubeDB`) with the pre-installed plugins; repository-s3, repository-azure, repository-hdfs, and repository-gcs. ```bash -$ kubectl get elasticsearchversions +kubectl get elasticsearchversions +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE kubedb-xpack-7.12.0 7.12.0 KubeDB kubedb/elasticsearch:7.12.0-xpack-v2021.08.23 4h44m kubedb-xpack-7.13.2 7.13.2 KubeDB kubedb/elasticsearch:7.13.2-xpack-v2021.08.23 4h44m xpack-8.19.9 7.14.0 KubeDB kubedb/elasticsearch:7.14.0-xpack-v2021.08.23 4h44m kubedb-xpack-7.9.1 7.9.1 KubeDB kubedb/elasticsearch:7.9.1-xpack-v2021.08.23 4h44m -``` In case, you want to build your own custom Elasticsearch image with your own custom set of Elasticsearch plugins, visit the [elasticsearch-docker](https://github.com/kubedb/elasticsearch-docker/tree/release-7.14-xpack) github repository. diff --git a/docs/guides/elasticsearch/plugins-backup/s3-repository/index.md b/docs/guides/elasticsearch/plugins-backup/s3-repository/index.md index 50e30692ff..ed487ed37c 100644 --- a/docs/guides/elasticsearch/plugins-backup/s3-repository/index.md +++ b/docs/guides/elasticsearch/plugins-backup/s3-repository/index.md @@ -28,13 +28,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/elasticsearch/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/plugins-backup/s3-repository/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs) @@ -71,9 +73,9 @@ stringData: Let's create the k8s secret with secure settings: ```bash -$ kubectl apply -f secure-settings-secret.yaml -secret/es-secure-settings created +kubectl apply -f secure-settings-secret.yaml ``` +secret/es-secure-settings created In [S3 Client Settings](https://www.elastic.co/guide/en/elasticsearch/plugins/7.14/repository-s3-client.html), If you do not configure the `endpoint`, it default to `s3.amazonaws.com`. Since we are using Linode Bucket instead of AWS S3, we need to configure the endpoint too. Let's create another secret with custom client configurations: @@ -93,9 +95,9 @@ stringData: Let's create the k8s secret with custom configurations: ```bash -$ kubectl apply -f custom-configuration.yaml -secret/es-custom-config created +kubectl apply -f custom-configuration.yaml ``` +secret/es-custom-config created ### Deploy Elasticsearch Cluster @@ -131,36 +133,41 @@ spec: Let's deploy the Elasticsearch and wait for it to become ready to use: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/plugins-backup/s3-repository/yamls/elasticsearch.yaml -elasticsearch.kubedb.com/sample-es created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/plugins-backup/s3-repository/yamls/elasticsearch.yaml ``` +elasticsearch.kubedb.com/sample-es created ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE sample-es xpack-9.2.3 0s sample-es xpack-9.2.3 Provisioning 19s sample-es xpack-9.2.3 Ready 41s -``` ### Populate Data To connect to our Elasticsearch cluster, let's port-forward the Elasticsearch service to local machine: ```bash -$ kubectl port-forward -n demo svc/sample-es 9200 +kubectl port-forward -n demo svc/sample-es 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Keep it like that and switch to another terminal window: ```bash -$ export ELASTIC_USER=$(kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.username}' | base64 -d) +export ELASTIC_USER=$(kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ export ELASTIC_PASSWORD=$(kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.password}' | base64 -d) +```bash +export ELASTIC_PASSWORD=$(kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "sample-es", "status" : "green", @@ -178,12 +185,12 @@ $ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_c "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` So, our cluster status is green. Let's create some indices with dummy data: ```bash -$ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d ' +curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d ' +``` { "name": "KubeDB", "vendor": "AppsCode Inc.", @@ -191,24 +198,25 @@ $ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/p } ' -$ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_doc?pretty" -H 'Content-Type: application/json' -d ' +```bash +curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_doc?pretty" -H 'Content-Type: application/json' -d ' +``` { "name": "AppsCode Inc.", "mission": "Accelerate the transition to Containers by building a Kubernetes-native Data Platform", "products": ["KubeDB", "Stash", "KubeVault", "Kubeform", "ByteBuilders"] } ' -``` Now, let’s verify that the indexes have been created successfully. ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases oiaZfJA8Q5CihQon0oR8hA 1 1 42 0 81.6mb 40.8mb green open companies GuGisWJ8Tkqnq8vhREQ2-A 1 1 1 0 11.5kb 5.7kb green open products wyu-fImDRr-Hk_GXVF7cDw 1 1 1 0 10.6kb 5.3kb -``` ### Repository Settings @@ -217,7 +225,8 @@ The s3 repository type supports a [number of settings](https://www.elastic.co/gu Let's create the `_snapshot` repository `sample_s3_repo` with our bucket name `sample-s3-bucket`: ```bash -$ curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_snapshot/sample_s3_repo?pretty" -H 'Content-Type: application/json' -d' +curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_snapshot/sample_s3_repo?pretty" -H 'Content-Type: application/json' -d' +``` { "type": "s3", "settings": { @@ -228,7 +237,6 @@ $ curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_ { "acknowledged" : true } -``` We've successfully created our repository. Ready to take our first snapshot. @@ -237,8 +245,8 @@ We've successfully created our repository. Ready to take our first snapshot. A repository can contain multiple snapshots of the same cluster. Snapshots are identified by unique names within the cluster. For more details, visit [Create a snapshot](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/snapshots-take-snapshot.html). ```bash -$ curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_snapshot/sample_s3_repo/snapshot_1?wait_for_completion=true&pretty" - +curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_snapshot/sample_s3_repo/snapshot_1?wait_for_completion=true&pretty" +``` { "snapshot" : { "snapshot" : "snapshot_1", @@ -275,7 +283,6 @@ $ curl -k -X PUT -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_ ] } } -``` We've successfully taken our first snapshot. @@ -284,26 +291,27 @@ We've successfully taken our first snapshot. Let's delete all the indices: ```bash -$ curl -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" -X DELETE "https://localhost:9200/_all?pretty" +curl -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" -X DELETE "https://localhost:9200/_all?pretty" +``` { "acknowledged" : true } -``` List and varify the deletion: ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases oiaZfJA8Q5CihQon0oR8hA 1 1 42 0 81.6mb 40.8mb -``` For more details about restore, visit [Restore a snapshot](https://www.elastic.co/guide/en/elasticsearch/reference/7.14/snapshots-restore-snapshot.html#snapshots-restore-snapshot). Let's restore the data from our `snapshot_1`: ```bash -$ curl -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" -X POST "https://localhost:9200/_snapshot/sample_s3_repo/snapshot_1/_restore?pretty" -H 'Content-Type: application/json' -d' +curl -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" -X POST "https://localhost:9200/_snapshot/sample_s3_repo/snapshot_1/_restore?pretty" -H 'Content-Type: application/json' -d' +``` { "indices": "companies,products" } @@ -312,7 +320,6 @@ $ curl -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" -X POST "https://localhost:9200/_ { "accepted" : true } -``` We've successfully restored our indices. @@ -323,17 +330,18 @@ We've successfully restored our indices. To varify our data, let's list the indices: ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases oiaZfJA8Q5CihQon0oR8hA 1 1 42 0 81.6mb 40.8mb green open companies drsv-5tvQwCcte7bkUT0uQ 1 1 1 0 11.7kb 5.8kb green open products 7TXoXy5kRFiVgZDuyqffQA 1 1 1 0 10.6kb 5.3kb -``` Check the content inside: ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_search?pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_search?pretty" +``` { "took" : 3, "timed_out" : false, @@ -364,10 +372,10 @@ $ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/pr ] } } -``` ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_search?pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_search?pretty" +``` { "took" : 3, "timed_out" : false, @@ -404,6 +412,5 @@ $ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/co ] } } -``` So, we have successfully retored our data from the snapshot. diff --git a/docs/guides/elasticsearch/plugins/search-guard/configuration.md b/docs/guides/elasticsearch/plugins/search-guard/configuration.md index fe32dacd7d..5f62b3741a 100644 --- a/docs/guides/elasticsearch/plugins/search-guard/configuration.md +++ b/docs/guides/elasticsearch/plugins/search-guard/configuration.md @@ -31,18 +31,20 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` We will use `htpasswd`** to hash user password. Install `apache2-utils` package for this. ```bash -$ sudo apt-get install apache2-utils +sudo apt-get install apache2-utils ``` To keep configuration files separated, open a new terminal and create a directory `/tmp/kubedb/sg` @@ -100,7 +102,7 @@ searchguard: ``` ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_config.yml +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_config.yml ``` ### sg_internal_users.yml @@ -149,7 +151,7 @@ readall: Run following command to write user information in `sg_internal_users.yml` file with password. ```bash -$ curl https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_internal_users.yml | envsubst > sg_internal_users.yml +curl https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_internal_users.yml | envsubst > sg_internal_users.yml ``` > Note: If user does not provide `spec.authSecret`, KubeDB will generate random password for both admin and readall user. @@ -173,7 +175,7 @@ See details about [action groups](http://docs.search-guard.com/v5/action-groups) Run following command to get action groups we will use in this tutorial ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_action_groups.yml +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_action_groups.yml ``` ```yml @@ -255,7 +257,7 @@ sg_readall: ``` ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_roles.yml +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_roles.yml ``` ### sg_roles_mapping.yml @@ -292,7 +294,7 @@ See details about [backend roles mapping](http://docs.search-guard.com/v5/mappin Get roles mapping by running ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_roles_mapping.yml +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-config/sg_roles_mapping.yml ``` ```yml @@ -318,7 +320,7 @@ sg_readall: Now create a Secret with these files to use in your Elasticsearch object. ```bash -$ kubectl create secret generic -n demo config-elasticsearch-auth \ +kubectl create secret generic -n demo config-elasticsearch-auth \ --from-file=sg_config.yml \ --from-file=sg_internal_users.yml \ --from-file=sg_action_groups.yml \ @@ -328,9 +330,8 @@ $ kubectl create secret generic -n demo config-elasticsearch-auth \ --from-literal=ADMIN_PASSWORD=$ADMIN_PASSWORD \ --from-literal=READALL_USERNAME=readall \ --from-literal=READALL_PASSWORD=$READALL_PASSWORD - -secret/config-elasticsearch-auth created ``` +secret/config-elasticsearch-auth created Here, @@ -381,32 +382,32 @@ Here, Create example above with following command ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/config-elasticsearch.yaml -elasticsearch.kubedb.com/config-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/config-elasticsearch.yaml ``` +elasticsearch.kubedb.com/config-elasticsearch created KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. ```bash -$ kubectl get es -n demo config-elasticsearch -o wide +kubectl get es -n demo config-elasticsearch -o wide +``` NAME VERSION STATUS AGE config-elasticsearch searchguard-7.9.3 Running 1m -``` ## Connect to Elasticsearch Database At first, forward port 9200 of `config-elasticsearch-0` pod. Run following command on a separate terminal, ```bash -$ kubectl port-forward -n demo config-elasticsearch-0 9200 +kubectl port-forward -n demo config-elasticsearch-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, you can connect to this database at `localhost:9200`. ```bash -$ curl --user "admin:$ADMIN_PASSWORD" "localhost:9200/_cluster/health?pretty" +curl --user "admin:$ADMIN_PASSWORD" "localhost:9200/_cluster/health?pretty" ``` ```json @@ -434,10 +435,15 @@ $ curl --user "admin:$ADMIN_PASSWORD" "localhost:9200/_cluster/health?pretty" To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo es/config-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo es/config-elasticsearch +kubectl patch -n demo es/config-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete ns demo +```bash +kubectl delete -n demo es/config-elasticsearch +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/plugins/search-guard/disable-searchguard.md b/docs/guides/elasticsearch/plugins/search-guard/disable-searchguard.md index 56cb7e9725..26a960f1c5 100644 --- a/docs/guides/elasticsearch/plugins/search-guard/disable-searchguard.md +++ b/docs/guides/elasticsearch/plugins/search-guard/disable-searchguard.md @@ -27,13 +27,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -61,17 +63,17 @@ spec: Let's create the Elasticsearch object we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/es-sg-disabled.yaml -elasticsearch.kubedb.com/es-sg-disabled created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/es-sg-disabled.yaml ``` +elasticsearch.kubedb.com/es-sg-disabled created Wait for Elasticsearch to be ready, ```bash -$ kubectl get es -n demo es-sg-disabled +kubectl get es -n demo es-sg-disabled +``` NAME VERSION STATUS AGE es-sg-disabled searchguard-7.9.3 Running 27m -``` ## Connect to Elasticsearch Database @@ -80,17 +82,17 @@ As we have disabled Search Guard plugin, we no longer require *username* and *pa At first, forward port 9200 of `es-sg-disabled-0` pod. Run following command in a separate terminal, ```bash -$ kubectl port-forward -n demo es-sg-disabled-0 9200 +kubectl port-forward -n demo es-sg-disabled-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, we can connect with the database at `localhost:9200`. Let's check health of our Elasticsearch database. ```bash -$ curl "localhost:9200/_cluster/health?pretty" +curl "localhost:9200/_cluster/health?pretty" ``` ```json @@ -118,10 +120,15 @@ $ curl "localhost:9200/_cluster/health?pretty" To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo es/es-sg-disabled -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo es/es-sg-disabled +kubectl patch -n demo es/es-sg-disabled -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete ns demo +```bash +kubectl delete -n demo es/es-sg-disabled +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/plugins/search-guard/issue-certificate.md b/docs/guides/elasticsearch/plugins/search-guard/issue-certificate.md index f5ed1bb67c..f4048912ce 100644 --- a/docs/guides/elasticsearch/plugins/search-guard/issue-certificate.md +++ b/docs/guides/elasticsearch/plugins/search-guard/issue-certificate.md @@ -37,22 +37,24 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` You also need to have [*OpenSSL*](https://www.openssl.org) and Java *keytool* for generating all required artifacts. In order to find out if you have OpenSSL installed, open a terminal and type ```bash -$ openssl version -OpenSSL 1.0.2g 1 Mar 2016 +openssl version ``` +OpenSSL 1.0.2g 1 Mar 2016 Make sure it’s version 1.0.1k or higher @@ -82,7 +84,7 @@ You need to follow these steps 1. Get root certificate configuration file ```bash - $ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-ca.ini + wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-ca.ini ``` ```ini @@ -108,7 +110,7 @@ You need to follow these steps 2. Set a password of your keystore and truststore files ```bash - $ export KEY_PASS=secret + export KEY_PASS=secret ``` > Note: You need to provide this KEY_PASS in your Secret as `key_pass` @@ -116,7 +118,7 @@ You need to follow these steps 3. Generate private key and certificate ```bash - $ openssl req -x509 -config openssl-ca.ini -newkey rsa:4096 -sha256 -nodes -out root.pem -keyout root-key.pem -batch -passin "pass:$KEY_PASS" + openssl req -x509 -config openssl-ca.ini -newkey rsa:4096 -sha256 -nodes -out root.pem -keyout root-key.pem -batch -passin "pass:$KEY_PASS" ``` Here, @@ -127,7 +129,7 @@ You need to follow these steps 4. Finally, import certificate as keystore ```bash - $ keytool -import -file root.pem -keystore root.jks -storepass $KEY_PASS -srcstoretype pkcs12 -noprompt + keytool -import -file root.pem -keystore root.jks -storepass $KEY_PASS -srcstoretype pkcs12 -noprompt ``` Here, @@ -149,7 +151,7 @@ You need to follow these steps to generate three keystore. To sign certificate, we need another configuration file. ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-sign.ini +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-sign.ini ``` ```ini @@ -231,11 +233,23 @@ Here, Now run following commands ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-node.ini -$ openssl req -config openssl-node.ini -newkey rsa:4096 -sha256 -nodes -out node-csr.pem -keyout node-key.pem -$ openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out node.pem -infiles node-csr.pem -$ openssl pkcs12 -export -certfile root.pem -inkey node-key.pem -in node.pem -password "pass:$KEY_PASS" -out node.pkcs12 -$ keytool -importkeystore -srckeystore node.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore node.jks -deststoretype pkcs12 +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-node.ini +``` + +```bash +openssl req -config openssl-node.ini -newkey rsa:4096 -sha256 -nodes -out node-csr.pem -keyout node-key.pem +``` + +```bash +openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out node.pem -infiles node-csr.pem +``` + +```bash +openssl pkcs12 -export -certfile root.pem -inkey node-key.pem -in node.pem -password "pass:$KEY_PASS" -out node.pkcs12 +``` + +```bash +keytool -importkeystore -srckeystore node.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore node.jks -deststoretype pkcs12 ``` Generated `node.jks` will be used as keystore for transport layer TLS. @@ -272,11 +286,23 @@ Here, Now run following commands ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-client.ini -$ openssl req -config openssl-client.ini -newkey rsa:4096 -sha256 -nodes -out client-csr.pem -keyout client-key.pem -$ openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out client.pem -infiles client-csr.pem -$ openssl pkcs12 -export -certfile root.pem -inkey client-key.pem -in client.pem -password "pass:$KEY_PASS" -out client.pkcs12 -$ keytool -importkeystore -srckeystore client.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore client.jks -deststoretype pkcs12 +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-client.ini +``` + +```bash +openssl req -config openssl-client.ini -newkey rsa:4096 -sha256 -nodes -out client-csr.pem -keyout client-key.pem +``` + +```bash +openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out client.pem -infiles client-csr.pem +``` + +```bash +openssl pkcs12 -export -certfile root.pem -inkey client-key.pem -in client.pem -password "pass:$KEY_PASS" -out client.pkcs12 +``` + +```bash +keytool -importkeystore -srckeystore client.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore client.jks -deststoretype pkcs12 ``` Generated `client.jks` will be used as keystore for http layer TLS. @@ -312,11 +338,23 @@ Here, Now run following commands ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-sgadmin.ini -$ openssl req -config openssl-sgadmin.ini -newkey rsa:4096 -sha256 -nodes -out sgadmin-csr.pem -keyout sgadmin-key.pem -$ openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out sgadmin.pem -infiles sgadmin-csr.pem -$ openssl pkcs12 -export -certfile root.pem -inkey sgadmin-key.pem -in sgadmin.pem -password "pass:$KEY_PASS" -out sgadmin.pkcs12 -$ keytool -importkeystore -srckeystore sgadmin.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore sgadmin.jks -deststoretype pkcs12 +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/openssl-config/openssl-sgadmin.ini +``` + +```bash +openssl req -config openssl-sgadmin.ini -newkey rsa:4096 -sha256 -nodes -out sgadmin-csr.pem -keyout sgadmin-key.pem +``` + +```bash +openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out sgadmin.pem -infiles sgadmin-csr.pem +``` + +```bash +openssl pkcs12 -export -certfile root.pem -inkey sgadmin-key.pem -in sgadmin.pem -password "pass:$KEY_PASS" -out sgadmin.pkcs12 +``` + +```bash +keytool -importkeystore -srckeystore sgadmin.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore sgadmin.jks -deststoretype pkcs12 ``` Generated `sgadmin.pkcs12` will be used as keystore for admin usage. @@ -326,16 +364,15 @@ Generated `sgadmin.pkcs12` will be used as keystore for admin usage. Now create a Secret with these certificates to use in your Elasticsearch object. ```bash -$ kubectl create secret generic -n demo sg-elasticsearch-cert \ +kubectl create secret generic -n demo sg-elasticsearch-cert \ --from-file=root.pem \ --from-file=root.jks \ --from-file=node.jks \ --from-file=client.jks \ --from-file=sgadmin.jks \ --from-literal=key_pass=$KEY_PASS - -secret/sg-elasticsearch-cert created ``` +secret/sg-elasticsearch-cert created > Note: `root.pem` is added in Secret so that user can use these to connect Elasticsearch @@ -370,27 +407,32 @@ Here, Create example above with following command ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-elasticsearch.yaml -elasticsearch.kubedb.com/sg-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/sg-elasticsearch.yaml ``` +elasticsearch.kubedb.com/sg-elasticsearch created KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. ```bash -$ kubectl get es -n demo sg-elasticsearch -o wide +kubectl get es -n demo sg-elasticsearch -o wide +``` NAME VERSION STATUS AGE sg-elasticsearch searchguard-7.9.3 Running 1m -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo es/sg-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo es/sg-elasticsearch +kubectl patch -n demo es/sg-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo es/sg-elasticsearch +``` -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/plugins/search-guard/use-tls.md b/docs/guides/elasticsearch/plugins/search-guard/use-tls.md index 991c024e03..364dbda897 100644 --- a/docs/guides/elasticsearch/plugins/search-guard/use-tls.md +++ b/docs/guides/elasticsearch/plugins/search-guard/use-tls.md @@ -27,13 +27,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -63,15 +65,15 @@ spec: Let's create the Elasticsearch object we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/ssl-elasticsearch.yaml -elasticsearch.kubedb.com/ssl-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/search-guard/ssl-elasticsearch.yaml ``` +elasticsearch.kubedb.com/ssl-elasticsearch created ```bash -$ kubectl get es -n demo ssl-elasticsearch +kubectl get es -n demo ssl-elasticsearch +``` NAME STATUS AGE ssl-elasticsearch Running 17m -``` ## Connect to Elasticsearch Database @@ -80,7 +82,7 @@ As we have enabled TLS for our Elasticsearch cluster, only HTTPS calls are allow Let's check the certificates that has been created for Elasticsearch `ssl-elasticsearch` by KubeDB operator. ```bash -$ kubectl get secret -n demo ssl-elasticsearch-cert -o yaml +kubectl get secret -n demo ssl-elasticsearch-cert -o yaml ``` ```yaml @@ -111,10 +113,10 @@ Here, `root.pem` file is the root CA in `.pem` format. We will require to provid Let's forward port 9200 of `ssl-elasticsearch-0` pod. Run following command in a separate terminal, ```bash -$ kubectl port-forward -n demo ssl-elasticsearch-0 9200 +kubectl port-forward -n demo ssl-elasticsearch-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, we can connect with the database at `localhost:9200`. @@ -124,27 +126,27 @@ Now, we can connect with the database at `localhost:9200`. - Username: Run following command to get *username* ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d - elastic + kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d ``` + elastic - Password: Run following command to get *password* ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d - uv2io5au + kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d ``` + uv2io5au - Root CA: Run following command to get `root.pem` file ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem + kubectl get secrets -n demo ssl-elasticsearch-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem ``` Now, let's check health of our Elasticsearch database. ```bash -$ curl --user "elastic:uv2io5au" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem +curl --user "elastic:uv2io5au" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem ``` ```json @@ -172,10 +174,15 @@ $ curl --user "elastic:uv2io5au" "https://localhost:9200/_cluster/health?pretty" To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo es/ssl-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo es/ssl-elasticsearch +kubectl patch -n demo es/ssl-elasticsearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete ns demo +```bash +kubectl delete -n demo es/ssl-elasticsearch +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/elasticsearch/plugins/search-guard/x-pack-monitoring.md b/docs/guides/elasticsearch/plugins/search-guard/x-pack-monitoring.md index f47e2d5d70..90e34c0f2c 100644 --- a/docs/guides/elasticsearch/plugins/search-guard/x-pack-monitoring.md +++ b/docs/guides/elasticsearch/plugins/search-guard/x-pack-monitoring.md @@ -27,13 +27,15 @@ As KubeDB uses [Search Guard](https://search-guard.com/) plugin for authenticati To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -158,7 +160,7 @@ monitor: Here, we have used `admin@secret` password for `admin` user and `monitor@secret` password for `monitor` user. You can use `htpasswd` to generate the bcrypt encrypted password hashes. ```bash -$htpasswd -bnBC 12 "" | tr -d ':\n' +htpasswd -bnBC 12 "" | tr -d ':\n' ``` **sg_roles_mapping.yml:** @@ -202,8 +204,8 @@ searchguard: Now, create a secret with these Search Guard configuration files. -```bash - $ kubectl create secret generic -n demo es-auth \ + ```bash + kubectl create secret generic -n demo es-auth \ --from-literal=ADMIN_USERNAME=admin \ --from-literal=ADMIN_PASSWORD=admin@secret \ --from-file=./sg_action_groups.yml \ @@ -211,8 +213,8 @@ Now, create a secret with these Search Guard configuration files. --from-file=./sg_internal_users.yml \ --from-file=./sg_roles_mapping.yml \ --from-file=./sg_roles.yml + ``` secret/es-auth created -``` Verify the secret has desired configuration files, @@ -254,10 +256,10 @@ xpack.monitoring.exporters: Create a ConfigMap using this file, ```bash -$ kubectl create configmap -n demo es-custom-config \ +kubectl create configmap -n demo es-custom-config \ --from-file=./common-config.yaml -configmap/es-custom-config created ``` +configmap/es-custom-config created Verify that the ConfigMap has desired configuration, @@ -287,9 +289,9 @@ metadata: Now, create Elasticsearch crd specifying `spec.authSecret` and `spec.configuration` field. ```bash -$ kubectl apply -f kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/es-mon-demo.yaml -elasticsearch.kubedb.com/es-mon-demo created +kubectl apply -f kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/es-mon-demo.yaml ``` +elasticsearch.kubedb.com/es-mon-demo created Below is the YAML for the Elasticsearch crd we just created. @@ -321,7 +323,8 @@ Now, wait for few minutes. KubeDB will create necessary secrets, services, and p Check resources created in demo namespace by KubeDB, ```bash -$ kubectl get all -n demo -l=app.kubernetes.io/instance=es-mon-demo + kubectl get all -n demo -l=app.kubernetes.io/instance=es-mon-demo +``` NAME READY STATUS RESTARTS AGE pod/es-mon-demo-0 1/1 Running 0 37s @@ -331,20 +334,20 @@ service/es-mon-demo-master ClusterIP 10.104.12.90 9300/TCP NAME DESIRED CURRENT AGE petset.apps/es-mon-demo 1 1 39s -``` Once everything is created, Elasticsearch will go to Running state. Check that Elasticsearch is in running state. ```bash -$ kubectl get es -n demo es-mon-demo +kubectl get es -n demo es-mon-demo +``` NAME VERSION STATUS AGE es-mon-demo searchguard-7.9.3 Running 1m -``` Now, check elasticsearch log to see if the cluster is ready to accept requests, ```bash -$ kubectl logs -n demo es-mon-demo-0 -f +kubectl logs -n demo es-mon-demo-0 -f +``` ... Starting runit... ... @@ -359,7 +362,6 @@ Number of data nodes: 1 ... Done with success ... -``` Once you see `Done with success` success line in the log, the cluster is ready to accept requests. Now, it is time to connect with Kibana. @@ -401,9 +403,9 @@ configmap/kibana-config created Finally, deploy Kibana deployment, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/kibana/kibana-deployment.yaml -deployment.apps/kibana created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/kibana/kibana-deployment.yaml ``` +deployment.apps/kibana created Below is the YAML for the Kibana deployment we just created. @@ -437,19 +439,19 @@ spec: Now, wait for few minutes. Let the Kibana pod go in`Running` state. Check pod is in `Running` using this command, -```bash - $ kubectl get pods -n demo -l app=kibana + ```bash + kubectl get pods -n demo -l app=kibana + ``` NAME READY STATUS RESTARTS AGE kibana-84b8cbcf7c-mg699 1/1 Running 0 3m -``` Now, watch the Kibana pod's log to see if Kibana is ready to access, ```bash -$ kubectl logs -n demo kibana-84b8cbcf7c-mg699 -f +kubectl logs -n demo kibana-84b8cbcf7c-mg699 -f +``` ... {"type":"log","@timestamp":"2018-08-27T09:50:47Z","tags":["listening","info"],"pid":1,"message":"Server running at http://0.0.0.0:5601"} -``` Once you see `"message":"Server running at http://0.0.0.0:5601"` in the log, Kibana is ready. Now it is time to access Kibana UI. @@ -458,10 +460,10 @@ Kibana is running on port `5601` in of `kibana-84b8cbcf7c-mg699` pod. In order t First, open a new terminal and run, ```bash -$ kubectl port-forward -n demo kibana-84b8cbcf7c-mg699 5601 +kubectl port-forward -n demo kibana-84b8cbcf7c-mg699 5601 +``` Forwarding from 127.0.0.1:5601 -> 5601 Forwarding from [::1]:5601 -> 5601 -``` Now, open `localhost:5601` in your browser. When you will open the address, you will be greeted with Search Guard login UI. When you will open the address, you will be greeted with Search Guard login UI. @@ -489,17 +491,27 @@ Now, your production clusters will send monitoring data to the monitoring-cluste To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo es/es-mon-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo es/es-mon-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete -n demo es/es-mon-demo +```bash +kubectl delete -n demo es/es-mon-demo +``` -$ kubectl delete -n demo configmap/es-custom-config +```bash +kubectl delete -n demo configmap/es-custom-config +``` -$ kubectl delete -n demo configmap/kibana-config +```bash +kubectl delete -n demo configmap/kibana-config +``` -$ kubectl delete -n demo deployment/kibana +```bash +kubectl delete -n demo deployment/kibana +``` -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` To uninstall KubeDB follow this [guide](/docs/setup/README.md). diff --git a/docs/guides/elasticsearch/plugins/x-pack/configuration.md b/docs/guides/elasticsearch/plugins/x-pack/configuration.md index a77c902e5b..7d28f39ac2 100644 --- a/docs/guides/elasticsearch/plugins/x-pack/configuration.md +++ b/docs/guides/elasticsearch/plugins/x-pack/configuration.md @@ -25,13 +25,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -103,9 +105,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/config-elasticsearch.yaml -elasticsearch.kubedb.com/config-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/config-elasticsearch.yaml ``` +elasticsearch.kubedb.com/config-elasticsearch created The deployed elasticsearch object specs, after the mutation is done by kubedb: @@ -156,8 +158,11 @@ As we can see, KubeDB has created a secret named `config-elasticsearch-auth`, wh If you want to provide your own password, you need to create a secret that contains two keys: `ADMIN_USERNAME`, `ADMIN_PASSWORD`. ```bash -$ export ADMIN_PASSWORD=admin-password -$ kubectl create secret generic -n demo config-elasticsearch-auth \ +export ADMIN_PASSWORD=admin-password +``` + +```bash +kubectl create secret generic -n demo config-elasticsearch-auth \ --from-literal=ADMIN_USERNAME=elastic \ --from-literal=ADMIN_PASSWORD=harderPASSWORD \ secret/config-elasticsearch-auth created @@ -170,18 +175,18 @@ secret/config-elasticsearch-auth created KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. ```bash -$ kubectl get es -n demo config-elasticsearch -o wide +kubectl get es -n demo config-elasticsearch -o wide +``` NAME VERSION STATUS AGE config-elasticsearch xpack-9.2.3 Running 2m8s -``` To connect to the elasticsearch node, we are going to use port forward to the elasticsearch pod. Run following command on a separate terminal, ```bash -$ kubectl port-forward -n demo config-elasticsearch-0 9200 +kubectl port-forward -n demo config-elasticsearch-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` **Connection information:** @@ -189,21 +194,21 @@ Forwarding from [::1]:9200 -> 9200 - Username: Run following command to get *username* ```bash - $ kubectl get secrets -n demo config-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d - elastic + kubectl get secrets -n demo config-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d ``` + elastic - Password: Run following command to get *password* ```bash - $ kubectl get secrets -n demo config-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d - ruobj2eo + kubectl get secrets -n demo config-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d ``` + ruobj2eo Firstly, try to connect to this database without providing any authentication. You will face the following error: ```bash -$ curl "localhost:9200/_cluster/health?pretty" +curl "localhost:9200/_cluster/health?pretty" ``` ```json diff --git a/docs/guides/elasticsearch/plugins/x-pack/disable-xpack.md b/docs/guides/elasticsearch/plugins/x-pack/disable-xpack.md index b4acb50ca8..e0aad7fcf9 100644 --- a/docs/guides/elasticsearch/plugins/x-pack/disable-xpack.md +++ b/docs/guides/elasticsearch/plugins/x-pack/disable-xpack.md @@ -27,13 +27,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,7 +48,7 @@ Here, we are going to use ElasticsearchVersion `xpack-8.19.9`. > To change authPlugin, it is recommended to create another `ElasticsearchVersion` CRD. Then, use that `ElasticsearchVersion` to install an Elasticsearch without authentication, or with other authPlugin. ```bash -$ kubectl get elasticsearchversions xpack-8.19.9 -o yaml +kubectl get elasticsearchversions xpack-8.19.9 -o yaml ``` ```yaml @@ -105,17 +107,17 @@ spec: Let's create the Elasticsearch object, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/es-xpack-disabled.yaml -elasticsearch.kubedb.com/es-xpack-disabled created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/es-xpack-disabled.yaml ``` +elasticsearch.kubedb.com/es-xpack-disabled created Wait for Elasticsearch to be ready, ```bash -$ kubectl get es -n demo es-xpack-disabled +kubectl get es -n demo es-xpack-disabled +``` NAME VERSION STATUS AGE es-xpack-disabled xpack-9.2.3 Running 6m14s -``` ## Connect to Elasticsearch Database @@ -124,17 +126,17 @@ As we have disabled X-Pack security, we no longer require *username* and *passwo At first, forward port 9200 of `es-xpack-disabled-0` pod. Run following command in a separate terminal, ```bash -$ kubectl port-forward -n demo es-xpack-disabled-0 9200 +kubectl port-forward -n demo es-xpack-disabled-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, we can connect with the database at `localhost:9200`. Let's check health of our Elasticsearch database. ```bash -$ curl "localhost:9200/_cluster/health?pretty" +curl "localhost:9200/_cluster/health?pretty" ``` ```json diff --git a/docs/guides/elasticsearch/plugins/x-pack/issue-certificate.md b/docs/guides/elasticsearch/plugins/x-pack/issue-certificate.md index 2272d5e593..a384b006ea 100644 --- a/docs/guides/elasticsearch/plugins/x-pack/issue-certificate.md +++ b/docs/guides/elasticsearch/plugins/x-pack/issue-certificate.md @@ -36,18 +36,18 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created You also need to have [*OpenSSL*](https://www.openssl.org) and Java *keytool* for generating all required artifacts. In order to find out if you have OpenSSL installed, open a terminal and type ```bash -$ openssl version -OpenSSL 1.0.2g 1 Mar 2016 +openssl version ``` +OpenSSL 1.0.2g 1 Mar 2016 Make sure it’s version 1.0.1k or higher @@ -77,7 +77,7 @@ You need to follow these steps 1. Get root certificate configuration file ```bash - $ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-ca.ini + wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-ca.ini ``` ```ini @@ -103,7 +103,7 @@ You need to follow these steps 2. Set a password of your keystore and truststore files ```bash - $ export KEY_PASS=secret + export KEY_PASS=secret ``` > Note: You need to provide this KEY_PASS in your Secret as `key_pass` @@ -111,7 +111,7 @@ You need to follow these steps 3. Generate private key and certificate ```bash - $ openssl req -x509 -config openssl-ca.ini -newkey rsa:4096 -sha256 -nodes -out root.pem -keyout root-key.pem -batch -passin "pass:$KEY_PASS" + openssl req -x509 -config openssl-ca.ini -newkey rsa:4096 -sha256 -nodes -out root.pem -keyout root-key.pem -batch -passin "pass:$KEY_PASS" ``` Here, @@ -122,7 +122,7 @@ You need to follow these steps 4. Finally, import certificate as keystore ```bash - $ keytool -import -file root.pem -keystore root.jks -storepass $KEY_PASS -srcstoretype pkcs12 -noprompt + keytool -import -file root.pem -keystore root.jks -storepass $KEY_PASS -srcstoretype pkcs12 -noprompt ``` Here, @@ -144,7 +144,7 @@ You need to follow these steps to generate three keystore. To sign certificate, we need another configuration file. ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-sign.ini +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-sign.ini ``` ```ini @@ -226,11 +226,23 @@ Here, Now run following commands ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-node.ini -$ openssl req -config openssl-node.ini -newkey rsa:4096 -sha256 -nodes -out node-csr.pem -keyout node-key.pem -$ openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out node.pem -infiles node-csr.pem -$ openssl pkcs12 -export -certfile root.pem -inkey node-key.pem -in node.pem -password "pass:$KEY_PASS" -out node.pkcs12 -$ keytool -importkeystore -srckeystore node.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore node.jks -deststoretype pkcs12 +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-node.ini +``` + +```bash +openssl req -config openssl-node.ini -newkey rsa:4096 -sha256 -nodes -out node-csr.pem -keyout node-key.pem +``` + +```bash +openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out node.pem -infiles node-csr.pem +``` + +```bash +openssl pkcs12 -export -certfile root.pem -inkey node-key.pem -in node.pem -password "pass:$KEY_PASS" -out node.pkcs12 +``` + +```bash +keytool -importkeystore -srckeystore node.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore node.jks -deststoretype pkcs12 ``` Generated `node.jks` will be used as keystore for transport layer TLS. @@ -267,11 +279,23 @@ Here, Now run following commands ```bash -$ wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-client.ini -$ openssl req -config openssl-client.ini -newkey rsa:4096 -sha256 -nodes -out client-csr.pem -keyout client-key.pem -$ openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out client.pem -infiles client-csr.pem -$ openssl pkcs12 -export -certfile root.pem -inkey client-key.pem -in client.pem -password "pass:$KEY_PASS" -out client.pkcs12 -$ keytool -importkeystore -srckeystore client.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore client.jks -deststoretype pkcs12 +wget https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/openssl-config/openssl-client.ini +``` + +```bash +openssl req -config openssl-client.ini -newkey rsa:4096 -sha256 -nodes -out client-csr.pem -keyout client-key.pem +``` + +```bash +openssl ca -config openssl-sign.ini -batch -policy signing_policy -extensions signing_req -out client.pem -infiles client-csr.pem +``` + +```bash +openssl pkcs12 -export -certfile root.pem -inkey client-key.pem -in client.pem -password "pass:$KEY_PASS" -out client.pkcs12 +``` + +```bash +keytool -importkeystore -srckeystore client.pkcs12 -storepass $KEY_PASS -srcstoretype pkcs12 -srcstorepass $KEY_PASS -destkeystore client.jks -deststoretype pkcs12 ``` Generated `client.jks` will be used as keystore for http layer TLS. @@ -281,15 +305,14 @@ Generated `client.jks` will be used as keystore for http layer TLS. Now create a Secret with these certificates to use in your Elasticsearch object. ```bash -$ kubectl create secret generic -n demo custom-certificate-es-ssl-cert \ +kubectl create secret generic -n demo custom-certificate-es-ssl-cert \ --from-file=root.pem \ --from-file=root.jks \ --from-file=node.jks \ --from-file=client.jks \ --from-literal=key_pass=$KEY_PASS - -secret/custom-certificate-es-ssl-cert created ``` +secret/custom-certificate-es-ssl-cert created > Note: `root.pem` is added in Secret so that user can use these to connect Elasticsearch @@ -324,17 +347,17 @@ Here, Create example above with following command ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/custom-certificate-es-ssl.yaml -elasticsearch.kubedb.com/custom-certificate-es-ssl created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/custom-certificate-es-ssl.yaml ``` +elasticsearch.kubedb.com/custom-certificate-es-ssl created KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. ```bash -$ kubectl get es -n demo custom-certificate-es-ssl -o wide +kubectl get es -n demo custom-certificate-es-ssl -o wide +``` NAME VERSION STATUS AGE custom-certificate-es-ssl xpack-9.2.3 Running 1m -``` ## Connect to Elasticsearch Database @@ -343,10 +366,10 @@ We need to provide `root.pem` to connect to elasticsearch nodes. Let's forward port 9200 of `custom-certificate-es-ssl-0` pod. Run following command in a separate terminal, ```bash -$ kubectl port-forward -n demo custom-certificate-es-ssl-0 9200 +kubectl port-forward -n demo custom-certificate-es-ssl-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, we can connect with the database at `localhost:9200`. @@ -356,27 +379,27 @@ Now, we can connect with the database at `localhost:9200`. - Username: Run following command to get *username* ```bash - $ kubectl get secrets -n demo custom-certificate-es-ssl-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d - elastic + kubectl get secrets -n demo custom-certificate-es-ssl-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d ``` + elastic - Password: Run following command to get *password* ```bash - $ kubectl get secrets -n demo custom-certificate-es-ssl-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d - uft73z6j + kubectl get secrets -n demo custom-certificate-es-ssl-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d ``` + uft73z6j - Root CA: Run following command to get `root.pem` file ```bash - $ kubectl get secrets -n demo custom-certificate-es-ssl-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem + kubectl get secrets -n demo custom-certificate-es-ssl-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem ``` Now, let's check health of our Elasticsearch database. ```bash -$ curl --user "elastic:uft73z6j" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem +curl --user "elastic:uft73z6j" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem ``` ```json diff --git a/docs/guides/elasticsearch/plugins/x-pack/use-tls.md b/docs/guides/elasticsearch/plugins/x-pack/use-tls.md index 62941e467a..8a54930f91 100644 --- a/docs/guides/elasticsearch/plugins/x-pack/use-tls.md +++ b/docs/guides/elasticsearch/plugins/x-pack/use-tls.md @@ -27,13 +27,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -63,15 +65,15 @@ spec: Let's create the Elasticsearch object we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/ssl-elasticsearch.yaml -elasticsearch.kubedb.com/ssl-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/x-pack/ssl-elasticsearch.yaml ``` +elasticsearch.kubedb.com/ssl-elasticsearch created ```bash -$ kubectl get es -n demo ssl-elasticsearch +kubectl get es -n demo ssl-elasticsearch +``` NAME VERSION STATUS AGE ssl-elasticsearch xpack-9.2.3 Running 5m54s -``` ## Connect to Elasticsearch Database @@ -80,7 +82,7 @@ As we have enabled TLS for our Elasticsearch cluster, only HTTPS calls are allow Let's check the certificates that has been created for Elasticsearch `ssl-elasticsearch` by KubeDB operator. ```bash -$ kubectl get secret -n demo ssl-elasticsearch-cert -o yaml +kubectl get secret -n demo ssl-elasticsearch-cert -o yaml ``` ```yaml @@ -111,10 +113,10 @@ Here, `root.pem` file is the root CA in `.pem` format. We will require to provid Let's forward port 9200 of `ssl-elasticsearch-0` pod. Run following command in a separate terminal, ```bash -$ kubectl port-forward -n demo ssl-elasticsearch-0 9200 +kubectl port-forward -n demo ssl-elasticsearch-0 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, we can connect with the database at `localhost:9200`. @@ -124,27 +126,27 @@ Now, we can connect with the database at `localhost:9200`. - Username: Run following command to get *username* ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d - elastic + kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_USERNAME}' | base64 -d ``` + elastic - Password: Run following command to get *password* ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d - err5ns7w + kubectl get secrets -n demo ssl-elasticsearch-auth -o jsonpath='{.data.\ADMIN_PASSWORD}' | base64 -d ``` + err5ns7w - Root CA: Run following command to get `root.pem` file ```bash - $ kubectl get secrets -n demo ssl-elasticsearch-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem + kubectl get secrets -n demo ssl-elasticsearch-cert -o jsonpath='{.data.\root\.pem}' | base64 --decode > root.pem ``` Now, let's check health of our Elasticsearch database. ```bash -$ curl --user "elastic:err5ns7w" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem +curl --user "elastic:err5ns7w" "https://localhost:9200/_cluster/health?pretty" --cacert root.pem ``` ```json diff --git a/docs/guides/elasticsearch/private-registry/using-private-registry.md b/docs/guides/elasticsearch/private-registry/using-private-registry.md index ed7e1046bc..d2427c8173 100644 --- a/docs/guides/elasticsearch/private-registry/using-private-registry.md +++ b/docs/guides/elasticsearch/private-registry/using-private-registry.md @@ -23,13 +23,15 @@ At first, you need to have a Kubernetes cluster, and the kubectl command-line to To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,13 +50,27 @@ For Elasticsearch, push the following images to your private registry. - [kubedb/yq](https://hub.docker.com/r/kubedb/yq) ```bash -$ export DOCKER_REGISTRY= +export DOCKER_REGISTRY= +``` + +```bash +docker pull kubedb/operator:{{< param "info.version" >}} ; docker tag kubedb/operator:{{< param "info.version" >}} $DOCKER_REGISTRY/operator:{{< param "info.version" >}} ; docker push $DOCKER_REGISTRY/operator:{{< param "info.version" >}} +``` + +```bash +docker pull kubedb/elasticsearch:7.3.2 ; docker tag kubedb/elasticsearch:7.3.2 $DOCKER_REGISTRY/elasticsearch:7.3.2 ; docker push $DOCKER_REGISTRY/elasticsearch:7.3.2 +``` + +```bash +docker pull kubedb/elasticsearch-tools:7.3.2 ; docker tag kubedb/elasticsearch-tools:7.3.2 $DOCKER_REGISTRY/elasticsearch-tools:7.3.2 ; docker push $DOCKER_REGISTRY/elasticsearch-tools:7.3.2 +``` -$ docker pull kubedb/operator:{{< param "info.version" >}} ; docker tag kubedb/operator:{{< param "info.version" >}} $DOCKER_REGISTRY/operator:{{< param "info.version" >}} ; docker push $DOCKER_REGISTRY/operator:{{< param "info.version" >}} -$ docker pull kubedb/elasticsearch:7.3.2 ; docker tag kubedb/elasticsearch:7.3.2 $DOCKER_REGISTRY/elasticsearch:7.3.2 ; docker push $DOCKER_REGISTRY/elasticsearch:7.3.2 -$ docker pull kubedb/elasticsearch-tools:7.3.2 ; docker tag kubedb/elasticsearch-tools:7.3.2 $DOCKER_REGISTRY/elasticsearch-tools:7.3.2 ; docker push $DOCKER_REGISTRY/elasticsearch-tools:7.3.2 -$ docker pull kubedb/elasticsearch_exporter:1.0.2 ; docker tag kubedb/elasticsearch_exporter:1.0.2 $DOCKER_REGISTRY/elasticsearch_exporter:1.0.2 ; docker push $DOCKER_REGISTRY/elasticsearch_exporter:1.0.2 -$ docker pull kubedb/yq:2.4.0 ; docker tag kubedb/yq:2.4.0 $DOCKER_REGISTRY/yq:2.4.0 ; docker push $DOCKER_REGISTRY/yq:2.4.0 +```bash +docker pull kubedb/elasticsearch_exporter:1.0.2 ; docker tag kubedb/elasticsearch_exporter:1.0.2 $DOCKER_REGISTRY/elasticsearch_exporter:1.0.2 ; docker push $DOCKER_REGISTRY/elasticsearch_exporter:1.0.2 +``` + +```bash +docker pull kubedb/yq:2.4.0 ; docker tag kubedb/yq:2.4.0 $DOCKER_REGISTRY/yq:2.4.0 ; docker push $DOCKER_REGISTRY/yq:2.4.0 ``` ## Create ImagePullSecret @@ -64,13 +80,13 @@ ImagePullSecrets is a type of a Kubernetes Secret whose sole purpose is to pull Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry myregistrykey \ +kubectl create secret docker-registry myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret "myregistrykey" created. ``` +secret "myregistrykey" created. If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -114,9 +130,9 @@ spec: Now, create the ElasticsearchVersion crd, ```bash -$ kubectl apply -f pvt-elasticsearchversion.yaml -elasticsearchversion.kubedb.com/xpack-8.19.9 created +kubectl apply -f pvt-elasticsearchversion.yaml ``` +elasticsearchversion.kubedb.com/xpack-8.19.9 created ## Install KubeDB operator @@ -152,17 +168,17 @@ spec: Now run the command to deploy this Elasticsearch object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/private-registry/private-registry.yaml -elasticsearch.kubedb.com/pvt-reg-elasticsearch created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/private-registry/private-registry.yaml ``` +elasticsearch.kubedb.com/pvt-reg-elasticsearch created To check if the images pulled successfully from the repository, see if the Elasticsearch is in running state: ```bash -$ kubectl get es -n demo pvt-reg-elasticsearch -o wide +kubectl get es -n demo pvt-reg-elasticsearch -o wide +``` NAME VERSION STATUS AGE pvt-reg-elasticsearch xpack-9.2.3 Running 33m -``` ## Snapshot diff --git a/docs/guides/elasticsearch/quickstart/overview/elasticsearch/index.md b/docs/guides/elasticsearch/quickstart/overview/elasticsearch/index.md index 4f3d82d144..382a72b248 100644 --- a/docs/guides/elasticsearch/quickstart/overview/elasticsearch/index.md +++ b/docs/guides/elasticsearch/quickstart/overview/elasticsearch/index.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/elasticsearch/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ demo Active 9s We will have to provide `StorageClass` in Elasticsearch CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d2h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -58,7 +60,8 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named [ElasticsearchVersion](/docs/guides/elasticsearch/concepts/catalog/index.md). The installation process comes with a set of tested ElasticsearchVersion objects. Let's check available ElasticsearchVersions by, ```bash -$ kubectl get elasticsearchversions +kubectl get elasticsearchversions +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE kubedb-searchguard-5.6.16 5.6.16 KubeDB kubedb/elasticsearch:5.6.16-searchguard-v2022.02.22 4h24m kubedb-xpack-7.12.0 7.12.0 KubeDB kubedb/elasticsearch:7.12.0-xpack-v2021.08.23 4h24m @@ -127,7 +130,6 @@ xpack-8.19.9 7.9.1 ElasticStack elasticsearch:7.9.1 xpack-7.9.1-v2 7.9.1 ElasticStack elasticsearch:7.9.1 4h24m xpack-8.2.3 8.2.0 ElasticStack elasticsearch:8.2.0 4h24m xpack-8.5.2 8.5.2 ElasticStack elasticsearch:8.5.2 4h24m -``` Notice the `DEPRECATED` column. Here, `true` means that this ElasticsearchVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated ElasticsearchVersion. @@ -165,9 +167,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml -elasticsearch.kubedb.com/es-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml ``` +elasticsearch.kubedb.com/es-quickstart created Here, @@ -183,17 +185,18 @@ Here, The Elasticsearch's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-quickstart xpack-9.2.3 Provisioning 7s ... ... es-quickstart xpack-9.2.3 Ready 39s -``` Describe the Elasticsearch object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo es-quickstart +kubectl describe elasticsearch -n demo es-quickstart +``` Name: es-quickstart Namespace: demo Labels: @@ -419,14 +422,14 @@ Events: Normal Successful 82s KubeDB Operator Successfully governing service Normal Successful 74s KubeDB Operator Successfully governing service Normal Successful 66s KubeDB Operator Successfully governing service -``` ### KubeDB Operator Generated Resources On deployment of an Elasticsearch CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-quickstart' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/es-quickstart-0 1/1 Running 0 8m2s pod/es-quickstart-1 1/1 Running 0 5m15s @@ -460,7 +463,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-es-quickstart-0 Bound pvc-e5227633-2fc0-4a50-a599-57cba8b31d14 1Gi RWO standard 8m2s persistentvolumeclaim/data-es-quickstart-1 Bound pvc-fbacd36c-4132-4e2a-a5c5-91149054044c 1Gi RWO standard 5m15s persistentvolumeclaim/data-es-quickstart-2 Bound pvc-9f9c6eaf-1ba6-4167-a37d-86eaf1f7e103 1Gi RWO standard 5m8s -``` - `PetSet` - a PetSet named after the Elasticsearch instance. In topology mode, the operator creates 3 petSets with name `{Elasticsearch-Name}-{Sufix}`. - `Services` - 3 services are generated for each Elasticsearch database. @@ -481,10 +483,10 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `9200` to local machine: ```bash -$ kubectl port-forward -n demo svc/es-quickstart 9200 +kubectl port-forward -n demo svc/es-quickstart 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Now, our Elasticsearch cluster is accessible at `localhost:9200`. @@ -494,22 +496,22 @@ Now, our Elasticsearch cluster is accessible at `localhost:9200`. - Username: ```bash - $ kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.username}' | base64 -d - elastic + kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.username}' | base64 -d ``` + elastic - Password: ```bash - $ kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.password}' | base64 -d - vIHoIfHn=!Z8F4gP + kubectl get secret -n demo es-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` + vIHoIfHn=!Z8F4gP Now let's check the health of our Elasticsearch database. ```bash -$ curl -XGET -k -u 'elastic:vIHoIfHn=!Z8F4gP' "https://localhost:9200/_cluster/health?pretty" - +curl -XGET -k -u 'elastic:vIHoIfHn=!Z8F4gP' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "es-quickstart", "status" : "green", @@ -527,7 +529,6 @@ $ curl -XGET -k -u 'elastic:vIHoIfHn=!Z8F4gP' "https://localhost:9200/_cluster/h "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` From the health information above, we can see that our Elasticsearch cluster's status is `green` which means the cluster is healthy. @@ -538,23 +539,23 @@ KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or lat To halt the database, we have to set `spec.deletionPolicy:` to `Halt` by updating it, ```bash -$ kubectl edit elasticsearch -n demo es-quickstart - +kubectl edit elasticsearch -n demo es-quickstart +``` >> spec: >> deletionPolicy: Halt -``` Now, if you delete the Elasticsearch object, the KubeDB operator will delete every resource created for this Elasticsearch CR, but leaves the auth secrets, and PVCs. ```bash -$ kubectl delete elasticsearch -n demo es-quickstart -elasticsearch.kubedb.com "es-quickstart" deleted + kubectl delete elasticsearch -n demo es-quickstart ``` +elasticsearch.kubedb.com "es-quickstart" deleted Check resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-quickstart' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-quickstart' +``` NAME TYPE DATA AGE secret/es-quickstart-apm-system-cred kubernetes.io/basic-auth 2 5m39s secret/es-quickstart-beats-system-cred kubernetes.io/basic-auth 2 5m39s @@ -568,8 +569,6 @@ persistentvolumeclaim/data-es-quickstart-0 Bound pvc-5b657e2a-6c32-4631-bac persistentvolumeclaim/data-es-quickstart-1 Bound pvc-e44d7ab8-fc2b-4cfe-9bef-74f2a2d875f5 1Gi RWO standard 5m23s persistentvolumeclaim/data-es-quickstart-2 Bound pvc-dad75b1b-37ed-4318-a82a-5e38f04d36bc 1Gi RWO standard 5m18s -``` - ## Resume Elasticsearch Say, the Elasticsearch CR was deleted with `spec.deletionPolicy` to `Halt` and you want to re-create the Elasticsearch cluster using the existing auth secrets and the PVCs. @@ -577,24 +576,28 @@ Say, the Elasticsearch CR was deleted with `spec.deletionPolicy` to `Halt` and y You can do it by simpily re-deploying the original Elasticsearch object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml -elasticsearch.kubedb.com/es-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml ``` +elasticsearch.kubedb.com/es-quickstart created ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo elasticsearch es-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo elasticsearch es-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` elasticsearch.kubedb.com/es-quickstart patched -$ kubectl delete -n demo es/es-quickstart +```bash +kubectl delete -n demo es/es-quickstart +``` elasticsearch.kubedb.com "es-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/elasticsearch/quickstart/overview/opensearch/index.md b/docs/guides/elasticsearch/quickstart/overview/opensearch/index.md index 84c7f5b5e9..94e03e0892 100644 --- a/docs/guides/elasticsearch/quickstart/overview/opensearch/index.md +++ b/docs/guides/elasticsearch/quickstart/overview/opensearch/index.md @@ -31,23 +31,25 @@ This tutorial will show you how to use KubeDB to run an OpenSearch database. * [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required for CRD specification. Check the available StorageClass in cluster. ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 11h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/elasticsearch/quickstart/overview/opensearch/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/opensearch/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -59,7 +61,8 @@ demo Active 9s When you install the KubeDB operator, it registers a CRD named [ElasticsearchVersion](/docs/guides/elasticsearch/concepts/catalog/index.md). The installation process comes with a set of tested ElasticsearchVersion objects. Let's check available ElasticsearchVersions by following command, ```bash -$ kubectl get elasticsearchversions +kubectl get elasticsearchversions +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE kubedb-xpack-7.12.0 7.12.0 KubeDB kubedb/elasticsearch:7.12.0-xpack-v2021.08.23 17h kubedb-xpack-7.13.2 7.13.2 KubeDB kubedb/elasticsearch:7.13.2-xpack-v2021.08.23 17h @@ -122,7 +125,6 @@ xpack-7.7.1-v1 7.7.1 ElasticStack elasticsearch:7.7.1 xpack-7.8.0-v1 7.8.0 ElasticStack elasticsearch:7.8.0 17h xpack-8.19.9 7.9.1 ElasticStack elasticsearch:7.9.1 17h xpack-7.9.1-v2 7.9.1 ElasticStack elasticsearch:7.9.1 17h -``` Notice the `DEPRECATED` column. Here, `true` means that this ElasticsearchVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated ElasticsearchVersion. @@ -160,9 +162,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/opensearch/yamls/opensearch-v1.yaml -elasticsearch.kubedb.com/es-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/opensearch/yamls/opensearch-v1.yaml ``` +elasticsearch.kubedb.com/es-quickstart created Here, @@ -178,19 +180,23 @@ Here, Wait for few minutes until the `STATUS` will go from `Provisioning` to `Ready`. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE sample-opensearch opensearch-3.4.0 Provisioning 49s ... ... -$ kubectl get elasticsearch -n demo -w + +```bash +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE sample-opensearch opensearch-3.4.0 Ready 5m4s -``` Describe the object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe elasticsearch -n demo sample-opensearch +kubectl describe elasticsearch -n demo sample-opensearch +``` Name: sample-opensearch Namespace: demo Labels: @@ -326,14 +332,14 @@ Events: ---- ------ ---- ---- ------- Normal Successful 56m KubeDB Operator Successfully governing service Normal Successful 56m KubeDB Operator Successfully governing service -``` ### KubeDB Operator Generated Resources after the deployment, the operator creates the following resources: ```bash -$ kubectl get all,secret -n demo -l 'app.kubernetes.io/instance=sample-opensearch' +kubectl get all,secret -n demo -l 'app.kubernetes.io/instance=sample-opensearch' +``` NAME READY STATUS RESTARTS AGE pod/sample-opensearch-0 1/1 Running 0 23m pod/sample-opensearch-1 1/1 Running 0 23m @@ -364,8 +370,6 @@ secret/sample-opensearch-readall-cred kubernetes.io/basic-auth 2 secret/sample-opensearch-snapshotrestore-cred kubernetes.io/basic-auth 2 23m secret/sample-opensearch-transport-cert kubernetes.io/tls 3 23m -``` - - `PetSet` - a PetSet named after the OpenSearch instance. - `Services` - 3 services are generated for each OpenSearch database. - `{OpenSearch-Name}` - the client service which is used to connect to the database. It points to the `ingest` nodes. @@ -386,27 +390,28 @@ In this section, we are going to create few indexes in the deployed OpenSearch. KubeDB will create few Services to connect with the database. Let’s see the Services created by KubeDB for our OpenSearch, ```bash -$ kubectl get service -n demo +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-opensearch ClusterIP 10.48.14.99 9200/TCP 4m33s sample-opensearch-master ClusterIP None 9300/TCP 4m33s sample-opensearch-pods ClusterIP None 9200/TCP 4m33s -``` Here, we are going to use the `sample-opensearch` Service to connect with the database. Now, let’s port-forward the `sample-opensearch` Service. -```bash # Port-forward the service to local machine -$ kubectl port-forward -n demo svc/sample-opensearch 9200 +```bash +kubectl port-forward -n demo svc/sample-opensearch 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` #### Export the Credentials KubeDB will create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `sample-opensearch`. ```bash -$ kubectl get secret -n demo | grep sample-opensearch +kubectl get secret -n demo | grep sample-opensearch +``` sample-opensearch-admin-cert kubernetes.io/tls 3 10m sample-opensearch-auth kubernetes.io/basic-auth 2 10m sample-opensearch-ca-cert kubernetes.io/tls 2 10m @@ -418,7 +423,6 @@ sample-opensearch-readall-cred kubernetes.io/basic-auth 2 sample-opensearch-snapshotrestore-cred kubernetes.io/basic-auth 2 10m sample-opensearch-token-zbn46 kubernetes.io/service-account-token 3 10m sample-opensearch-transport-cert kubernetes.io/tls 3 10m -``` Now, we can connect to the database using the `sample-opensearch-auth` secret, which holds the `admin` credentials used to connect with the database. @@ -427,16 +431,20 @@ Now, we can connect to the database using the `sample-opensearch-auth` secret, w To access the database through CLI, we have to get the credentials to access. Let’s export the credentials as environment variable to our current shell : ```bash -$ kubectl get secret -n demo sample-opensearch-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo sample-opensearch-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo sample-opensearch-auth -o jsonpath='{.data.password}' | base64 -d -9aHT*ZhEK_qjPS~v + +```bash +kubectl get secret -n demo sample-opensearch-auth -o jsonpath='{.data.password}' | base64 -d ``` +9aHT*ZhEK_qjPS~v Then login and check the health of our OpenSearch database. ```bash -$ curl -XGET -k -u 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/_cluster/health?pretty" +curl -XGET -k -u 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "sample-opensearch", "status" : "green", @@ -455,33 +463,33 @@ $ curl -XGET -k -u 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/_cluster/hea "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` Now, insert some data into OpenSearch: ```bash -$ curl -XPOST -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/bands/_doc?pretty" -H 'Content-Type: application/json' -d' +curl -XPOST -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/bands/_doc?pretty" -H 'Content-Type: application/json' -d' +``` { "Name": "Backstreet Boys", "Album": "Millennium", "Song": "Show Me The Meaning" } ' -``` Let’s verify that the index have been created successfully. ```bash -$ curl -XGET -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .opendistro_security ARYAKuVwQsKel2_0Fl3H2w 1 2 9 0 150.3kb 59.9kb green open bands 1z6Moj6XS12tpDwFPZpqYw 1 1 1 0 10.4kb 5.2kb green open security-auditlog-2022.02.10 j8-mj4o_SKqCD1g-Nz2PAA 1 1 5 0 183.2kb 91.6kb -``` Also, let’s verify the data in the indexes: ```bash -$ curl -XGET -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/bands/_search?pretty" +curl -XGET -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/bands/_search?pretty" +``` { "took" : 183, "timed_out" : false, @@ -513,22 +521,24 @@ $ curl -XGET -k --user 'admin:9aHT*ZhEK_qjPS~v' "https://localhost:9200/bands/_s } } -``` - ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo elasticsearch sample-opensearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo elasticsearch sample-opensearch -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` elasticsearch.kubedb.com/sample-opensearch patched -$ kubectl delete -n demo es/sample-opensearch +```bash +kubectl delete -n demo es/sample-opensearch +``` elasticsearch.kubedb.com "sample-opensearch" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash +kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/elasticsearch/reconfigure/elasticsearch-combined.md b/docs/guides/elasticsearch/reconfigure/elasticsearch-combined.md index 9db90f8833..6d6f9d257f 100644 --- a/docs/guides/elasticsearch/reconfigure/elasticsearch-combined.md +++ b/docs/guides/elasticsearch/reconfigure/elasticsearch-combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -67,9 +67,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-combined-custom-config.yaml -secret/es-combined-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-combined-custom-config.yaml ``` +secret/es-combined-custom-config created In this section, we are going to create an Elasticsearch object specifying `spec.configuration.secretName` field to apply this custom configuration. Below is the YAML of the `Elasticsearch` CR that we are going to create, @@ -99,27 +99,27 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-combined.yaml -elasticsearch.kubedb.com/es-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-combined.yaml ``` +elasticsearch.kubedb.com/es-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE es-combined xpack-8.19.9 Ready 20m -``` Now, we will check if the Elasticsearch has started with the custom configuration we have provided. Exec into the Elasticsearch pod and query the cluster settings to see the configuration: ```bash -$ kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +``` "max_clause_count" : "2048" "max_clause_count" : "2048" -``` Here, we can see that our given configuration is applied to the Elasticsearch cluster for all nodes. `indices.query.bool.max_clause_count` is set to `2048` from the default value `1024`. @@ -149,9 +149,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/new-es-combined-custom-config.yaml -secret/new-es-combined-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/new-es-combined-custom-config.yaml ``` +secret/new-es-combined-custom-config created #### Create ElasticsearchOpsRequest @@ -183,9 +183,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-update-combined.yaml -elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-update-combined.yaml ``` +elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-combined created #### Verify the new configuration is working @@ -194,15 +194,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get elasticsearchopsrequests -n demo +kubectl get elasticsearchopsrequests -n demo +``` NAME TYPE STATUS AGE esops-reconfigure-combined Reconfigure Successful 73s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe elasticsearchopsrequest -n demo esops-reconfigure-combined + kubectl describe elasticsearchopsrequest -n demo esops-reconfigure-combined +``` Name: esops-reconfigure-combined Namespace: demo Labels: @@ -304,15 +305,14 @@ Events: Warning create es client; ConditionStatus:True 60s KubeDB Ops-manager Operator create es client; ConditionStatus:True Normal RestartNodes 55s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Successful 54s KubeDB Ops-manager Operator Successfully reconfigured all elasticsearch nodes. -``` Now let's exec into one of the instances and query the cluster settings to check the new configuration. ```bash -$ kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +``` "max_clause_count" : "4096" "max_clause_count" : "4096" -``` As we can see from the configuration of the ready Elasticsearch, the value of `indices.query.bool.max_clause_count` has been changed from `2048` to `4096`. So the reconfiguration of the cluster is successful. @@ -352,9 +352,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-apply-combined.yaml -elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-apply-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-apply-combined.yaml ``` +elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-apply-combined created #### Verify the new configuration is working @@ -363,18 +363,18 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get elasticsearchopsrequests -n demo esops-reconfigure-apply-combined +kubectl get elasticsearchopsrequests -n demo esops-reconfigure-apply-combined +``` NAME TYPE STATUS AGE esops-reconfigure-apply-combined Reconfigure Successful 118s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. Now let's exec into one of the instances and check the new configuration. ```bash -$ kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +kubectl exec -it -n demo es-combined-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:X4gzeLWqUHKMoQT7" | grep max_clause_count +``` "max_clause_count" : "8192" "max_clause_count" : "8192" -``` As we can see from the configuration of the ready Elasticsearch, the value of `indices.query.bool.max_clause_count` has been changed from `4096` to `8192`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/elasticsearch/reconfigure/elasticsearch-topology.md b/docs/guides/elasticsearch/reconfigure/elasticsearch-topology.md index 8628e5951d..4912e6028b 100644 --- a/docs/guides/elasticsearch/reconfigure/elasticsearch-topology.md +++ b/docs/guides/elasticsearch/reconfigure/elasticsearch-topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -85,9 +85,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-topology-custom-config.yaml -secret/es-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-topology-custom-config.yaml ``` +secret/es-topology-custom-config created In this section, we are going to create an Elasticsearch object specifying `spec.configuration.secretName` field to apply this custom configuration. Below is the YAML of the `Elasticsearch` CR that we are going to create, @@ -137,45 +137,45 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-topology.yaml -elasticsearch.kubedb.com/es-topology created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-topology.yaml ``` +elasticsearch.kubedb.com/es-topology created Now, wait until `es-topology` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-topology xpack-8.19.9 Provisioning 0s es-topology xpack-8.19.9 Provisioning 24s . . es-topology xpack-8.19.9 Ready 92s -``` Now, we will check if the Elasticsearch has started with the custom configuration we have provided. Exec into the master node and check the cluster setting: ```bash -$ kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node - "max_shards_per_node" : "2000", +kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node ``` + "max_shards_per_node" : "2000", Exec into a data node and check the index settings: ```bash -$ kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +``` "max_clause_count" : "2048" "max_clause_count" : "2048" -``` Exec into the ingest node and check the HTTP settings: ```bash -$ kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_content_length - "max_content_length" : "200mb", +kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_content_length ``` + "max_content_length" : "200mb", Here, we can see that our given configurations are applied to the respective node roles. @@ -221,9 +221,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/new-es-topology-custom-config.yaml -secret/new-es-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/new-es-topology-custom-config.yaml ``` +secret/new-es-topology-custom-config created #### Create ElasticsearchOpsRequest @@ -255,9 +255,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-update-topology.yaml -elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-update-topology.yaml ``` +elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-topology created #### Verify the new configuration is working @@ -266,15 +266,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get elasticsearchopsrequests -n demo +kubectl get elasticsearchopsrequests -n demo +``` NAME TYPE STATUS AGE esops-reconfigure-topology Reconfigure Successful 4m55s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe elasticsearchopsrequest -n demo esops-reconfigure-topology +kubectl describe elasticsearchopsrequest -n demo esops-reconfigure-topology +``` Name: esops-reconfigure-topology Namespace: demo Labels: @@ -415,21 +416,24 @@ Events: Warning create es client; ConditionStatus:True 3m39s KubeDB Ops-manager Operator create es client; ConditionStatus:True Normal RestartNodes 3m34s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Successful 3m33s KubeDB Ops-manager Operator Successfully reconfigured all elasticsearch nodes. -``` Now let's exec into a master node, a data node, and the ingest node to verify the new configuration. ```bash -$ kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node +kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node +``` "max_shards_per_node" : "3000", -$ kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +```bash +kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +``` "max_clause_count" : "4096" "max_clause_count" : "4096" -$ kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_content_length - "max_content_length" : "300mb", +```bash +kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_content_length ``` + "max_content_length" : "300mb", As we can see, the values have been updated on their respective node roles. So the reconfiguration of the cluster is successful. @@ -471,33 +475,37 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-apply-topology.yaml -elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-apply-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure/es-reconfigure-apply-topology.yaml ``` +elasticsearchopsrequest.ops.kubedb.com/esops-reconfigure-apply-topology created #### Verify the new configuration is working Let's wait for `ElasticsearchOpsRequest` to be `Successful`. ```bash -$ kubectl get elasticsearchopsrequests -n demo esops-reconfigure-apply-topology + kubectl get elasticsearchopsrequests -n demo esops-reconfigure-apply-topology +``` NAME TYPE STATUS AGE esops-reconfigure-apply-topology Reconfigure Successful 6m52s -``` Now let's verify the updated values on each node role. ```bash -$ kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node +kubectl exec -it -n demo es-topology-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.cluster&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_shards_per_node +``` "max_shards_per_node" : "4000", -$ kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +```bash +kubectl exec -it -n demo es-topology-data-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.indices&pretty" --user "elastic:$ELASTIC_USER_PASSWORD" | grep max_clause_count +``` "max_clause_count" : "8192" "max_clause_count" : "8192" -$ kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:X4am_*ihVy~M)m0j" | grep max_content_length - "max_content_length" : "400mb", +```bash +kubectl exec -it -n demo es-topology-ingest-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_nodes/settings?filter_path=nodes.*.settings.http&pretty" --user "elastic:X4am_*ihVy~M)m0j" | grep max_content_length ``` + "max_content_length" : "400mb", As we can see, `cluster.max_shards_per_node` has been changed from `3000` to `4000` on master nodes, `indices.query.bool.max_clause_count` has been changed from `4096` to `8192` on data nodes, and `http.max_content_length` has been changed from `300mb` to `400mb` on ingest nodes. So the reconfiguration using the `applyConfig` field is successful. diff --git a/docs/guides/elasticsearch/reconfigure_tls/elasticsearch.md b/docs/guides/elasticsearch/reconfigure_tls/elasticsearch.md index f85695fe20..6f5a4fefa1 100644 --- a/docs/guides/elasticsearch/reconfigure_tls/elasticsearch.md +++ b/docs/guides/elasticsearch/reconfigure_tls/elasticsearch.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,24 +67,23 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch.yaml -Elasticsearch.kubedb.com/es-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch.yaml ``` +Elasticsearch.kubedb.com/es-demo created Now, wait until `es-demo` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-demo xpack-9.2.3 Ready 26h -``` - Now, we can exec one elasticsearch pod and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -n demo es-demo-0 -- \ +kubectl exec -n demo es-demo-0 -- \ cat /usr/share/elasticsearch/config/elasticsearch.yml | grep -A 2 -i xpack.security - +``` Defaulted container "elasticsearch" out of: elasticsearch, init-sysctl (init), config-merger (init) xpack.security.enabled: true @@ -95,8 +94,6 @@ xpack.security.transport.ssl.certificate: certs/transport/tls.crt xpack.security.transport.ssl.certificate_authorities: [ "certs/transport/ca.crt" ] xpack.security.http.ssl.enabled: false - -``` Here, transport TLS is enabled but HTTP TLS is disabled. So, internal node to node communication is encrypted but communication from client to node is not encrypted. ### Create Issuer/ ClusterIssuer @@ -106,23 +103,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 es-ca \ +kubectl create secret tls es-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/es-ca created ``` +secret/es-ca created Now, Let's create an `Issuer` using the `Elasticsearch-ca` secret that we have just created. The `YAML` file looks like this: @@ -140,9 +137,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-issuer.yaml -issuer.cert-manager.io/es-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-issuer.yaml ``` +issuer.cert-manager.io/es-issuer created ### Create ElasticsearchOpsRequest @@ -184,24 +181,25 @@ Let's create the `ElasticsearchOpsRequest` CR we have shown above, > **Note:** For combined Elasticsearch, you just need to refer Elasticsearch combined object in `databaseRef` field. To learn more about combined Elasticsearch, please visit [here](/docs/guides/elasticsearch/clustering/combined-cluster/index.md). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-add-tls.yaml -Elasticsearchopsrequest.ops.kubedb.com/add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-add-tls.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/add-tls created #### Verify TLS Enabled Successfully Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CRO, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE add-tls ReconfigureTLS Successful 73m -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo add-tls +kubectl describe Elasticsearchopsrequest -n demo add-tls +``` Name: add-tls Namespace: demo Labels: @@ -324,14 +322,13 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Lets exec into a Elasticsearch pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -n demo es-demo-0 -- \ +kubectl exec -n demo es-demo-0 -- \ cat /usr/share/elasticsearch/config/elasticsearch.yml | grep -A 2 -i xpack.security - +``` Defaulted container "elasticsearch" out of: elasticsearch, init-sysctl (init), config-merger (init) xpack.security.enabled: true @@ -346,8 +343,6 @@ xpack.security.http.ssl.key: certs/http/tls.key xpack.security.http.ssl.certificate: certs/http/tls.crt xpack.security.http.ssl.certificate_authorities: [ "certs/http/ca.crt" ] -``` - We can see from the above output that, `xpack.security.http.ssl.enabled: true` which means TLS is enabled for HTTP communication. ## Rotate Certificate @@ -355,15 +350,14 @@ We can see from the above output that, `xpack.security.http.ssl.enabled: true` Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -n demo es-demo-0 -- /bin/sh -c '\ +kubectl exec -n demo es-demo-0 -- /bin/sh -c '\ openssl s_client -connect localhost:9200 -showcerts < /dev/null 2>/dev/null | \ sed -ne "/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p" > /tmp/server.crt && \ openssl x509 -in /tmp/server.crt -noout -enddate' +``` Defaulted container "elasticsearch" out of: elasticsearch, init-sysctl (init), config-merger (init) notAfter=Feb 26 05:16:15 2026 GMT -``` - So, the certificate will expire on this time `Feb 26 05:16:17 2026 GMT`. ### Create ElasticsearchOpsRequest @@ -393,25 +387,25 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/esops-rotate.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/esops-rotate.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CRO, ```bash -$ kubectl get Elasticsearchopsrequest -n demo esops-rotate +kubectl get Elasticsearchopsrequest -n demo esops-rotate +``` NAME TYPE STATUS AGE esops-rotate ReconfigureTLS Successful 85m -``` - We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo esops-rotate +kubectl describe Elasticsearchopsrequest -n demo esops-rotate +``` Name: esops-rotate Namespace: demo Labels: @@ -530,7 +524,6 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` @@ -543,22 +536,20 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +``` .+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*........+.....+......+...+.+..............+....+..+.+...+......+.....+.........+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.......+........+.......+...+......+.....+..........+..+.........+......+....+...+..+....+..+.......+............+...+..+...+.+............+..+................+.....+................+.....+.+........+.+.....+.........................+........+......+....+...........+.+....................+.+..+......+......+...+...+...+......+.+...+.........+.....+.......+...+..+.............+.....+.+..............+......+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ..+........+...+...............+...+....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+...+...+...................+.....+.+......+.....+.........+....+...+.....+...+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+...+..+............+....+..+...+..........+.........+......+.........+...........+....+..+.+..+.......+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -``` - - Now we are going to create a new ca-secret using the certificate files that we have just generated. ```bash -$ kubectl create secret tls es-new-ca \ +kubectl create secret tls es-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/es-new-ca created - ``` +secret/es-new-ca created Now, Let's create a new `Issuer` using the `es-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -576,9 +567,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-new-issuer.yaml -issuer.cert-manager.io/es-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-new-issuer.yaml ``` +issuer.cert-manager.io/es-new-issuer created ### Create ElasticsearchOpsRequest @@ -610,24 +601,25 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-update-tls-issuer.yaml -Elasticsearchpsrequest.ops.kubedb.com/esops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/Elasticsearch-update-tls-issuer.yaml ``` +Elasticsearchpsrequest.ops.kubedb.com/esops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CRO, ```bash -$ kubectl get Elasticsearchopsrequests -n demo esops-update-issuer +kubectl get Elasticsearchopsrequests -n demo esops-update-issuer +``` NAME TYPE STATUS AGE esops-update-issuer ReconfigureTLS Successful 6m28s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo esops-update-issuer +kubectl describe Elasticsearchopsrequest -n demo esops-update-issuer +``` Name: esops-update-issuer Namespace: demo Labels: @@ -792,19 +784,16 @@ Events: Warning create es client; ConditionStatus:True 3m57s KubeDB Ops-manager Operator create es client; ConditionStatus:True Normal RestartNodes 3m52s KubeDB Ops-manager Operator Successfully restarted all the nodes -``` - Now, Let's exec into a Elasticsearch node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo es-demo-0 -- bash +kubectl exec -it -n demo es-demo-0 -- bash +``` elasticsearch@es-demo-0:~$ openssl x509 -in /usr/share/elasticsearch/config/certs/http/..2025_11_28_09_34_24.3912740802/tls.crt -noout -issuer issuer=CN = ca-updated, O = kubedb-updated elasticsearch@es-demo-0:~$ openssl x509 -in /usr/share/elasticsearch/config/certs/transport/..2025_11_28_09_34_24.2105953641/tls.crt -noout -issuer issuer=CN = ca-updated, O = kubedb-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 @@ -838,25 +827,25 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/esops-remove.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/reconfigure-tls/esops-remove.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-remove created #### Verify TLS Removed Successfully Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CRO, ```bash -$ kubectl get Elasticsearchopsrequest -n demo esops-remove +kubectl get Elasticsearchopsrequest -n demo esops-remove +``` NAME TYPE STATUS AGE esops-remove ReconfigureTLS Successful 3m16s -``` - We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo esops-remove +kubectl describe Elasticsearchopsrequest -n demo esops-remove +``` Name: esops-remove Namespace: demo Labels: @@ -971,14 +960,12 @@ Events: Normal ResumeDatabase 2m10s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-demo Normal Successful 2m10s KubeDB Ops-manager Operator Successfully Reconfigured TLS -``` - Now, Let's exec into one of the node and find out that TLS is disabled or not. ```bash -$ kubectl exec -n demo es-demo-0 -- \ +kubectl exec -n demo es-demo-0 -- \ cat /usr/share/elasticsearch/config/elasticsearch.yml | grep -A 2 -i xpack.security - +``` Defaulted container "elasticsearch" out of: elasticsearch, init-sysctl (init), config-merger (init) xpack.security.enabled: true @@ -990,8 +977,6 @@ xpack.security.transport.ssl.certificate_authorities: [ "certs/transport/ca.crt" xpack.security.http.ssl.enabled: false -``` - So, we can see from the above that, `xpack.security.http.ssl.enabled` is set to `false` which means TLS is disabled for HTTP layer. Also, the transport layer TLS settings are removed from the `elasticsearch.yml` file. ## Cleaning up diff --git a/docs/guides/elasticsearch/restart/index.md b/docs/guides/elasticsearch/restart/index.md index a8e50d62f1..698ece07e8 100644 --- a/docs/guides/elasticsearch/restart/index.md +++ b/docs/guides/elasticsearch/restart/index.md @@ -64,9 +64,9 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml -Elasticsearch.kubedb.com/es created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/quickstart/overview/elasticsearch/yamls/elasticsearch-v1.yaml ``` +Elasticsearch.kubedb.com/es created let's wait until all pods are in the `Running` state, ```shell @@ -82,19 +82,24 @@ es-2 2/2 Running 0 6m28s To connect to our Elasticsearch cluster, let's port-forward the Elasticsearch service to local machine: ```bash -$ kubectl port-forward -n demo svc/es 9200 +kubectl port-forward -n demo svc/es 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` Keep it like that and switch to another terminal window: ```bash -$ export ELASTIC_USER=$(kubectl get secret -n demo es-o jsonpath='{.data.username}' | base64 -d) +export ELASTIC_USER=$(kubectl get secret -n demo es-o jsonpath='{.data.username}' | base64 -d) +``` -$ export ELASTIC_PASSWORD=$(kubectl get secret -n demo es-o jsonpath='{.data.password}' | base64 -d) +```bash +export ELASTIC_PASSWORD=$(kubectl get secret -n demo es-o jsonpath='{.data.password}' | base64 -d) +``` -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cluster/health?pretty" +```bash +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cluster/health?pretty" +``` { "cluster_name" : "sample-es", "status" : "green", @@ -112,12 +117,12 @@ $ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_c "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` So, our cluster status is green. Let's create some indices with dummy data: ```bash -$ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d ' +curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d ' +``` { "name": "KubeDB", "vendor": "AppsCode Inc.", @@ -125,24 +130,25 @@ $ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/p } ' -$ curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_doc?pretty" -H 'Content-Type: application/json' -d ' +```bash +curl -XPOST -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/companies/_doc?pretty" -H 'Content-Type: application/json' -d ' +``` { "name": "AppsCode Inc.", "mission": "Accelerate the transition to Containers by building a Kubernetes-native Data Platform", "products": ["KubeDB", "Stash", "KubeVault", "Kubeform", "ByteBuilders"] } ' -``` Now, let’s verify that the indexes have been created successfully. ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size green open .geoip_databases oiaZfJA8Q5CihQon0oR8hA 1 1 42 0 81.6mb 40.8mb green open companies GuGisWJ8Tkqnq8vhREQ2-A 1 1 1 0 11.5kb 5.7kb green open products wyu-fImDRr-Hk_GXVF7cDw 1 1 1 0 10.6kb 5.3kb -``` # Apply Restart opsRequest @@ -174,9 +180,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/restart/yamls/restart.yaml -ElasticsearchOpsRequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/restart/yamls/restart.yaml ``` +ElasticsearchOpsRequest.ops.kubedb.com/restart created In a Elasticsearch cluster, all pods act as primary nodes. When you apply a restart OpsRequest, the KubeDB operator will restart the pods sequentially, one by one, to maintain cluster availability. @@ -203,12 +209,15 @@ es-2 2/2 Terminating 0 56m ``` -```shell -$ kubectl get Elasticsearchopsrequest -n demo +```bash +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 64m -$ kubectl get Elasticsearchopsrequest -n demo restart -oyaml +```bash +kubectl get Elasticsearchopsrequest -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: ElasticsearchOpsRequest metadata: @@ -299,32 +308,28 @@ status: type: Successful observedGeneration: 1 phase: Successful - -``` **Verify Data Persistence** After the restart, reconnect to the database and verify that the previously created database still exists: Let's port-forward the port `9200` to local machine: ```bash -$ kubectl port-forward -n demo svc/es 9200 +kubectl port-forward -n demo svc/es 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` - Now let's check the data persistencyof our Elasticsearch database. ```bash -$ curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +curl -XGET -k -u "$ELASTIC_USER:$ELASTIC_PASSWORD" "https://localhost:9200/_cat/indices?v&s=index&pretty" +``` health status index uuid pri rep docs.count docs.deleted store.size pri.store.size dataset.size green open companies 02UKouHARfuMs2lZXMkVQQ 1 1 1 0 13.6kb 6.8kb 6.8kb green open kubedb-system 2Fr26ppkSyy7uJrkfIhzvg 1 1 1 6 433.3kb 191.1kb 191.1kb green open products XxAYeIKOSLaOqp2rczCwFg 1 1 1 0 12.4kb 6.2kb 6.2kb -``` - As you can see, the previously created indices `companies` and `products` are still present after the restart, confirming data persistence after the restart operation. diff --git a/docs/guides/elasticsearch/rotateauth/rotateauth.md b/docs/guides/elasticsearch/rotateauth/rotateauth.md index 2802e0f3b3..121373cff2 100644 --- a/docs/guides/elasticsearch/rotateauth/rotateauth.md +++ b/docs/guides/elasticsearch/rotateauth/rotateauth.md @@ -31,9 +31,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Create a Elasticsearch database The KubeDB operator implements an Elasticsearch CRD to define the specification of an Elasticsearch database. @@ -86,19 +86,19 @@ spec: ``` Let's create the above `Elasticsearch` object, -```console -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/elasticsearch/sample_es.yaml -elasticsearch.kubedb.com/sample-es created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/backup/stash/kubedb/examples/elasticsearch/sample_es.yaml ``` +elasticsearch.kubedb.com/sample-es created Now, wait until `sample-es` has status Ready. i.e, -```shell -$ kubectl get Elasticsearch -n demo -w +```bash +kubectl get Elasticsearch -n demo -w +``` NAME VERSION STATUS AGE sample-es xpack-9.2.3 Ready 3m12s -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the Secret. @@ -115,23 +115,23 @@ Now, you can exec into the pod `sample-es` and connect to database using `userna **Port-forward the Service** At first, let’s port-forward the `sample-es` Service. Run the following command into a separate terminal. -```shell -$ kubectl port-forward -n demo service/sample-es 9200 +```bash +kubectl port-forward -n demo service/sample-es 9200 +``` Forwarding from 127.0.0.1:9200 -> 9200 Forwarding from [::1]:9200 -> 9200 -``` **Insert database** -```shell -$ curl -XPOST --user "elastic:l;)1knmenzgH0c2M" "http://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d' +```bash +curl -XPOST --user "elastic:l;)1knmenzgH0c2M" "http://localhost:9200/products/_doc?pretty" -H 'Content-Type: application/json' -d' +``` { "name": "KubeDB", "vendor": "AppsCode Inc.", "description": "Database Operator for Kubernetes" } ' -``` You'll see: ```shell { @@ -173,19 +173,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Elasticsearch. Let's create the `ElasticsearchOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/rotateauth/yamls/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/rotateauth/yamls/rotate-auth-generated.yaml + ``` Elasticsearchopsrequest.ops.kubedb.com/essops-rotate-auth-generated created -``` Let's wait for `ElasticsearchOpsrequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsrequest` CRO -```shell -$ kubectl get esops -n demo +```bash +kubectl get esops -n demo +``` NAME TYPE STATUS AGE essops-rotate-auth-generated RotateAuth Successful 7m12s -``` If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Elasticsearchopsrequest -n demo essops-rotate-auth-generated +```bash +kubectl describe Elasticsearchopsrequest -n demo essops-rotate-auth-generated +``` Name: essops-rotate-auth-generated Namespace: demo Labels: @@ -351,26 +352,33 @@ Events: Normal ResumeDatabase 5m14s KubeDB Ops-manager Operator Resuming Elasticsearch demo/sample-es Normal ResumeDatabase 5m14s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/sample-es Normal Successful 5m14s KubeDB Ops-manager Operator Successfully updated authsecret. - -``` **Verify Auth is rotated** -```shell -$ kubectl get es -n demo sample-es -ojson | jq .spec.authSecret.name +```bash +kubectl get es -n demo sample-es -ojson | jq .spec.authSecret.name +``` "sample-es-auth" -$ kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic⏎ -$ kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.password}' | base64 -d -k3pcRRtJi8iMhlVy⏎ + +```bash +kubectl get secret -n demo sample-es-auth -o jsonpath='{.data.password}' | base64 -d ``` +k3pcRRtJi8iMhlVy⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo sample-es-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo sample-es-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` elastic⏎ -$ kubectl get secret -n demo sample-es-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -l;)1knmenzgH0c2M⏎ + +```bash +kubectl get secret -n demo sample-es-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +l;)1knmenzgH0c2M⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials @@ -378,13 +386,13 @@ At first, we need to create a secret with kubernetes.io/basic-auth type using cu > Note: `username` must be `elastic`. -```shell -$ kubectl create secret generic sample-es-auth-user -n demo \ +```bash +kubectl create secret generic sample-es-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=elastic \ --from-literal=password=testpassword -secret/sample-es-auth-user created ``` +secret/sample-es-auth-user created Now create a `ElasticsearchOpsRequest` with `RotateAuth` type. Below is the YAML of the `ElasticsearchOpsRequest` that we are going to create, ```shell @@ -412,21 +420,22 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/rotateauth/yamls/rotate-auth-user.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/elasticsearch/rotateauth/yamls/rotate-auth-user.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-rotate-auth-user created Let’s wait for `ElasticsearchOpsRequest` to be Successful. Run the following command to watch `ElasticsearchOpsRequest` CRO: -```shell -$ kubectl get Elasticsearchopsrequest -n demo +```bash +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE essops-rotate-auth-generated RotateAuth Successful 100s esops-rotate-auth-user RotateAuth Successful 62s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed. -```shell -$kubectl describe Elasticsearchopsrequest -n demo esops-rotate-auth-user +```bash +kubectl describe Elasticsearchopsrequest -n demo esops-rotate-auth-user +``` Name: esops-rotate-auth-user Namespace: demo Labels: @@ -594,23 +603,31 @@ Events: Normal ResumeDatabase 2m7s KubeDB Ops-manager Operator Resuming Elasticsearch demo/sample-es Normal ResumeDatabase 2m7s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/sample-es Normal Successful 2m7s KubeDB Ops-manager Operator Successfully updated authsecret. -``` **Verify auth is rotate** -```shell -$ kubectl get Elasticsearch -n demo sample-es -ojson | jq .spec.authSecret.name +```bash +kubectl get Elasticsearch -n demo sample-es -ojson | jq .spec.authSecret.name +``` "sample-es-auth-user" -$ kubectl get secret -n demo sample-es-auth-user -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo sample-es-auth-user -o jsonpath='{.data.username}' | base64 -d +``` elastic⏎ -$ kubectl get secret -n demo sample-es-auth-user -o jsonpath='{.data.password}' | base64 -d -testpassword⏎ + +```bash +kubectl get secret -n demo sample-es-auth-user -o jsonpath='{.data.password}' | base64 -d ``` +testpassword⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo sample-es-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo sample-es-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` elastic -$ kubectl get secret -n demo sample-es-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d -k3pcRRtJi8iMhlVy⏎ + +```bash +kubectl get secret -n demo sample-es-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +k3pcRRtJi8iMhlVy⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -619,15 +636,21 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Elasticsearchopsrequest essps-rotate-auth-generated esops-rotate-auth-user -n demo +```bash +kubectl delete Elasticsearchopsrequest essps-rotate-auth-generated esops-rotate-auth-user -n demo +``` Elasticsearchopsrequest.ops.kubedb.com "essops-rotate-auth-generated" deleted Elasticsearchopsrequest.ops.kubedb.com "esops-rotate-auth-user" deleted -$ kubectl delete secret -n demo sample-es-auth-user + +```bash +kubectl delete secret -n demo sample-es-auth-user +``` secret "sample-es-auth-user" deleted -$ kubectl delete secret -n demo sample-es-auth -secret "sample-es-auth" deleted + +```bash +kubectl delete secret -n demo sample-es-auth ``` +secret "sample-es-auth" deleted ## Next Steps - [Quickstart Kibana](/docs/guides/elasticsearch/elasticsearch-dashboard/kibana/index.md) with KubeDB Operator. diff --git a/docs/guides/elasticsearch/scaling/horizontal/combined.md b/docs/guides/elasticsearch/scaling/horizontal/combined.md index bc5ad00ac4..7bece6aa13 100644 --- a/docs/guides/elasticsearch/scaling/horizontal/combined.md +++ b/docs/guides/elasticsearch/scaling/horizontal/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the E To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,27 +73,29 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/overview/quickstart/elasticsearch/yamls/elasticsearch-v1.yaml -Elasticsearch.kubedb.com/es created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/overview/quickstart/elasticsearch/yamls/elasticsearch-v1.yaml ``` +Elasticsearch.kubedb.com/es created Now, wait until `es` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE es xpack-9.2.3 Ready 3m53s -``` Let's check the number of replicas has from Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get elasticsearch -n demo es -o json | jq '.spec.replicas' -2 -$ kubectl get petsets -n demo es -o json | jq '.spec.replicas' +kubectl get elasticsearch -n demo es -o json | jq '.spec.replicas' +``` 2 +```bash +kubectl get petsets -n demo es -o json | jq '.spec.replicas' ``` +2 We can see from both command that the cluster has 2 replicas. @@ -102,7 +104,8 @@ Also, we can verify the replicas of the combined from an internal Elasticsearch Now lets check the number of replicas, ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es' +``` NAME READY STATUS RESTARTS AGE pod/es-0 1/1 Running 0 5m pod/es-1 1/1 Running 0 4m54s @@ -132,8 +135,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-es-0 Bound pvc-7c8cc17d-7427-4411-9262-f213e826540b 1Gi RWO standard 5m5s persistentvolumeclaim/data-es-1 Bound pvc-f2cf7ac9-b0c2-4c44-93dc-476cc06c25b4 1Gi RWO standard 4m59s -``` - We can see from the above output that the Elasticsearch has 2 nodes. We are now ready to apply the `ElasticsearchOpsRequest` CR to scale this cluster. @@ -169,9 +170,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-up-combined.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-up-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-up-combined.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-up-combined created #### Verify Combined cluster replicas scaled up successfully @@ -180,15 +181,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-hscale-up-combined HorizontalScaling Successful 2m42s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequests -n demo esops-hscale-up-combined +kubectl describe Elasticsearchopsrequests -n demo esops-hscale-up-combined +``` Name: esops-hscale-up-combined Namespace: demo Labels: @@ -259,17 +261,17 @@ Events: Normal Successful 2m16s KubeDB Ops-manager Operator Successfully Horizontally Scaled Database bonusree@bonusree-HP-ProBook-450-G4 ~> -``` - Now, we are going to verify the number of replicas this cluster has from the Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get Elasticsearch -n demo es -o json | jq '.spec.replicas' +kubectl get Elasticsearch -n demo es -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo es -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo es -o json | jq '.spec.replicas' ``` +3 @@ -306,9 +308,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-down-combined.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-down-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-down-combined.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-down-combined created #### Verify Combined cluster replicas scaled down successfully @@ -317,15 +319,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-hscale-down-combined HorizontalScaling Successful 76s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequests -n demo esops-hscale-down-combined + kubectl describe Elasticsearchopsrequests -n demo esops-hscale-down-combined +``` Name: esops-hscale-down-combined Namespace: demo Labels: @@ -451,17 +454,18 @@ Events: Normal ResumeDatabase 83s KubeDB Ops-manager Operator Resuming Elasticsearch demo/es Normal ResumeDatabase 83s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es Normal Successful 83s KubeDB Ops-manager Operator Successfully Horizontally Scaled Database -``` Now, we are going to verify the number of replicas this cluster has from the Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get Elasticsearch -n demo es -o json | jq '.spec.replicas' +kubectl get Elasticsearch -n demo es -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo es -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo es -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the combined cluster is `2`. That means we have successfully scaled down the replicas of the Elasticsearch combined cluster. diff --git a/docs/guides/elasticsearch/scaling/horizontal/topology.md b/docs/guides/elasticsearch/scaling/horizontal/topology.md index 570b8451dc..dbf14f4e97 100644 --- a/docs/guides/elasticsearch/scaling/horizontal/topology.md +++ b/docs/guides/elasticsearch/scaling/horizontal/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the E To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -92,28 +92,34 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/topology.yaml -Elasticsearch.kubedb.com/es-hscale-topology created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/topology.yaml ``` +Elasticsearch.kubedb.com/es-hscale-topology created Now, wait until `es-hscale-topology` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE es-hscale-topology xpack-9.2.3 Ready 3m53s -``` Let's check the number of replicas has from Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' -3 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' +``` 3 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' +``` 3 + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' ``` +3 We can see from both command that the cluster has 3 replicas. @@ -122,7 +128,8 @@ Also, we can verify the replicas of the Topology from an internal Elasticsearch Now lets check the number of replicas, ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-hscale-topology' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=es-hscale-topology' +``` NAME READY STATUS RESTARTS AGE pod/es-hscale-topology-data-0 1/1 Running 0 27m pod/es-hscale-topology-data-1 1/1 Running 0 25m @@ -166,8 +173,6 @@ persistentvolumeclaim/data-es-hscale-topology-master-0 Bound pvc-902a0ebb-b persistentvolumeclaim/data-es-hscale-topology-master-1 Bound pvc-f97215e6-1a91-4e77-8bfb-78d907828e51 1Gi RWO standard 25m persistentvolumeclaim/data-es-hscale-topology-master-2 Bound pvc-a9160094-c08e-4d40-b4ea-ec5681f8be30 1Gi RWO standard 24m -``` - We can see from the above output that the Elasticsearch has 3 nodes. We are now ready to apply the `ElasticsearchOpsRequest` CR to scale this cluster. @@ -213,9 +218,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-down-Topology.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-down-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-down-Topology.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-down-topology created #### Verify Topology cluster replicas scaled down successfully @@ -224,15 +229,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-hscale-down-Topology HorizontalScaling Successful 76s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequests -n demo esops-hscale-down-topology +kubectl describe Elasticsearchopsrequests -n demo esops-hscale-down-topology +``` Name: esops-hscale-down-topology Namespace: demo Labels: @@ -393,18 +399,23 @@ Events: Normal ResumeDatabase 33s KubeDB Ops-manager Operator Resuming Elasticsearch demo/es-hscale-topology Normal ResumeDatabase 33s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-hscale-topology Normal Successful 33s KubeDB Ops-manager Operator Successfully Horizontally Scaled Database -``` Now, we are going to verify the number of replicas this cluster has from the Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' -2 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' +``` 2 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' +``` 2 + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' ``` +2 From all the above outputs we can see that the replicas of the Topology cluster is `2`. That means we have successfully scaled down the replicas of the Elasticsearch Topology cluster. Only one node can be scaling down at a time. So we are scaling down the `ingest` node. @@ -464,9 +475,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-up-Topology.yaml -Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-up-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/horizontal/Elasticsearch-hscale-up-Topology.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/esops-hscale-up-topology created #### Verify Topology cluster replicas scaled up successfully @@ -475,15 +486,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo + kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE esops-hscale-up-topology HorizontalScaling Successful 13m -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequests -n demo esops-hscale-up-topology +kubectl describe Elasticsearchopsrequests -n demo esops-hscale-up-topology +``` Name: esops-hscale-up-topology Namespace: demo Labels: @@ -575,18 +587,23 @@ Events: Normal ResumeDatabase 4m52s KubeDB Ops-manager Operator Resuming Elasticsearch demo/es-hscale-topology Normal ResumeDatabase 4m52s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-hscale-topology Normal Successful 4m51s KubeDB Ops-manager Operator Successfully Horizontally Scaled Database -``` Now, we are going to verify the number of replicas this cluster has from the Elasticsearch object, number of pods the petset have, ```bash -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' -3 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.master.replicas' +``` 3 -$ kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.data.replicas' +``` 3 + +```bash +kubectl get elasticsearch -n demo es-hscale-topology -o json | jq '.spec.topology.ingest.replicas' ``` +3 From all the above outputs we can see that the brokers of the Topology Elasticsearch is `3`. That means we have successfully scaled up the replicas of the Elasticsearch Topology cluster. diff --git a/docs/guides/elasticsearch/scaling/vertical/combined.md b/docs/guides/elasticsearch/scaling/vertical/combined.md index 98ea2c2854..8a07a6ef1d 100644 --- a/docs/guides/elasticsearch/scaling/vertical/combined.md +++ b/docs/guides/elasticsearch/scaling/vertical/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -74,23 +74,23 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/multi-node-es.yaml -Elasticsearch.kubedb.com/es-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/multi-node-es.yaml ``` +Elasticsearch.kubedb.com/es-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get elasticsearch -n demo -w +kubectl get elasticsearch -n demo -w +``` NAME VERSION STATUS AGE es-combined xpack-9.2.3 Ready 3h17m -``` - Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -100,8 +100,6 @@ $ kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resourc "memory": "1536Mi" } } - -``` This is the default resources of the Elasticsearch combined cluster set by the `KubeDB` operator. We are now ready to apply the `ElasticsearchOpsRequest` CR to update the resources of this database. @@ -145,7 +143,7 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/topology-es.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/topology-es.yaml ``` #### Verify Elasticsearch Combined cluster resources updated successfully @@ -155,16 +153,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get elasticsearchopsrequest -n demo +kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE vscale-combined VerticalScaling Successful 2m38s -``` - We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo vscale-combined +kubectl describe Elasticsearchopsrequest -n demo vscale-combined +``` Name: vscale-combined Namespace: demo Labels: @@ -272,12 +270,11 @@ Events: Normal ResumeDatabase 74s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-combined Normal Successful 74s KubeDB Ops-manager Operator Successfully Updated Database -``` - Now, we are going to verify from one of the Pod yaml whether the resources of the combined cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1500m", @@ -289,8 +286,6 @@ $ kubectl get pod -n demo es-combined-0 -o json | jq '.spec.containers[].resourc } } -``` - The above output verifies that we have successfully scaled up the resources of the Elasticsearch combined cluster. ## Cleaning Up diff --git a/docs/guides/elasticsearch/scaling/vertical/topology.md b/docs/guides/elasticsearch/scaling/vertical/topology.md index f22b88a88a..ad2c39f2d4 100644 --- a/docs/guides/elasticsearch/scaling/vertical/topology.md +++ b/docs/guides/elasticsearch/scaling/vertical/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -92,23 +92,23 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/Elasticsearch-topology.yaml -Elasticsearch.kubedb.com/es-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/Elasticsearch-topology.yaml ``` +Elasticsearch.kubedb.com/es-cluster created Now, wait until `es-cluster` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 53m -``` - Let's check the Pod containers resources for both `data`,`ingest` and `master` of the Elasticsearch topology cluster. Run the following command to get the resources of the `broker` and `controller` containers of the Elasticsearch topology cluster ```bash -$ kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -118,7 +118,10 @@ $ kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].re "memory": "1536Mi" } } -$ kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -129,7 +132,9 @@ $ kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[]. } } -$ kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -139,8 +144,6 @@ $ kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[]. "memory": "1536Mi" } } - -``` This is the default resources of the Elasticsearch topology cluster set by the `KubeDB` operator. We are now ready to apply the `ElasticsearchOpsRequest` CR to update the resources of this database. @@ -193,9 +196,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/vertical/Elasticsearch-vertical-scaling-topology.yaml -Elasticsearchopsrequest.ops.kubedb.com/vscale-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/scaling/vertical/Elasticsearch-vertical-scaling-topology.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/vscale-topology created #### Verify Elasticsearch Topology cluster resources updated successfully @@ -204,16 +207,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get elasticsearchopsrequest -n demo +kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE vscale-topology VerticalScaling Successful 18m -``` - We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo vscale-topology +kubectl describe Elasticsearchopsrequest -n demo vscale-topology +``` Name: vscale-topology Namespace: demo Labels: @@ -632,12 +635,11 @@ Events: Warning create es client; ConditionStatus:True 11m KubeDB Ops-manager Operator create es client; ConditionStatus:True Warning re enable shard allocation; ConditionStatus:True 11m KubeDB Ops-manager Operator re enable shard allocation; ConditionStatus:True Normal RestartNodes 11m KubeDB Ops-manager Operator Successfully restarted all nodes - -``` Now, we are going to verify from one of the Pod yaml whether the resources of the topology cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "900m", @@ -648,7 +650,10 @@ $ kubectl get pod -n demo es-cluster-ingest-0 -o json | jq '.spec.containers[]. "memory": "1Gi" } } -$ kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "900Mi" @@ -658,7 +663,10 @@ $ kubectl get pod -n demo es-cluster-data-0 -o json | jq '.spec.containers[].re "memory": "900Mi" } } -$ kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "750m", @@ -670,8 +678,6 @@ $ kubectl get pod -n demo es-cluster-master-0 -o json | jq '.spec.containers[]. } } -``` - The above output verifies that we have successfully scaled up the resources of the Elasticsearch topology cluster. ## Cleaning Up diff --git a/docs/guides/elasticsearch/tls/elasticsearch-combined.md b/docs/guides/elasticsearch/tls/elasticsearch-combined.md index 8f15d958b8..bf01f2685a 100644 --- a/docs/guides/elasticsearch/tls/elasticsearch-combined.md +++ b/docs/guides/elasticsearch/tls/elasticsearch-combined.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Elasticsearch. This tutorial wi - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,12 +64,12 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - Now create a ca-secret using the certificate files you have just generated. ```bash -$ kubectl create secret tls es-ca \ +kubectl create secret tls es-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/es-ca created ``` +secret/es-ca created Now, create an `Issuer` using the `ca-secret` you have just created. The `YAML` file looks like this: @@ -87,9 +87,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-issuer.yaml -issuer.cert-manager.io/es-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-issuer.yaml ``` +issuer.cert-manager.io/es-ca-issuer created ## TLS/SSL encryption in Elasticsearch Combined Cluster @@ -122,28 +122,29 @@ spec: ### Deploy Elasticsearch Combined Cluster ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-combined-tls.yaml -elasticsearch.kubedb.com/es-combined-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-combined-tls.yaml ``` +elasticsearch.kubedb.com/es-combined-tls created Now, wait until `es-combined-tls` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-combined-tls xpack-8.19.9 Provisioning 0s es-combined-tls xpack-8.19.9 Provisioning 15s . . es-combined-tls xpack-8.19.9 Ready 82s -``` ### Verify TLS/SSL in Elasticsearch Combined Cluster KubeDB creates a client certificate secret for Elasticsearch. Let's check it: ```bash -$ kubectl describe secret -n demo es-combined-tls-client-cert +kubectl describe secret -n demo es-combined-tls-client-cert +``` Name: es-combined-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -169,13 +170,13 @@ Data tls.key: 1708 bytes ca.crt: 1172 bytes tls.crt: 1387 bytes -``` Now, let's exec into an Elasticsearch pod and verify the configuration that TLS is enabled for both transport and HTTP layers. ```bash -$ kubectl exec -n demo es-combined-tls-0 -c elasticsearch -- \ +kubectl exec -n demo es-combined-tls-0 -c elasticsearch -- \ cat /usr/share/elasticsearch/config/elasticsearch.yml | grep -A 2 -i xpack.security +``` xpack.security.enabled: true xpack.security.transport.ssl.enabled: true @@ -188,14 +189,14 @@ xpack.security.http.ssl.enabled: true xpack.security.http.ssl.key: certs/http/tls.key xpack.security.http.ssl.certificate: certs/http/tls.crt xpack.security.http.ssl.certificate_authorities: [ "certs/http/ca.crt" ] -``` We can see from the above output that both `xpack.security.transport.ssl.enabled: true` and `xpack.security.http.ssl.enabled: true` are set, which means TLS is enabled for both node-to-node and client-to-node communication. Now, let's connect to the Elasticsearch cluster using HTTPS to confirm it is accessible with TLS. ```bash -$ kubectl exec -it -n demo es-combined-tls-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_cluster/health?pretty" --user "elastic:$ELASTIC_USER_PASSWORD" + kubectl exec -it -n demo es-combined-tls-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_cluster/health?pretty" --user "elastic:$ELASTIC_USER_PASSWORD" +``` { "cluster_name" : "es-combined-tls", "status" : "green", @@ -214,7 +215,6 @@ $ kubectl exec -it -n demo es-combined-tls-0 -c elasticsearch -- curl -k -XGET "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` From the above output, we can see that we are able to connect to the Elasticsearch cluster using the TLS configuration. diff --git a/docs/guides/elasticsearch/tls/elasticsearch-topology.md b/docs/guides/elasticsearch/tls/elasticsearch-topology.md index c728bba545..ba79dcc811 100644 --- a/docs/guides/elasticsearch/tls/elasticsearch-topology.md +++ b/docs/guides/elasticsearch/tls/elasticsearch-topology.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Elasticsearch. This tutorial wi - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -87,9 +87,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-issuer.yaml -issuer.cert-manager.io/es-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-issuer.yaml ``` +issuer.cert-manager.io/es-ca-issuer created ## TLS/SSL encryption in Elasticsearch Topology Cluster @@ -142,28 +142,29 @@ spec: ### Deploy Elasticsearch Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-topology-tls.yaml -elasticsearch.kubedb.com/es-topology-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/tls/es-topology-tls.yaml ``` +elasticsearch.kubedb.com/es-topology-tls created Now, wait until `es-topology-tls` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-topology-tls xpack-8.19.9 Provisioning 0s es-topology-tls xpack-8.19.9 Provisioning 18s . . es-topology-tls xpack-8.19.9 Ready 2m5s -``` ### Verify TLS/SSL in Elasticsearch Topology Cluster KubeDB creates a client certificate secret for Elasticsearch. Let's check it: ```bash -$ kubectl describe secret -n demo es-topology-tls-client-cert +kubectl describe secret -n demo es-topology-tls-client-cert +``` Name: es-topology-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -189,13 +190,13 @@ Data ca.crt: 1172 bytes tls.crt: 1387 bytes tls.key: 1704 bytes -``` Now, let's exec into the master node and verify the configuration that TLS is enabled for both transport and HTTP layers. ```bash -$ kubectl exec -n demo es-topology-tls-master-0 -c elasticsearch -- \ +kubectl exec -n demo es-topology-tls-master-0 -c elasticsearch -- \ cat /usr/share/elasticsearch/config/elasticsearch.yml | grep -A 2 -i xpack.security +``` xpack.security.enabled: true xpack.security.transport.ssl.enabled: true @@ -208,14 +209,14 @@ xpack.security.http.ssl.enabled: true xpack.security.http.ssl.key: certs/http/tls.key xpack.security.http.ssl.certificate: certs/http/tls.crt xpack.security.http.ssl.certificate_authorities: [ "certs/http/ca.crt" ] -``` We can see from the above output that both `xpack.security.transport.ssl.enabled: true` and `xpack.security.http.ssl.enabled: true` are set, which means TLS is enabled for both node-to-node and client-to-node communication across all topology node roles. Now, let's exec into the master node and connect using HTTPS to confirm the topology cluster is accessible with TLS. ```bash -$ kubectl exec -it -n demo es-topology-tls-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_cluster/health?pretty" --user "elastic:$ELASTIC_USER_PASSWORD" +kubectl exec -it -n demo es-topology-tls-master-0 -c elasticsearch -- curl -k -XGET "https://localhost:9200/_cluster/health?pretty" --user "elastic:$ELASTIC_USER_PASSWORD" +``` { "cluster_name" : "es-topology-tls", "status" : "green", @@ -233,7 +234,6 @@ $ kubectl exec -it -n demo es-topology-tls-master-0 -c elasticsearch -- curl -k "task_max_waiting_in_queue_millis" : 0, "active_shards_percent_as_number" : 100.0 } -``` From the above output, we can see that we are able to connect to the Elasticsearch topology cluster using the TLS configuration. The cluster has 4 nodes total (1 master + 2 data + 1 ingest) and is reporting `green` status. diff --git a/docs/guides/elasticsearch/update-version/elasticsearch.md b/docs/guides/elasticsearch/update-version/elasticsearch.md index 133f80652c..be8d2559ae 100644 --- a/docs/guides/elasticsearch/update-version/elasticsearch.md +++ b/docs/guides/elasticsearch/update-version/elasticsearch.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/elasticsearch](/docs/examples/elasticsearch) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -69,19 +69,18 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/update-version/Elasticsearch.yaml -Elasticsearch.kubedb.com/es-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/update-version/Elasticsearch.yaml ``` +Elasticsearch.kubedb.com/es-demo created Now, wait until `es-demo` created has status `Ready`. i.e, ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE es-demo xpack-8.18.8 Ready 9m10s -``` - We are now ready to apply the `ElasticsearchOpsRequest` CR to update. ### update Elasticsearch Version @@ -117,9 +116,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/update-version/update-version.yaml -Elasticsearchopsrequest.ops.kubedb.com/Elasticsearch-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/update-version/update-version.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/Elasticsearch-update-version created #### Verify Elasticsearch version updated successfully @@ -128,15 +127,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE Elasticsearch-update-version UpdateVersion Successful 2m6s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo es-demo-update +kubectl describe Elasticsearchopsrequest -n demo es-demo-update +``` Name: es-demo-update Namespace: demo Labels: @@ -284,21 +284,22 @@ Events: Normal ResumeDatabase 28m KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-demo Normal Successful 28m KubeDB Ops-manager Operator Successfully Updated Database -``` - Now, we are going to verify whether the `Elasticsearch` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get es -n demo es-demo -o=jsonpath='{.spec.version}{"\n"}' +kubectl get es -n demo es-demo -o=jsonpath='{.spec.version}{"\n"}' +``` xpack-9.2.3 -$ kubectl get petset -n demo es-demo -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo es-demo -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/elastic:9.2.3@sha256:e0b89e3ace47308fa5fa842823bc622add3733e47c1067cd1e6afed2cfd317ca -$ kubectl get pods -n demo es-demo-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/elastic:9.2.3 - +```bash +kubectl get pods -n demo es-demo-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/elastic:9.2.3 You can see from above, our `Elasticsearch` has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/elasticsearch/volume-expansion/combined.md b/docs/guides/elasticsearch/volume-expansion/combined.md index 9042468f96..a8442a9f4c 100644 --- a/docs/guides/elasticsearch/volume-expansion/combined.md +++ b/docs/guides/elasticsearch/volume-expansion/combined.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Elasticsearch` combined using a supported versio At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `standard` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -86,29 +86,30 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/multi-node-es.yaml -Elasticsearch.kubedb.com/es-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/clustering/multi-node-es.yaml ``` +Elasticsearch.kubedb.com/es-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo -w +kubectl get es -n demo -w +``` NAME VERSION STATUS AGE es-combined xpack-9.2.3 Ready 75s -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo -NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE -pvc-edeeff75-9823-4aeb-9189-37adad567ec7 1Gi RWO Delete Bound demo/data-es-combined-0 standard 2m21s +```bash +kubectl get pv -n demo ``` +NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE +pvc-edeeff75-9823-4aeb-9189-37adad567ec7 1Gi RWO Delete Bound demo/data-es-combined-0 standard 2m21s You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -146,9 +147,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/elasticsearch-volume-expansion-combined.yaml -Elasticsearchopsrequest.ops.kubedb.com/es-volume-expansion-combinedcreated +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/elasticsearch-volume-expansion-combined.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/es-volume-expansion-combinedcreated #### Verify Elasticsearch Combined volume expanded successfully @@ -157,15 +158,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE es-volume-expansion-combined VolumeExpansion Successful 2m4s -``` We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo es-volume-expansion-combined +kubectl describe Elasticsearchopsrequest -n demo es-volume-expansion-combined +``` Name: es-volume-expansion-combined Namespace: demo Labels: @@ -333,18 +335,18 @@ Events: Normal ResumeDatabase 11s KubeDB Ops-manager Operator Successfully resumed Elasticsearch demo/es-combined Normal Successful 11s KubeDB Ops-manager Operator Successfully Updated Database -``` - Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + kubectl get petset -n demo es-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "4Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-edeeff75-9823-4aeb-9189-37adad567ec7 4Gi RWO Delete Bound demo/data-es-combined-0 standard 13m -``` The above output verifies that we have successfully expanded the volume of the Elasticsearch. diff --git a/docs/guides/elasticsearch/volume-expansion/topology.md b/docs/guides/elasticsearch/volume-expansion/topology.md index 17b04f9bbe..251fdd13f2 100644 --- a/docs/guides/elasticsearch/volume-expansion/topology.md +++ b/docs/guides/elasticsearch/volume-expansion/topology.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/elasticsearch](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Elasticsearch` topology using a supported versio At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -105,29 +105,38 @@ spec: Let's create the `Elasticsearch` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}docs/examples/elasticsearch/clustering/topology-es.yaml -Elasticsearch.kubedb.com/es-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}docs/examples/elasticsearch/clustering/topology-es.yaml ``` +Elasticsearch.kubedb.com/es-cluster created Now, wait until `es-cluster` has status `Ready`. i.e, ```bash -$ kubectl get es -n demo +kubectl get es -n demo +``` NAME VERSION STATUS AGE es-cluster xpack-9.2.3 Ready 22h -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo es-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo es-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo es-cluster-master -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo es-cluster-master -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo es-cluster-ingest -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo es-cluster-ingest -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-11b48c6e-d996-45a7-8ba2-f8d71a655912 1Gi RWO Delete Bound demo/data-es-cluster-ingest-2 longhorn 22h pvc-1904104c-bbf2-4754-838a-8a647b2bd23e 1Gi RWO Delete Bound demo/data-es-cluster-data-2 longhorn 22h @@ -138,7 +147,6 @@ pvc-ae5ccc43-d078-4816-a553-8a3cd1f674be 1Gi RWO Delete pvc-b4225042-c69f-41df-99b2-1b3191057a85 1Gi RWO Delete Bound demo/data-es-cluster-data-1 longhorn 22h pvc-bd4b7d5a-8494-4ee2-a25c-697a6f23cb79 1Gi RWO Delete Bound demo/data-es-cluster-ingest-1 longhorn 22h pvc-c9057b3b-4412-467f-8ae5-f6414e0059c3 1Gi RWO Delete Bound demo/data-es-cluster-master-2 longhorn 22h -``` You can see the petsets have 1Gi storage, and the capacity of all the persistent volumes are also 1Gi. @@ -182,9 +190,9 @@ Here, Let's create the `ElasticsearchOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/elasticsearch-volume-expansion-topology.yaml -Elasticsearchopsrequest.ops.kubedb.com/volume-expansion-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/elasticsearch-volume-expansion-topology.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/volume-expansion-topology created #### Verify Elasticsearch Topology volume expanded successfully @@ -193,16 +201,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `ElasticsearchOpsRequest` to be `Successful`. Run the following command to watch `ElasticsearchOpsRequest` CR, ```bash -$ kubectl get Elasticsearchopsrequest -n demo +kubectl get Elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE volume-expansion-topology VolumeExpansion Successful 44m -``` - We can see from the above output that the `ElasticsearchOpsRequest` has succeeded. If we describe the `ElasticsearchOpsRequest` we will get an overview of the steps that were followed to expand the volume of Elasticsearch. ```bash -$ kubectl describe Elasticsearchopsrequest -n demo volume-expansion-topology +kubectl describe Elasticsearchopsrequest -n demo volume-expansion-topology +``` Name: volume-expansion-topology Namespace: demo Labels: @@ -698,19 +706,26 @@ Events: Normal Successful 31m KubeDB Ops-manager Operator Successfully Updated Database Normal UpdatePetSets 31m KubeDB Ops-manager Operator successfully reconciled the Elasticsearch resources -``` - Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo es-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo es-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "5Gi" -$ kubectl get petset -n demo es-cluster-master -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo es-cluster-master -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "5Gi" -$ kubectl get petset -n demo es-cluster-ingest -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo es-cluster-ingest -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "4Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-37f7398d-0251-4d3c-a439-d289b8cec6d2 5Gi RWO Delete Bound demo/data-es-cluster-master-2 longhorn 111m pvc-3a5d2b3e-dd39-4468-a8da-5274992a6502 5Gi RWO Delete Bound demo/data-es-cluster-master-0 longhorn 111m @@ -721,7 +736,6 @@ pvc-81d6c1d3-0aa6-4190-9ee0-dd4a8d62b6b3 4Gi RWO Delete pvc-942c6dce-4701-4e1a-b6f9-bf7d4ab56a11 5Gi RWO Delete Bound demo/data-es-cluster-data-1 longhorn 111m pvc-b706647d-c9ba-4296-94aa-2f6ef2230b6e 4Gi RWO Delete Bound demo/data-es-cluster-ingest-1 longhorn 111m pvc-c274f913-5452-47e1-ab42-ba584bdae297 5Gi RWO Delete Bound demo/data-es-cluster-data-0 longhorn 111m -``` The above output verifies that we have successfully expanded the volume of the Elasticsearch. @@ -745,9 +759,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/volume-expansion-topo-data.yaml -Elasticsearchopsrequest.ops.kubedb.com/volume-expansion-data-nodes created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/elasticsearch/volume-expansion/volume-expansion-topo-data.yaml ``` +Elasticsearchopsrequest.ops.kubedb.com/volume-expansion-data-nodes created ## Cleaning Up To clean up the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/hanadb/clustering/system-replication.md b/docs/guides/hanadb/clustering/system-replication.md index e6fe4e90a7..8fb0dd8e39 100644 --- a/docs/guides/hanadb/clustering/system-replication.md +++ b/docs/guides/hanadb/clustering/system-replication.md @@ -28,9 +28,9 @@ Replication cluster and inspects its replication state. - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Create a System Replication Cluster @@ -73,9 +73,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/clustering/system-replication.yaml -hanadb.kubedb.com/hanadb-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/clustering/system-replication.yaml ``` +hanadb.kubedb.com/hanadb-cluster created Here, @@ -92,31 +92,31 @@ Here, Wait until `hanadb-cluster` is `Ready`: ```bash -$ kubectl get hanadb.kubedb.com -n demo hanadb-cluster +kubectl get hanadb.kubedb.com -n demo hanadb-cluster +``` NAME VERSION STATUS AGE hanadb-cluster 2.0.82 Ready 12m -``` KubeDB labels each pod with its role (`kubedb.com/role`). Note the `hanadb-cluster-arbiter-0` pod — because `spec.replicas` is even (2), KubeDB added an arbiter as the raft tie-breaker: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE hanadb-cluster-0 2/2 Running 0 12m primary hanadb-cluster-1 2/2 Running 0 12m secondary hanadb-cluster-arbiter-0 1/1 Running 0 5m33s arbiter -``` The Services route traffic to the primary and (read-only) secondary: ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=hanadb-cluster +kubectl get svc -n demo -l app.kubernetes.io/instance=hanadb-cluster +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hanadb-cluster ClusterIP 10.43.65.245 39017/TCP 12m hanadb-cluster-pods ClusterIP None 39001/TCP,39017/TCP 12m hanadb-cluster-secondary ClusterIP 10.43.219.128 39017/TCP 12m -``` Here `hanadb-cluster` always points at the primary, `hanadb-cluster-secondary` at the read-only secondary (created because `operationMode` is `logreplay_readaccess`), and `hanadb-cluster-pods` is the @@ -127,8 +127,9 @@ governing headless Service. Identify the primary pod (role `primary`) and inspect HANA's System Replication status: ```bash -$ kubectl exec -n demo hanadb-cluster-0 -c hanadb -- /bin/sh -lc \ +kubectl exec -n demo hanadb-cluster-0 -c hanadb -- /bin/sh -lc \ 'source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbnsutil -sr_state' +``` System Replication State ~~~~~~~~~~~~~~~~~~~~~~~~ online: true @@ -145,20 +146,22 @@ Site Mappings: SITE_hanadb-cluster-0 (primary/primary) |---SITE_hanadb-cluster-1 (sync/logreplay_readaccess) done. -``` The HANA SystemReplication status confirms the secondary is connected and `ACTIVE`. (HANA maps the `fullsync` replication mode to `SYNC` plus the full-sync option, so the runtime mode reads `SYNC`.) ```bash -$ HANA_PASSWORD="$(kubectl get secret hanadb-cluster-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" -$ kubectl exec -n demo hanadb-cluster-0 -c hanadb -- /bin/sh -lc \ +HANA_PASSWORD="$(kubectl get secret hanadb-cluster-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +``` + +```bash +kubectl exec -n demo hanadb-cluster-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' \ \"SELECT SITE_NAME, SECONDARY_SITE_NAME, REPLICATION_MODE, REPLICATION_STATUS FROM SYS.M_SERVICE_REPLICATION\"" +``` SITE_NAME,SECONDARY_SITE_NAME,REPLICATION_MODE,REPLICATION_STATUS "SITE_hanadb-cluster-0","SITE_hanadb-cluster-1","SYNC","ACTIVE" 1 row selected -``` ## Day-2 Operations @@ -172,8 +175,11 @@ Once the cluster is running you can: ## Cleaning Up ```bash -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete ns demo +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/configuration/using-config-file.md b/docs/guides/hanadb/configuration/using-config-file.md index fc14d2dacf..30274d9668 100644 --- a/docs/guides/hanadb/configuration/using-config-file.md +++ b/docs/guides/hanadb/configuration/using-config-file.md @@ -26,9 +26,9 @@ see [Reconfigure](/docs/guides/hanadb/reconfigure/reconfigure.md). - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Overview @@ -54,9 +54,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/configuration/hanadb-configuration.yaml -secret/hanadb-configuration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/configuration/hanadb-configuration.yaml ``` +secret/hanadb-configuration created The key inside the secret **must** be `global.ini`. Here `global_allocation_limit = 8589934592` caps the HANA global allocation at 8 GiB. @@ -88,33 +88,35 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/configuration/standalone-cus-conf.yaml -hanadb.kubedb.com/hanadb-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/configuration/standalone-cus-conf.yaml ``` +hanadb.kubedb.com/hanadb-custom-config created Wait for the database to become `Ready`: ```bash -$ kubectl get hanadb.kubedb.com -n demo hanadb-custom-config +kubectl get hanadb.kubedb.com -n demo hanadb-custom-config +``` NAME VERSION STATUS AGE hanadb-custom-config 2.0.82 Ready 24m -``` ## Verify the Configuration Read the password and query `M_INIFILE_CONTENTS` to confirm HANA picked up the custom value: ```bash -$ HANA_PASSWORD="$(kubectl get secret hanadb-custom-config-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +HANA_PASSWORD="$(kubectl get secret hanadb-custom-config-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +``` -$ kubectl exec -n demo hanadb-custom-config-0 -c hanadb -- /bin/sh -lc \ +```bash +kubectl exec -n demo hanadb-custom-config-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' \ \"SELECT LAYER_NAME, VALUE FROM M_INIFILE_CONTENTS WHERE FILE_NAME='global.ini' AND SECTION='memorymanager' AND KEY='global_allocation_limit'\"" +``` LAYER_NAME,VALUE "SYSTEM","8589934592" "DEFAULT","0" 2 rows selected -``` The `SYSTEM` layer shows the custom value `8589934592` (8 GiB) merged into `global.ini` from the configuration secret, overriding the `DEFAULT` layer. @@ -122,9 +124,15 @@ configuration secret, overriding the `DEFAULT` layer. ## Cleaning Up ```bash -$ kubectl delete hanadb.kubedb.com -n demo hanadb-custom-config -$ kubectl delete secret -n demo hanadb-configuration -$ kubectl delete ns demo +kubectl delete hanadb.kubedb.com -n demo hanadb-custom-config +``` + +```bash +kubectl delete secret -n demo hanadb-configuration +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/monitoring/using-builtin-prometheus.md b/docs/guides/hanadb/monitoring/using-builtin-prometheus.md index aea6bf4527..4c8ef9bb7c 100644 --- a/docs/guides/hanadb/monitoring/using-builtin-prometheus.md +++ b/docs/guides/hanadb/monitoring/using-builtin-prometheus.md @@ -25,9 +25,9 @@ annotation can collect its metrics. - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Deploy a HanaDB with Builtin Monitoring @@ -56,9 +56,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/monitoring/builtin-prometheus.yaml -hanadb.kubedb.com/hanadb-builtin-prometheus created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/monitoring/builtin-prometheus.yaml ``` +hanadb.kubedb.com/hanadb-builtin-prometheus created Wait until the database is `Ready`. @@ -67,22 +67,25 @@ Wait until the database is `Ready`. KubeDB adds an `exporter` container and a `-stats` Service: ```bash -$ kubectl get pod -n demo hanadb-builtin-prometheus-0 -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}' +kubectl get pod -n demo hanadb-builtin-prometheus-0 -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}' +``` hanadb exporter -$ kubectl get svc -n demo -l app.kubernetes.io/instance=hanadb-builtin-prometheus +```bash +kubectl get svc -n demo -l app.kubernetes.io/instance=hanadb-builtin-prometheus +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hanadb-builtin-prometheus ClusterIP 10.43.27.56 39017/TCP 17m hanadb-builtin-prometheus-pods ClusterIP None 39001/TCP,39017/TCP 17m hanadb-builtin-prometheus-stats ClusterIP 10.43.169.153 9668/TCP 17m -``` The stats Service carries the `prometheus.io/scrape`, `prometheus.io/port`, and `prometheus.io/path` annotations a builtin Prometheus uses to discover the target: ```bash -$ kubectl get svc -n demo hanadb-builtin-prometheus-stats -o jsonpath='{.metadata.annotations}' | jq +kubectl get svc -n demo hanadb-builtin-prometheus-stats -o jsonpath='{.metadata.annotations}' | jq +``` { "monitoring.appscode.com/agent": "prometheus.io/builtin", "prometheus.io/path": "/metrics", @@ -90,24 +93,26 @@ $ kubectl get svc -n demo hanadb-builtin-prometheus-stats -o jsonpath='{.metadat "prometheus.io/scheme": "http", "prometheus.io/scrape": "true" } -``` Scrape the metrics to confirm the exporter is serving (the `exporter` container is distroless, so curl the stats Service from a throwaway pod): ```bash -$ kubectl run hdb-metrics-check -n demo --rm -i --restart=Never --image=curlimages/curl:8.10.1 -- \ +kubectl run hdb-metrics-check -n demo --rm -i --restart=Never --image=curlimages/curl:8.10.1 -- \ curl -s http://hanadb-builtin-prometheus-stats.demo.svc:9668/metrics | grep -E '^hanadb_' | head +``` hanadb_column_tables_used_memory_mb{database_name="SYSTEMDB",host="hanadb-builtin-prometheus-0",insnr="90",sid="HXE"} 6.0 hanadb_schema_used_memory_mb{database_name="SYSTEMDB",host="hanadb-builtin-prometheus-0",insnr="90",schema_name="_SYS_REPO",sid="HXE"} 1.0 hanadb_schema_used_memory_mb{database_name="SYSTEMDB",host="hanadb-builtin-prometheus-0",insnr="90",schema_name="_SYS_DI",sid="HXE"} 1.0 -``` ## Cleaning Up ```bash -$ kubectl delete hanadb.kubedb.com -n demo hanadb-builtin-prometheus -$ kubectl delete ns demo +kubectl delete hanadb.kubedb.com -n demo hanadb-builtin-prometheus +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/monitoring/using-prometheus-operator.md b/docs/guides/hanadb/monitoring/using-prometheus-operator.md index 64d6a48a91..b6e9eaebf0 100644 --- a/docs/guides/hanadb/monitoring/using-prometheus-operator.md +++ b/docs/guides/hanadb/monitoring/using-prometheus-operator.md @@ -27,9 +27,9 @@ This guide deploys a HanaDB with the `prometheus.io/operator` agent so the note the label its `Prometheus` uses to select `ServiceMonitor`s (often `release: prometheus`): ```bash -$ kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.serviceMonitorSelector}'; echo -{} +kubectl get prometheus -n monitoring -o jsonpath='{.items[0].spec.serviceMonitorSelector}'; echo ``` +{} > An empty `serviceMonitorSelector` (`{}`) means this Prometheus selects **all** `ServiceMonitor`s in the > namespaces it watches. If your Prometheus uses a non-empty selector, set @@ -67,9 +67,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/monitoring/prometheus-operator.yaml -hanadb.kubedb.com/hanadb-prometheus-operator created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/monitoring/prometheus-operator.yaml ``` +hanadb.kubedb.com/hanadb-prometheus-operator created Wait until the database is `Ready`. @@ -79,23 +79,28 @@ KubeDB creates a `ServiceMonitor` carrying the `release: prometheus` label so th selects it: ```bash -$ kubectl get servicemonitor -n demo -l app.kubernetes.io/instance=hanadb-prometheus-operator +kubectl get servicemonitor -n demo -l app.kubernetes.io/instance=hanadb-prometheus-operator +``` NAME AGE hanadb-prometheus-operator-stats 17m -$ kubectl get servicemonitor -n demo hanadb-prometheus-operator-stats \ +```bash +kubectl get servicemonitor -n demo hanadb-prometheus-operator-stats \ -o jsonpath='port={.spec.endpoints[0].port} interval={.spec.endpoints[0].interval}{"\n"}selector={.spec.selector.matchLabels}{"\n"}' +``` port=metrics interval=10s selector={"app.kubernetes.io/instance":"hanadb-prometheus-operator","app.kubernetes.io/managed-by":"kubedb.com","app.kubernetes.io/name":"hanadbs.kubedb.com","kubedb.com/role":"stats"} -``` Once Prometheus reloads, the HanaDB target appears in its **Status → Targets** page. ## Cleaning Up ```bash -$ kubectl delete hanadb.kubedb.com -n demo hanadb-prometheus-operator -$ kubectl delete ns demo +kubectl delete hanadb.kubedb.com -n demo hanadb-prometheus-operator +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/quickstart/quickstart.md b/docs/guides/hanadb/quickstart/quickstart.md index ec72a75086..fbc1632a3a 100644 --- a/docs/guides/hanadb/quickstart/quickstart.md +++ b/docs/guides/hanadb/quickstart/quickstart.md @@ -30,29 +30,29 @@ database using KubeDB. To keep things isolated, this tutorial uses a separate namespace called `demo`: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Check Available StorageClass ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 19d -``` ## Find Available HanaDBVersion KubeDB maintains a `HanaDBVersion` CRD with all supported SAP HANA versions and their images: ```bash -$ kubectl get hanadbversions +kubectl get hanadbversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2.0.76 2.0.76 docker.io/saplabs/hanaexpress:2.00.076.00.20240701.1 31h 2.0.82 2.0.82 docker.io/saplabs/hanaexpress:2.00.082.00.20250528.1 6d13h 2.0.88 2.0.88 docker.io/saplabs/hanaexpress:2.00.088.00.20251110.1 31h -``` ## Create a HanaDB Database @@ -80,9 +80,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/quickstart/standalone.yaml -hanadb.kubedb.com/hanadb-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/quickstart/standalone.yaml ``` +hanadb.kubedb.com/hanadb-quickstart created Here, @@ -101,18 +101,19 @@ governing (headless) `Service`, an authentication `Secret`, and an `AppBinding` ## Wait for the Database to be Ready ```bash -$ kubectl get hanadb.kubedb.com -n demo hanadb-quickstart -w +kubectl get hanadb.kubedb.com -n demo hanadb-quickstart -w +``` NAME VERSION STATUS AGE hanadb-quickstart 2.0.82 Provisioning 2m hanadb-quickstart 2.0.82 Provisioning 18m hanadb-quickstart 2.0.82 Ready 19m -``` When `status.phase` becomes `Ready`, the database is ready for traffic. Let's look at the details with `kubectl describe`: ```bash -$ kubectl describe hanadb.kubedb.com -n demo hanadb-quickstart +kubectl describe hanadb.kubedb.com -n demo hanadb-quickstart +``` Name: hanadb-quickstart Namespace: demo API Version: kubedb.com/v1alpha2 @@ -173,7 +174,6 @@ Status: Status: True Type: Provisioned Phase: Ready -``` Note that KubeDB filled in sensible defaults — for example the default resources on the `hanadb` container and the `12000:79` security context derived from the `HanaDBVersion`. @@ -181,7 +181,8 @@ container and the `12000:79` security context derived from the `HanaDBVersion`. ## Check Resources Created by KubeDB ```bash -$ kubectl get hanadb.kubedb.com,pods,pvc,svc -n demo -l app.kubernetes.io/instance=hanadb-quickstart +kubectl get hanadb.kubedb.com,pods,pvc,svc -n demo -l app.kubernetes.io/instance=hanadb-quickstart +``` NAME VERSION STATUS AGE hanadb.kubedb.com/hanadb-quickstart 2.0.82 Ready 19m @@ -194,7 +195,6 @@ persistentvolumeclaim/data-hanadb-quickstart-0 Bound pvc-83118378-1265-4843 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/hanadb-quickstart ClusterIP 10.43.188.77 39017/TCP 6m33s service/hanadb-quickstart-pods ClusterIP None 39001/TCP,39017/TCP 6m33s -``` - `hanadb-quickstart` (port `39017`) is the primary SQL `Service`. - `hanadb-quickstart-pods` is the governing headless `Service` (nameserver port `39001`, SQL port `39017`). @@ -204,42 +204,44 @@ service/hanadb-quickstart-pods ClusterIP None 39001/ KubeDB stores the `SYSTEM` user credentials in the `hanadb-quickstart-auth` Secret: ```bash -$ kubectl get secret -n demo hanadb-quickstart-auth -o jsonpath='{.type}' +kubectl get secret -n demo hanadb-quickstart-auth -o jsonpath='{.type}' +``` kubernetes.io/basic-auth -$ kubectl get secret -n demo hanadb-quickstart-auth -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +```bash +kubectl get secret -n demo hanadb-quickstart-auth -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +``` password password.json username -``` Read the password into a shell variable (avoid pasting real passwords into shared terminals): ```bash -$ HANA_PASSWORD="$(kubectl get secret hanadb-quickstart-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +HANA_PASSWORD="$(kubectl get secret hanadb-quickstart-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" ``` Run a query with `hdbsql` from inside the database pod. Source the HANA environment first: ```bash -$ kubectl exec -n demo hanadb-quickstart-0 -c hanadb -- /bin/sh -lc \ +kubectl exec -n demo hanadb-quickstart-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' 'SELECT 1 AS HELLO FROM DUMMY'" +``` HELLO 1 1 row selected (overall time 3143 usec; server time 158 usec) -``` List the databases inside the HANA instance: ```bash -$ kubectl exec -n demo hanadb-quickstart-0 -c hanadb -- /bin/sh -lc \ +kubectl exec -n demo hanadb-quickstart-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' \"SELECT DATABASE_NAME, ACTIVE_STATUS FROM SYS.M_DATABASES\"" +``` DATABASE_NAME,ACTIVE_STATUS "SYSTEMDB","YES" "HXE","YES" "KUBEDB_HEALTH_CHECK","YES" 3 rows selected -``` Here, `SYSTEMDB` is the HANA system database, `HXE` is the tenant database, and `KUBEDB_HEALTH_CHECK` is the tenant database KubeDB uses for its periodic write probe. @@ -249,9 +251,15 @@ is the tenant database KubeDB uses for its periodic write probe. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo hanadb.kubedb.com/hanadb-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete hanadb.kubedb.com -n demo hanadb-quickstart -$ kubectl delete ns demo +kubectl patch -n demo hanadb.kubedb.com/hanadb-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-quickstart +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/reconfigure/reconfigure.md b/docs/guides/hanadb/reconfigure/reconfigure.md index 871752e83b..91b2ce18f6 100644 --- a/docs/guides/hanadb/reconfigure/reconfigure.md +++ b/docs/guides/hanadb/reconfigure/reconfigure.md @@ -25,9 +25,9 @@ This guide shows how to change the custom `global.ini` configuration of a runnin - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Deploy a HanaDB @@ -64,9 +64,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/reconfigure/standalone-ops.yaml -hanadb.kubedb.com/hanadb-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/reconfigure/standalone-ops.yaml ``` +hanadb.kubedb.com/hanadb-standalone created Wait until `hanadb-standalone` is `Ready`. @@ -75,15 +75,17 @@ Wait until `hanadb-standalone` is `Ready`. Read the current value of `[memorymanager] global_allocation_limit`: ```bash -$ HANA_PASSWORD="$(kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +HANA_PASSWORD="$(kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +``` -$ kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ +```bash +kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' \ \"SELECT LAYER_NAME, VALUE FROM M_INIFILE_CONTENTS WHERE FILE_NAME='global.ini' AND SECTION='memorymanager' AND KEY='global_allocation_limit'\"" +``` LAYER_NAME,VALUE "DEFAULT","0" 1 row selected -``` The database starts with no custom override (only the `DEFAULT` layer, value `0` = HANA decides). @@ -113,9 +115,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/reconfigure/reconfigure.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-reconfigure created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/reconfigure/reconfigure.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-reconfigure created Here, @@ -129,13 +131,14 @@ Here, Wait for the ops request to reach `Successful`: ```bash -$ kubectl get hdbops -n demo hdbops-reconfigure +kubectl get hdbops -n demo hdbops-reconfigure +``` NAME TYPE STATUS AGE hdbops-reconfigure Reconfigure Successful 111s -``` ```bash -$ kubectl describe hdbops -n demo hdbops-reconfigure +kubectl describe hdbops -n demo hdbops-reconfigure +``` ... Status: Conditions: @@ -155,20 +158,19 @@ Status: Status: True Type: Successful Phase: Successful -``` Confirm the new value is live (it shows up under the `SYSTEM` layer once the pod has restarted with the updated configuration): ```bash -$ kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ +kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$HANA_PASSWORD' \ \"SELECT LAYER_NAME, VALUE FROM M_INIFILE_CONTENTS WHERE FILE_NAME='global.ini' AND SECTION='memorymanager' AND KEY='global_allocation_limit'\"" +``` LAYER_NAME,VALUE "DEFAULT","0" "SYSTEM","9663676416" 2 rows selected -``` The `SYSTEM` layer now carries the new value `9663676416` (9 GiB). @@ -178,9 +180,15 @@ To **remove** all custom configuration, set `spec.configuration.removeCustomConf ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-reconfigure -$ kubectl delete hanadb.kubedb.com -n demo hanadb-standalone -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-reconfigure +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/restart/restart.md b/docs/guides/hanadb/restart/restart.md index 158027a0a4..0a6887fb13 100644 --- a/docs/guides/hanadb/restart/restart.md +++ b/docs/guides/hanadb/restart/restart.md @@ -26,9 +26,9 @@ restarted last** to minimize avoidable failovers. - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Deploy a HanaDB System Replication Cluster @@ -68,19 +68,19 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/restart/system-replication-ops.yaml -hanadb.kubedb.com/hanadb-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/restart/system-replication-ops.yaml ``` +hanadb.kubedb.com/hanadb-cluster created Wait until `hanadb-cluster` is `Ready`. Note the current pod ages and which pod is primary: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE hanadb-cluster-0 2/2 Running 0 14m primary hanadb-cluster-1 2/2 Running 0 14m secondary hanadb-cluster-arbiter-0 1/1 Running 0 8m arbiter -``` ## Create a Restart HanaDBOpsRequest @@ -99,9 +99,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/restart/restart.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-restart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/restart/restart.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-restart created Here `spec.apply: Always` lets the restart proceed even if the database is not `Ready`, which is useful for recovering an unhealthy database. @@ -109,13 +109,14 @@ for recovering an unhealthy database. ## Verify the Restart ```bash -$ kubectl get hdbops -n demo hdbops-restart +kubectl get hdbops -n demo hdbops-restart +``` NAME TYPE STATUS AGE hdbops-restart Restart Successful 7m32s -``` ```bash -$ kubectl describe hdbops -n demo hdbops-restart +kubectl describe hdbops -n demo hdbops-restart +``` ... Status: Conditions: @@ -136,30 +137,37 @@ Status: Status: True Type: Successful Phase: Successful -``` The operator evicts the secondary (`hanadb-cluster-1`) first and the primary (`hanadb-cluster-0`) last. The pods now show a fresh age and the database is back to `Ready`. Note that restarting the old primary triggers a normal HANA SystemReplication takeover, so the `primary`/`secondary` roles may swap: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=hanadb-cluster -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE hanadb-cluster-0 2/2 Running 0 4m30s secondary hanadb-cluster-1 2/2 Running 0 7m16s primary hanadb-cluster-arbiter-0 1/1 Running 0 15m arbiter -$ kubectl get hanadb.kubedb.com -n demo hanadb-cluster +```bash +kubectl get hanadb.kubedb.com -n demo hanadb-cluster +``` NAME VERSION STATUS AGE hanadb-cluster 2.0.82 Ready 22m -``` ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-restart -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-restart +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/rotate-authentication/rotate-authentication.md b/docs/guides/hanadb/rotate-authentication/rotate-authentication.md index 247202f51c..811576018b 100644 --- a/docs/guides/hanadb/rotate-authentication/rotate-authentication.md +++ b/docs/guides/hanadb/rotate-authentication/rotate-authentication.md @@ -39,14 +39,16 @@ KubeDB-generated passwords already satisfy these rules. ## Check the Current Credentials ```bash -$ kubectl get secret hanadb-standalone-auth -n demo -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +kubectl get secret hanadb-standalone-auth -n demo -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +``` password password.json username -$ kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d; echo -SYSTEM +```bash +kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d; echo ``` +SYSTEM ## Option A — Rotate with a KubeDB-generated password @@ -67,20 +69,21 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/rotate-authentication/rotate-auth-generated.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-rotate-auth-generated created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/rotate-authentication/rotate-auth-generated.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-rotate-auth-generated created Wait for the ops request to succeed: ```bash -$ kubectl get hdbops -n demo hdbops-rotate-auth-generated +kubectl get hdbops -n demo hdbops-rotate-auth-generated +``` NAME TYPE STATUS AGE hdbops-rotate-auth-generated RotateAuth Successful 4m22s -``` ```bash -$ kubectl describe hdbops -n demo hdbops-rotate-auth-generated +kubectl describe hdbops -n demo hdbops-rotate-auth-generated +``` ... Status: Conditions: @@ -105,37 +108,41 @@ Status: Status: True Type: Successful Phase: Successful -``` KubeDB updates the `hanadb-standalone-auth` secret with the new password (keeping the previous one under `.prev` keys) and verifies connectivity with the new credentials: ```bash -$ kubectl get secret hanadb-standalone-auth -n demo -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +kubectl get secret hanadb-standalone-auth -n demo -o go-template='{{range $k,$v := .data}}{{$k}}{{"\n"}}{{end}}' +``` password password.json password.prev username username.prev -$ NEW_PASSWORD="$(kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" -$ kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ +```bash +NEW_PASSWORD="$(kubectl get secret hanadb-standalone-auth -n demo -o jsonpath='{.data.password}' | base64 -d)" +``` + +```bash +kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p '$NEW_PASSWORD' 'SELECT 1 AS OK FROM DUMMY'" +``` OK 1 1 row selected -``` ## Option B — Rotate with a user-provided password First create a `Secret` with the new credentials (username `SYSTEM`): ```bash -$ kubectl create secret generic hanadb-new-auth -n demo \ +kubectl create secret generic hanadb-new-auth -n demo \ --from-literal=username=SYSTEM \ --from-literal=password='NewHanaPass1' -secret/hanadb-new-auth created ``` +secret/hanadb-new-auth created Then reference it from the ops request: @@ -158,40 +165,49 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/rotate-authentication/rotate-auth-user.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-rotate-auth-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/rotate-authentication/rotate-auth-user.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-rotate-auth-user created ```bash -$ kubectl get hdbops -n demo hdbops-rotate-auth-user +kubectl get hdbops -n demo hdbops-rotate-auth-user +``` NAME TYPE STATUS AGE hdbops-rotate-auth-user RotateAuth Successful 2m33s -``` After the request succeeds, KubeDB pins `spec.authSecret` to your secret (`externallyManaged: true`): ```bash -$ kubectl get hanadb.kubedb.com hanadb-standalone -n demo -o jsonpath='{.spec.authSecret}' -{"activeFrom":"...","externallyManaged":true,"name":"hanadb-new-auth"} +kubectl get hanadb.kubedb.com hanadb-standalone -n demo -o jsonpath='{.spec.authSecret}' ``` +{"activeFrom":"...","externallyManaged":true,"name":"hanadb-new-auth"} You can now connect with the password you supplied: ```bash -$ kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ +kubectl exec -n demo hanadb-standalone-0 -c hanadb -- /bin/sh -lc \ "source /usr/sap/HXE/HDB90/HDBSettings.sh; hdbsql -i 90 -d SYSTEMDB -u SYSTEM -p 'NewHanaPass1' 'SELECT 1 AS OK FROM DUMMY'" +``` OK 1 1 row selected -``` ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-rotate-auth-generated hdbops-rotate-auth-user -$ kubectl delete secret -n demo hanadb-new-auth -$ kubectl delete hanadb.kubedb.com -n demo hanadb-standalone -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-rotate-auth-generated hdbops-rotate-auth-user +``` + +```bash +kubectl delete secret -n demo hanadb-new-auth +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/hanadb/scaling/vertical-scaling/vertical-scaling.md index 55bf22c49b..ec1ed101de 100644 --- a/docs/guides/hanadb/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/hanadb/scaling/vertical-scaling/vertical-scaling.md @@ -28,7 +28,8 @@ cluster). ## Check Resources Before Scaling ```bash -$ kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | select(.name=="hanadb") | .resources' +kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | select(.name=="hanadb") | .resources' +``` { "limits": { "cpu": "4", @@ -39,7 +40,6 @@ $ kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | se "memory": "8Gi" } } -``` ## Create a VerticalScaling HanaDBOpsRequest @@ -67,9 +67,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/scaling/system-replication-vertical-scaling.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/scaling/system-replication-vertical-scaling.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-vscale created Here, @@ -80,13 +80,14 @@ Here, ## Verify the Scaling ```bash -$ kubectl get hdbops -n demo hdbops-vscale +kubectl get hdbops -n demo hdbops-vscale +``` NAME TYPE STATUS AGE hdbops-vscale VerticalScaling Successful 4m22s -``` ```bash -$ kubectl describe hdbops -n demo hdbops-vscale +kubectl describe hdbops -n demo hdbops-vscale +``` ... Status: Conditions: @@ -107,16 +108,18 @@ Status: Status: True Type: Successful Phase: Successful -``` Confirm the new resources are in effect on the PetSet and pods: ```bash -$ kubectl get petset -n demo hanadb-cluster \ +kubectl get petset -n demo hanadb-cluster \ -o jsonpath='{range .spec.template.spec.containers[?(@.name=="hanadb")]}{.name}{": "}{.resources}{"\n"}{end}' +``` hanadb: {"limits":{"cpu":"4","memory":"14Gi"},"requests":{"cpu":"2100m","memory":"8448Mi"}} -$ kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | select(.name=="hanadb") | .resources' +```bash +kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | select(.name=="hanadb") | .resources' +``` { "limits": { "cpu": "4", @@ -127,14 +130,19 @@ $ kubectl get pod -n demo hanadb-cluster-0 -o json | jq '.spec.containers[] | se "memory": "8448Mi" } } -``` ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-vscale -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-vscale +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/storage-migration/storage-migration.md b/docs/guides/hanadb/storage-migration/storage-migration.md index e29c9d4be1..f728a340f2 100644 --- a/docs/guides/hanadb/storage-migration/storage-migration.md +++ b/docs/guides/hanadb/storage-migration/storage-migration.md @@ -45,8 +45,11 @@ parameters: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/longhorn-single.yaml -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/longhorn-single-migrated.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/longhorn-single.yaml +``` + +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/longhorn-single-migrated.yaml ``` ## Deploy a HanaDB on the Source StorageClass @@ -55,20 +58,20 @@ The base manifest places the data on `longhorn-single` and adds an init containe permissions (HANA runs as `12000:79`): ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/storage-migration-base.yaml -hanadb.kubedb.com/hanadb-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/storage-migration-base.yaml ``` +hanadb.kubedb.com/hanadb-cluster created Wait until `hanadb-cluster` is `Ready`, then note the source StorageClass of the PVCs: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-hanadb-cluster-0 longhorn-single 64Gi data-hanadb-cluster-1 longhorn-single 64Gi data-hanadb-cluster-arbiter-0 longhorn-single 2Gi -``` ## Create a StorageMigration HanaDBOpsRequest @@ -89,9 +92,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/storage-migration.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-storage-migration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/storage-migration/storage-migration.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-storage-migration created Here, @@ -101,13 +104,14 @@ Here, ## Verify the Migration ```bash -$ kubectl get hdbops -n demo hdbops-storage-migration +kubectl get hdbops -n demo hdbops-storage-migration +``` NAME TYPE STATUS AGE hdbops-storage-migration StorageMigration Successful 14m -``` ```bash -$ kubectl describe hdbops -n demo hdbops-storage-migration +kubectl describe hdbops -n demo hdbops-storage-migration +``` ... Status: Conditions: @@ -120,31 +124,38 @@ Status: Status: True Type: Successful Phase: Successful -``` KubeDB migrates the data PVCs one node at a time (the primary last); the small arbiter volume is left on its original StorageClass. Confirm the data PVCs are now bound to the target StorageClass and the database is `Ready`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-hanadb-cluster-0 longhorn-single-migrated 64Gi data-hanadb-cluster-1 longhorn-single-migrated 64Gi data-hanadb-cluster-arbiter-0 longhorn-single 2Gi -$ kubectl get hanadb.kubedb.com -n demo hanadb-cluster +```bash +kubectl get hanadb.kubedb.com -n demo hanadb-cluster +``` NAME VERSION STATUS AGE hanadb-cluster 2.0.82 Ready 26m -``` ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-storage-migration -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-storage-migration +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/tls/overview.md b/docs/guides/hanadb/tls/overview.md index 0ecf9a1845..b39082f9a2 100644 --- a/docs/guides/hanadb/tls/overview.md +++ b/docs/guides/hanadb/tls/overview.md @@ -28,9 +28,9 @@ running database with a `HanaDBOpsRequest`. - Create a namespace: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## How TLS works in HanaDB @@ -50,11 +50,14 @@ their **alias**: These guides use a self-signed CA `Issuer`. First create a CA key pair and a `Secret`, then an `Issuer` that signs with it. -```bash # generate a CA -$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=ca/O=kubedb" +```bash +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=ca/O=kubedb" +``` + # store it as a Secret -$ kubectl create secret tls hdb-ca --cert=ca.crt --key=ca.key -n demo +```bash +kubectl create secret tls hdb-ca --cert=ca.crt --key=ca.key -n demo ``` ```yaml @@ -69,9 +72,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/hdb-ca-issuer.yaml -issuer.cert-manager.io/hdb-ca-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/hdb-ca-issuer.yaml ``` +issuer.cert-manager.io/hdb-ca-issuer created ## Option A — Deploy a HanaDB with TLS enabled @@ -107,9 +110,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/system-replication-tls.yaml -hanadb.kubedb.com/hanadb-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/system-replication-tls.yaml ``` +hanadb.kubedb.com/hanadb-cluster created ## Option B — Add TLS to a running HanaDB (ReconfigureTLS) @@ -135,9 +138,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/reconfigure-add-tls.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/reconfigure-add-tls.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-add-tls created > `ReconfigureTLS` performs a **rolling restart** of the HANA pods to load the new certificates. Request > success alone is not enough — verify the database returns to `Ready` and that TLS connections work. @@ -145,13 +148,14 @@ hanadbopsrequest.ops.kubedb.com/hdbops-add-tls created Wait for the ops request to succeed: ```bash -$ kubectl get hdbops -n demo hdbops-add-tls +kubectl get hdbops -n demo hdbops-add-tls +``` NAME TYPE STATUS AGE hdbops-add-tls ReconfigureTLS Successful 7m -``` ```bash -$ kubectl describe hdbops -n demo hdbops-add-tls +kubectl describe hdbops -n demo hdbops-add-tls +``` ... Status: Conditions: @@ -174,14 +178,14 @@ Status: Reason: Successful Type: Successful Phase: Successful -``` ## Verify TLS Confirm the certificates and secrets exist, and that the server cert is mounted: ```bash -$ kubectl get issuer,certificate -n demo +kubectl get issuer,certificate -n demo +``` NAME READY AGE issuer.cert-manager.io/hdb-ca-issuer True 10m @@ -190,22 +194,23 @@ certificate.cert-manager.io/hanadb-cluster-client-cert True hanad certificate.cert-manager.io/hanadb-cluster-metrics-exporter-cert True hanadb-cluster-metrics-exporter-cert 3m certificate.cert-manager.io/hanadb-cluster-server-cert True hanadb-cluster-server-cert 3m -$ kubectl exec -n demo hanadb-cluster-1 -c hanadb -- /bin/sh -lc 'ls -l /etc/hanadb-tls/server' +```bash +kubectl exec -n demo hanadb-cluster-1 -c hanadb -- /bin/sh -lc 'ls -l /etc/hanadb-tls/server' +``` total 0 lrwxrwxrwx 1 root root ... ca.crt -> ..data/ca.crt lrwxrwxrwx 1 root root ... tls.crt -> ..data/tls.crt lrwxrwxrwx 1 root root ... tls.key -> ..data/tls.key -``` Verify the TLS handshake against the SQL port (`39017`) using `openssl s_client`: ```bash -$ kubectl run hdb-tls-check -n demo --rm -i --restart=Never --image=alpine:3.20 -- \ +kubectl run hdb-tls-check -n demo --rm -i --restart=Never --image=alpine:3.20 -- \ sh -lc "apk add --no-cache openssl >/dev/null && echo | openssl s_client -connect hanadb-cluster.demo.svc:39017 -servername hanadb-cluster.demo.svc" +``` ... New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 ... -``` The handshake completes over TLS 1.3, confirming the SQL port now requires TLS. (SAP HANA serves the SQL endpoint from its own internal PKI keystore, so the certificate subject shown by `openssl` is HANA's @@ -234,16 +239,19 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/reconfigure-rotate-tls.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/tls/reconfigure-rotate-tls.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-rotate-tls created KubeDB re-issues all three certificates from the same issuer and performs a rolling restart so the pods pick up the new material. Track the request and confirm the database returns to `Ready`: ```bash -$ kubectl get hdbops -n demo hdbops-rotate-tls -$ kubectl get hanadb.kubedb.com -n demo hanadb-cluster +kubectl get hdbops -n demo hdbops-rotate-tls +``` + +```bash +kubectl get hanadb.kubedb.com -n demo hanadb-cluster ``` > After a certificate rotation on a System Replication cluster, verify that a `primary` role is @@ -261,10 +269,19 @@ database it restores HANA's built-in ClientPKI. Either way the pods are restarte ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-add-tls hdbops-rotate-tls -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete issuer -n demo hdb-ca-issuer -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-add-tls hdbops-rotate-tls +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete issuer -n demo hdb-ca-issuer +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hanadb/volume-expansion/volume-expansion.md b/docs/guides/hanadb/volume-expansion/volume-expansion.md index 52139ea2b5..9feb59c746 100644 --- a/docs/guides/hanadb/volume-expansion/volume-expansion.md +++ b/docs/guides/hanadb/volume-expansion/volume-expansion.md @@ -26,11 +26,11 @@ This guide shows how to grow the data volumes of a HanaDB using a `HanaDBOpsRequ Verify this before you start: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 19d longhorn-single driver.longhorn.io Delete Immediate true 1h -``` > The `local-path` provisioner used in the other guides does **not** support volume expansion > (`ALLOWVOLUMEEXPANSION` is `false`). For this guide, deploy the database on an expansion-capable @@ -77,20 +77,20 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/volume-expansion/system-replication-ops.yaml -hanadb.kubedb.com/hanadb-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/volume-expansion/system-replication-ops.yaml ``` +hanadb.kubedb.com/hanadb-cluster created Wait until `hanadb-cluster` is `Ready`, then check the current PVC sizes: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-hanadb-cluster-0 longhorn-single 64Gi data-hanadb-cluster-1 longhorn-single 64Gi data-hanadb-cluster-arbiter-0 longhorn-single 2Gi -``` ## Create a VolumeExpansion HanaDBOpsRequest @@ -112,9 +112,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/volume-expansion/volume-expansion.yaml -hanadbopsrequest.ops.kubedb.com/hdbops-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hanadb/volume-expansion/volume-expansion.yaml ``` +hanadbopsrequest.ops.kubedb.com/hdbops-volume-expansion created Here, @@ -125,13 +125,14 @@ Here, ## Verify the Expansion ```bash -$ kubectl get hdbops -n demo hdbops-volume-expansion +kubectl get hdbops -n demo hdbops-volume-expansion +``` NAME TYPE STATUS AGE hdbops-volume-expansion VolumeExpansion Successful 2m36s -``` ```bash -$ kubectl describe hdbops -n demo hdbops-volume-expansion +kubectl describe hdbops -n demo hdbops-volume-expansion +``` ... Status: Conditions: @@ -152,25 +153,30 @@ Status: Status: True Type: Successful Phase: Successful -``` Confirm the data PVCs grew to the requested size (the small arbiter volume is unchanged): ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ +kubectl get pvc -n demo -l app.kubernetes.io/instance=hanadb-cluster \ -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-hanadb-cluster-0 longhorn-single 65Gi data-hanadb-cluster-1 longhorn-single 65Gi data-hanadb-cluster-arbiter-0 longhorn-single 2Gi -``` ## Cleaning Up ```bash -$ kubectl delete hdbops -n demo hdbops-volume-expansion -$ kubectl delete hanadb.kubedb.com -n demo hanadb-cluster -$ kubectl delete ns demo +kubectl delete hdbops -n demo hdbops-volume-expansion +``` + +```bash +kubectl delete hanadb.kubedb.com -n demo hanadb-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/hazelcast/autoscaler/compute/hazelcast-compute.md b/docs/guides/hazelcast/autoscaler/compute/hazelcast-compute.md index 3658fa6a70..815514ab32 100644 --- a/docs/guides/hazelcast/autoscaler/compute/hazelcast-compute.md +++ b/docs/guides/hazelcast/autoscaler/compute/hazelcast-compute.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](/docs/examples/hazelcast) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -89,26 +89,27 @@ spec: Let's create the `Hazelcast` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-dev created Now, wait until `hazelcast-dev` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo -w +kubectl get hz -n demo -w +``` NAME TYPE VERSION STATUS AGE hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 0s hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 24s . . hazelcast-dev kubedb.com/v1alpha2 5.5.2 Ready 92s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -118,11 +119,11 @@ $ kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resou "memory": "1Gi" } } -``` Let's check the Hazelcast resources, ```bash -$ kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -132,7 +133,6 @@ $ kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.sp "memory": "1Gi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the hazelcast. @@ -191,16 +191,17 @@ Here, Let's create the `HazelcastAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/compute/hazelcast-autoscaler.yaml -hazelcastautoscaler.autoscaling.kubedb.com/hz-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/compute/hazelcast-autoscaler.yaml ``` +hazelcastautoscaler.autoscaling.kubedb.com/hz-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `hazelcastautoscaler` resource is created successfully, ```bash -$ kubectl describe hazelcastautoscaler hz--autoscaler -n demo +kubectl describe hazelcastautoscaler hz--autoscaler -n demo +``` Name: hz-autoscaler Namespace: demo Labels: @@ -291,8 +292,6 @@ Status: Memory: 2Gi Vpa Name: hazelcast-dev Events: - -``` So, the `hazelcastautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `hazelcastopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. @@ -300,24 +299,25 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `hazelcastopsrequest` in the demo namespace to see if any `hazelcastopsrequest` object is created. After some time you'll see that a `hazelcastopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get hazelcastopsrequest -n demo +watch kubectl get hazelcastopsrequest -n demo +``` Every 2.0s: kubectl get hazelcastopsrequest -n demo NAME TYPE STATUS AGE hzops-hazelcast-dev-68lrza VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hzops-hazelcast-dev-68lrza VerticalScaling Successful 3m2s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$kubectl describe hzops -n demo hzops-hazelcast-dev-68lrza +kubectl describe hzops -n demo hzops-hazelcast-dev-68lrza +``` Name: hzops-hazelcast-dev-68lrza Namespace: demo Labels: app.kubernetes.io/component=database @@ -421,12 +421,12 @@ Events: Normal RestartPods 2m27s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 2m27s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hazelcast-dev Normal Successful 2m27s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hazelcast-dev for HazelcastOpsRequest: hzops-hazelcast-dev-68lrza -``` Now, we are going to verify from the Pod, and the Hazelcast yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1717986918" @@ -437,9 +437,9 @@ $ kubectl get pod -n demo hazelcast-dev-0 -o json | jq '.spec.containers[].resou } } - - -$ kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +```bash +kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1717986918" @@ -450,8 +450,6 @@ $ kubectl get hazelcast -n demo hazelcast-dev -o json | jq '.spec.podTemplate.sp } } -``` - The above output verifies that we have successfully auto-scaled the resources of the Hazelcast cluster. diff --git a/docs/guides/hazelcast/autoscaler/storage/hazelcast-storage.md b/docs/guides/hazelcast/autoscaler/storage/hazelcast-storage.md index 20c382d216..82a003498a 100644 --- a/docs/guides/hazelcast/autoscaler/storage/hazelcast-storage.md +++ b/docs/guides/hazelcast/autoscaler/storage/hazelcast-storage.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Hazel To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](/docs/examples/hazelcast) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,10 +48,10 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -96,33 +96,35 @@ spec: Let's create the `Hazelcast` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-dev created Now, wait until `hazelcast-dev` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo -w +kubectl get hz -n demo -w +``` NAME TYPE VERSION STATUS AGE hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 0s hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 24s . . hazelcast-dev kubedb.com/v1alpha2 5.5.2 Ready 92s -``` Let's check volume size from statefulset, and from the persistent volume, ```bash -$ kubectl get statefulset -n demo hazelcast-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get statefulset -n demo hazelcast-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 1Gi RWO Delete Bound demo/hazelcast-dev-data-hazelcast-dev-0 longhorn 40s pvc-f068d245-718b-4561-b452-f3130bb260f6 1Gi RWO Delete Bound demo/hazelcast-dev-data-hazelcast-dev-1 longhorn 35s -``` You can see the statefulset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -168,9 +170,9 @@ Here, Let's create the `HazelcastAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/storage/hazelcast-storage-autoscaler.yaml -hazelcastautoscaler.autoscaling.kubedb.com/hz-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/autoscaler/storage/hazelcast-storage-autoscaler.yaml ``` +hazelcastautoscaler.autoscaling.kubedb.com/hz-storage-autoscaler created #### Storage Autoscaling is set up successfully @@ -232,8 +234,9 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the cluster pod and fill the cluster volume using the following commands: -```bash - $ kubectl exec -it -n demo hazelcast-dev-0 -- bash + ```bash + kubectl exec -it -n demo hazelcast-dev-0 -- bash + ``` hazelcast@hazelcast-dev-0:~$ df -h /data/hazelcast Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 974M 168K 958M 1% /data/hazelcast @@ -244,31 +247,31 @@ hazelcast@hazelcast-dev-0:~$ dd if=/dev/zero of=/data/hazelcast/file.img bs=600M hazelcast@hazelcast-dev-0:~$ df -h /data/hazelcast Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 974M 601M 358M 63% /data/hazelcast -``` So, from the above output we can see that the storage usage is 63%, which exceeded the `usageThreshold` 1%. Let's watch the `hazelcastopsrequest` in the demo namespace to see if any `hazelcastopsrequest` object is created. After some time you'll see that a `hazelcastopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get hazelcastopsrequest -n demo +watch kubectl get hazelcastopsrequest -n demo +``` Every 2.0s: kubectl get hazelcastopsrequest -n demo NAME TYPE STATUS AGE hzops-hazelcast-dev-a89pwf VolumeExpansion Progressing 111s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hzops-hazelcast-dev-sa4thn VolumeExpansion Successful 97s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe hzops -n demo hzops-hazelcast-dev-a89pwf +kubectl describe hzops -n demo hzops-hazelcast-dev-a89pwf +``` Name: hzops-hazelcast-dev-a89pwf Namespace: demo Labels: app.kubernetes.io/component=database @@ -419,18 +422,19 @@ Events: Warning get stateful set; ConditionStatus:True 65s KubeDB Ops-manager Operator get stateful set; ConditionStatus:True Normal ReadyStatefulSets 65s KubeDB Ops-manager Operator StatefulSet is recreated -``` - Now, we are going to verify from the `Statefulset`, and the `Persistent Volume` whether the volume of the cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get statefulset -n demo hazelcast-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get statefulset -n demo hazelcast-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1531054080" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 1462Mi RWO Delete Bound demo/hazelcast-dev-data-hazelcast-dev-0 longhorn 30m5s pvc-f068d245-718b-4561-b452-f3130bb260f6 1462Mi RWO Delete Bound demo/hazelcast-dev-data-hazelcast-dev-1 longhorn 30m1s -``` The above output verifies that we have successfully autoscaled the volume of the Hazelcast cluster. diff --git a/docs/guides/hazelcast/concepts/hazelcast.md b/docs/guides/hazelcast/concepts/hazelcast.md index 3c8d4b4d9e..7b0320e561 100644 --- a/docs/guides/hazelcast/concepts/hazelcast.md +++ b/docs/guides/hazelcast/concepts/hazelcast.md @@ -181,11 +181,11 @@ AuthSecret contains a `username` key and a `password` key which contains the `us Example: ```bash -$ kubectl create secret generic hazelcast-sample-auth -n demo \ +kubectl create secret generic hazelcast-sample-auth -n demo \ --from-literal=username=admin \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "hazelcast-sample-auth" created ``` +secret "hazelcast-sample-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/hazelcast/configuration/hazelcast-config.md b/docs/guides/hazelcast/configuration/hazelcast-config.md index a605138b49..a9d26dd4d5 100644 --- a/docs/guides/hazelcast/configuration/hazelcast-config.md +++ b/docs/guides/hazelcast/configuration/hazelcast-config.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast/configuration/ ) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Hazelcast CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -83,9 +85,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/configuration/configsecret.yaml -secret/hz created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/configuration/configsecret.yaml ``` +secret/hz created Before deploying hazelcast we need to create license secret since we are running enterprise version of hazelcast. ```bash @@ -121,21 +123,21 @@ spec: Now, create the Hazelcast object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/configuration/hazelcast-config.yaml -hazelcast.kubedb.com/hazelcast-dev created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/configuration/hazelcast-config.yaml ``` +hazelcast.kubedb.com/hazelcast-dev created Now, wait for the Hazelcast to become ready: ```bash -$ kubectl get hz -n demo -w +kubectl get hz -n demo -w +``` NAME TYPE VERSION STATUS AGE hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 0s hazelcast-dev kubedb.com/v1alpha2 5.5.2 Provisioning 24s . . hazelcast-dev kubedb.com/v1alpha2 5.5.2 Ready 92s -``` ## Verify Configuration @@ -144,9 +146,9 @@ Let's exec into one of the hazelcast pod that we have created and check the conf Exec into the Hazelcast pod: ```bash -$ kubectl exec -it -n demo hazelcast-dev-0 -- bash -hazelcast@hazelcast-dev-0:~$ +kubectl exec -it -n demo hazelcast-dev-0 -- bash ``` +hazelcast@hazelcast-dev-0:~$ Now, execute the following commands to see the configurations: ```bash @@ -166,9 +168,15 @@ Here, we can see that our given persistence configuration is applied to the Haze To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete hz -n demo hazelcast-dev -$ kubectl delete secret -n demo hz -$ kubectl delete namespace demo +kubectl delete hz -n demo hazelcast-dev +``` + +```bash +kubectl delete secret -n demo hz +``` + +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/hazelcast/monitoring/prometheus-builtin.md b/docs/guides/hazelcast/monitoring/prometheus-builtin.md index c1eb211a72..a4576aaa05 100644 --- a/docs/guides/hazelcast/monitoring/prometheus-builtin.md +++ b/docs/guides/hazelcast/monitoring/prometheus-builtin.md @@ -33,12 +33,14 @@ This tutorial will show you how to monitor Hazelcast database using builtin [Pro - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -82,32 +84,33 @@ Here, Let's create the Hazelcast crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/monitoring/hazelcast-builtin.yaml -hazelcast.kubedb.com/builtin-prom-hz created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/monitoring/hazelcast-builtin.yaml ``` +hazelcast.kubedb.com/builtin-prom-hz created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE builtin-prom-hz kubedb.com/v1alpha2 5.5.2 Ready 59m -``` KubeDB will create a separate stats service with name `{Hazelcast crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo -l 'app.kubernetes.io/instance=builtin-prom-hz' +kubectl get svc -n demo -l 'app.kubernetes.io/instance=builtin-prom-hz' +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-hz ClusterIP 10.43.10.145 5701/TCP 39m builtin-prom-hz-pods ClusterIP None 5701/TCP 39m builtin-prom-hz-stats ClusterIP 10.43.234.9 56790/TCP 39m -``` Here, `builtin-prom-hz-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-hz-stats +kubectl describe svc -n demo builtin-prom-hz-stats +``` Name: builtin-prom-hz-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -131,7 +134,6 @@ Endpoints: 10.42.0.67:56790,10.42.0.68:56790,10.42.0.69:56790 Session Affinity: None Internal Traffic Policy: Cluster Events: -``` You can see that the service contains following annotations. @@ -295,20 +297,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -319,9 +321,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -330,18 +332,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-7479654b9-bwx8f 1/1 Running 0 60m -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7479654b9-bwx8f` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-7479654b9-bwx8f 9090 +kubectl port-forward -n monitoring prometheus-7479654b9-bwx8f 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-hz-stats` service as one of the targets. @@ -358,14 +360,29 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo es/builtin-prom-es +kubectl delete -n demo es/builtin-prom-es +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` \ No newline at end of file diff --git a/docs/guides/hazelcast/monitoring/prometheus-operator.md b/docs/guides/hazelcast/monitoring/prometheus-operator.md index 2862bd640d..1169034d1e 100644 --- a/docs/guides/hazelcast/monitoring/prometheus-operator.md +++ b/docs/guides/hazelcast/monitoring/prometheus-operator.md @@ -28,13 +28,15 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. -```bash - $ kubectl create ns monitoring + ```bash + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -49,17 +51,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus -A +kubectl get prometheus -A +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 11d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -180,7 +183,6 @@ status: shards: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.labels` field of Hazelcast crd. @@ -226,34 +228,35 @@ Here, Let's create the Hazelcast object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/monitoring/hazelcast-operator.yaml -hazelcast.kubedb.com/operator-prom-hz created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/monitoring/hazelcast-operator.yaml ``` +hazelcast.kubedb.com/operator-prom-hz created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE operator-prom-hz kubedb.com/v1alpha2 5.5.2 Ready 55m -``` KubeDB will create a separate stats service with name `{Hazelcast crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo -l 'app.kubernetes.io/instance=operator-prom-hz' +kubectl get svc -n demo -l 'app.kubernetes.io/instance=operator-prom-hz' +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE operator-prom-hz ClusterIP 10.43.177.245 5701/TCP 56m operator-prom-hz-pods ClusterIP None 5701/TCP 56m operator-prom-hz-stats ClusterIP 10.43.64.206 56790/TCP 56m -``` Here, `operator-prom-hz-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo operator-prom-hz-stats +kubectl describe svc -n demo operator-prom-hz-stats +``` Name: operator-prom-hz-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -274,22 +277,22 @@ Endpoints: 10.42.0.58:56790,10.42.0.59:56790,10.42.0.60:56790 Session Affinity: None Internal Traffic Policy: Cluster Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `operator-prom-hz-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE operator-prom-hz-stats 125m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Hazelcast crd. ```bash -$ kubectl get servicemonitor -n demo operator-prom-hz-stats -oyaml +kubectl get servicemonitor -n demo operator-prom-hz-stats -oyaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -328,7 +331,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: hazelcasts.kubedb.com kubedb.com/role: stats -``` Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in Hazelcast crd. @@ -339,7 +341,8 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring +kubectl get pod -n monitoring +``` NAME READY STATUS RESTARTS AGE alertmanager-prometheus-kube-prometheus-alertmanager-0 2/2 Running 0 13d prometheus-grafana-6956bd7864-lggrr 3/3 Running 0 13d @@ -348,20 +351,17 @@ prometheus-kube-state-metrics-f8fc86d54-x8qjk 1/1 Running 0 prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 13d prometheus-prometheus-node-exporter-szndm 1/1 Running 0 13d -``` - Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 Handling connection for 9090 -``` - Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `operator-prom-hz-stats` service as one of the targets.

diff --git a/docs/guides/hazelcast/quickstart/overview/index.md b/docs/guides/hazelcast/quickstart/overview/index.md index ea653e9093..a4b805dd4f 100644 --- a/docs/guides/hazelcast/quickstart/overview/index.md +++ b/docs/guides/hazelcast/quickstart/overview/index.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [docs/guides/hazelcast/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ demo Active 9s We will have to provide `StorageClass` in Hazelcast CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -58,10 +60,10 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named `HazelcastVersions`. The installation process comes with a set of tested HazelcastVersion objects. Let's check available HazelcastVersions by, ```bash -$ kubectl get hzversion +kubectl get hzversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 5.5.2 5.5.2 hazelcast/hazelcast-enterprise:5.5.2 148m -``` Notice the `DEPRECATED` column. Here, `true` means that this HazelcastVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated HazelcastVersion. @@ -120,24 +122,24 @@ Here, Let's create the Hazelcast CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-sample created The Hazelcast's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get hazelcast -n demo +kubectl get hazelcast -n demo +``` NAME TYPE VERSION STATUS AGE hazelcast-sample kubedb.com/v1alpha2 5.5.2 Ready 3m -``` - Describe the Hazelcast object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe hz hazelcast-sample -n demo +kubectl describe hz hazelcast-sample -n demo +``` Name: hazelcast-sample Namespace: demo Labels: @@ -278,14 +280,14 @@ Status: Type: DatabaseReadAccess Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a Hazelcast CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=hazelcast-sample' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=hazelcast-sample' +``` NAME READY STATUS RESTARTS AGE pod/hazelcast-sample-0 1/1 Running 0 76m pod/hazelcast-sample-1 1/1 Running 0 75m @@ -309,7 +311,6 @@ NAME STATUS VOLUME persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-0 Bound pvc-d88feaed-2680-44f5-b2ac-5f5ec8216db8 2Gi RWO standard 76m persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-1 Bound pvc-970da06b-a76e-442f-8350-97603efbe9df 2Gi RWO standard 75m persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-2 Bound pvc-3bd48f9c-14f9-40af-ba5d-1e0ed6538722 2Gi RWO standard 74m -``` - `StatefulSet` - a StatefulSet named after the Hazelcast instance. In topology mode, the operator creates 3 PetSets with name `{Hazelcast-Name}`. - `Services` - 2 services are generated for each Hazelcast database. @@ -327,11 +328,11 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `8983` to local machine: ```bash -$ kubectl port-forward -n demo svc/hazelcast-sample 5701 +kubectl port-forward -n demo svc/hazelcast-sample 5701 +``` Forwarding from 127.0.0.1:5701 -> 5701 Forwarding from [::1]:5701 -> 5701 Handling connection for 5701 -``` Now, our Hazelcast cluster is accessible at `localhost:5701`. @@ -341,21 +342,22 @@ Now, our Hazelcast cluster is accessible at `localhost:5701`. - Username: ```bash - $ kubectl get secret -n demo hazelcast-sample-auth -o jsonpath='{.data.username}' | base64 -d + kubectl get secret -n demo hazelcast-sample-auth -o jsonpath='{.data.username}' | base64 -d + ``` admin - ``` - Password: ```bash - $ kubectl get secret -n demo hazelcast-sample-auth -o jsonpath='{.data.password}' | base64 -d - v_;HzZUg3;un~fIs + kubectl get secret -n demo hazelcast-sample-auth -o jsonpath='{.data.password}' | base64 -d ``` + v_;HzZUg3;un~fIs Now let's check the health of our Hazelcast database. ```bash -$ curl -XGET -k -u 'admin:v_;HzZUg3;un~fIs' "http://localhost:5701/hazelcast/health" | jq +curl -XGET -k -u 'admin:v_;HzZUg3;un~fIs' "http://localhost:5701/hazelcast/health" | jq +``` { "nodeState": "ACTIVE", "clusterState": "ACTIVE", @@ -364,8 +366,6 @@ $ curl -XGET -k -u 'admin:v_;HzZUg3;un~fIs' "http://localhost:5701/hazelcast/hea "clusterSize": 3 } -``` - ## Halt Hazelcast KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` deletion policy. If admission webhook is enabled, it prevents the user from deleting the database as long as the `spec.deletionPolicy` is set `DoNotTerminate`. @@ -373,21 +373,22 @@ KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or lat To halt the database, we have to set `spec.deletionPolicy:` to `Halt` by updating it, ```bash -$ kubectl patch -n demo hazelcast hazelcast-sample -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -hazelcast.kubedb.com/hazelcast-sample patched +kubectl patch -n demo hazelcast hazelcast-sample -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +hazelcast.kubedb.com/hazelcast-sample patched Now, if you delete the Hazelcast object, the KubeDB operator will delete every resource created for this Hazelcast CR, but leaves the auth secrets, and PVCs. ```bash -$ kubectl delete hazelcast -n demo hazelcast-sample -hazelcast.kubedb.com "hazelcast-sample" deleted + kubectl delete hazelcast -n demo hazelcast-sample ``` +hazelcast.kubedb.com "hazelcast-sample" deleted Check resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=hazelcast-sample' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=hazelcast-sample' +``` NAME TYPE DATA AGE secret/hazelcast-sample-auth kubernetes.io/basic-auth 2 109m secret/hazelcast-sample-config Opaque 2 98m @@ -396,7 +397,6 @@ NAME STATUS VOLUME persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-0 Bound pvc-d88feaed-2680-44f5-b2ac-5f5ec8216db8 2Gi RWO standard 98m persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-1 Bound pvc-970da06b-a76e-442f-8350-97603efbe9df 2Gi RWO standard 97m persistentvolumeclaim/hazelcast-sample-data-hazelcast-sample-2 Bound pvc-3bd48f9c-14f9-40af-ba5d-1e0ed6538722 2Gi RWO standard 96m -``` ## Resume Hazelcast @@ -405,24 +405,28 @@ Say, the Hazelcast CR was deleted with `spec.deletionPolicy` to `Halt` and you w You can do it by simpily re-deploying the original Hazelcast object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-sample created ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo hazelcast hazelcast-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo hazelcast hazelcast-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` hazelcast.kubedb.com/hazelcast-sample patched -$ kubectl delete -n demo hz/hazelcast-sample +```bash +kubectl delete -n demo hz/hazelcast-sample +``` hazelcast.kubedb.com "hazelcast-sample" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/hazelcast/reconfigure-tls/hazelcast.md b/docs/guides/hazelcast/reconfigure-tls/hazelcast.md index 60dde5a793..a7018268e2 100644 --- a/docs/guides/hazelcast/reconfigure-tls/hazelcast.md +++ b/docs/guides/hazelcast/reconfigure-tls/hazelcast.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -72,21 +72,21 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast.yaml -hazelcast.kubedb.com/hz-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast.yaml ``` +hazelcast.kubedb.com/hz-prod created Now, wait until `hz-prod` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo -w +kubectl get hz -n demo -w +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1 5.2.2 Provisioning 0s hz-prod kubedb.com/v1 5.2.2 Provisioning 9s . . hz-prod kubedb.com/v1 5.2.2 Ready 2m10s -``` Now, we can exec one hazelcast pod and verify configuration that the TLS is disabled. @@ -105,23 +105,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 hz-ca \ +kubectl create secret tls hz-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/hz-ca created ``` +secret/hz-ca created Now, Let's create an `Issuer` using the `hz-ca` secret that we have just created. The `YAML` file looks like this: @@ -139,9 +139,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-issuer.yaml -issuer.cert-manager.io/hz-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-issuer.yaml ``` +issuer.cert-manager.io/hz-issuer created ### Create HazelcastOpsRequest @@ -183,24 +183,25 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-add-tls.yaml -hazelcastopsrequest.ops.kubedb.com/hzops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-add-tls.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hzops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CRO, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hzops-add-tls ReconfigureTLS Successful 4m36s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe hazelcastopsrequest -n demo hzops-add-tls +kubectl describe hazelcastopsrequest -n demo hzops-add-tls +``` Name: hzops-add-tls Namespace: demo Labels: @@ -374,8 +375,6 @@ Events: Normal Starting 81s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 81s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hzops-add-tls -``` - Now, Let's exec into a hazelcast pod and verify the configuration that the TLS is enabled. ```bash @@ -429,24 +428,25 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-rotate.yaml -hazelcastopsrequest.ops.kubedb.com/hzops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-rotate.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hzops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CRO, ```bash -$ kubectl get hazelcastopsrequests -n demo hzops-rotate +kubectl get hazelcastopsrequests -n demo hzops-rotate +``` NAME TYPE STATUS AGE hzops-rotate ReconfigureTLS Successful 4m4s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe hazelcastopsrequest -n demo hzops-rotate +kubectl describe hazelcastopsrequest -n demo hzops-rotate +``` Name: hzops-rotate Namespace: demo Labels: @@ -610,18 +610,17 @@ Events: Normal RestartNodes 62s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 62s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 62s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hzops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -n demo hz-prod-0 -- /bin/sh -c '\ +kubectl exec -n demo hz-prod-0 -- /bin/sh -c '\ openssl s_client -connect localhost:5701 -showcerts < /dev/null 2>/dev/null | \ sed -ne "/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p" > /tmp/server.crt && \ openssl x509 -in /tmp/server.crt -noout -enddate' +``` Defaulted container "hazelcast" out of: hazelcast, hazelcast-init (init) notAfter=Nov 17 06:10:38 2025 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -632,23 +631,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 hz-new-ca \ +kubectl create secret tls hz-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/hz-new-ca created ``` +secret/hz-new-ca created Now, Let's create a new `Issuer` using the `hz-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -666,9 +665,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-new-issuer.yaml -issuer.cert-manager.io/hz-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-new-issuer.yaml ``` +issuer.cert-manager.io/hz-new-issuer created ### Create HazelcastOpsRequest @@ -700,24 +699,25 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-update-tls-issuer.yaml -Hazelcastopsrequest.ops.kubedb.com/hzops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-update-tls-issuer.yaml ``` +Hazelcastopsrequest.ops.kubedb.com/hzops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CRO, ```bash -$ kubectl get hazelcastopsrequests -n demo hzops-update-issuer +kubectl get hazelcastopsrequests -n demo hzops-update-issuer +``` NAME TYPE STATUS AGE hzops-update-issuer ReconfigureTLS Successful 8m6s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe hazelcastopsrequest -n demo hzops-update-issuer +kubectl describe hazelcastopsrequest -n demo hzops-update-issuer +``` Name: hzops-update-issuer Namespace: demo Labels: @@ -888,7 +888,6 @@ Events: Normal RestartNodes 2m32s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 2m32s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 2m32s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hzops-update-issuer -``` Now, Let's exec into a hazelcast server pod and find out the ca subject to see if it matches the one we have provided. @@ -942,25 +941,24 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-remove-tls.yaml -hazelcastopsrequest.ops.kubedb.com/hzops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/reconfigure-tls/hazelcast-remove-tls.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hzops-remove created #### Verify TLS Removed Successfully Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CRO, ```bash -$ kubectl get hazelcastopsrequest -n demo hzops-remove +kubectl get hazelcastopsrequest -n demo hzops-remove +``` NAME TYPE STATUS AGE hzops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe hazelcastopsrequest -n demo hzops-remove - +kubectl describe hazelcastopsrequest -n demo hzops-remove ``` Now, Let's exec into one of the broker node and find out that TLS is disabled or not. diff --git a/docs/guides/hazelcast/restart/hazelcast.md b/docs/guides/hazelcast/restart/hazelcast.md index ab25bbb010..ed145c4eef 100644 --- a/docs/guides/hazelcast/restart/hazelcast.md +++ b/docs/guides/hazelcast/restart/hazelcast.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Hazelcast database via a HazelcastOpsRequest. Res - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,9 +67,9 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/restart/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/restart/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-quickstart created ## Apply Restart opsRequest @@ -95,9 +95,9 @@ spec: Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/restart/ops.yaml -hazelcastopsrequest.ops.kubedb.com/hazelcast-restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/restart/ops.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hazelcast-restart created Now the Ops-manager operator will restart the hazelcast members as per the request. diff --git a/docs/guides/hazelcast/rotate-auth/hazelcast.md b/docs/guides/hazelcast/rotate-auth/hazelcast.md index 4a226a221a..fd5b02a045 100644 --- a/docs/guides/hazelcast/rotate-auth/hazelcast.md +++ b/docs/guides/hazelcast/rotate-auth/hazelcast.md @@ -25,28 +25,28 @@ section_menu_id: guides - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. - ```bash - $ kubectl get storageclasses + ```bash + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available HazelcastVersion When you have installed KubeDB, it has created `HazelcastVersion` CR for all supported Hazelcast versions. Check it by using the `kubectl get hazelcastversions` command. You can also use `hzversion` shorthand instead of `hazelcastversions`. ```bash -$ kubectl get hzversion +kubectl get hzversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 5.5.2 5.5.2 hazelcast/hazelcast-enterprise:5.5.2 3m52s 5.5.6 5.5.6 hazelcast/hazelcast-enterprise:5.5.6 3m52s -``` ## Create a Hazelcast server KubeDB implements a `Hazelcast` CRD to define the specification of a Hazelcast server. @@ -81,9 +81,9 @@ spec: ``` Let's create the Hazelcast CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/hazelcast/quickstart/overview/yamls/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-sample created ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an example showing how to retrieve the credentials from the Secret. @@ -97,12 +97,9 @@ pp5rmyri3A2SskRi⏎ ```` Now, you can exec into the pod `hazelcast-quickstart-0` and run a REST api using `username` and `password` ```bash - -$ kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'0TdsoNJez9zjJddh' http://localhost:5701/hazelcast/rest/cluster - -{"members":[{"address":"[10.244.0.21]:5701","liteMember":false,"localMember":true,"uuid":"f6c9c447-7abd-4254-9a52-3457f1e85713","memberVersion":"5.5.2"},{"address":"[10.244.0.23]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ - +kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'0TdsoNJez9zjJddh' http://localhost:5701/hazelcast/rest/cluster ``` +{"members":[{"address":"[10.244.0.21]:5701","liteMember":false,"localMember":true,"uuid":"f6c9c447-7abd-4254-9a52-3457f1e85713","memberVersion":"5.5.2"},{"address":"[10.244.0.23]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ If you can access the map and retrieve values using the REST API, it means the secrets are working correctly. ## Create RotateAuth HazelcastOpsRequest @@ -127,19 +124,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Hazelcast. Let's create the `HazelcastOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/hazelcast/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/hazelcast/rotate-auth/rotate-auth-generated.yaml + ``` hazelcastopsrequest.ops.kubedb.com/hzops-rotate-auth-generated created -``` Let's wait for `HazelcastOpsrequest` to be `Successful`. Run the following command to watch `HazelcastOpsrequest` CRO -```shell - $ kubectl get Hazelcastopsrequest -n demo + ```bash + kubectl get Hazelcastopsrequest -n demo + ``` NAME TYPE STATUS AGE hzops-rotate-auth-generated RotateAuth Successful 2m32s -``` If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Hazelcastopsrequest -n demo hzops-rotate-auth-generated +```bash +kubectl describe Hazelcastopsrequest -n demo hzops-rotate-auth-generated +``` Name: hzops-rotate-auth-generated Namespace: demo Labels: @@ -236,7 +234,6 @@ Events: Normal RestartNodes 3m3s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 3m3s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hazelcast-quickstart Normal Successful 3m3s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hazelcast-quickstart for HazelcastOpsRequest: hzops-rotate-auth-generated -``` **Verify Auth is rotated** ````shell $ kubectl get hz -n demo hazelcast-quickstart -ojson | jq .spec.authSecret.name @@ -248,21 +245,21 @@ CYIpaMGLwfHmvA!h ```` Now, you can exec into the pod `hazelcast-quickstart-0` and run a REST api using `username` and `password` ```bash -$ kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'CYIpaMGLwfHmvA!h' http://localhost:5701/hazelcast/rest/cluster -{"members":[{"address":"[10.244.0.25]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"},{"address":"[10.244.0.24]:5701","liteMember":false,"localMember":true,"uuid":"dc476cf0-74cd-4c8b-987c-c0bec27fbd26","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ +kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'CYIpaMGLwfHmvA!h' http://localhost:5701/hazelcast/rest/cluster ``` +{"members":[{"address":"[10.244.0.25]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"},{"address":"[10.244.0.24]:5701","liteMember":false,"localMember":true,"uuid":"dc476cf0-74cd-4c8b-987c-c0bec27fbd26","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ If you can access the map and retrieve values using the REST API, it means the secrets are working correctly. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > Note: The `username` must be fixed as `admin`. -```shell -$ kubectl create secret generic hazelcast-quickstart-usergen-auth -n demo \ +```bash +kubectl create secret generic hazelcast-quickstart-usergen-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=admin \ --from-literal=password=test-password -secret/hazelcast-quickstart-usergen-auth created ``` +secret/hazelcast-quickstart-usergen-auth created Now create a `HazelcastOpsRequest` with `RotateAuth` type. Below is the YAML of the `HazelcastOpsRequest` that we are going to create, ```shell apiVersion: ops.kubedb.com/v1alpha1 @@ -289,19 +286,20 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/hazelcast/rotate-auth/rotate-auth-user-generated.yaml -hazelcastopsrequest.ops.kubedb.com/hzops-rotate-auth-user-generated created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/hazelcast/rotate-auth/rotate-auth-user-generated.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hzops-rotate-auth-user-generated created Let's wait for `HazelcastOpsrequest` to be `Successful`. Run the following command to watch `HazelcastOpsrequest` CRO -```shell -$ kubectl get Hazelcastopsrequest -n demo +```bash +kubectl get Hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hzops-rotate-auth-user-generated RotateAuth Successful 2m32s -``` If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Hazelcastopsrequest -n demo hzops-rotate-auth-user-generated +```bash +kubectl describe Hazelcastopsrequest -n demo hzops-rotate-auth-user-generated +``` Name: hzops-rotate-auth-user-generated Namespace: demo Labels: @@ -401,7 +399,6 @@ Events: Normal RestartNodes 4m30s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 4m30s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hazelcast-quickstart Normal Successful 4m30s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hazelcast-quickstart for HazelcastOpsRequest: hzops-rotate-auth-user-generated -``` **Verify Auth is rotated** ````shell $ kubectl get hz -n demo hazelcast-quickstart -ojson | jq .spec.authSecret.name @@ -414,28 +411,43 @@ test-password⏎ Now, you can exec into the pod `hazelcast-quickstart-0` and run a REST api using `username` and `password` ```bash -$ kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'test-password' http://localhost:5701/hazelcast/rest/cluster -{"members":[{"address":"[10.244.0.26]:5701","liteMember":false,"localMember":true,"uuid":"dc476cf0-74cd-4c8b-987c-c0bec27fbd26","memberVersion":"5.5.2"},{"address":"[10.244.0.27]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ +kubectl exec -it -n demo hazelcast-quickstart-0 -c hazelcast -- curl -u admin:'test-password' http://localhost:5701/hazelcast/rest/cluster ``` +{"members":[{"address":"[10.244.0.26]:5701","liteMember":false,"localMember":true,"uuid":"dc476cf0-74cd-4c8b-987c-c0bec27fbd26","memberVersion":"5.5.2"},{"address":"[10.244.0.27]:5701","liteMember":false,"localMember":false,"uuid":"9490ac0d-6d0c-437d-898c-c6c6aa81402e","memberVersion":"5.5.2"}],"connectionCount":1,"allConnectionCount":2}⏎ If you can access the map and retrieve values using the REST API, it means the secrets are working correctly. Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo hazelcast-quickstart-usergen-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d +```bash +kubectl get secret -n demo hazelcast-quickstart-usergen-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d +``` CYIpaMGLwfHmvA!h⏎ -$ kubectl get secret -n demo hazelcast-quickstart-usergen-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d -admin⏎ + +```bash +kubectl get secret -n demo hazelcast-quickstart-usergen-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d ``` +admin⏎ ## Cleaning up To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Hazelcastopsrequest hzops-rotate-auth-generated hzops-rotate-auth-user-generated -n demo -$ kubectl delete secret -n demo hazelcast-quickstart-usergen-auth -$ kubectl delete secret -n demo hazelcast-quickstart-auth -$ kubectl delete hz -n demo hazelcast-quickstart -$ kubectl delete ns demo +```bash +kubectl delete Hazelcastopsrequest hzops-rotate-auth-generated hzops-rotate-auth-user-generated -n demo +``` + +```bash +kubectl delete secret -n demo hazelcast-quickstart-usergen-auth +``` + +```bash +kubectl delete secret -n demo hazelcast-quickstart-auth +``` + +```bash +kubectl delete hz -n demo hazelcast-quickstart +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/hazelcast/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/hazelcast/scaling/horizontal-scaling/horizontal-scaling.md index 96f90a119c..db702dd05d 100644 --- a/docs/guides/hazelcast/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/hazelcast/scaling/horizontal-scaling/horizontal-scaling.md @@ -30,9 +30,9 @@ This guide will give an overview on how KubeDB Ops-manager operator scales up or To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,30 +79,34 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hazelcast.yaml -hazelcast.kubedb.com/hz-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hazelcast.yaml ``` +hazelcast.kubedb.com/hz-prod created Now, wait until `hz-prod` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1alpha2 5.5.2 Ready 4m -``` Let's check the number of member nodes this database has from the Hazelcast object, number of pods the Statefulset have, ```bash -$ kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +``` 3 -$ kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +```bash +kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +``` 3 -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l -4 +```bash +kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l ``` +4 You can see from all the above outputs that the database has 3 member nodes. @@ -139,9 +143,9 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hz-hscale-up.yaml -hazelcastopsrequest.ops.kubedb.com/hz-hscale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hz-hscale-up.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hz-hscale-up created ### Verify hazelcast node scaled up successfully @@ -150,15 +154,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the number of Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CR, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hazelcast-scale-up HorizontalScaling Successful 2m5s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe hazelcastopsrequest -n demo hazelcast-scale-up +kubectl describe hazelcastopsrequest -n demo hazelcast-scale-up +``` Name: hazelcast-scale-up Namespace: demo Labels: @@ -220,20 +225,23 @@ Events: Normal HorizontalScale 2m29s KubeDB Ops-manager Operator ScaleUp hz-prod nodes Normal Starting 2m29s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 2m29s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hazelcast-scale-up -``` Now, we are going to verify the number of member nodes this database has from the Hazelcast object, number of pods the Stateful have, ```bash -$ kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +``` 4 -$ kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +```bash +kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +``` 4 -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l -5 +```bash +kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l ``` +5 From all the above outputs we can see that the number of member nodes are 4. That means we have successfully scaled up the member nodes of the Hazelcast database. @@ -268,9 +276,9 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hz-hscale-down.yaml -hazelcastopsrequest.ops.kubedb.com/hz-hscale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/horizontal-scaling/hz-hscale-down.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hz-hscale-down created ### Verify Member nodes scaled down successfully @@ -279,25 +287,29 @@ If everything goes well, `KubeDB` Enterprise operator will update the number of Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CR, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hz-hscale-down HorizontalScaling Successful 2m38s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. Now, we are going to verify the number of member nodes this database has from the Hazelcast object, number of pods the PetSet have, ```bash -$ kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +kubectl get hazelcast -n demo hz-prod -o json | jq '.spec.replicas' +``` 2 -$ kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +```bash +kubectl get statefulset -n demo hz-prod -o json | jq '.spec.replicas' +``` 2 -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l -3 +```bash +kubectl get pods -n demo --selector="app.kubernetes.io/instance=hz-prod" | wc -l ``` +3 From all the above outputs we can see that the number of member nodes are 2. That means we have successfully scaled down the member nodes of the Hazelcast database. diff --git a/docs/guides/hazelcast/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/hazelcast/scaling/vertical-scaling/vertical-scaling.md index a048af425d..fa6ab43d81 100644 --- a/docs/guides/hazelcast/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/hazelcast/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -78,22 +78,23 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/vertical-scaling/hazelcast.yaml -hazelcast.kubedb.com/hz-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/vertical-scaling/hazelcast.yaml ``` +hazelcast.kubedb.com/hz-prod created Now, wait until `hz-prod` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1alpha2 5.5.2 Ready 4m -``` Let's check the container resources, ```bash -$ kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -104,8 +105,6 @@ $ kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' } } -``` - You can see the container has `500m` CPU and `1Gi` memory as resource limits. We are now ready to apply the `HazelcastOpsRequest` CR to update the resources of this database. @@ -148,9 +147,9 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/vertical-scaling/hz-vscale-up.yaml -hazelcastopsrequest.ops.kubedb.com/hz-vscale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/scaling/vertical-scaling/hz-vscale-up.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hz-vscale-up created ### Verify Hazelcast resources updated successfully @@ -159,15 +158,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CR, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hz-vscale-up VerticalScaling Successful 3m2s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to update the database. ```bash -$ kubectl describe hazelcastopsrequest -n demo hz-vscale-up +kubectl describe hazelcastopsrequest -n demo hz-vscale-up +``` Name: hz-vscale-up Namespace: demo Labels: @@ -262,12 +262,11 @@ Events: Normal Starting 67s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 67s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hz-vscale-up -``` - Now, we are going to verify from the Pod, and the PetSet that the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -278,8 +277,6 @@ $ kubectl get pod -n demo hz-prod-0 -o json | jq '.spec.containers[].resources' } } -``` - The above output verifies that we have successfully scaled up the resources of the Hazelcast database. ## Cleaning up diff --git a/docs/guides/hazelcast/tls/hazelcast.md b/docs/guides/hazelcast/tls/hazelcast.md index 37abafbdf7..08b3eda3e3 100644 --- a/docs/guides/hazelcast/tls/hazelcast.md +++ b/docs/guides/hazelcast/tls/hazelcast.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for `Hazelcast`. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -85,9 +85,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/tls/hz-issuer.yaml -issuer.cert-manager.io/self-signed-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/tls/hz-issuer.yaml ``` +issuer.cert-manager.io/self-signed-issuer created ## TLS/SSL encryption in Hazelcast @@ -139,22 +139,23 @@ spec: ### Deploy Hazelcast with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/tls/hazelcast.yaml -hazelcast.kubedb.com/hazelcast-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/tls/hazelcast.yaml ``` +hazelcast.kubedb.com/hazelcast-sample created Now, wait until `hazelcast-sample` created has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE hazelcast-sample kubedb.com/v1alpha2 5.5.2 Ready 165m -``` ### Verify TLS/SSL in Hazelcast ```bash -$ kubectl describe secret hazelcast-sample-client-cert -n demo +kubectl describe secret hazelcast-sample-client-cert -n demo +``` Name: hazelcast-sample-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -182,7 +183,6 @@ keystore.p12: 3615 bytes tls.crt: 1627 bytes tls.key: 1675 bytes truststore.p12: 1114 bytes -``` We can see from the above output that, keystore location is `/var/Hazelcast/etc` which means that TLS is enabled. diff --git a/docs/guides/hazelcast/update-version/hazelcast.md b/docs/guides/hazelcast/update-version/hazelcast.md index 430f5bf310..c338b49c61 100644 --- a/docs/guides/hazelcast/update-version/hazelcast.md +++ b/docs/guides/hazelcast/update-version/hazelcast.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](/docs/examples/hazelcast) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -75,17 +75,17 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/update-version/hazelcast.yaml -hazelcast.kubedb.com/hz-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/update-version/hazelcast.yaml ``` +hazelcast.kubedb.com/hz-prod created Now, wait until `hz-prod` has status `Ready`. i.e, ```bash -$ kubectl get hazelcast -n demo +kubectl get hazelcast -n demo +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1alpha2 5.5.2 Ready 3h4m -``` We are now ready to apply the `HazelcastOpsRequest` CR to update this database. @@ -120,9 +120,9 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/update-version/opsrequest-version-update.yaml -hazelcastopsrequest.ops.kubedb.com/hzops-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/update-version/opsrequest-version-update.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hzops-update-version created #### Verify Hazelcast version updated successfully: @@ -131,15 +131,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CR, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hzops-update-version UpdateVersion Successful 3m2s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to update the database. ```bash -$ kubectl describe hazelcastopsrequest -n demo hzops-update-version +kubectl describe hazelcastopsrequest -n demo hzops-update-version +``` Name: hzops-update-version Namespace: demo Labels: @@ -238,32 +239,31 @@ Events: Normal RestartPods 15s KubeDB Ops-manager Operator Successfully Restarted Hazelcast nodes Normal Starting 15s KubeDB Ops-manager Operator Resuming Hazelcast database: demo/hz-prod Normal Successful 15s KubeDB Ops-manager Operator Successfully resumed Hazelcast database: demo/hz-prod for HazelcastOpsRequest: hzops-update-version -``` Now, we are going to verify whether the `Hazelcast` and the related `StatefulSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get hazelcast -n demo hz-prod -o=jsonpath='{.spec.version}{"\n"}' -5.5.6 +kubectl get hazelcast -n demo hz-prod -o=jsonpath='{.spec.version}{"\n"}' ``` +5.5.6 ```bash -$ kubectl get statefulset -n demo hz-prod -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/hazelcast:5.5.6@sha256:abc123def456... +kubectl get statefulset -n demo hz-prod -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/hazelcast:5.5.6@sha256:abc123def456... ```bash -$ kubectl get pods -n demo hz-prod-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/hazelcast:5.5.6@sha256:abc123def456... +kubectl get pods -n demo hz-prod-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/hazelcast:5.5.6@sha256:abc123def456... Let's also verify that the database is ready to take connections: ```bash -$ kubectl get hazelcast -n demo hz-prod +kubectl get hazelcast -n demo hz-prod +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1alpha2 5.5.6 Ready 3h14m -``` You can see from the above outputs that the `Hazelcast` object and related resources have been updated with the new version `5.5.6`. diff --git a/docs/guides/hazelcast/volume-expansion/volume-expansion.md b/docs/guides/hazelcast/volume-expansion/volume-expansion.md index 4b18c56f3c..6da1792902 100644 --- a/docs/guides/hazelcast/volume-expansion/volume-expansion.md +++ b/docs/guides/hazelcast/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/hazelcast](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/hazelcast) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,28 +70,30 @@ spec: Let's create the `Hazelcast` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/volume-expansion/hazelcast.yaml -hazelcast.kubedb.com/hz-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/volume-expansion/hazelcast.yaml ``` +hazelcast.kubedb.com/hz-prod created Now, wait until `hz-prod` has status `Ready`. i.e, ```bash -$ kubectl get hz -n demo +kubectl get hz -n demo +``` NAME TYPE VERSION STATUS AGE hz-prod kubedb.com/v1alpha2 5.2.2 Ready 3m -``` Let's check volume size from statefulset, and from the persistent volume, ```bash -$ kubectl get statefulset -n demo hz-prod -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get statefulset -n demo hz-prod -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -o json | jq '.items[].spec.capacity.storage' +```bash +kubectl get pv -o json | jq '.items[].spec.capacity.storage' +``` "1Gi" "1Gi" -``` You can see the statefulset has 1Gi storage, and the capacity of all the persistent volumes are 1Gi. @@ -129,9 +131,9 @@ Here, Let's create the `HazelcastOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/volume-expansion/ops.yaml -hazelcastopsrequest.ops.kubedb.com/hz-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/hazelcast/volume-expansion/ops.yaml ``` +hazelcastopsrequest.ops.kubedb.com/hz-volume-expansion created #### Verify Hazelcast volume expanded successfully @@ -140,15 +142,16 @@ If everything goes well, `KubeDB` Ops-manager operator will expand the volume of Let's wait for `HazelcastOpsRequest` to be `Successful`. Run the following command to watch `HazelcastOpsRequest` CR, ```bash -$ kubectl get hazelcastopsrequest -n demo +kubectl get hazelcastopsrequest -n demo +``` NAME TYPE STATUS AGE hz-volume-expansion VolumeExpansion Successful 3m2s -``` We can see from the above output that the `HazelcastOpsRequest` has succeeded. If we describe the `HazelcastOpsRequest` we will get an overview of the steps that were followed to expand the database volume. ```bash -$ kubectl describe hazelcastopsrequest -n demo hz-volume-expansion +kubectl describe hazelcastopsrequest -n demo hz-volume-expansion +``` Name: hz-volume-expansion Namespace: demo Labels: @@ -239,18 +242,19 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, we are going to verify from the `statefulset`, and the `PersistentVolume` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get statefulset -n demo hz-prod -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get statefulset -n demo hz-prod -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -o json | jq '.items[].spec.capacity.storage' +```bash +kubectl get pv -o json | jq '.items[].spec.capacity.storage' +``` "2Gi" "2Gi" -``` The above output verifies that we have successfully expanded the volume of the Hazelcast database. diff --git a/docs/guides/ignite/autoscaler/compute/compute-autoscale.md b/docs/guides/ignite/autoscaler/compute/compute-autoscale.md index 915eb2c043..4500f46794 100644 --- a/docs/guides/ignite/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/ignite/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscaling compute resources i. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/ignite](/docs/examples/ignite) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -77,22 +77,23 @@ spec: Let's create the `Ignite` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/autoscaling/compute/ignite-autoscale.yaml -ignite.kubedb.com/ignite-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/autoscaling/compute/ignite-autoscale.yaml ``` +ignite.kubedb.com/ignite-autoscale created Now, wait until `ignite-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME TYPE VERSION STATUS AGE ignite-autoscale kubedb.com/v1alpha2 2.17.0 Ready 22s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -103,11 +104,11 @@ $ kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].re "memory": "1Gi" } } -``` Let's check the Ignite resources, ```bash -$ kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -118,7 +119,6 @@ $ kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.sp "memory": "1Gi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the ignite. @@ -172,20 +172,23 @@ Here, Let's create the `IgniteAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/autoscaling/compute/ignite-autoscaler.yaml -igniteautoscaler.autoscaling.kubedb.com/ignite-autoscaler-ops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/autoscaling/compute/ignite-autoscaler.yaml ``` +igniteautoscaler.autoscaling.kubedb.com/ignite-autoscaler-ops created #### Verify Autoscaling is set up successfully Let's check that the `igniteautoscaler` resource is created successfully, ```bash -$ kubectl get igniteautoscaler -n demo +kubectl get igniteautoscaler -n demo +``` NAME AGE ignite-autoscale-ops 6m55s -$ kubectl describe igniteautoscaler ignite-autoscale-ops -n demo +```bash +kubectl describe igniteautoscaler ignite-autoscale-ops -n demo +``` Name: ignite-autoscale-ops Namespace: demo Labels: @@ -268,7 +271,6 @@ Status: Memory: 2Gi Vpa Name: ignite-autoscale Events: -``` So, the `Igniteautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our Ignite. Our autoscaler operator continuously watches the recommendation generated and creates an `igniteopsrequest` based on the recommendations, if the ignite pods are needed to scaled up or down. @@ -276,25 +278,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `igniteopsrequest` in the demo namespace to see if any `igniteopsrequest` object is created. After some time you'll see that a `igniteopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get igniteopsrequest -n demo +watch kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE igops-ignite-autoscale-zzell6 VerticalScaling Progressing 1m48s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get igniteopsrequest -n demo +watch kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE igops-ignite-autoscale-zzell6 VerticalScaling Successful 3m40s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to scale the Ignite. ```bash -$ kubectl describe igniteopsrequest -n demo igops-ignite-autoscale-zzell6 +kubectl describe igniteopsrequest -n demo igops-ignite-autoscale-zzell6 +``` Name: igops-ignite-autoscale-zzell6 Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -393,12 +396,12 @@ Events: Normal RestartPods 7m31s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 7m31s KubeDB Ops-manager Operator Resuming ignite database: demo/ignite-autoscale Normal Successful 7m30s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ignite-autoscale for IgniteOpsRequest: igops-ignite-autoscale-zzell6 -``` Now, we are going to verify from the Pod, and the Ignite yaml whether the resources of the Ignite has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -410,7 +413,9 @@ $ kubectl get pod -n demo ignite-autoscale-0 -o json | jq '.spec.containers[].re } } -$ kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +```bash +kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -421,7 +426,6 @@ $ kubectl get ignite -n demo ignite-autoscale -o json | jq '.spec.podTemplate.sp "memory": "1.2Gi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the ignite. diff --git a/docs/guides/ignite/autoscaler/storage/storage-autoscale.md b/docs/guides/ignite/autoscaler/storage/storage-autoscale.md index 53db46cfc7..1112bf4293 100644 --- a/docs/guides/ignite/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/ignite/autoscaler/storage/storage-autoscale.md @@ -37,20 +37,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Ignit To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -100,30 +100,32 @@ spec: Let's create the `Ignite` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/autoscaler/storage/cluster/examples/sample-ignite.yaml -ignite.kubedb.com/ignite-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/autoscaler/storage/cluster/examples/sample-ignite.yaml ``` +ignite.kubedb.com/ignite-autoscale created Now, wait until `ignite-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get ignite -n demo +kubectl get ignite -n demo +``` NAME VERSION STATUS AGE ignite-autoscale 2.17.0 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo ignite-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo ignite-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-sample-ignite-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-sample-ignite-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-ignite-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -165,20 +167,23 @@ Here, Let's create the `igniteAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/autoscaler/storage/cluster/examples/ig-storage-autoscale-ops.yaml -igniteautoscaler.autoscaling.kubedb.com/ignite-storage-autosclaer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/autoscaler/storage/cluster/examples/ig-storage-autoscale-ops.yaml ``` +igniteautoscaler.autoscaling.kubedb.com/ignite-storage-autosclaer created #### Storage Autoscaling is set up successfully Let's check that the `igniteautoscaler` resource is created successfully, ```bash -$ kubectl get igniteautoscaler -n demo +kubectl get igniteautoscaler -n demo +``` NAME AGE ignite-storage-autosclaer 33s -$ kubectl describe igniteautoscaler ignite-storage-autoscaler -n demo +```bash +kubectl describe igniteautoscaler ignite-storage-autoscaler -n demo +``` Name: ignite-storage-autosclaer Namespace: demo Labels: @@ -200,30 +205,30 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `igniteautoscaler` resource is created successfully. Let's watch the `igniteopsrequest` in the demo namespace to see if any `igniteopsrequest` object is created. After some time you'll see that a `igniteopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE igops-ignite-autoscale-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE igops-ignite-autoscale-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe igniteopsrequest -n demo igops-ignite-autoscale-xojkua +kubectl describe igniteopsrequest -n demo igops-ignite-autoscale-xojkua +``` Name: igops-ignite-autoscaleq-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -286,19 +291,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming ignite database: demo/ignite-autoscale Normal Successful 103s KubeDB Enterprise Operator Successfully resumed ignite database: demo/ignite-autoscale Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of ignite: demo/ignite-autoscale -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo ignite-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo ignite-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-ignite-autoscale-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-signite-autoscale-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-ignite-autoscale-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the ignite cluster. diff --git a/docs/guides/ignite/custom-configuration/using-config-file.md b/docs/guides/ignite/custom-configuration/using-config-file.md index ba2089bd4c..cf5704c8ca 100644 --- a/docs/guides/ignite/custom-configuration/using-config-file.md +++ b/docs/guides/ignite/custom-configuration/using-config-file.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for Ignite. This tutorial will sh - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - - $ kubectl get ns demo + + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,10 +72,10 @@ metadata: ``` Here, `authenticationEnabled's` default value is `false`. In this secret, we make the value `true`. -```bash - $ kubectl apply -f ignite-configuration.yaml + ```bash + kubectl apply -f ignite-configuration.yaml + ``` secret/ignite-configuration created -``` Let's get the ignite-configuration `secret` with custom configuration: @@ -98,9 +100,9 @@ type: Opaque Now, create Ignite crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/custom-ignite.yaml -ignite.kubedb.com/custom-ignite created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/custom-ignite.yaml ``` +ignite.kubedb.com/custom-ignite created Below is the YAML for the Ignite crd we just created. @@ -130,16 +132,17 @@ Now, wait a few minutes. KubeDB operator will create necessary petset, services Check if the database is ready ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME VERSION STATUS AGE custom-ignite 2.17.0 Ready 17m -``` Now, we will check if the database has started with the custom configuration we have provided. We will connect to `custom-ignite-0` pod: ```bash -$ kubectl exec -it -n demo custom-ignite-0 -c ignite -- bash +kubectl exec -it -n demo custom-ignite-0 -c ignite -- bash +``` [ignite@custom-ignite-0 config]$ cat /ignite/config/node-configuration.xml @@ -153,7 +156,6 @@ http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> -``` Here, we can see `authenticationEnabled's` value is `true`. diff --git a/docs/guides/ignite/custom-configuration/using-podtemplate.md b/docs/guides/ignite/custom-configuration/using-podtemplate.md index 5cde4a4a0c..9ea7b0f051 100644 --- a/docs/guides/ignite/custom-configuration/using-podtemplate.md +++ b/docs/guides/ignite/custom-configuration/using-podtemplate.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Ignite via [PodTemplate](/doc - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -86,30 +86,36 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/custom-podtemplate.yaml -ignite.kubedb.com/custom-ignite created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/custom-podtemplate.yaml ``` +ignite.kubedb.com/custom-ignite 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-ignite-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE custom-ignite-0 1/1 Running 0 30s -``` Now, check if the ignite 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 -n demo custom-ignite-0 -c ignite -- sh -$ echo $Ignite_Key +kubectl exec -it -n demo custom-ignite-0 -c ignite -- sh +``` + +```bash +echo $Ignite_Key +``` KubeDB -$ echo $Ignite_Value + +```bash +echo $Ignite_Value +``` 123 exit -``` So, we can see that the additional environment variables are set correctly. ## Custom Sidecar Containers @@ -135,8 +141,11 @@ 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 +docker build -t repository_name/custom_filebeat:latest . +``` + +```bash +docker push repository_name/custom_filebeat:latest ``` Now we will deploy our ignite with custom sidecar container and will also use the `spec.initConfig` to configure the logs related settings. Here is the yaml of our ignite: ```yaml @@ -171,20 +180,19 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/sidecar-container.yaml -ignite.kubedb.com/ignite-custom-sidecar created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/sidecar-container.yaml ``` +ignite.kubedb.com/ignite-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 `ignite-custom-sidecar-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE ignite-custom-sidecar-0 2/2 Running 0 33s -``` - Now, let’s checked the ignite database with the 2 containers with their given resources: ```yaml @@ -292,31 +300,32 @@ So, we have successfully checked our sidecar filebeat container in Ignite databa Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our ignite 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -332,7 +341,6 @@ Labels: beta.kubernetes.io/arch=amd64 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 ignite with this new label as nodeSelector. Below is the yaml we are going to apply: @@ -352,24 +360,24 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/node-selector.yaml -ignite.kubedb.com/ignite-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/node-selector.yaml ``` +ignite.kubedb.com/ignite-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 `ignite-node-selector-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE ignite-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 ignite-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo ignite-node-selector-0 -o wide +kubectl get pods -n demo ignite-node-selector-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ignite-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 @@ -377,28 +385,33 @@ We can successfully verify that our pod was scheduled to our desired node. Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our ignite 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key2=node2:NoSchedule +```bash +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 +```bash +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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -423,7 +436,6 @@ lke212553-307295-5b53c5520000 "value": "node3" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a ignite without proper tolerations. Here is the yaml of ignite we are going to createc ```yaml apiVersion: kubedb.com/v1alpha2 @@ -437,20 +449,21 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/ignite-without-tolerations.yaml -ignite.kubedb.com/ignite-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/ignite-without-tolerations.yaml ``` +ignite.kubedb.com/ignite-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 `ignite-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE ignite-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 ignite-without-tolerations-0 +kubectl describe pods -n demo ignite-without-tolerations-0 +``` Name: ignite-without-tolerations-0 Namespace: demo Priority: 0 @@ -538,7 +551,6 @@ Events: 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 ignite. Here is the yaml we are going to apply, @@ -562,24 +574,24 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/with-tolerations.yaml -ignite.kubedb.com/ignite-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-config/with-tolerations.yaml ``` +ignite.kubedb.com/ignite-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 `ignite-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE ignite-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 ignite-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo ignite-with-tolerations-0 -o wide +kubectl get pods -n demo ignite-with-tolerations-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES ignite-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 diff --git a/docs/guides/ignite/custom-rbac/using-custom-rbac.md b/docs/guides/ignite/custom-rbac/using-custom-rbac.md index 3cba97c3fb..cc3e5da499 100644 --- a/docs/guides/ignite/custom-rbac/using-custom-rbac.md +++ b/docs/guides/ignite/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the Ignite instance named `quick-ignite`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -98,10 +98,9 @@ This permission is required for Ignite pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -130,9 +129,9 @@ subjects: Now, create a Ignite crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-db.yaml -ignite.kubedb.com/ignite-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-db.yaml ``` +ignite.kubedb.com/ignite-quickstart created Below is the YAML for the Ignite crd we just created. @@ -165,12 +164,12 @@ Now, wait a few minutes. the KubeDB operator will create necessary petset, servi Check that the pod is running: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE ignite-quickstart-0 1/1 Running 0 5m54s ignite-quickstart-1 1/1 Running 0 4m42s ignite-quickstart-2 1/1 Running 0 3m31s -``` ## Reusing Service Account @@ -179,9 +178,9 @@ An existing service account can be reused in another Ignite instance. No new acc Now, create Ignite crd `minute-ignite` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-db-two.yaml -ignite.kubedb.com/ignite-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/custom-rbac/ig-custom-db-two.yaml ``` +ignite.kubedb.com/ignite-quickstart created Below is the YAML for the Ignite crd we just created. @@ -214,40 +213,54 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the pod is running: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE minute-ignite-0 1/1 Running 0 5m52s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ig/ignite-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ig/ignite-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` ignite.kubedb.com/ignite-quickstart patched -$ kubectl delete -n demo ig/ignite-quickstart +```bash +kubectl delete -n demo ig/ignite-quickstart +``` ignite.kubedb.com "ignite-quickstart" deleted -$ kubectl patch -n demo ig/minute-ignite -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo ig/minute-ignite -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` ignite.kubedb.com/minute-ignite patched -$ kubectl delete -n demo ig/minute-ignite +```bash +kubectl delete -n demo ig/minute-ignite +``` ignite.kubedb.com "minute-ignite" deleted -$ kubectl delete -n demo role my-custom-role +```bash +kubectl delete -n demo role my-custom-role +``` role.rbac.authorization.k8s.io "my-custom-role" deleted -$ kubectl delete -n demo rolebinding my-custom-rolebinding +```bash +kubectl delete -n demo rolebinding my-custom-rolebinding +``` rolebinding.rbac.authorization.k8s.io "my-custom-rolebinding" deleted -$ kubectl delete sa -n demo my-custom-serviceaccount +```bash +kubectl delete sa -n demo my-custom-serviceaccount +``` serviceaccount "my-custom-serviceaccount" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted If you would like to uninstall the KubeDB operator, please follow the steps [here](/docs/setup/README.md). diff --git a/docs/guides/ignite/monitoring/using-builtin-prometheus.md b/docs/guides/ignite/monitoring/using-builtin-prometheus.md index 2030903c60..f78c2b842c 100644 --- a/docs/guides/ignite/monitoring/using-builtin-prometheus.md +++ b/docs/guides/ignite/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Ignite server using builtin [Promethe - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the Ignite crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/monitoring/builtin-prom-ignite.yaml -ignite.kubedb.com/builtin-prom-ignite created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/monitoring/builtin-prom-ignite.yaml ``` +ignite.kubedb.com/builtin-prom-ignite created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get ig -n demo builtin-prom-ignite +kubectl get ig -n demo builtin-prom-ignite +``` NAME VERSION STATUS AGE builtin-prom-ignite 1.6.22 Ready 30s -``` KubeDB will create a separate stats service with name `{Ignite crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-ignite" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-ignite" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-ignite ClusterIP 10.96.168.132 11211/TCP 20s builtin-prom-ignite-pods ClusterIP None 11211/TCP 20s builtin-prom-ignite-stats ClusterIP 10.96.40.60 56790/TCP 20s -``` Here, `builtin-prom-ignite-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-ignite-stats +kubectl describe svc -n demo builtin-prom-ignite-stats +``` Name: builtin-prom-ignite-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -114,7 +117,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.186:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -269,20 +271,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/v2024.8.21/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/v2024.8.21/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -293,9 +295,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -304,18 +306,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-d64b668fb-4jq99 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-d64b668fb-4jq99` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-d64b668fb-4jq99 9090 +kubectl port-forward -n monitoring prometheus-d64b668fb-4jq99 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoints of `builtin-prom-ignite-stats` service as targets. @@ -330,16 +332,31 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo ig/builtin-prom-ignite +kubectl delete -n demo ig/builtin-prom-ignite +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/ignite/monitoring/using-prometheus-operator.md b/docs/guides/ignite/monitoring/using-prometheus-operator.md index 4902d036ed..490ab5f3de 100644 --- a/docs/guides/ignite/monitoring/using-prometheus-operator.md +++ b/docs/guides/ignite/monitoring/using-prometheus-operator.md @@ -34,12 +34,14 @@ The following diagram shows how KubeDB Provisioner operator monitor `Ignite` usi - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -50,12 +52,11 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 3m -``` - > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. @@ -215,27 +216,27 @@ Here, Let's create the Ignite object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/monitoring/ignite.yaml -ignite.kubedb.com/ignite created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/monitoring/ignite.yaml ``` +ignite.kubedb.com/ignite created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get ig -n demo ignite +kubectl get ig -n demo ignite +``` NAME VERSION STATUS AGE ignite 2.17.0 Ready 2m -``` KubeDB will create a separate stats service with name `{Ignite crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=ignite" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=ignite" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ignite ClusterIP 10.96.91.51 11211/TCP 3m9s ignite-pods ClusterIP None 11211/TCP 3m9s ignite-stats ClusterIP 10.96.50.21 56790/TCP 3m9s -``` Here, `ignite-stats` service has been created for monitoring purpose. @@ -269,10 +270,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `ignite-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE ignite-stats 5m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Ignite crd. @@ -326,20 +327,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 16m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `ignite-stats` service as one of the targets. diff --git a/docs/guides/ignite/private-registry/using-private-registry.md b/docs/guides/ignite/private-registry/using-private-registry.md index ece23c23c5..a205999428 100644 --- a/docs/guides/ignite/private-registry/using-private-registry.md +++ b/docs/guides/ignite/private-registry/using-private-registry.md @@ -27,10 +27,10 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For ignite, push `DB_IMAGE`, `EXPORTER_IMAGE` of following IgniteVersions, where `deprecated` is not true, to your private registry. ```bash - $ kubectl get igniteversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + kubectl get igniteversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + ``` NAME VERSION DB_IMAGE EXPORTER_IMAGE DEPRECATED 2.17.0 2.17.0 ghcr.io/appscode-images/ignite:2.17.0 ghcr.io/kubedb/ignite-init:2.17.0-v1 - ``` - Update KubeDB catalog for private Docker registry. Ex: @@ -50,9 +50,9 @@ KubeDB operator supports using private Docker registry. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - ``` ## Create ImagePullSecret @@ -61,13 +61,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -109,14 +109,15 @@ spec: Now run the command to deploy this `Ignite` object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/private-registry/demo-2.yaml -ignite.kubedb.com/ig-pvt-reg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/private-registry/demo-2.yaml ``` +ignite.kubedb.com/ig-pvt-reg created To check if the images pulled successfully from the repository, see if the `Ignite` is in running state: ```bash -$ kubectl get pods -n demo -w +kubectl get pods -n demo -w +``` NAME READY STATUS RESTARTS AGE ig-pvt-reg-694d4d44df-bwtk8 0/1 ContainerCreating 0 18s ig-pvt-reg-694d4d44df-tkqc4 0/1 ContainerCreating 0 17s @@ -125,28 +126,35 @@ ig-pvt-reg-694d4d44df-bwtk8 1/1 Running 0 25s ig-pvt-reg-694d4d44df-zhj4l 1/1 Running 0 26s ig-pvt-reg-694d4d44df-tkqc4 1/1 Running 0 27s -$ kubectl get ig -n demo +```bash +kubectl get ig -n demo +``` NAME VERSION STATUS AGE ig-pvt-reg 2.17.0 Running 59s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ig/ig-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ig/ig-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` ignite.kubedb.com/ig-pvt-reg patched -$ kubectl delete -n demo ig/ig-pvt-reg +```bash +kubectl delete -n demo ig/ig-pvt-reg +``` ignite.kubedb.com "ig-pvt-reg" deleted -$ kubectl delete -n demo secret myregistrykey +```bash +kubectl delete -n demo secret myregistrykey +``` secret "myregistrykey" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/ignite/quickstart/quickstart.md b/docs/guides/ignite/quickstart/quickstart.md index 8f0f795b5a..2ea383e786 100644 --- a/docs/guides/ignite/quickstart/quickstart.md +++ b/docs/guides/ignite/quickstart/quickstart.md @@ -31,23 +31,25 @@ This tutorial will show you how to use KubeDB to run a Ignite server. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 1s -``` ## Find Available IgniteVersion When you have installed KubeDB, it has created `IgniteVersion` crd for all supported Ignite versions. Check 0 ```bash -$ kubectl get igniteversions +kubectl get igniteversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2.17.0 2.17.0 ghcr.io/appscode-images/ignite:2.17.0 2h -``` ## Create a Ignite server @@ -72,9 +74,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/quickstart/demo.yaml -ignite.kubedb.com/ignite-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/quickstart/demo.yaml ``` +ignite.kubedb.com/ignite-quickstart created Here, @@ -85,11 +87,14 @@ Here, KubeDB operator watches for `Ignite` objects using Kubernetes api. When a `Ignite` object is created, KubeDB operator will create a new PetSet and a Service with the matching Ignite object name. ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME TYPE VERSION STATUS AGE ignite-quickstart kubedb.com/v1alpha2 2.17.0 Ready 2m -$ kubectl describe ig -n demo ignite-quickstart +```bash +kubectl describe ig -n demo ignite-quickstart +``` Name: ignite-quickstart Namespace: demo Labels: @@ -202,15 +207,18 @@ Status: Phase: Ready Events: -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME AGE ignite-quickstart 2m -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ignite-quickstart ClusterIP 10.96.163.80 8080/TCP,10800/TCP,47500/TCP,47100/TCP 4m8s ignite-quickstart-pods ClusterIP None 8080/TCP,10800/TCP,47500/TCP,47100/TCP 4m8s -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified Ignite object: @@ -334,7 +342,8 @@ Now, you can connect to this database using `sqlline`. Here, firstly we will exec one of the running pod: ```bash -$ kubectl exec -it -n demo ignite-quickstart-0 -c ignite -- bash +kubectl exec -it -n demo ignite-quickstart-0 -c ignite -- bash +``` ignite@ignite-quickstart-0:/# apache-ignite/bin/sqlline.sh -u jdbc:ignite:thin://127.0.0.1/ -n ignite -p 'pyX39AdZlOog!3Lt' sqlline version 1.9.0 0: jdbc:ignite:thin://127.0.0.1/> CREATE TABLE City (id LONG PRIMARY KEY, name VARCHAR); @@ -354,7 +363,6 @@ No rows affected (0.087 seconds) | 1 | Forest Hill | +----+----------------+ 3 rows selected (0.039 seconds) -``` ## Database DeletionPolicy @@ -365,9 +373,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete ig ignite-quickstart -n demo -Error from server (Forbidden): admission webhook "ignitewebhook.validators.kubedb.com" denied the request: ignite demo/ignite-quickstart is can't terminated. To delete, change spec.deletionPolicy +kubectl delete ig ignite-quickstart -n demo ``` +Error from server (Forbidden): admission webhook "ignitewebhook.validators.kubedb.com" denied the request: ignite demo/ignite-quickstart is can't terminated. To delete, change spec.deletionPolicy Learn details of all `DeletionPolicy` [here](/docs/guides/ignite/concepts/ignite.md#specdeletionpolicy). **Delete:** @@ -379,18 +387,18 @@ When the [DeletionPolicy](/docs/guides/ignite/concepts/ignite.md#specdeletionpol Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete -n demo ig/ignite-quickstart -ignite.kubedb.com "ignite-quickstart" deleted +kubectl delete -n demo ig/ignite-quickstart ``` +ignite.kubedb.com "ignite-quickstart" deleted Now, run the following command to get all ignite resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/ignite-quickstart-auth kubernetes.io/basic-auth 2 27m secret/ignite-quickstart-config Opaque 1 27m -``` From the above output, you can see that all ignite resources(`PetSet`, `Service` etc.) are deleted except `Secret`. @@ -410,9 +418,9 @@ ignite.kubedb.com "ignite-quickstart" deleted Now, run the following command to get all ignite resources in `demo` namespaces, ```bash -$ kubectl get petsets,svc,secret -n demo -No resources found in demo namespace. +kubectl get petsets,svc,secret -n demo ``` +No resources found in demo namespace. From the above output, you can see that all ignite resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. @@ -423,15 +431,19 @@ From the above output, you can see that all ignite resources are deleted. there To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ig/ignite-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ig/ignite-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` ignite.kubedb.com/ignite-quickstart patched -$ kubectl delete -n demo ig/ignite-quickstart +```bash +kubectl delete -n demo ig/ignite-quickstart +``` ignite.kubedb.com "ignite-quickstart" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/ignite/reconfigure-tls/reconfigure-tls.md b/docs/guides/ignite/reconfigure-tls/reconfigure-tls.md index 31c79da994..0f6fbb8c9f 100644 --- a/docs/guides/ignite/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/ignite/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,25 +62,27 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/ig.yaml -ignite.kubedb.com/ig created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/ig.yaml ``` +ignite.kubedb.com/ig created Now, wait until `ig` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME VERSION STATUS AGE ig 2.17.0 Ready 10m -``` ```bash -$ kubectl get secrets -n demo ig-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo ig-auth -o jsonpath='{.data.username}' | base64 -d +``` ignite -$ kubectl get secrets -n demo ig-auth -o jsonpath='{.data.password}' | base64 -d -U6(h_pYrekLZ2OOd +```bash +kubectl get secrets -n demo ig-auth -o jsonpath='{.data.password}' | base64 -d ``` +U6(h_pYrekLZ2OOd We can verify from the above output that TLS is disabled for this database. @@ -91,23 +93,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 ignite-ca \ +kubectl create secret tls ignite-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/ignite-ca created ``` +secret/ignite-ca created Now, Let's create an `Issuer` using the `mongo-ca` secret that we have just created. The `YAML` file looks like this: @@ -125,9 +127,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/issuer.yaml -issuer.cert-manager.io/ig-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/issuer.yaml ``` +issuer.cert-manager.io/ig-issuer created ### Create IgniteOpsRequest @@ -169,25 +171,26 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/igops-add-tls.yaml -igniteopsrequest.ops.kubedb.com/igops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/igops-add-tls.yaml ``` +igniteopsrequest.ops.kubedb.com/igops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CRO, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE igops-add-tls ReconfigureTLS Successful 91s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe igniteopsrequest -n demo igops-add-tls +kubectl describe igniteopsrequest -n demo igops-add-tls +``` Name: igops-add-tls Namespace: demo Labels: @@ -290,17 +293,16 @@ Events: Normal ResumeDatabase 10s KubeDB Ops-manager operator Resuming Ignite demo/ig Normal ResumeDatabase 10s KubeDB Ops-manager operator Successfully resumed Ignite demo/ig Normal Successful 10s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` ## Rotate Certificate Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it ig-2 -n demo bash +kubectl exec -it ig-2 -n demo bash +``` root@ig-2:/# openssl x509 -in /ignite/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 13:32:20 2025 GMT -``` So, the certificate will expire on this time `Jun 9 13:32:20 2025 GMT`. @@ -331,25 +333,26 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Ignite/reconfigure-tls/igops-rotate.yaml -Igniteopsrequest.ops.kubedb.com/igops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Ignite/reconfigure-tls/igops-rotate.yaml ``` +Igniteopsrequest.ops.kubedb.com/igops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CRO, ```bash -$ kubectl get Igniteopsrequest -n demo +kubectl get Igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE igops-rotate ReconfigureTLS Successful 112s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe igniteopsrequest -n demo igops-rotate +kubectl describe igniteopsrequest -n demo igops-rotate +``` Name: igops-rotate Namespace: demo Labels: @@ -439,15 +442,14 @@ Events: Normal CertificateIssuingSuccessful 2m10s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 25s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 25s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it ig-2 -n demo bash +kubectl exec -it ig-2 -n demo bash +``` root@ig-2:/# openssl x509 -in /ignite/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 16:17:55 2025 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -458,23 +460,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 ig-new-ca \ +kubectl create secret tls ig-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/ig-new-ca created ``` +secret/ig-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -492,9 +494,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/ig-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/ig-new-issuer created ### Create IgniteOpsRequest @@ -526,25 +528,26 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/ig-change-issuer.yaml -igniteopsrequest.ops.kubedb.com/ig-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/ig-change-issuer.yaml ``` +igniteopsrequest.ops.kubedb.com/ig-change-issuer created #### Verify Issuer is changed successfully Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CRO, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE ig-change-issuer ReconfigureTLS Successful 105s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe igniteopsrequest -n demo ig-change-issuer +kubectl describe igniteopsrequest -n demo ig-change-issuer +``` Name: ig-change-issuer Namespace: demo Labels: @@ -635,15 +638,14 @@ Events: Normal CertificateIssuingSuccessful 2m27s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 42s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 42s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it ig-2 -n demo bash +kubectl exec -it ig-2 -n demo bash +``` root@ig-2:/$ openssl x509 -in /ignite/certs/client/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -678,25 +680,26 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/mops-remove.yaml -igniteopsrequest.ops.kubedb.com/mops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/reconfigure-tls/mops-remove.yaml ``` +igniteopsrequest.ops.kubedb.com/mops-remove created #### Verify TLS Removed Successfully Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CRO, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE mops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe igniteopsrequest -n demo mops-remove +kubectl describe igniteopsrequest -n demo mops-remove +``` Name: mops-remove Namespace: demo Labels: @@ -784,7 +787,6 @@ Events: Normal ResumeDatabase 35s KubeDB Ops-manager operator Resuming Ignite demo/ig Normal ResumeDatabase 35s KubeDB Ops-manager operator Successfully resumed Ignite demo/ig Normal Successful 35s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/ignite/reconfigure/reconfigure.md b/docs/guides/ignite/reconfigure/reconfigure.md index c9b4fc934e..5c81711171 100644 --- a/docs/guides/ignite/reconfigure/reconfigure.md +++ b/docs/guides/ignite/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [examples](/docs/examples/ignite) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,9 +49,9 @@ At first, we will create `node-configuration.xml` file containing required confi Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo ig-custom-config --from-file=./node-configuration.xml -secret/ig-custom-config created +kubectl create secret generic -n demo ig-custom-config --from-file=./node-configuration.xml ``` +secret/ig-custom-config created In this section, we are going to create a Ignite object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Ignite` CR that we are going to create, @@ -78,37 +78,39 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/cluster/ig-custom-config.yaml -ignite.kubedb.com/ig-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/cluster/ig-custom-config.yaml ``` +ignite.kubedb.com/ig-cluster created Now, wait until `ig-cluster` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME TYPE VERSION STATUS AGE ig-cluster kubedb.com/v1alpha2 2.17.0 Ready 79m -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a Ignite instance, ```bash -$ kubectl get secrets -n demo ig-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo ig-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` ignite -$ kubectl get secrets -n demo ig-cluster-auth -o jsonpath='{.data.password}' | base64 -d -m6lXjZugrC4VEpB8 +```bash +kubectl get secrets -n demo ig-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +m6lXjZugrC4VEpB8 ### Reconfigure using new secret Now, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./node-configuration.xml -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./node-configuration.xml ``` +secret/new-custom-config created #### Create IgniteOpsRequest @@ -141,9 +143,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/opsrequests/ig-reconfigure-with-secret.yaml -igniteopsrequest.ops.kubedb.com/reconfigure-ig-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/opsrequests/ig-reconfigure-with-secret.yaml ``` +igniteopsrequest.ops.kubedb.com/reconfigure-ig-cluster created #### Verify the new configuration is working @@ -152,16 +154,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ watch kubectl get igniteopsrequest -n demo +watch kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE reconfigure-ig-cluster Reconfigure Successful 3m -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe igniteopsrequest -n demo reconfigure-ig-cluster +kubectl describe igniteopsrequest -n demo reconfigure-ig-cluster +``` Name: reconfigure-ig-cluster Namespace: demo Labels: @@ -238,7 +241,6 @@ Events: Normal RestartNodes 5m40s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5m40s KubeDB Ops-manager Operator Resuming Ignite database: demo/ig-cluster Normal Successful 5m39s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ig-cluster for IgniteOpsRequest: reconfigure-ig-cluster -``` ### Reconfigure using apply config @@ -286,9 +288,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/opsrequests/ignite-reconfigure-apply.yaml -igniteopsrequest.ops.kubedb.com/reconfigure-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/opsrequests/ignite-reconfigure-apply.yaml ``` +igniteopsrequest.ops.kubedb.com/reconfigure-apply created ## Cleaning Up diff --git a/docs/guides/ignite/restart/restart.md b/docs/guides/ignite/restart/restart.md index 3caa4f7902..ef1622c2f9 100644 --- a/docs/guides/ignite/restart/restart.md +++ b/docs/guides/ignite/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Ignite database via a IgniteOpsRequest. Restartin - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -58,9 +58,9 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/restart/ig.yaml -ignite.kubedb.com/ig created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/restart/ig.yaml ``` +ignite.kubedb.com/ig created ## Apply Restart opsRequest @@ -87,18 +87,21 @@ spec: Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/restart/ops.yaml -igniteopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/restart/ops.yaml ``` +igniteopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will restrart the pods sequetially by their cardinal suffix. -```shell -$ kubectl get igniteopsrequest -n demo +```bash +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 10m -$ kubectl get igniteopsrequest -n demo -oyaml restart +```bash +kubectl get igniteopsrequest -n demo -oyaml restart +``` apiVersion: ops.kubedb.com/v1alpha1 kind: IgniteOpsRequest metadata: @@ -139,7 +142,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/ignite/rotate-auth/rotateauth.md b/docs/guides/ignite/rotate-auth/rotateauth.md index 3d3267c57b..d759b0fbe9 100644 --- a/docs/guides/ignite/rotate-auth/rotateauth.md +++ b/docs/guides/ignite/rotate-auth/rotateauth.md @@ -29,9 +29,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Create an Ignite database @@ -56,17 +56,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/quickstart/examples/ignite-quickstart.yaml -ignite.kubedb.com/ignite-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/quickstart/examples/ignite-quickstart.yaml ``` +ignite.kubedb.com/ignite-quickstart created Now, wait until ignite-quickstart has status Ready. i.e, -```shell -$ kubectl get ignite -n demo -w +```bash +kubectl get ignite -n demo -w +``` NAME VERSION STATUS AGE ignite-quickstart 2.16.0 Ready 30m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the Secret. @@ -106,19 +106,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Ignite. Let's create the `IgniteOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/rotate-auth/overview/examples/Ignite-rotate-auth-generated.yaml -igniteopsrequest.ops.kubedb.com/igops-rotate-auth-generated created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/rotate-auth/overview/examples/Ignite-rotate-auth-generated.yaml ``` +igniteopsrequest.ops.kubedb.com/igops-rotate-auth-generated created Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CRO -```shell -$ kubectl get igniteopsrequest -n demo +```bash +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE igops-rotate-auth-generated RotateAuth Successful 7m7s -``` If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe igniteopsrequest -n demo igops-rotate-auth-generated +```bash +kubectl describe igniteopsrequest -n demo igops-rotate-auth-generated +``` Name: igops-rotate-auth-generated Namespace: demo Labels: @@ -242,25 +243,33 @@ Events: Normal RestartNodes 4m49s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 4m49s KubeDB Ops-manager Operator Resuming Ignite database: demo/ignite-quickstart Normal Successful 4m49s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ignite-quickstart for IgniteOpsRequest: igops-rotate-auth-generated -``` **Verify Auth is rotated** -```shell -$ kubectl get ignite -n demo ignite-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get ignite -n demo ignite-quickstart -ojson | jq .spec.authSecret.name +``` "ignite-quickstart-auth" -$ kubectl get secret -n demo ignite-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo ignite-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d +``` ignite⏎ -$ kubectl get secret -n demo ignite-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d -is0x8KNq6hGFfmvU⏎ + +```bash +kubectl get secret -n demo ignite-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d ``` +is0x8KNq6hGFfmvU⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo ignite-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo ignite-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` ignite⏎ -$ kubectl get secret -n demo ignite-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -EO3AhW7uypPxPsQQ⏎ + +```bash +kubectl get secret -n demo ignite-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +EO3AhW7uypPxPsQQ⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials @@ -269,13 +278,13 @@ At first, we need to create a secret with kubernetes.io/basic-auth type using cu > Note: You cannot change the database `username`, but you can update the `password` while keeping the existing `username`. -```shell -$ kubectl create secret generic ignite-quickstart-auth-user -n demo \ +```bash +kubectl create secret generic ignite-quickstart-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=ignite \ --from-literal=password=testpassword -secret/ignite-quickstart-auth-user created ``` +secret/ignite-quickstart-auth-user created Now create an `IgniteOpsRequest` with `RotateAuth` type. Below is the YAML of the `IgniteOpsRequest` that we are going to create, ```shell @@ -303,21 +312,22 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/rotate-auth/overview/examples/rotate-auth-user.yaml -igniteopsrequest.ops.kubedb.com/igops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/ignite/rotate-auth/overview/examples/rotate-auth-user.yaml ``` +igniteopsrequest.ops.kubedb.com/igops-rotate-auth-user created Let's wait for `IgniteOpsRequest` to be Successful. Run the following command to watch `IgniteOpsRequest` CRO: -```shell -$ kubectl get igniteopsrequest -n demo +```bash +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE igops-rotate-auth-generated RotateAuth Successful 15m igops-rotate-auth-user RotateAuth Successful 4m34s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe igniteopsrequest -n demo igops-rotate-auth-user +```bash +kubectl describe igniteopsrequest -n demo igops-rotate-auth-user +``` Name: igops-rotate-auth-user Namespace: demo Labels: @@ -446,24 +456,32 @@ Events: Normal RestartNodes 2m12s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 2m12s KubeDB Ops-manager Operator Resuming Ignite database: demo/ignite-quickstart Normal Successful 2m12s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ignite-quickstart for IgniteOpsRequest: igops-rotate-auth-user -``` **Verify auth is rotate** -```shell -$ kubectl get ignite -n demo ignite-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get ignite -n demo ignite-quickstart -ojson | jq .spec.authSecret.name +``` "ignite-quickstart-auth-user" -$ kubectl get secret -n demo ignite-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo ignite-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d +``` ignite⏎ -$ kubectl get secret -n demo ignite-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d -testpassword⏎ + +```bash +kubectl get secret -n demo ignite-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d ``` +testpassword⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo ignite-quickstart-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo ignite-quickstart-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` ignite⏎ -$ kubectl get secret -n demo ignite-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d -is0x8KNq6hGFfmvU⏎ + +```bash +kubectl get secret -n demo ignite-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +is0x8KNq6hGFfmvU⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -472,15 +490,21 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete igniteopsrequest igops-rotate-auth-generated igops-rotate-auth-user -n demo +```bash +kubectl delete igniteopsrequest igops-rotate-auth-generated igops-rotate-auth-user -n demo +``` igniteopsrequest.ops.kubedb.com "igops-rotate-auth-generated" deleted igniteopsrequest.ops.kubedb.com "igops-rotate-auth-user" deleted -$ kubectl delete secret -n demo ignite-quickstart-auth-user + +```bash +kubectl delete secret -n demo ignite-quickstart-auth-user +``` secret "ignite-quickstart-auth-user" deleted -$ kubectl delete secret -n demo ignite-quickstart-auth -secret "ignite-quickstart-auth" deleted + +```bash +kubectl delete secret -n demo ignite-quickstart-auth ``` +secret "ignite-quickstart-auth" deleted ## Next Steps diff --git a/docs/guides/ignite/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/ignite/scaling/horizontal-scaling/horizontal-scaling.md index 75030c16d2..655d7adbdd 100644 --- a/docs/guides/ignite/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/ignite/scaling/horizontal-scaling/horizontal-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the I To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/ignite](/docs/examples/ignite) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,27 +66,29 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/ignite-cluster.yaml -ignite.kubedb.com/ignite created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/ignite-cluster.yaml ``` +ignite.kubedb.com/ignite created Now, wait until `ignite` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME TYPE VERSION STATUS AGE ignite kubedb.com/v1alpha2 2.17.0 Ready 2m -``` Let's check the number of replicas this ignite has from the Ignite object, number of pods the PetSet have, ```bash -$ kubectl get ignite -n demo ignite -o json | jq '.spec.replicas' +kubectl get ignite -n demo ignite -o json | jq '.spec.replicas' +``` 1 -$ kubectl get petset -n demo ignite -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo ignite -o json | jq '.spec.replicas' ``` +1 We can see from both command that the ignite has 3 replicas. @@ -123,9 +125,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/horizontal-scaling/ig-hscale-up-ops.yaml -igniteopsrequest.ops.kubedb.com/ignite-horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/horizontal-scaling/ig-hscale-up-ops.yaml ``` +igniteopsrequest.ops.kubedb.com/ignite-horizontal-scale-up created #### Verify replicas scaled up successfully @@ -134,16 +136,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ watch kubectl get igniteopsrequest -n demo +watch kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE ignite-horizontal-scale-up HorizontalScaling Successful 2m49s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to scale the ignite. ```bash -$ kubectl describe igniteopsrequest -n demo ignite-horizontal-scale-up +kubectl describe igniteopsrequest -n demo ignite-horizontal-scale-up +``` Name: ignite-horizontal-scale-up Namespace: demo Labels: @@ -225,17 +228,18 @@ Events: Normal UpdatePetSets 7m42s KubeDB Ops-manager Operator successfully reconciled the Ignite with modified node Normal Starting 7m42s KubeDB Ops-manager Operator Resuming Ignite database: demo/ignite Normal Successful 7m42s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ignite for IgniteOpsRequest: ignite-horizontal-scale-up -``` Now, we are going to verify the number of replicas this ignite has from the Ignite object, number of pods the PetSet have, ```bash -$ kubectl get ig -n demo ignite -o json | jq '.spec.replicas' +kubectl get ig -n demo ignite -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo ignite -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo ignite -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the ignite is `3`. That means we have successfully scaled up the replicas of the Ignite. @@ -270,9 +274,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/horizontal-scaling/igops-hscale-down-ops.yaml -igniteopsrequest.ops.kubedb.com/ignite-horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/horizontal-scaling/igops-hscale-down-ops.yaml ``` +igniteopsrequest.ops.kubedb.com/ignite-horizontal-scale-down created #### Verify replicas scaled down successfully @@ -281,16 +285,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ watch kubectl get igniteopsrequest -n demo +watch kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE ignite-horizontal-scale-down HorizontalScaling Successful 75s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to scale the ignite. ```bash -$ kubectl describe igniteopsrequest -n demo ignite-horizontal-scale-down +kubectl describe igniteopsrequest -n demo ignite-horizontal-scale-down +``` Name: ignite-horizontal-scale-down Namespace: demo Labels: @@ -377,17 +382,18 @@ Events: Normal UpdateDatabase 48s KubeDB Ops-manager Operator Successfully updated Ignite Normal Starting 48s KubeDB Ops-manager Operator Resuming Ignite database: demo/ignite Normal Successful 48s KubeDB Ops-manager Operator Successfully resumed Ignite database: demo/ignite for IgniteOpsRequest: ignite-horizontal-scale-down -``` Now, we are going to verify the number of replicas this ignite has from the Ignite object, number of pods the petset have, ```bash -$ kubectl get ig -n demo ignite -o json | jq '.spec.replicas' +kubectl get ig -n demo ignite -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo ignite -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo ignite -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the ignite is `2`. That means we have successfully scaled up the replicas of the Ignite. ## Cleaning Up diff --git a/docs/guides/ignite/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/ignite/scaling/vertical-scaling/vertical-scaling.md index 372292da25..a2a6588c77 100644 --- a/docs/guides/ignite/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/ignite/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/ignite](/docs/examples/ignite) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -69,22 +69,23 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/ig.yaml -ignite.kubedb.com/ig created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/ig.yaml ``` +ignite.kubedb.com/ig created Now, wait until `ig` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME VERSION STATUS AGE ig 2.17.0 Ready 5m56s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -95,7 +96,6 @@ $ kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -142,9 +142,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/vertical-scaling/igops-vscale.yaml -igniteopsrequest.ops.kubedb.com/igops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/scaling/vertical-scaling/igops-vscale.yaml ``` +igniteopsrequest.ops.kubedb.com/igops-vscale created #### Verify Ignite resources updated successfully @@ -153,16 +153,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE igops-vscale VerticalScaling Successful 108s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe igniteopsrequest -n demo igops-vscale +kubectl describe igniteopsrequest -n demo igops-vscale +``` Name: igops-vscale Namespace: demo Labels: @@ -273,12 +274,11 @@ Events: Normal ResumeDatabase 3s KubeDB Ops-manager Operator Successfully resumed Ignite demo/ig Normal Successful 3s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` - Now, we are going to verify from the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -289,7 +289,6 @@ $ kubectl get pod -n demo ig-0 -o json | jq '.spec.containers[].resources' "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the Ignite database. diff --git a/docs/guides/ignite/update-version/update-version.md b/docs/guides/ignite/update-version/update-version.md index ee6b8a642a..0e3bb2b2d3 100644 --- a/docs/guides/ignite/update-version/update-version.md +++ b/docs/guides/ignite/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/ignite](/docs/examples/ignite) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,17 +66,17 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/update-version/ignite.yaml -ignite.kubedb.com/ignite-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/update-version/ignite.yaml ``` +ignite.kubedb.com/ignite-quickstart created Now, wait until `ignite-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get ignite -n demo +kubectl get ignite -n demo +``` NAME VERSION STATUS AGE ignite-quickstart 2.16.0 Ready 109s -``` We are now ready to apply the `IgniteOpsRequest` CR to update this database. @@ -114,9 +114,9 @@ Here, Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/update-version/ig-version-upgrade-ops.yaml -igniteopsrequest.ops.kubedb.com/upgrade-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/update-version/ig-version-upgrade-ops.yaml ``` +igniteopsrequest.ops.kubedb.com/upgrade-topology created #### Verify Ignite version updated successfully @@ -125,16 +125,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` Every 2.0s: kubectl get igniteopsrequest -n demo NAME TYPE STATUS AGE upgrade-topology UpdateVersion Successful 84s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe igniteopsrequest -n demo upgrade-topology +kubectl describe igniteopsrequest -n demo upgrade-topology +``` Name: upgrade-topology Namespace: demo Labels: @@ -234,20 +235,23 @@ Events: Normal RestartPods 7m25s KubeDB Ops-manager Operator Successfully Restarted Ignite nodes Normal Starting 7m25s KubeDB Ops-manager Operator Resuming Ignite database: demo/ignite-quickstart Normal Successful 7m25s KubeDB Ops-manager Operator Successfully updated Ignite version -``` Now, we are going to verify whether the `Ignite` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get ignite -n demo ignite-quickstart -o=jsonpath='{.spec.version}{"\n"}' +kubectl get ignite -n demo ignite-quickstart -o=jsonpath='{.spec.version}{"\n"}' +``` 2.17.0 -$ kubectl get petset -n demo ignite-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo ignite-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/ignite:2.17.0 -$ kubectl get pods -n demo ignite-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/ignite:2.17.0 +```bash +kubectl get pods -n demo ignite-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/ignite:2.17.0 You can see from above, our `Ignite` cluster has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/ignite/volume-expansion/volume-expansion.md b/docs/guides/ignite/volume-expansion/volume-expansion.md index 96e0a9407c..c4cee1c86a 100644 --- a/docs/guides/ignite/volume-expansion/volume-expansion.md +++ b/docs/guides/ignite/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/Ignite](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/ignite) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,10 +47,10 @@ Here, we are going to deploy a `Ignite` standalone using a supported version by At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -81,28 +81,30 @@ spec: Let's create the `Ignite` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Ignite/volume-expansion/ig-standalone.yaml -Ignite.kubedb.com/ig-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Ignite/volume-expansion/ig-standalone.yaml ``` +Ignite.kubedb.com/ig-standalone created Now, wait until `ig-standalone` has status `Ready`. i.e, ```bash -$ kubectl get ig -n demo +kubectl get ig -n demo +``` NAME VERSION STATUS AGE ig-standalone 2.17.0 Ready 2m53s -``` Let's check volume size from PetSet, and from the persistent volume, ```bash -$ kubectl get petset -n demo ig-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo ig-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 1Gi RWO Delete Bound demo/datadir-ig-standalone-0 longhorn 49s -``` You can see the PetSet has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -143,9 +145,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `IgniteOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/volume-expansion/igops-volume-exp-standalone.yaml -igniteopsrequest.ops.kubedb.com/igops-volume-exp-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/ignite/volume-expansion/igops-volume-exp-standalone.yaml ``` +igniteopsrequest.ops.kubedb.com/igops-volume-exp-standalone created #### Verify Ignite Standalone volume expanded successfully @@ -154,15 +156,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `IgniteOpsRequest` to be `Successful`. Run the following command to watch `IgniteOpsRequest` CR, ```bash -$ kubectl get igniteopsrequest -n demo +kubectl get igniteopsrequest -n demo +``` NAME TYPE STATUS AGE igops-volume-exp-standalone VolumeExpansion Successful 75s -``` We can see from the above output that the `IgniteOpsRequest` has succeeded. If we describe the `IgniteOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe igniteopsrequest -n demo igops-volume-exp-standalone +kubectl describe igniteopsrequest -n demo igops-volume-exp-standalone +``` Name: igops-volume-exp-standalone Namespace: demo Labels: @@ -217,18 +220,19 @@ $ kubectl describe igniteopsrequest -n demo igops-volume-exp-standalone Normal ResumeDatabase 29s KubeDB Ops-manager operator Resuming Ignite Normal ResumeDatabase 29s KubeDB Ops-manager operator Successfully Resumed Ignite Normal Successful 29s KubeDB Ops-manager operator Successfully Scaled Database -``` Now, we are going to verify from the `Statefulset`, and the `Persistent Volume` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo ig -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo ig -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 2Gi RWO Delete Bound demo/datadir-ig-0 longhorn 4m29s -``` The above output verifies that we have successfully expanded the volume of the Ignite database. diff --git a/docs/guides/kafka/autoscaler/compute/combined.md b/docs/guides/kafka/autoscaler/compute/combined.md index 5ef2ea0d12..c3329fd138 100644 --- a/docs/guides/kafka/autoscaler/compute/combined.md +++ b/docs/guides/kafka/autoscaler/compute/combined.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,26 +80,27 @@ spec: Let's create the `Kafka` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -109,11 +110,11 @@ $ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources "memory": "1Gi" } } -``` Let's check the Kafka resources, ```bash -$ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -123,7 +124,6 @@ $ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.conta "memory": "1Gi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the kafka. @@ -182,16 +182,17 @@ Here, Let's create the `KafkaAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-combined-autoscaler.yaml -kafkaautoscaler.autoscaling.kubedb.com/kf-combined-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-combined-autoscaler.yaml ``` +kafkaautoscaler.autoscaling.kubedb.com/kf-combined-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `kafkaautoscaler` resource is created successfully, ```bash -$ kubectl describe kafkaautoscaler kf-combined-autoscaler -n demo +kubectl describe kafkaautoscaler kf-combined-autoscaler -n demo +``` Name: kf-combined-autoscaler Namespace: demo Labels: @@ -280,7 +281,6 @@ Status: Memory: 2Gi Vpa Name: kafka-dev Events: -``` So, the `kafkaautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `kafkaopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. @@ -288,24 +288,25 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `kafkaopsrequest` in the demo namespace to see if any `kafkaopsrequest` object is created. After some time you'll see that a `kafkaopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` Every 2.0s: kubectl get kafkaopsrequest -n demo NAME TYPE STATUS AGE kfops-kafka-dev-z8d3l5 VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-dev-z8d3l5 VerticalScaling Successful 3m2s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-dev-z8d3l5 +kubectl describe kafkaopsrequests -n demo kfops-kafka-dev-z8d3l5 +``` Name: kfops-kafka-dev-z8d3l5 Namespace: demo Labels: app.kubernetes.io/component=database @@ -417,12 +418,12 @@ Events: Normal RestartPods 3m35s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 3m35s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 3m35s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-kafka-dev-z8d3l5 -``` Now, we are going to verify from the Pod, and the Kafka yaml whether the resources of the topology database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -433,8 +434,9 @@ $ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources } } - -$ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +```bash +kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -444,7 +446,6 @@ $ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.podTemplate.spec.conta "memory": "1536Mi" } } -``` The above output verifies that we have successfully auto scaled the resources of the Kafka combined cluster. diff --git a/docs/guides/kafka/autoscaler/compute/topology.md b/docs/guides/kafka/autoscaler/compute/topology.md index 5f511de3cd..5338d59798 100644 --- a/docs/guides/kafka/autoscaler/compute/topology.md +++ b/docs/guides/kafka/autoscaler/compute/topology.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -101,28 +101,29 @@ spec: Let's create the `Kafka` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-prod kubedb.com/v1 3.9.0 Ready 118s -``` ## Kafka Topology Autoscaler(Broker) Let's check the Broker Pod containers resources, ```bash -$ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -132,11 +133,11 @@ $ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].r "memory": "1Gi" } } -``` Let's check the Kafka resources for broker, ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTemplate.spec.containers[].resources' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -146,7 +147,6 @@ $ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTe "memory": "1Gi" } } -``` You can see from the above outputs that the resources for broker are same as the one we have assigned while deploying the kafka. @@ -205,17 +205,21 @@ Here, Let's create the `KafkaAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-broker-autoscaler.yaml -kafkaautoscaler.autoscaling.kubedb.com/kf-broker-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-broker-autoscaler.yaml ``` +kafkaautoscaler.autoscaling.kubedb.com/kf-broker-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `kafkaautoscaler` resource is created successfully, ```bash -$ kubectl describe kafkaautoscaler kf-broker-autoscaler -n demo -$ kubectl describe kafkaautoscaler kf-broker-autoscaler -n demo +kubectl describe kafkaautoscaler kf-broker-autoscaler -n demo +``` + +```bash +kubectl describe kafkaautoscaler kf-broker-autoscaler -n demo +``` Name: kf-broker-autoscaler Namespace: demo Labels: @@ -312,7 +316,6 @@ Status: Memory: 2Gi Vpa Name: kafka-prod-broker Events: -``` So, the `kafkaautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `kafkaopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. @@ -320,24 +323,25 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `kafkaopsrequest` in the demo namespace to see if any `kafkaopsrequest` object is created. After some time you'll see that a `kafkaopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` Every 2.0s: kubectl get kafkaopsrequest -n demo NAME TYPE STATUS AGE kfops-kafka-prod-broker-f6qbth VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-prod-broker-f6qbth VerticalScaling Successful 3m2s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-broker-f6qbth +kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-broker-f6qbth +``` Name: kfops-kafka-prod-broker-f6qbth Namespace: demo Labels: app.kubernetes.io/component=database @@ -449,12 +453,12 @@ Events: Normal RestartPods 4m2s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 4m1s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 4m1s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-kafka-prod-broker-f6qbth -``` Now, we are going to verify from the Pod, and the Kafka yaml whether the resources of the broker node has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -465,8 +469,9 @@ $ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].r } } - -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTemplate.spec.containers[].resources' +```bash +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -476,14 +481,14 @@ $ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.podTe "memory": "1536Mi" } } -``` ## Kafka Topology Autoscaler(Controller) Let's check the Controller Pod containers resources, ```bash -$ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -493,11 +498,11 @@ $ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers "memory": "1Gi" } } -``` Let's check the Kafka resources for broker, ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.podTemplate.spec.containers[].resources' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -507,7 +512,6 @@ $ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.p "memory": "1Gi" } } -``` You can see from the above outputs that the resources for controller are same as the one we have assigned while deploying the kafka. @@ -566,16 +570,17 @@ Here, Let's create the `KafkaAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-controller-autoscaler.yaml -kafkaautoscaler.autoscaling.kubedb.com/kf-controller-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/compute/kafka-controller-autoscaler.yaml ``` +kafkaautoscaler.autoscaling.kubedb.com/kf-controller-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `kafkaautoscaler` resource is created successfully, ```bash -$ kubectl describe kafkaautoscaler kf-controller-autoscaler -n demo +kubectl describe kafkaautoscaler kf-controller-autoscaler -n demo +``` Name: kf-controller-autoscaler Namespace: demo Labels: @@ -664,7 +669,6 @@ Status: Memory: 2Gi Vpa Name: kafka-prod-controller Events: -``` So, the `kafkaautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our controller cluster. Our autoscaler operator continuously watches the recommendation generated and creates an `kafkaopsrequest` based on the recommendations, if the controller node pods resources are needed to scaled up or down. @@ -672,24 +676,25 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `kafkaopsrequest` in the demo namespace to see if any `kafkaopsrequest` object is created. After some time you'll see that a `kafkaopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` Every 2.0s: kubectl get kafkaopsrequest -n demo NAME TYPE STATUS AGE kfops-kafka-prod-controller-3vlvzr VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-prod-controller-3vlvzr VerticalScaling Successful 3m2s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-controller-3vlvzr +kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-controller-3vlvzr +``` Name: kfops-kafka-prod-controller-3vlvzr Namespace: demo Labels: app.kubernetes.io/component=database @@ -801,12 +806,12 @@ Events: Normal RestartPods 90s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 90s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 90s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-kafka-prod-controller-3vlvzr -``` Now, we are going to verify from the Pod, and the Kafka yaml whether the resources of the controller node has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -817,8 +822,9 @@ $ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers } } - -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.podTemplate.spec.containers[].resources' +```bash +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.podTemplate.spec.containers[].resources' +``` { "limits": { "memory": "1536Mi" @@ -828,7 +834,6 @@ $ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.p "memory": "1536Mi" } } -``` The above output verifies that we have successfully auto scaled the resources of the Kafka topology cluster for broker and controller. You can create a similar `KafkaAutoscaler` object with both broker and controller resources to auto scale the resources of the Kafka topology cluster. diff --git a/docs/guides/kafka/autoscaler/storage/kafka-combined.md b/docs/guides/kafka/autoscaler/storage/kafka-combined.md index 12d5b28a21..0efaa22c71 100644 --- a/docs/guides/kafka/autoscaler/storage/kafka-combined.md +++ b/docs/guides/kafka/autoscaler/storage/kafka-combined.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Kafka To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,10 +48,10 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -94,33 +94,35 @@ spec: Let's create the `Kafka` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 1Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-0 longhorn 40s pvc-f068d245-718b-4561-b452-f3130bb260f6 1Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-1 longhorn 35s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -162,9 +164,9 @@ Here, Let's create the `KafkaAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/storage/kafka-storage-autoscaler-combined.yaml -kafkaautoscaler.autoscaling.kubedb.com/kf-storage-autoscaler-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/storage/kafka-storage-autoscaler-combined.yaml ``` +kafkaautoscaler.autoscaling.kubedb.com/kf-storage-autoscaler-combined created #### Storage Autoscaling is set up successfully @@ -216,8 +218,9 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the cluster pod and fill the cluster volume using the following commands: -```bash - $ kubectl exec -it -n demo kafka-dev-0 -- bash + ```bash + kubectl exec -it -n demo kafka-dev-0 -- bash + ``` kafka@kafka-dev-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 974M 168K 958M 1% /var/log/kafka @@ -228,31 +231,31 @@ kafka@kafka-dev-0:~$ dd if=/dev/zero of=/var/log/kafka/file.img bs=600M count=1 kafka@kafka-dev-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 974M 601M 358M 63% /var/log/kafka -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 60%. Let's watch the `kafkaopsrequest` in the demo namespace to see if any `kafkaopsrequest` object is created. After some time you'll see that a `kafkaopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` Every 2.0s: kubectl get kafkaopsrequest -n demo NAME TYPE STATUS AGE kfops-kafka-dev-sa4thn VolumeExpansion Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-dev-sa4thn VolumeExpansion Successful 97s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-dev-sa4thn +kubectl describe kafkaopsrequests -n demo kfops-kafka-dev-sa4thn +``` Name: kfops-kafka-dev-sa4thn Namespace: demo Labels: app.kubernetes.io/component=database @@ -434,18 +437,20 @@ Events: Normal ReadyPetSets 20s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 20s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 20s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-kafka-dev-sa4thn -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the combined cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1531054080" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-129be4b9-f7e8-489e-8bc5-cd420e680f51 1462Mi RWO Delete Bound demo/kafka-dev-data-kafka-dev-0 longhorn 30m5s pvc-f068d245-718b-4561-b452-f3130bb260f6 1462Mi RWO Delete Bound demo/kafka-dev-data-kafka-dev-1 longhorn 30m1s -``` The above output verifies that we have successfully autoscaled the volume of the Kafka combined cluster. diff --git a/docs/guides/kafka/autoscaler/storage/kafka-topology.md b/docs/guides/kafka/autoscaler/storage/kafka-topology.md index a3ffb8cb97..048aa8a969 100644 --- a/docs/guides/kafka/autoscaler/storage/kafka-topology.md +++ b/docs/guides/kafka/autoscaler/storage/kafka-topology.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Kafka To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,10 +48,10 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -95,36 +95,42 @@ spec: Let's create the `Kafka` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-prod kubedb.com/v1 3.9.0 Ready 119s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-128d9138-64da-4021-8a7c-7ca80823e842 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-1 longhorn 33s pvc-27fe9102-2e7d-41e0-b77d-729a82c64e21 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-0 longhorn 51s pvc-3bb98ba1-9cea-46ad-857f-fc843c265d57 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-0 longhorn 50s pvc-68f86aac-33d1-423a-bc56-8a905b546db2 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-1 longhorn 32s -``` You can see the petset for both broker and controller has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -171,9 +177,9 @@ Here, Let's create the `KafkaAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/storage/kafka-storage-autoscaler-topology.yaml -kafkaautoscaler.autoscaling.kubedb.com/kf-storage-autoscaler-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/autoscaler/storage/kafka-storage-autoscaler-topology.yaml ``` +kafkaautoscaler.autoscaling.kubedb.com/kf-storage-autoscaler-topology created #### Storage Autoscaling is set up successfully @@ -235,7 +241,8 @@ We are autoscaling volume for both broker and controller. So we need to fill up 1. Let's exec into the broker pod and fill the cluster volume using the following commands: ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- bash +kubectl exec -it -n demo kafka-prod-broker-0 -- bash +``` kafka@kafka-prod-broker-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-27fe9102-2e7d-41e0-b77d-729a82c64e21 974M 256K 958M 1% /var/log/kafka @@ -246,12 +253,12 @@ kafka@kafka-prod-broker-0:~$ dd if=/dev/zero of=/var/log/kafka/file.img bs=600M kafka@kafka-prod-broker-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-27fe9102-2e7d-41e0-b77d-729a82c64e21 974M 601M 358M 63% /var/log/kafka -``` 2. Let's exec into the controller pod and fill the cluster volume using the following commands: ```bash -$ kubectl exec -it -n demo kafka-prod-controller-0 -- bash +kubectl exec -it -n demo kafka-prod-controller-0 -- bash +``` kafka@kafka-prod-controller-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-3bb98ba1-9cea-46ad-857f-fc843c265d57 974M 192K 958M 1% /var/log/kafka @@ -262,7 +269,6 @@ kafka@kafka-prod-controller-0:~$ dd if=/dev/zero of=/var/log/kafka/file.img bs=6 kafka@kafka-prod-controller-0:~$ df -h /var/log/kafka Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-3bb98ba1-9cea-46ad-857f-fc843c265d57 974M 601M 358M 63% /var/log/kafka -``` So, from the above output we can see that the storage usage is 63% for both nodes, which exceeded the `usageThreshold` 60%. @@ -270,24 +276,25 @@ There will be two `KafkaOpsRequest` created for both broker and controller to ex Let's watch the `kafkaopsrequest` in the demo namespace to see if any `kafkaopsrequest` object is created. After some time you'll see that a `kafkaopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` Every 2.0s: kubectl get kafkaopsrequest -n demo NAME TYPE STATUS AGE kfops-kafka-prod-7qwpbn VolumeExpansion Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-prod-7qwpbn VolumeExpansion Successful 2m37s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-7qwpbn +kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-7qwpbn +``` Name: kfops-kafka-prod-7qwpbn Namespace: demo Labels: app.kubernetes.io/component=database @@ -450,30 +457,30 @@ Events: Normal ReadyPetSets 101s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 101s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 101s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-kafka-prod-7qwpbn -``` After a few minutes, another `KafkaOpsRequest` of type `VolumeExpansion` will be created for the controller node. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-prod-7qwpbn VolumeExpansion Successful 2m47s kfops-kafka-prod-sa4thn VolumeExpansion Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-kafka-prod-7qwpbn VolumeExpansion Successful 4m47s kfops-kafka-prod-sa4thn VolumeExpansion Successful 2m10s -``` We can see from the above output that the `KafkaOpsRequest` `kfops-kafka-prod-sa4thn` has also succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-2ta9m6 +kubectl describe kafkaopsrequests -n demo kfops-kafka-prod-2ta9m6 +``` Name: kfops-kafka-prod-2ta9m6 Namespace: demo Labels: app.kubernetes.io/component=database @@ -645,22 +652,27 @@ Events: Normal ReadyPetSets 3m7s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 3m7s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 3m7s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-kafka-prod-2ta9m6 -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the topology cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2041405440" -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2041405440" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-128d9138-64da-4021-8a7c-7ca80823e842 1948Mi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-1 longhorn 33s pvc-27fe9102-2e7d-41e0-b77d-729a82c64e21 1948Mi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-0 longhorn 51s pvc-3bb98ba1-9cea-46ad-857f-fc843c265d57 1948Mi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-0 longhorn 50s pvc-68f86aac-33d1-423a-bc56-8a905b546db2 1948Mi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-1 longhorn 32s -``` The above output verifies that we have successfully autoscaled the volume of the Kafka topology cluster for both broker and controller. diff --git a/docs/guides/kafka/cli/cli.md b/docs/guides/kafka/cli/cli.md index 286a0ec120..a071d28ec5 100644 --- a/docs/guides/kafka/cli/cli.md +++ b/docs/guides/kafka/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a Kafka object as specified in `kafka.yaml`. ```bash -$ kubectl create -f kafka.yaml -kafka.kubedb.com/kafka created +kubectl create -f kafka.yaml ``` +kafka.kubedb.com/kafka created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f kafka.yaml --namespace=kube-system -kafka.kubedb.com/kafka created +kubectl create -f kafka.yaml --namespace=kube-system ``` +kafka.kubedb.com/kafka created `kubectl create` command also considers `stdin` as input. @@ -45,18 +45,18 @@ cat kafka.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all Kafka objects in `default` namespace, run the following command: ```bash -$ kubectl get kafka +kubectl get kafka +``` NAME TYPE VERSION STATUS AGE kafka kubedb.com/v1alpha2 3.9.0 Ready 36m -``` You can also use short-form (`kf`) for kafka CR. ```bash -$ kubectl get kf +kubectl get kf +``` NAME TYPE VERSION STATUS AGE kafka kubedb.com/v1alpha2 3.9.0 Ready 36m -``` To get YAML of an object, use `--output=yaml` or `-oyaml` flag. Use `-n` flag for referring namespace. @@ -172,7 +172,8 @@ status: To get JSON of an object, use `--output=json` or `-ojson` flag. ```bash -$ kubectl get kf kafka -n demo -ojson +kubectl get kf kafka -n demo -ojson +``` { "apiVersion": "kubedb.com/v1alpha2", "kind": "Kafka", @@ -324,12 +325,12 @@ $ kubectl get kf kafka -n demo -ojson "phase": "Ready" } } -``` To list all KubeDB objects managed by KubeDB including secrets, use following command: ```bash -$ kubectl get all,secret -A -l app.kubernetes.io/managed-by=kubedb.com -owide +kubectl get all,secret -A -l app.kubernetes.io/managed-by=kubedb.com -owide +``` NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES demo pod/kafka-broker-0 1/1 Running 0 45m 10.244.0.49 kind-control-plane demo pod/kafka-broker-1 1/1 Running 0 45m 10.244.0.53 kind-control-plane @@ -356,14 +357,14 @@ demo secret/kafka-client-cert kubernetes.io/tls 3 4 demo secret/kafka-controller-config Opaque 3 45m demo secret/kafka-keystore-cred Opaque 3 46m demo secret/kafka-server-cert kubernetes.io/tls 5 46m -``` Flag `--output=wide` or `-owide` is used to print additional information. List command supports short names for each object types. You can use it like `kubectl get `. You can print labels with objects. The following command will list all Snapshots with their corresponding labels. ```bash -$ kubectl get pods -n demo --show-labels +kubectl get pods -n demo --show-labels +``` NAME READY STATUS RESTARTS AGE LABELS kafka-broker-0 1/1 Running 0 47m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com,controller-revision-hash=kafka-broker-5f568d57c9,kubedb.com/role=broker,petset.kubernetes.io/pod-name=kafka-broker-0 kafka-broker-1 1/1 Running 0 47m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com,controller-revision-hash=kafka-broker-5f568d57c9,kubedb.com/role=broker,petset.kubernetes.io/pod-name=kafka-broker-1 @@ -371,21 +372,21 @@ kafka-broker-2 1/1 Running 0 47m app.kubernetes.io/com kafka-controller-0 1/1 Running 0 47m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com,controller-revision-hash=kafka-controller-96ddd885f,kubedb.com/role=controller,petset.kubernetes.io/pod-name=kafka-controller-0 kafka-controller-1 1/1 Running 0 47m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com,controller-revision-hash=kafka-controller-96ddd885f,kubedb.com/role=controller,petset.kubernetes.io/pod-name=kafka-controller-1 kafka-controller-2 1/1 Running 3 (47m ago) 47m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com,controller-revision-hash=kafka-controller-96ddd885f,kubedb.com/role=controller,petset.kubernetes.io/pod-name=kafka-controller-2 -``` You can also filter list using `--selector` flag. ```bash -$ kubectl get services -n demo --selector='app.kubernetes.io/name=kafkas.kubedb.com' --show-labels +kubectl get services -n demo --selector='app.kubernetes.io/name=kafkas.kubedb.com' --show-labels +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS kafka-broker ClusterIP None 9092/TCP,29092/TCP 49m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com kafka-controller ClusterIP None 9093/TCP 49m app.kubernetes.io/component=database,app.kubernetes.io/instance=kafka,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=kafkas.kubedb.com -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name -n demo +kubectl get all -o name -n demo +``` pod/kafka-broker-0 pod/kafka-broker-1 pod/kafka-broker-2 @@ -397,14 +398,14 @@ service/kafka-controller petset.apps/kafka-broker petset.apps/kafka-controller appbinding.appcatalog.appscode.com/kafka -``` ### How to Describe Objects `kubectl describe` command allows users to describe any KubeDB object. The following command will describe Kafka instance `kafka` with relevant information. ```bash -$ kubectl describe -n demo kf kafka +kubectl describe -n demo kf kafka +``` Name: kafka Namespace: demo Labels: @@ -617,7 +618,6 @@ Events: Warning Failed 50m KubeDB Ops-manager Operator Fail to be ready database: "kafka". Reason: services "kafka-broker" not found Normal Successful 50m KubeDB Ops-manager Operator Successfully created Kafka server certificates Normal Successful 50m KubeDB Ops-manager Operator Successfully created Kafka client-certificates -``` `kubectl describe` command provides following basic information about a database. @@ -635,19 +635,19 @@ To hide events on KubeDB object, use flag `--show-events=false` To describe all Kafka objects in `default` namespace, use following command ```bash -$ kubectl describe kf +kubectl describe kf ``` To describe all Kafka objects from every namespace, provide `--all-namespaces` flag. ```bash -$ kubectl describe kf --all-namespaces +kubectl describe kf --all-namespaces ``` You can also describe KubeDb objects with matching labels. The following command will describe all Kafka objects with specified labels from every namespace. ```bash -$ kubectl describe kf --all-namespaces --selector='app.kubernetes.io/component=database' +kubectl describe kf --all-namespaces --selector='app.kubernetes.io/component=database' ``` To learn about various options of `describe` command, please visit [here](/docs/reference/cli/kubectl-dba_describe.md). @@ -679,16 +679,16 @@ Kafka: `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a Kafka instance `kafka` in demo namespace ```bash -$ kubectl delete kf kafka -n demo -kafka.kubedb.com "kafka" deleted +kubectl delete kf kafka -n demo ``` +kafka.kubedb.com "kafka" deleted You can also use YAML files to delete objects. The following command will delete an Kafka using the type and name specified in `kafka.yaml`. ```bash -$ kubectl delete -f kafka.yaml -kafka.kubedb.com "kafka" deleted +kubectl delete -f kafka.yaml ``` +kafka.kubedb.com "kafka" deleted `kubectl delete` command also takes input from `stdin`. @@ -699,20 +699,25 @@ cat kafka.yaml | kubectl delete -f - To delete database with matching labels, use `--selector` flag. The following command will delete kafka with label `app.kubernetes.io/instance=kafka`. ```bash -$ kubectl delete kf -l app.kubernetes.io/instance=kafka +kubectl delete kf -l app.kubernetes.io/instance=kafka ``` ## Using Kubectl You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # List objects -$ kubectl get kafka -$ kubectl get kafka.kubedb.com +```bash +kubectl get kafka +``` + +```bash +kubectl get kafka.kubedb.com +``` # Delete objects -$ kubectl delete kafka +```bash +kubectl delete kafka ``` ## Next Steps diff --git a/docs/guides/kafka/clustering/combined-cluster/index.md b/docs/guides/kafka/clustering/combined-cluster/index.md index eaade2165e..c91836b45c 100644 --- a/docs/guides/kafka/clustering/combined-cluster/index.md +++ b/docs/guides/kafka/clustering/combined-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/clustering) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,14 +64,15 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-standalone.yaml -kafka.kubedb.com/kafka-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-standalone.yaml ``` +kafka.kubedb.com/kafka-standalone created Watch the bootstrap progress: ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-standalone kubedb.com/v1alpha2 3.9.0 Provisioning 8s kafka-standalone kubedb.com/v1alpha2 3.9.0 Provisioning 14s @@ -77,13 +80,13 @@ kafka-standalone kubedb.com/v1alpha2 3.9.0 Provisioning 35s kafka-standalone kubedb.com/v1alpha2 3.9.0 Provisioning 35s kafka-standalone kubedb.com/v1alpha2 3.9.0 Provisioning 36s kafka-standalone kubedb.com/v1alpha2 3.9.0 Ready 41s -``` Hence, the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Kafka CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-standalone' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-standalone' +``` NAME READY STATUS RESTARTS AGE pod/kafka-standalone-0 1/1 Running 0 8m56s @@ -102,7 +105,6 @@ secret/kafka-standalone-config Opaque 2 8m59s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/kafka-standalone-data-kafka-standalone-0 Bound pvc-56f8284a-249e-4444-ab3d-31e01662a9a0 1Gi RWO standard 8m56s -``` ## Create Multi-Node Combined Kafka Cluster @@ -131,27 +133,28 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-multinode.yaml -kafka.kubedb.com/kafka-multinode created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-multinode.yaml ``` +kafka.kubedb.com/kafka-multinode created Watch the bootstrap progress: ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` kafka-multinode kubedb.com/v1alpha2 3.9.0 Provisioning 9s kafka-multinode kubedb.com/v1alpha2 3.9.0 Provisioning 14s kafka-multinode kubedb.com/v1alpha2 3.9.0 Provisioning 18s kafka-multinode kubedb.com/v1alpha2 3.9.0 Provisioning 2m6s kafka-multinode kubedb.com/v1alpha2 3.9.0 Provisioning 2m8s kafka-multinode kubedb.com/v1alpha2 3.9.0 Ready 2m14s -``` Hence, the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Kafka CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-multinode' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-multinode' +``` NAME READY STATUS RESTARTS AGE pod/kafka-multinode-0 1/1 Running 0 6m2s pod/kafka-multinode-1 1/1 Running 0 5m56s @@ -174,17 +177,16 @@ NAME STATUS VOLUME persistentvolumeclaim/kafka-multinode-data-kafka-multinode-0 Bound pvc-15cc2329-15ba-4781-8b7f-f0fe6cf81614 1Gi RWO standard 6m2s persistentvolumeclaim/kafka-multinode-data-kafka-multinode-1 Bound pvc-bc3773cc-dff0-458c-b71a-7ef6aa877549 1Gi RWO standard 5m56s persistentvolumeclaim/kafka-multinode-data-kafka-multinode-2 Bound pvc-e4829946-b2bb-473e-84d9-c5f9c360f3f0 1Gi RWO standard 5m51s -``` ## Publish & Consume messages with Kafka We will create a Kafka topic using `kafka-topics.sh` script which is provided by kafka container itself. We will use `kafka console producer` and `kafka console consumer` as clients for publishing messages to the topic and then consume those messages. Exec into one of the kafka brokers in interactive mode first. ```bash -$ kubectl exec -it -n demo kafka-multinode-0 -- bash +kubectl exec -it -n demo kafka-multinode-0 -- bash +``` kafka@kafka-multinode-0:~# pwd /opt/kafka -``` You will find a file named `clientauth.properties` in the config directory. This file is generated by the operator which contains necessary authentication/authorization configurations that are required during publishing or subscribing messages to a kafka topic. @@ -198,7 +200,8 @@ sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule require Now, we have to use a bootstrap server to perform operations in a kafka broker. For this demo, we are going to use the http endpoint of the headless service `kafka-multinode-pods` as bootstrap server for publishing & consuming messages to kafka brokers. These endpoints are pointing to all the kafka broker pods. We will set an environment variable for the `clientauth.properties` filepath as well. At first, describe the service to get the http endpoints. ```bash -$ kubectl describe svc -n demo kafka-multinode-pods +kubectl describe svc -n demo kafka-multinode-pods +``` Name: kafka-multinode-pods Namespace: demo Labels: app.kubernetes.io/component=database @@ -223,7 +226,6 @@ TargetPort: internal/TCP Endpoints: 10.244.0.69:29092,10.244.0.71:29092,10.244.0.73:29092 Session Affinity: None Events: -``` Use the `http endpoints` and `clientauth.properties` file to set environment variables. These environment variables will be useful for handling console command operations easily. @@ -292,17 +294,27 @@ Notice that, messages are coming to the consumer as you continue sending message TO clean up the k8s resources created by this tutorial, run: -```bash # standalone cluster -$ kubectl patch -n demo kf kafka-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete kf -n demo kafka-standalone +```bash +kubectl patch -n demo kf kafka-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete kf -n demo kafka-standalone +``` # multinode cluster -$ kubectl patch -n demo kf kafka-multinode -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete kf -n demo kafka-multinode +```bash +kubectl patch -n demo kf kafka-multinode -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete kf -n demo kafka-multinode +``` # delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/kafka/clustering/topology-cluster/index.md b/docs/guides/kafka/clustering/topology-cluster/index.md index 35d2f45a22..ea24c2a9ab 100644 --- a/docs/guides/kafka/clustering/topology-cluster/index.md +++ b/docs/guides/kafka/clustering/topology-cluster/index.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/clustering) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -74,9 +76,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml -issuer.cert-manager.io/kafka-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml ``` +issuer.cert-manager.io/kafka-ca-issuer created ### Provision TLS secure Kafka @@ -122,26 +124,27 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/clustering/kf-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Watch the bootstrap progress: ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1alpha2 3.9.0 Provisioning 6s kafka-prod kubedb.com/v1alpha2 3.9.0 Provisioning 14s kafka-prod kubedb.com/v1alpha2 3.9.0 Provisioning 50s kafka-prod kubedb.com/v1alpha2 3.9.0 Ready 68s -``` Hence, the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Kafka CRO: ```bash -$ kubectl get all,petset,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-prod' +kubectl get all,petset,secret,pvc -n demo -l 'app.kubernetes.io/instance=kafka-prod' +``` NAME READY STATUS RESTARTS AGE pod/kafka-prod-broker-0 1/1 Running 0 4m10s pod/kafka-prod-broker-1 1/1 Running 0 4m4s @@ -175,17 +178,16 @@ persistentvolumeclaim/kafka-prod-data-kafka-prod-broker-2 Bound pvc-b7e persistentvolumeclaim/kafka-prod-data-kafka-prod-controller-0 Bound pvc-8e3ae399-fb87-4906-91d8-3f5a09014d2a 1Gi RWO standard 4m8s persistentvolumeclaim/kafka-prod-data-kafka-prod-controller-1 Bound pvc-faf53264-e125-430a-9a73-c2c73da1b97e 1Gi RWO standard 4m persistentvolumeclaim/kafka-prod-data-kafka-prod-controller-2 Bound pvc-d962a03b-7af7-41ba-9d53-044e8ffa03f2 1Gi RWO standard 3m53s -``` ## Publish & Consume messages with Kafka We will create a Kafka topic using `kafka-topics.sh` script which is provided by kafka container itself. We will use `kafka console producer` and `kafka console consumer` as clients for publishing messages to the topic and then consume those messages. Exec into one of the kafka broker pods in interactive mode first. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- bash +kubectl exec -it -n demo kafka-prod-broker-0 -- bash +``` root@kafka-prod-broker-0:~# pwd /opt/kafka -``` You will find a file named `clientauth.properties` in the config directory. This file is generated by the operator which contains necessary authentication/authorization configurations that are required during publishing or subscribing messages to a kafka topic. @@ -201,7 +203,8 @@ ssl.truststore.password=*********** Now, we have to use a bootstrap server to perform operations in a kafka broker. For this demo, we are going to use the http endpoint of the headless service `kafka-prod-broker` as bootstrap server for publishing & consuming messages to kafka brokers. These endpoints are pointing to all the kafka broker pods. We will set an environment variable for the `clientauth.properties` filepath as well. At first, describe the service to get the http endpoints. ```bash -$ kubectl describe svc -n demo kafka-prod-pods +kubectl describe svc -n demo kafka-prod-pods +``` Name: kafka-prod-pods Namespace: demo Labels: app.kubernetes.io/component=database @@ -226,7 +229,6 @@ TargetPort: local/TCP Endpoints: 10.244.0.33:29092,10.244.0.37:29092,10.244.0.41:29092 Session Affinity: None Events: -``` Use the `http endpoints` and `clientauth.properties` file to set environment variables. These environment variables will be useful for handling console command operations easily. @@ -296,17 +298,27 @@ Notice that, messages are coming to the consumer as you continue sending message TO clean up the k8s resources created by this tutorial, run: -```bash # standalone cluster -$ kubectl patch -n demo kf kafka-prod -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete kf -n demo kafka-prod +```bash +kubectl patch -n demo kf kafka-prod -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete kf -n demo kafka-prod +``` # multinode cluster -$ kubectl patch -n demo kf kafka-prod -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete kf -n demo kafka-prod +```bash +kubectl patch -n demo kf kafka-prod -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete kf -n demo kafka-prod +``` # delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/kafka/concepts/connectcluster.md b/docs/guides/kafka/concepts/connectcluster.md index 4a13d69a25..6e2b73d754 100644 --- a/docs/guides/kafka/concepts/connectcluster.md +++ b/docs/guides/kafka/concepts/connectcluster.md @@ -195,11 +195,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic kcc-auth -n demo \ +kubectl create secret generic kcc-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "kcc-auth" created ``` +secret "kcc-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/kafka/concepts/kafka.md b/docs/guides/kafka/concepts/kafka.md index bbc7c47a09..3d5f8b3a3b 100644 --- a/docs/guides/kafka/concepts/kafka.md +++ b/docs/guides/kafka/concepts/kafka.md @@ -179,11 +179,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic kf-auth -n demo \ +kubectl create secret generic kf-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "kf-auth" created ``` +secret "kf-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/kafka/configuration/kafka-combined.md b/docs/guides/kafka/configuration/kafka-combined.md index 574ef4ba3b..faa18af543 100644 --- a/docs/guides/kafka/configuration/kafka-combined.md +++ b/docs/guides/kafka/configuration/kafka-combined.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/configuration/ ) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Kafka CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -74,9 +76,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/configsecret-combined.yaml -secret/configsecret-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/configsecret-combined.yaml ``` +secret/configsecret-combined created Now that the config secret is created, it needs to be mentioned in the [Kafka](/docs/guides/kafka/concepts/kafka.md) object's yaml: @@ -105,21 +107,21 @@ spec: Now, create the Kafka object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait for the Kafka to become ready: ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` ## Verify Configuration @@ -128,9 +130,9 @@ Lets exec into one of the kafka pod that we have created and check the configura Exec into the Kafka pod: ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- bash -kafka@kafka-dev-0:~$ +kubectl exec -it -n demo kafka-dev-0 -- bash ``` +kafka@kafka-dev-0:~$ Now, execute the following commands to see the configurations: ```bash @@ -148,9 +150,15 @@ Here, we can see that our given configuration is applied to the Kafka cluster fo To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete kf -n demo kafka-dev -$ kubectl delete secret -n demo configsecret-combined -$ kubectl delete namespace demo +kubectl delete kf -n demo kafka-dev +``` + +```bash +kubectl delete secret -n demo configsecret-combined +``` + +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/kafka/configuration/kafka-topology.md b/docs/guides/kafka/configuration/kafka-topology.md index 76b02487f7..20f66da111 100644 --- a/docs/guides/kafka/configuration/kafka-topology.md +++ b/docs/guides/kafka/configuration/kafka-topology.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/configuration/ ) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -41,10 +43,10 @@ demo Active 9s We will have to provide `StorageClass` in Kafka CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -84,9 +86,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/configsecret-topology.yaml -secret/configsecret-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/configsecret-topology.yaml ``` +secret/configsecret-topology created Now that the config secret is created, it needs to be mention in the [Kafka](/docs/guides/kafka/concepts/kafka.md) object's yaml: @@ -126,21 +128,21 @@ spec: Now, create the Kafka object by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/configuration/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait for the Kafka to become ready: ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 5s kafka-prod kubedb.com/v1 3.9.0 Provisioning 7s . . kafka-prod kubedb.com/v1 3.9.0 Ready 2m -``` ## Verify Configuration @@ -149,9 +151,9 @@ Let's exec into one of the kafka broker pod that we have created and check the c Exec into the Kafka broker: ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- bash -kafka@kafka-prod-broker-0:~$ +kubectl exec -it -n demo kafka-prod-broker-0 -- bash ``` +kafka@kafka-prod-broker-0:~$ Now, execute the following commands to see the configurations: ```bash @@ -169,9 +171,9 @@ Now, let's exec into one of the kafka controller pod that we have created and ch Exec into the Kafka controller: ```bash -$ kubectl exec -it -n demo kafka-prod-controller-0 -- bash -kafka@kafka-prod-controller-0:~$ +kubectl exec -it -n demo kafka-prod-controller-0 -- bash ``` +kafka@kafka-prod-controller-0:~$ Now, execute the following commands to see the metadata storage directory: ```bash @@ -186,11 +188,15 @@ Here, we can see that our given configuration is applied to the controller. Meta To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete kf -n demo kafka-dev +kubectl delete kf -n demo kafka-dev +``` -$ kubectl delete secret -n demo configsecret-combined +```bash +kubectl delete secret -n demo configsecret-combined +``` -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/kafka/connectcluster/connectcluster.md b/docs/guides/kafka/connectcluster/connectcluster.md index 00f3d6c48c..e26b81ebfd 100644 --- a/docs/guides/kafka/connectcluster/connectcluster.md +++ b/docs/guides/kafka/connectcluster/connectcluster.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/connectcluster) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -77,9 +79,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kcc-issuer.yaml -issuer.cert-manager.io/connectcluster-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kcc-issuer.yaml ``` +issuer.cert-manager.io/connectcluster-ca-issuer created ### Provision TLS secured ConnectCluster @@ -142,7 +144,8 @@ We are also running our cluster with custom configuration. The custom configurat Create a file named `config.properties` with the following content: ```bash -$ cat config.properties +cat config.properties +``` key.converter.schemas.enable=true value.converter.schemas.enable=true internal.key.converter.schemas.enable=true @@ -151,38 +154,38 @@ internal.key.converter=org.apache.kafka.connect.json.JsonConverter internal.value.converter=org.apache.kafka.connect.json.JsonConverter key.converter=org.apache.kafka.connect.json.JsonConverter value.converter=org.apache.kafka.connect.json.JsonConverter -``` Create a secret named `connectcluster-custom-config` with the `config.properties` file: ```bash -$ kubectl create secret generic connectcluster-custom-config --from-file=./config.properties -n demo +kubectl create secret generic connectcluster-custom-config --from-file=./config.properties -n demo ``` Let's create the ConnectCluster using the above YAML: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/kcc-distributed.yaml -connectcluster.kafka.kubedb.com/connectcluster-distributed created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/kcc-distributed.yaml ``` +connectcluster.kafka.kubedb.com/connectcluster-distributed created Watch the bootstrap progress: ```bash -$ kubectl get kcc -n demo -w +kubectl get kcc -n demo -w +``` NAME TYPE VERSION STATUS AGE connectcluster-distributed kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 0s connectcluster-distributed kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 33s . . connectcluster-distributed kafka.kubedb.com/v1alpha1 3.9.0 Ready 97s -``` Hence, the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of ConnectCluster: ```bash -$ kubectl get all,petset,secret -n demo -l 'app.kubernetes.io/instance=connectcluster-distributed' +kubectl get all,petset,secret -n demo -l 'app.kubernetes.io/instance=connectcluster-distributed' +``` NAME READY STATUS RESTARTS AGE pod/connectcluster-distributed-0 1/1 Running 0 8m55s pod/connectcluster-distributed-1 1/1 Running 0 8m52s @@ -204,7 +207,6 @@ secret/connectcluster-distributed-connect-cred kubernetes.io/basic-au secret/connectcluster-distributed-connect-keystore-cred Opaque 3 17m secret/connectcluster-distributed-kafka-client-cred Opaque 5 17m secret/connectcluster-distributed-server-connect-cert kubernetes.io/tls 5 17m -``` We are going to use the `postgres` source connector to stream data from a Postgres database to Kafka and the `jdbc` sink connector to stream data from Kafka to MySQL database. To do that, we need to create a Postgres database. You can create a Postgres database by following this [tutorial](/docs/guides/postgres/quickstart/quickstart.md). @@ -226,7 +228,8 @@ postgres=# show wal_level; To create a Postgres source connector with KubeDB `Connector` CR, you need to create a secret that contains the Postgres database credentials and the connector configuration. The secret should have the following configuration with filename `config.properties`: ```bash -$ cat config.properties +cat config.properties +``` connector.class=io.debezium.connector.postgresql.PostgresConnector tasks.max=1 database.hostname=postgres.demo.svc @@ -240,7 +243,6 @@ value.converter=org.apache.kafka.connect.json.JsonConverter value.converter.schemas.enable=true database.whitelist=public.users database.history.kafka.topic=schema-changes.users -``` Here, - `connector.class` - specifies the connector class. Here, the Postgres source connector will be used. - `tasks.max` - specifies the maximum number of tasks that should be created for this connector. @@ -255,7 +257,7 @@ ase. Update the value with the actual name of your Postgres database that you wa Now, create the secret named `postgres-source-connector-config` with the `config.properties` file: ```bash -$ kubectl create secret generic postgres-source-connector-config --from-file=./config.properties -n demo +kubectl create secret generic postgres-source-connector-config --from-file=./config.properties -n demo ``` Now, create a `Connector` CR to create the Postgres source connector: @@ -344,7 +346,8 @@ Now, let's create a JDBC sink connector to stream data from the Kafka topic to a To create a JDBC sink connector with KubeDB `Connector` CR, you need to create a secret that contains the MySQL database credentials and the connector configuration. The secret should have the following configuration with filename `config.properties`: ```bash -$ cat config.properties +cat config.properties +``` heartbeat.interval.ms=3000 autoReconnect=true connector.class=io.debezium.connector.jdbc.JdbcSinkConnector @@ -365,7 +368,6 @@ value.converter=org.apache.kafka.connect.json.JsonConverter table.name.format=${topic} topics=postgres.public.users pk.mode=kafka -``` Here, - `heartbeat.interval.ms` - specifies the interval in milliseconds at which the connector should send heartbeat messages to the database. - `autoReconnect` - specifies whether the connector should automatically reconnect to the database in case of a connection failure. @@ -384,7 +386,7 @@ Here, Now, create the secret named `mysql-sink-connector-config` with the `config.properties` file: ```bash -$ kubectl create secret generic mysql-sink-connector-config --from-file=./config.properties -n demo +kubectl create secret generic mysql-sink-connector-config --from-file=./config.properties -n demo ``` Before creating connector, create the database `sink_database` in MySQL database which is mentioned in the `connection.url` of the `config.properties` file. Example: `jdbc:mysql://:/`. @@ -484,15 +486,19 @@ You can customize the connector configuration by updating the `config.properties To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo connectcluster connectcluster-distributed -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo connectcluster connectcluster-distributed -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` connectcluster.kafka.kubedb.com/connectcluster-distributed patched -$ kubectl delete kf connectcluster-distributed -n demo +```bash +kubectl delete kf connectcluster-distributed -n demo +``` connectcluster.kafka.kubedb.com "connectcluster-distributed" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/kafka/connectcluster/quickstart.md b/docs/guides/kafka/connectcluster/quickstart.md index c9750000eb..ecd3c20989 100644 --- a/docs/guides/kafka/connectcluster/quickstart.md +++ b/docs/guides/kafka/connectcluster/quickstart.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [examples/kafka/connectcluster](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/connectcluster) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,7 +48,8 @@ demo Active 9s When you install the KubeDB operator, it registers a CRD named [KafkaVersion](/docs/guides/kafka/concepts/kafkaversion.md). ConnectCluster Version is using the KafkaVersion CR to define the specification of ConnectCluster. The installation process comes with a set of tested KafkaVersion objects. Let's check available KafkaVersions by, ```bash -$ kubectl get kfversion +kubectl get kfversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 3.5.2 3.5.2 ghcr.io/appscode-images/kafka-kraft:3.5.2 7d19h 3.6.1 3.6.1 ghcr.io/appscode-images/kafka-kraft:3.6.1 7d19h @@ -55,8 +58,6 @@ NAME VERSION DB_IMAGE DEPRECATED AGE 3.9.0 3.9.0 ghcr.io/appscode-images/kafka-kraft:3.9.0 7d19h 4.0.0 4.0.0 ghcr.io/appscode-images/kafka:4.0.0 7d19h -``` - Notice the `DEPRECATED` column. Here, `true` means that this KafkaVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated KafkaVersion. You can also use the short from `kfversion` to check available KafkaVersions. In this tutorial, we will use `3.9.0` KafkaVersion CR to create a Kafka Connect cluster. @@ -66,8 +67,8 @@ In this tutorial, we will use `3.9.0` KafkaVersion CR to create a Kafka Connect When you install the KubeDB operator, it registers a CRD named [KafkaConnectorVersion](/docs/guides/kafka/concepts/kafkaversion.md). KafkaConnectorVersion use to load connector-plugins to run ConnectCluster worker node(ex. mongodb-source/sink). The installation process comes with a set of tested KafkaConnectorVersion objects. Let's check available KafkaConnectorVersions by, ```bash -$ kubectl get kcversion - +kubectl get kcversion +``` NAME VERSION CONNECTOR_IMAGE DEPRECATED AGE gcs-0.13.0 0.13.0 ghcr.io/appscode-images/kafka-connector-gcs:0.13.0 28h jdbc-2.6.1.final 2.6.1 ghcr.io/appscode-images/kafka-connector-jdbc:2.6.1.final 28h @@ -80,7 +81,6 @@ mysql-3.0.5.final 3.0.5 ghcr.io/appscode-images/kafka-connector-mysql:3 postgres-2.7.4.final 2.7.4 ghcr.io/appscode-images/kafka-connector-postgres:2.7.4.final 28h postgres-3.0.5.final 3.0.5 ghcr.io/appscode-images/kafka-connector-postgres:3.0.5.final 28h s3-2.15.0 2.15.0 ghcr.io/appscode-images/kafka-connector-s3:2.15.0 28h -``` Notice the `DEPRECATED` column. Here, `true` means that this KafkaConnectorVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated KafkaConnectorVersion. You can also use the short from `kcversion` to check available KafkaConnectorVersions. @@ -156,14 +156,15 @@ Before create ConnectCluster, you have to deploy a `Kafka` cluster first. To dep Let's create the ConnectCluster CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/connectcluster-quickstart.yaml -connectcluster.kafka.kubedb.com/connectcluster-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/connectcluster-quickstart.yaml ``` +connectcluster.kafka.kubedb.com/connectcluster-quickstart created The ConnectCluster's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the ConnectCluster. ```bash -$ kubectl get connectcluster -n demo -w +kubectl get connectcluster -n demo -w +``` NAME TYPE VERSION STATUS AGE connectcluster-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 2s connectcluster-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 4s @@ -171,12 +172,11 @@ connectcluster-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning . connectcluster-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Ready 112s -``` - Describe the `ConnectCluster` object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe connectcluster -n demo connectcluster-quickstart +kubectl describe connectcluster -n demo connectcluster-quickstart +``` Name: connectcluster-quickstart Namespace: demo Labels: @@ -339,14 +339,13 @@ Status: Phase: Ready Events: -``` - ### KubeDB Operator Generated Resources On deployment of a ConnectCluster CR, the operator creates the following resources: ```bash -$ kubectl get all,petset,secret -n demo -l 'app.kubernetes.io/instance=connectcluster-quickstart' +kubectl get all,petset,secret -n demo -l 'app.kubernetes.io/instance=connectcluster-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/connectcluster-quickstart-0 1/1 Running 0 3m50s pod/connectcluster-quickstart-1 1/1 Running 0 3m7s @@ -366,8 +365,6 @@ NAME TYPE DATA secret/connectcluster-quickstart-config Opaque 1 3m55s secret/connectcluster-quickstart-connect-cred kubernetes.io/basic-auth 2 3m56s -``` - - `PetSet` - a PetSet named after the ConnectCluster instance. - `Services` - For a ConnectCluster instance headless service is created with name `{ConnectCluster-name}-{pods}` and a primary service created with name `{ConnectCluster-name}`. - `AppBinding` - an [AppBinding](/docs/guides/kafka/concepts/appbinding.md) which hold to connect information for the ConnectCluster worker nodes. It is also named after the ConnectCluster instance. @@ -383,8 +380,8 @@ To create a connector, you can use the Kafka Connect REST API. But, KubeDB opera At first, we will create `config.properties` file containing required configuration settings. I am using the `mongodb-source` connector here. You can use any other connector as per your requirement. ```bash -$ cat config.properties - +cat config.properties +``` connector.class=com.mongodb.kafka.connect.MongoSourceConnector tasks.max=1 connection.uri=mongodb://root:XbCj85wKfCPKapJ8@mg-rep.demo.svc:27017/ @@ -400,7 +397,6 @@ $ cat config.properties key.ignore=true value.converter=org.apache.kafka.connect.json.JsonConverter value.converter.schemas.enable=false -``` Here, 1. A MongoDB instance is already running. You can use your own MongoDB instance. To run mongodb instance, follow the [MongoDB Quickstart](/docs/guides/mongodb/quickstart/quickstart.md) guide. @@ -411,7 +407,7 @@ Here, Now, we will create secret containing `config.properties` file. ```bash -$ kubectl create secret generic mongodb-source-config --from-file=./config.properties -n demo +kubectl create secret generic mongodb-source-config --from-file=./config.properties -n demo ``` Now, we will use this secret to create a `Connector` CR. @@ -440,20 +436,19 @@ Here, Now, create the `Connector` CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/mongodb-source-connector.yaml -connector.kafka.kubedb.com/mongodb-source-connector created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/connectcluster/mongodb-source-connector.yaml ``` +connector.kafka.kubedb.com/mongodb-source-connector created ```bash -$ kubectl get connector -n demo -w - +kubectl get connector -n demo -w +``` NAME TYPE CONNECTCLUSTER STATUS AGE mongodb-source-connector kafka.kubedb.com/v1alpha1 connectcluster-quickstart Pending 0s mongodb-source-connector kafka.kubedb.com/v1alpha1 connectcluster-quickstart Pending 0s . . mongodb-source-connector kafka.kubedb.com/v1alpha1 connectcluster-quickstart Running 1s -``` MongoDB source connector is created successfully and the status is `Running`. Now, the connector is ready to fetch data from the MongoDB instance to the Kafka topic. @@ -492,12 +487,12 @@ rs1:PRIMARY> db.source.insertOne({"mongodb":"source"}) Exec into one of the kafka brokers in interactive mode. Run consumer command to check the data in the topic. ```bash -$ kubectl exec -it kafka-quickstart-1 -n demo -- bash +kubectl exec -it kafka-quickstart-1 -n demo -- bash +``` kafka@kafka-quickstart-1:~$ kafka-console-consumer.sh --bootstrap-server localhost:9092 --consumer.config config/clientauth.properties --topic mongo.mongodb.source --from-beginning "{\"_id\": {\"$oid\": \"66389ca8c43abff3a434b916\"}, \"hi\": \"kubedb\"}" "{\"_id\": {\"$oid\": \"66389cb4c43abff3a434b917\"}, \"kafka\": \"connectcluster\"}" "{\"_id\": {\"$oid\": \"66389cc0c43abff3a434b918\"}, \"mongodb\": \"source\"}" -``` You can see the data inserted in the MongoDB collection is fetched by the MongoDB source connector and published to the Kafka topic. @@ -506,15 +501,19 @@ You can see the data inserted in the MongoDB collection is fetched by the MongoD To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo connectcluster connectcluster-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo connectcluster connectcluster-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` connectcluster.kafka.kubedb.com/connectcluster-quickstart patched -$ kubectl delete kf connectcluster-quickstart -n demo +```bash +kubectl delete kf connectcluster-quickstart -n demo +``` connectcluster.kafka.kubedb.com "connectcluster-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/kafka/gitops/topology.md b/docs/guides/kafka/gitops/topology.md index 60d3843fc1..24331a6d4e 100644 --- a/docs/guides/kafka/gitops/topology.md +++ b/docs/guides/kafka/gitops/topology.md @@ -26,12 +26,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create Kafka dat - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -101,11 +103,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── Kafka.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `Kafka` CR is created in your cluster. @@ -113,18 +115,19 @@ Our `gitops` operator will create an actual `Kafka` database CR in the cluster. ```bash -$ kubectl get kafka.gitops.kubedb.com,kafka.kubedb.com -n demo +kubectl get kafka.gitops.kubedb.com,kafka.kubedb.com -n demo +``` NAME AGE kafka.gitops.kubedb.com/kafka-gitops 62m NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 62m -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` Kafka. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=kafka-gitops' + kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=kafka-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/kafka-gitops-broker 62m petset.apps.k8s.appscode.com/kafka-gitops-controller 62m @@ -143,7 +146,6 @@ service/kafka-gitops-pods ClusterIP None 9092/TC NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/kafka-gitops kubedb.com/kafka 3.9.0 62m -``` ## Update Kafka Database using GitOps @@ -206,7 +208,8 @@ The resource requests and limits for the topology broker have been updated to `1 Now, `gitops` operator will detect the resource changes and create a `KafkaOpsRequest` to update the `Kafka` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 64m @@ -215,11 +218,11 @@ kafka.gitops.kubedb.com/kafka-gitops 64m NAME TYPE STATUS AGE kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-c2ejz2 VerticalScaling Successful 10m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo Kafka-gitops-broker-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo Kafka-gitops-broker-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1540Mi" @@ -229,7 +232,10 @@ $ kubectl get pod -n demo Kafka-gitops-broker-0 -o json | jq '.spec.containers[0 "memory": "1536Mi" } } -$ kubectl get pod -n demo Kafka-gitops-controller-0 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo Kafka-gitops-controller-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1540Mi" @@ -239,7 +245,6 @@ $ kubectl get pod -n demo Kafka-gitops-controller-0 -o json | jq '.spec.containe "memory": "1536Mi" } } -``` ### Scale Kafka Replicas @@ -299,7 +304,8 @@ Update the replicas count for both the broker and controller to 3. Commit the ch Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` KafkaOpsRequest to update the `Kafka` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME TYPE VERSION STATUS AGE kafka.kubedb.com/kafka-gitops kubedb.com/v1 3.9.0 Ready 22h @@ -309,11 +315,11 @@ kafka.gitops.kubedb.com/kafka-gitops 22h NAME TYPE STATUS AGE kafkaopsrequest.ops.kubedb.com/kafka-gitops-horizontalscaling-j0wni6 HorizontalScaling Successful 13m kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-tfkvi8 VerticalScaling Successful 8m29s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=kafka-gitops' + kubectl get pod -n demo -l 'app.kubernetes.io/instance=kafka-gitops' +``` NAME READY STATUS RESTARTS AGE kafka-gitops-broker-0 1/1 Running 0 34m kafka-gitops-broker-1 1/1 Running 0 33m @@ -321,7 +327,6 @@ kafka-gitops-broker-2 1/1 Running 0 33m kafka-gitops-controller-0 1/1 Running 0 32m kafka-gitops-controller-1 1/1 Running 0 31m kafka-gitops-controller-2 1/1 Running 0 31m -``` We can also scale down the replicas by updating the `replicas` fields. @@ -384,7 +389,8 @@ Set the `storage.resources.requests.storage` for both the broker and controller Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` KafkaOpsRequest to update the `Kafka` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 6m51s @@ -395,11 +401,11 @@ NAME TYPE kafkaopsrequest.ops.kubedb.com/kafka-gitops-horizontalscaling-i7l7rn HorizontalScaling Successful 112m kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-mwqdzx VerticalScaling Successful 117m kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-7aweww VolumeExpansion Successful 4m30s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=kafka-gitops' + kubectl get pvc -n demo -l 'app.kubernetes.io/instance=kafka-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE kafka-gitops-data-kafka-gitops-broker-0 Bound pvc-a00ef6d5-44a6-40ce-8131-680b9d24d982 2Gi RWO longhorn 7m20s kafka-gitops-data-kafka-gitops-broker-1 Bound pvc-141798c5-9000-480f-a997-85a5743f63e2 2Gi RWO longhorn 7m4s @@ -407,7 +413,6 @@ kafka-gitops-data-kafka-gitops-broker-2 Bound pvc-819ba56b-4fda-4361-9f kafka-gitops-data-kafka-gitops-controller-0 Bound pvc-5a6cc06e-60ff-450a-875e-b84f75358f67 2Gi RWO longhorn 7m20s kafka-gitops-data-kafka-gitops-controller-1 Bound pvc-7cae3a1d-0efc-48a2-8953-12f4338a9602 2Gi RWO longhorn 7m4s kafka-gitops-data-kafka-gitops-controller-2 Bound pvc-22e0a63f-58c1-4a03-9493-e670498723db 2Gi RWO longhorn 6m46s -``` ## Reconfigure Kafka @@ -427,12 +432,12 @@ stringData: Now, we will add this file to `kubedb/kf-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── kf-configuration.yaml │ └── Kafka.yaml 1 directories, 2 files -``` Update the `Kafka.yaml` with the following, ```yaml @@ -493,7 +498,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` KafkaOpsRequest to update the `Kafka` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 19m @@ -505,7 +511,6 @@ kafkaopsrequest.ops.kubedb.com/kafka-gitops-horizontalscaling-i7l7rn Horizonta kafkaopsrequest.ops.kubedb.com/kafka-gitops-reconfigure-fszhk8 Reconfigure Successful 8m44s kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-mwqdzx VerticalScaling Successful 130m kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-7aweww VolumeExpansion Successful 16m -``` @@ -533,13 +538,13 @@ stringData: Now, we will add this file to `kubedb/kf-rotateauth.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── kf-configuration.yaml │ ├── kf-rotateauth.yaml │ └── Kafka.yaml 1 directories, 3 files -``` Update the `Kafka.yaml` with the following, @@ -604,7 +609,8 @@ Change the `authSecret` field to `kf-rotate-auth`. Commit the changes and push t Now, `gitops` operator will detect the auth changes and create a `RotateAuth` KafkaOpsRequest to update the `Kafka` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 17h @@ -617,7 +623,6 @@ kafkaopsrequest.ops.kubedb.com/kafka-gitops-reconfigure-fszhk8 Reconfigu kafkaopsrequest.ops.kubedb.com/kafka-gitops-rotate-auth-pkb3t1 RotateAuth Successful 13m kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-mwqdzx VerticalScaling Successful 18h kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-7aweww VolumeExpansion Successful 17h -``` ### TLS configuration @@ -629,18 +634,18 @@ To add tls, we are going to create an example `Issuer` that will be used to enab - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 kafka-ca \ +kubectl create secret tls kafka-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo @@ -661,7 +666,8 @@ spec: Let's add that to our `kubedb/kf-issuer.yaml` and kubedb/kf-secret.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── kf-configuration.yaml │ ├── kf-rotateauth.yaml @@ -669,7 +675,6 @@ $ tree . │ ├── kf-issuer.yaml │ └── Kafka.yaml 1 directories, 5 files -``` Update the `Kafka.yaml` with the following, ```yaml @@ -739,7 +744,8 @@ Add `sslMode` and `tls` fields in the spec. Commit the changes and push to your Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` KafkaOpsRequest to update the `Kafka` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops,pods -n demo +kubectl get kf,kafka,kfops,pods -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 3.9.0 Ready 67m @@ -753,7 +759,6 @@ kafkaopsrequest.ops.kubedb.com/kafka-gitops-reconfiguretls-wkax2u Reconfigu kafkaopsrequest.ops.kubedb.com/kafka-gitops-rotate-auth-y2vwx4 RotateAuth Successful 27m kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-c4llju VerticalScaling Successful 27m kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-9e85tf VolumeExpansion Successful 27m -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for Kafka. @@ -832,7 +837,8 @@ Update the `version` field to `4.2.0`. Commit the changes and push to your Git r Now, `gitops` operator will detect the version changes and create a `VersionUpdate` KafkaOpsRequest to update the `Kafka` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops,pods -n demo +kubectl get kf,kafka,kfops,pods -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 4.0.0 Ready 72m @@ -847,23 +853,34 @@ kafkaopsrequest.ops.kubedb.com/kafka-gitops-rotate-auth-y2vwx4 RotateAut kafkaopsrequest.ops.kubedb.com/kafka-gitops-versionupdate-6z70bp UpdateVersion Successful 4m16s kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-c4llju VerticalScaling Successful 32m kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-9e85tf VolumeExpansion Successful 32m -``` Now, we are going to verify whether the `Kafka`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get Kafka -n demo kafka-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get Kafka -n demo kafka-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` 4.0.0 -$ kubectl get petset -n demo kafka-gitops-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/kafka:4.0.0@sha256:62fb3652bc7672a74582d8d0abb7d0090155a237b7cf21bdb3837c3dba107010 -$ kubectl get pod -n demo kafka-gitops-broker-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get petset -n demo kafka-gitops-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/kafka:4.0.0@sha256:62fb3652bc7672a74582d8d0abb7d0090155a237b7cf21bdb3837c3dba107010 -$ kubectl get pod -n demo kafka-gitops-controller-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get pod -n demo kafka-gitops-broker-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/kafka:4.0.0@sha256:62fb3652bc7672a74582d8d0abb7d0090155a237b7cf21bdb3837c3dba107010 -$ kubectl get petset -n demo kafka-gitops-controller -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' + +```bash +kubectl get pod -n demo kafka-gitops-controller-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/kafka:4.0.0@sha256:62fb3652bc7672a74582d8d0abb7d0090155a237b7cf21bdb3837c3dba107010 + +```bash +kubectl get petset -n demo kafka-gitops-controller -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/kafka:4.0.0@sha256:62fb3652bc7672a74582d8d0abb7d0090155a237b7cf21bdb3837c3dba107010 ### Enable Monitoring @@ -945,7 +962,8 @@ Add `monitor` field in the `spec`. Commit the changes and push to your Git repos Now, `gitops` operator will detect the monitoring changes and create a `Restart` KafkaOpsRequest to add the `Kafka` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get kf,kafka,kfops -n demo +kubectl get kf,kafka,kfops -n demo +``` NAME VERSION STATUS AGE kafka.kubedb.com/kafka-gitops 4.0.0 Ready 90m @@ -961,7 +979,6 @@ kafkaopsrequest.ops.kubedb.com/kafka-gitops-rotate-auth-y2vwx4 RotateAut kafkaopsrequest.ops.kubedb.com/kafka-gitops-versionupdate-6z70bp UpdateVersion Successful 22m kafkaopsrequest.ops.kubedb.com/kafka-gitops-verticalscaling-c4llju VerticalScaling Successful 49m kafkaopsrequest.ops.kubedb.com/kafka-gitops-volumeexpansion-9e85tf VolumeExpansion Successful 49m -``` Verify the monitoring is enabled by checking the prometheus targets. diff --git a/docs/guides/kafka/migration/migration.md b/docs/guides/kafka/migration/migration.md index ddc555ec1d..9762696b78 100644 --- a/docs/guides/kafka/migration/migration.md +++ b/docs/guides/kafka/migration/migration.md @@ -32,9 +32,9 @@ Suppose you are running kafka cluster on-prem or on any other cloud provider and To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -86,9 +86,9 @@ stringData: Create the secret using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/source-kafka-auth.yaml -secret/source-kafka-auth created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/source-kafka-auth.yaml ``` +secret/source-kafka-auth created ```yaml apiVersion: kubedb.com/v1 @@ -116,21 +116,21 @@ spec: Create the Kafka cluster using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/source-kafka.yaml -kafka.kubedb.com/source-kafka created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/source-kafka.yaml ``` +kafka.kubedb.com/source-kafka created Now, wait until `source-kafka` has status `Ready`. i.e, ```bash -$ kubectl get kafka -n demo -w +kubectl get kafka -n demo -w +``` NAME VERSION STATUS AGE source-kafka 3.9.0 Provisioning 1s source-kafka 3.9.0 Provisioning 111s . . source-kafka 3.9.0 Ready 2m -``` ### Step 2: Create Producer and Consumer @@ -143,26 +143,26 @@ Exec into one of the broker pods: **Terminal 1:** ```bash -$ kubectl exec -it source-kafka-0 -n demo -- /bin/bash +kubectl exec -it source-kafka-0 -n demo -- /bin/bash +``` kafka@source-kafka-0:~$ kafka-topics.sh --create --topic foo --partitions 3 --replication-factor 2 --bootstrap-server localhost:9092 --command-config config/clientauth.properties Created topic foo. kafka@source-kafka-0:~$ kafka-console-producer.sh --topic foo --bootstrap-server localhost:9092 --producer.config config/clientauth.properties > Hello, World! > Welcome to KubeDB Kafka! > Starting Migration -``` Now, create another terminal and exec into one of the broker pods to consume the messages: **Terminal 2:** ```bash -$ kubectl exec -it source-kafka-0 -n demo -- /bin/bash +kubectl exec -it source-kafka-0 -n demo -- /bin/bash +``` kafka@source-kafka-0:~$ kafka-console-consumer.sh --topic foo --group foo-consumer --from-beginning --bootstrap-server localhost:9092 --consumer.config config/clientauth.properties Hello, World! Welcome to KubeDB Kafka! Starting Migration -``` Don't close the `Terminal 2`. This terminal acts like a consumer application for the source Kafka cluster. @@ -219,7 +219,8 @@ Create another terminal and exec into one of the broker pods to consume the mess **Terminal 3:** ```bash -$ kubectl exec -it source-kafka-0 -n demo -- /bin/bash +kubectl exec -it source-kafka-0 -n demo -- /bin/bash +``` kafka@source-kafka-0:~$ kafka-console-consumer.sh --topic bar --group bar-consumer --from-beginning --bootstrap-server localhost:9092 --consumer.config config/clientauth.properties {"timestamp": 1727759815, "value": 42} {"timestamp": 1727759818, "value": 43} @@ -239,7 +240,6 @@ kafka@source-kafka-0:~$ kafka-console-consumer.sh --topic bar --group bar-consum {"timestamp": 1727759858, "value": 14} . . -``` So, we have one producer and two consumers running in the source Kafka cluster. @@ -265,9 +265,9 @@ stringData: Create the secret using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/target-kafka-auth.yaml -secret/target-kafka-auth created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/target-kafka-auth.yaml ``` +secret/target-kafka-auth created ```yaml apiVersion: kubedb.com/v1 @@ -315,21 +315,21 @@ spec: Create the Kafka cluster using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/target-kafka.yaml -kafka.kubedb.com/target-kafka created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/target-kafka.yaml ``` +kafka.kubedb.com/target-kafka created Now, wait until `source-kafka` has status `Ready`. i.e, ```bash -$ kubectl get kafka -n demo target-kafka -w +kubectl get kafka -n demo target-kafka -w +``` NAME VERSION STATUS AGE target-kafka 3.9.0 Provisioning 1s target-kafka 3.9.0 Provisioning 111s . . target-kafka 3.9.0 Ready 2m -``` Now, create a `ConnectCluster` with monitoring enabled to migrate from the source Kafka cluster to the target Kafka cluster using `mirror-maker-2`. @@ -349,9 +349,9 @@ stringData: Create the secret using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-connect-auth.yaml -secret/mirror-connect-auth created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-connect-auth.yaml ``` +secret/mirror-connect-auth created ```yaml apiVersion: kafka.kubedb.com/v1alpha1 @@ -383,21 +383,21 @@ spec: Create the `ConnectCluster` using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-connect.yaml -connectcluster.kafka.kubedb.com/mirror-connect created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-connect.yaml ``` +connectcluster.kafka.kubedb.com/mirror-connect created Now, wait until `mirror-connect` has status `Ready`. i.e, ```bash -$ kubectl get connectcluster -n demo -w +kubectl get connectcluster -n demo -w +``` NAME VERSION STATUS AGE mirror-connect 3.9.0 Provisioning 1s mirror-connect 3.9.0 Provisioning 111s . . mirror-connect 3.9.0 Ready 90s -``` ### Step 4: Create MirrorSource Connector @@ -460,10 +460,10 @@ here, Create the `MirrorSource` connector using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-source.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-source.yaml +``` secret/mirror-source-config created connector.kafka.kubedb.com/mirror-source-connector created -``` ### Step 5: Create MirrorCheckpoint @@ -522,10 +522,10 @@ here, Create the `MirrorCheckpoint` connector using the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-checkpoint.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-checkpoint.yaml +``` secret/mirror-checkpoint-config created connector.kafka.kubedb.com/mirror-checkpoint-connector created -``` ### Step 6: Create MirrorHeartbeat @@ -573,10 +573,10 @@ here, - Properties with prefix `target.cluster` are the target Kafka cluster's authentication information. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-heartbeat.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/migration/mirror-heartbeat.yaml +``` secret/mirror-hearbeat-config created connector.kafka.kubedb.com/mirror-hearbeat-connector created -``` Check the status of the connectors: @@ -649,16 +649,19 @@ yamlApplicationConfig: Now, install Kafbat using the following command: ```bash -$ helm repo add kafbat-ui https://kafbat.github.io/helm-charts -$ helm install kafbat-ui kafbat-ui/kafka-ui -n demo -f values.yaml +helm repo add kafbat-ui https://kafbat.github.io/helm-charts +``` + +```bash +helm install kafbat-ui kafbat-ui/kafka-ui -n demo -f values.yaml ``` Now, port-forward the Kafbat service to access the UI: ```bash -$ kubectl port-forward svc/kafbat-ui-kafka-ui 8080:80 -n demo +kubectl port-forward svc/kafbat-ui-kafka-ui 8080:80 -n demo +``` Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080 -``` Now, open your browser and navigate to `http://localhost:8080` to view the Kafbat UI. @@ -692,11 +695,11 @@ Also, monitor the migration process using prometheus and grafana. To check the metrics port-forward the prometheus service: ```bash -$ kubectl port-forward -n monitoring svc/prometheus-operated 9090:9090 -n demo +kubectl port-forward -n monitoring svc/prometheus-operated 9090:9090 -n demo +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 Handling connection for 9090 -``` Now, open your browser and navigate to `http://localhost:9090/graph` to view the Prometheus UI. You can add queries to the query box like the following: There are two main metrics to notice: @@ -830,11 +833,23 @@ Below are some tips and tricks to make the migration process smoother: To clean up the Kubernetes resources created by this tutorial, you can run: ```bash -$ kubectl delete connector mirror-source-connector, mirror-checkpoint-connector, mirror-heartbeat-connector -n demo -$ kubectl delete secret mirror-source-config mirror-checkpoint-config mirror-heartbeat-config -n demo -$ kubectl delete connectcluster mirror-connect -n demo -$ kubectl delete kafka source-kafka target-kafka -n demo -$ kubectl delete ns demo +kubectl delete connector mirror-source-connector, mirror-checkpoint-connector, mirror-heartbeat-connector -n demo +``` + +```bash +kubectl delete secret mirror-source-config mirror-checkpoint-config mirror-heartbeat-config -n demo +``` + +```bash +kubectl delete connectcluster mirror-connect -n demo +``` + +```bash +kubectl delete kafka source-kafka target-kafka -n demo +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/kafka/monitoring/overview.md b/docs/guides/kafka/monitoring/overview.md index bf8b55402c..3d6fc63105 100644 --- a/docs/guides/kafka/monitoring/overview.md +++ b/docs/guides/kafka/monitoring/overview.md @@ -84,9 +84,9 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kf-with-monitoring.yaml -kafka.kubedb.com/kafka created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kf-with-monitoring.yaml ``` +kafka.kubedb.com/kafka created Here, we have specified that we are going to monitor this server using Prometheus operator through `spec.monitor.agent: prometheus.io/operator`. KubeDB will create a `ServiceMonitor` crd in databases namespace and this `ServiceMonitor` will have `release: prometheus` label. diff --git a/docs/guides/kafka/monitoring/using-builtin-prometheus.md b/docs/guides/kafka/monitoring/using-builtin-prometheus.md index 5bd3c7b35b..3b6b269f19 100644 --- a/docs/guides/kafka/monitoring/using-builtin-prometheus.md +++ b/docs/guides/kafka/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Kafka cluster using builtin [Promethe - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,9 +81,9 @@ Here, Let's create the Kafka crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kafka-builtin-prom.yaml -kafka.kubedb.com/kafka-builtin-prom created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kafka-builtin-prom.yaml ``` +kafka.kubedb.com/kafka-builtin-prom created Now, wait for the cluster to go into `Ready` state. @@ -93,16 +95,17 @@ kafka-builtin-prom kubedb.com/v1 3.9.0 Ready 31s KubeDB will create a separate stats service with name `{Kafka crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=kafka-builtin-prom" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=kafka-builtin-prom" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kafka-builtin-prom-pods ClusterIP None 9092/TCP,9093/TCP,29092/TCP 52s kafka-builtin-prom-stats ClusterIP 10.96.222.96 56790/TCP 52s -``` Here, `kafka-builtin-prom-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n kafka-demo builtin-prom-stats +kubectl describe svc -n kafka-demo builtin-prom-stats +``` Name: kafka-builtin-prom-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -125,7 +128,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.31:56790,10.244.0.33:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -289,20 +291,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -313,9 +315,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -324,18 +326,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-7bd56c6865-8dlpv 1/1 Running 0 28s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `kafka-builtin-prom-stats` service as one of the targets. diff --git a/docs/guides/kafka/monitoring/using-prometheus-operator.md b/docs/guides/kafka/monitoring/using-prometheus-operator.md index c10c63295f..ddbd7371dd 100644 --- a/docs/guides/kafka/monitoring/using-prometheus-operator.md +++ b/docs/guides/kafka/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. Alternatively, you can use `--create-namespace` flag while deploying prometheus. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,17 +47,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.42.0 1 1 True True 2d23h -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -145,7 +148,6 @@ status: updatedReplicas: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.serviceMonitor.labels` field of Kafka crd. @@ -197,33 +199,34 @@ Here, Let's create the kafka object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kf-with-monitoring.yaml -kafkas.kubedb.com/kafka created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/monitoring/kf-with-monitoring.yaml ``` +kafkas.kubedb.com/kafka created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get kf -n demo kafka +kubectl get kf -n demo kafka +``` NAME TYPE VERSION STATUS AGE kafka kubedb.com/v1alpha2 3.9.0 Ready 2m24s -``` KubeDB will create a separate stats service with name `{Kafka crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=kafka" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=kafka" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kafka-pods ClusterIP None 9092/TCP,9093/TCP,29092/TCP 3m22s kafka-stats ClusterIP 10.96.235.251 9091/TCP 3m19s -``` Here, `kafka-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo kafka-stats +kubectl describe svc -n demo kafka-stats +``` Name: kafka-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -243,17 +246,16 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.117:56790,10.244.0.119:56790,10.244.0.121:56790 Session Affinity: None Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `kafka-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE kafka-stats 4m49s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Kafka crd. @@ -309,20 +311,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 8 (4h27m ago) 3d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-kube-prometheus-prometheus` service which is pointing to the prometheus pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `kafka-stats` service as one of the targets. diff --git a/docs/guides/kafka/quickstart/kafka/index.md b/docs/guides/kafka/quickstart/kafka/index.md index 38b03e6a05..e0b7ed5491 100644 --- a/docs/guides/kafka/quickstart/kafka/index.md +++ b/docs/guides/kafka/quickstart/kafka/index.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [guides/kafka/quickstart/kafka/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/kafka/quickstart/kafka/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ demo Active 9s We will have to provide `StorageClass` in Kafka CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -58,7 +60,8 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named [KafkaVersion](/docs/guides/kafka/concepts/kafkaversion.md). The installation process comes with a set of tested KafkaVersion objects. Let's check available KafkaVersions by, ```bash -$ kubectl get kfversion +kubectl get kfversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 3.5.2 3.5.2 ghcr.io/appscode-images/kafka-kraft:3.5.2 7d19h 3.6.1 3.6.1 ghcr.io/appscode-images/kafka-kraft:3.6.1 7d19h @@ -67,8 +70,6 @@ NAME VERSION DB_IMAGE DEPRECATED AGE 3.9.0 3.9.0 ghcr.io/appscode-images/kafka-kraft:3.9.0 7d19h 4.0.0 4.0.0 ghcr.io/appscode-images/kafka:4.0.0 7d19h -``` - Notice the `DEPRECATED` column. Here, `true` means that this KafkaVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated KafkaVersion. You can also use the short from `kfversion` to check available KafkaVersions. In this tutorial, we will use `3.9.0` KafkaVersion CR to create a Kafka cluster. @@ -102,9 +103,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/kafka/quickstart/kafka/yamls/kafka-v1.yaml -kafka.kubedb.com/kafka-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/kafka/quickstart/kafka/yamls/kafka-v1.yaml ``` +kafka.kubedb.com/kafka-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -127,9 +128,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/kafka/quickstart/kafka/yamls/kafka-v1alpha2.yaml -kafka.kubedb.com/kafka-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/kafka/quickstart/kafka/yamls/kafka-v1alpha2.yaml ``` +kafka.kubedb.com/kafka-quickstart created Here, @@ -144,7 +145,8 @@ Here, The Kafka's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the Kafka. ```bash -$ kubectl get kafka -n demo -w +kubectl get kafka -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-quickstart kubedb.com/v1alpha2 3.9.0 Provisioning 2s kafka-quickstart kubedb.com/v1alpha2 3.9.0 Provisioning 4s @@ -152,12 +154,11 @@ kafka-quickstart kubedb.com/v1alpha2 3.9.0 Provisioning 4s . kafka-quickstart kubedb.com/v1alpha2 3.9.0 Ready 112s -``` - Describe the kafka object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe kafka -n demo kafka-quickstart +kubectl describe kafka -n demo kafka-quickstart +``` Name: kafka-quickstart Namespace: demo Labels: @@ -288,14 +289,13 @@ Status: Phase: Ready Events: -``` - ### KubeDB Operator Generated Resources On deployment of a Kafka CR, the operator creates the following resources: ```bash -$ kubectl get all,secret -n demo -l 'app.kubernetes.io/instance=kafka-quickstart' +kubectl get all,secret -n demo -l 'app.kubernetes.io/instance=kafka-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/kafka-quickstart-0 1/1 Running 0 8m50s pod/kafka-quickstart-1 1/1 Running 0 8m48s @@ -313,7 +313,6 @@ appbinding.appcatalog.appscode.com/kafka-quickstart kubedb.com/kafka 3.9.0 NAME TYPE DATA AGE secret/kafka-quickstart-auth kubernetes.io/basic-auth 2 8m52s secret/kafka-quickstart-config Opaque 2 8m52s -``` - `PetSet` - a PetSet named after the Kafka instance. In topology mode, the operator creates 3 petSets with name `{Kafka-Name}-{Sufix}`. - `Services` - For a combined Kafka instance only one service is created with name `{Kafka-name}-{pods}`. For topology mode, two services are created. @@ -330,12 +329,12 @@ secret/kafka-quickstart-config Opaque 2 8m52s We will use `kafka console producer` and `kafka console consumer` for creating kafka topic, publishing messages to kafka brokers and then consume those messages as well. Exec into one of the kafka brokers in interactive mode first, then navigate to `HOME` directory which is at path `/opt/kafka` ```bash -$ kubectl exec -it -n demo kafka-quickstart-0 -- bash +kubectl exec -it -n demo kafka-quickstart-0 -- bash +``` root@kafka-quickstart-0:/# cd $HOME root@kafka-quickstart-0:~# pwd /opt/kafka root@kafka-quickstart-0:~# -``` You will find a file named `clientauth.properties` in the config directory. This file is generated by the operator which contains necessary authentication/authorization configurations that are required during publishing or subscribing messages to a kafka topic. @@ -415,15 +414,19 @@ Notice that, messages are coming to the consumer as you continue sending message To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo kafka kafka-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo kafka kafka-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` kafka.kubedb.com/kafka-quickstart patched -$ kubectl delete kf kafka-quickstart -n demo +```bash +kubectl delete kf kafka-quickstart -n demo +``` kafka.kubedb.com "kafka-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/kafka/reconfigure-tls/kafka.md b/docs/guides/kafka/reconfigure-tls/kafka.md index bdbb60c1ec..f5cc5bfcaa 100644 --- a/docs/guides/kafka/reconfigure-tls/kafka.md +++ b/docs/guides/kafka/reconfigure-tls/kafka.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -75,26 +75,27 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 9s . . kafka-prod kubedb.com/v1 3.9.0 Ready 2m10s -``` Now, we can exec one kafka broker pod and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=null sensitive=false synonyms={} @@ -105,7 +106,6 @@ $ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-s ssl.keystore.location=null sensitive=false synonyms={} ssl.keystore.password=null sensitive=true synonyms={} ssl.keystore.type=JKS sensitive=false synonyms={DEFAULT_CONFIG:ssl.keystore.type=JKS} -``` We can verify from the above output that TLS is disabled for this cluster. @@ -116,23 +116,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 kafka-ca \ +kubectl create secret tls kafka-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/kafka-ca created ``` +secret/kafka-ca created Now, Let's create an `Issuer` using the `kafka-ca` secret that we have just created. The `YAML` file looks like this: @@ -150,9 +150,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-issuer.yaml -issuer.cert-manager.io/kf-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-issuer.yaml ``` +issuer.cert-manager.io/kf-issuer created ### Create KafkaOpsRequest @@ -196,24 +196,25 @@ Let's create the `KafkaOpsRequest` CR we have shown above, > **Note:** For combined kafka, you just need to refer kafka combined object in `databaseRef` field. To learn more about combined kafka, please visit [here](/docs/guides/kafka/clustering/combined-cluster/index.md). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-add-tls.yaml -kafkaopsrequest.ops.kubedb.com/kfops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-add-tls.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-add-tls ReconfigureTLS Successful 4m36s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-add-tls +kubectl describe kafkaopsrequest -n demo kfops-add-tls +``` Name: kfops-add-tls Namespace: demo Labels: @@ -394,12 +395,12 @@ Events: Normal RestartNodes 76s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 76s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 76s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-add-tls -``` Now, Let's exec into a kafka broker pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=/var/private/ssl/server.keystore.jks sensitive=false synonyms={STATIC_BROKER_CONFIG:ssl.keystore.location=/var/private/ssl/server.keystore.jks} @@ -410,7 +411,6 @@ $ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-s ssl.keystore.location=/var/private/ssl/server.keystore.jks sensitive=false synonyms={STATIC_BROKER_CONFIG:ssl.keystore.location=/var/private/ssl/server.keystore.jks} ssl.keystore.password=null sensitive=true synonyms={STATIC_BROKER_CONFIG:ssl.keystore.password=null} ssl.keystore.type=JKS sensitive=false synonyms={DEFAULT_CONFIG:ssl.keystore.type=JKS} -``` We can see from the above output that, keystore location is `/var/private/ssl/server.keystore.jks` which means that TLS is enabled. @@ -419,12 +419,12 @@ We can see from the above output that, keystore location is `/var/private/ssl/se Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ $ kubectl exec -it -n demo kafka-prod-broker-0 -- keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep -E 'Valid from|Alias name' +kubectl exec -it -n demo kafka-prod-broker-0 -- keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep -E 'Valid from|Alias name' +``` Alias name: ca Valid from: Wed Jul 31 06:11:30 UTC 2024 until: Thu Jul 31 06:11:30 UTC 2025 Alias name: certificate Valid from: Wed Jul 31 06:36:31 UTC 2024 until: Tue Oct 29 06:36:31 UTC 2024 -``` So, the certificate will expire on this time `Tue Oct 29 06:36:31 UTC 2024`. @@ -455,24 +455,25 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-rotate.yaml -kafkaopsrequest.ops.kubedb.com/kfops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-rotate.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequests -n demo kfops-rotate +kubectl get kafkaopsrequests -n demo kfops-rotate +``` NAME TYPE STATUS AGE kfops-rotate ReconfigureTLS Successful 4m4s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-rotate +kubectl describe kafkaopsrequest -n demo kfops-rotate +``` Name: kfops-rotate Namespace: demo Labels: @@ -640,17 +641,16 @@ Events: Normal RestartNodes 97s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 97s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 97s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep -E 'Valid from|Alias name' +kubectl exec -it -n demo kafka-prod-broker-0 -- keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep -E 'Valid from|Alias name' +``` Alias name: ca Valid from: Wed Jul 31 06:11:30 UTC 2024 until: Thu Jul 31 06:11:30 UTC 2025 Alias name: certificate Valid from: Wed Jul 31 07:05:40 UTC 2024 until: Tue Oct 29 07:05:40 UTC 2024 -``` As we can see from the above output, the certificate has been rotated successfully. @@ -661,23 +661,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 kafka-new-ca \ +kubectl create secret tls kafka-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/kafka-new-ca created ``` +secret/kafka-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -695,9 +695,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-new-issuer.yaml -issuer.cert-manager.io/kf-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-new-issuer.yaml ``` +issuer.cert-manager.io/kf-new-issuer created ### Create KafkaOpsRequest @@ -729,24 +729,25 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-update-tls-issuer.yaml -kafkapsrequest.ops.kubedb.com/kfops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-update-tls-issuer.yaml ``` +kafkapsrequest.ops.kubedb.com/kfops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequests -n demo kfops-update-issuer +kubectl get kafkaopsrequests -n demo kfops-update-issuer +``` NAME TYPE STATUS AGE kfops-update-issuer ReconfigureTLS Successful 8m6s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-update-issuer +kubectl describe kafkaopsrequest -n demo kfops-update-issuer +``` Name: kfops-update-issuer Namespace: demo Labels: @@ -878,16 +879,15 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Let's exec into a kafka node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it kafka-prod-broker-0 -- bash +kubectl exec -it kafka-prod-broker-0 -- bash +``` kafka@kafka-prod-broker-0:~$ keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass wt6f5pwxpg84 | grep 'Issuer' Issuer: O=kubedb-updated, CN=ca-updated Issuer: O=kubedb-updated, CN=ca-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. @@ -922,24 +922,25 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-remove-tls.yaml -kafkaopsrequest.ops.kubedb.com/kfops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure-tls/kafka-remove-tls.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-remove created #### Verify TLS Removed Successfully Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequest -n demo kfops-remove +kubectl get kafkaopsrequest -n demo kfops-remove +``` NAME TYPE STATUS AGE kfops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-remove +kubectl describe kafkaopsrequest -n demo kfops-remove +``` Name: kfops-remove Namespace: demo Labels: @@ -1047,12 +1048,12 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Let's exec into one of the broker node and find out that TLS is disabled or not. ```bash -$$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=null sensitive=false synonyms={} @@ -1062,7 +1063,6 @@ $$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap- ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=null sensitive=false synonyms={} ssl.keystore.password=null sensitive=true synonyms={} -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/kafka/reconfigure/kafka-combined.md b/docs/guides/kafka/reconfigure/kafka-combined.md index 9d0970eab9..ebbd3f9e06 100644 --- a/docs/guides/kafka/reconfigure/kafka-combined.md +++ b/docs/guides/kafka/reconfigure/kafka-combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -68,9 +68,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-combined-custom-config.yaml -secret/kf-combined-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-combined-custom-config.yaml ``` +secret/kf-combined-custom-config created In this section, we are going to create a Kafka object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Kafka` CR that we are going to create, @@ -99,31 +99,31 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Now, we will check if the kafka has started with the custom configuration we have provided. Exec into the Kafka pod and execute the following commands to see the configurations: ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- bash +kubectl exec -it -n demo kafka-dev-0 -- bash +``` kafka@kafka-dev-0:~$ kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep log.retention.hours log.retention.hours=100 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=100, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=100 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=100, DEFAULT_CONFIG:log.retention.hours=168} -``` Here, we can see that our given configuration is applied to the Kafka cluster for all brokers. `log.retention.hours` is set to `100` from the default value `168`. ### Reconfigure using new config secret @@ -152,9 +152,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/new-kafka-combined-custom-config.yaml -secret/new-kf-combined-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/new-kafka-combined-custom-config.yaml ``` +secret/new-kf-combined-custom-config created #### Create KafkaOpsRequest @@ -186,9 +186,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-update-combined.yaml -kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-update-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-combined created #### Verify the new configuration is working @@ -197,15 +197,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `.spec.co Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequests -n demo +kubectl get kafkaopsrequests -n demo +``` NAME TYPE STATUS AGE kfops-reconfigure-combined Reconfigure Successful 4m55s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-reconfigure-combined +kubectl describe kafkaopsrequest -n demo kfops-reconfigure-combined +``` Name: kfops-reconfigure-combined Namespace: demo Labels: @@ -302,15 +303,14 @@ Events: Normal RestartNodes 2m53s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 2m53s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 2m53s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-reconfigure-combined -``` Now let's exec one of the instance and run a kafka-configs.sh command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +kubectl exec -it -n demo kafka-dev-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +``` log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} -``` As we can see from the configuration of ready kafka, the value of `log.retention.hours` has been changed from `100` to `125`. So the reconfiguration of the cluster is successful. @@ -350,9 +350,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-apply-combined.yaml -kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-apply-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-apply-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-apply-combined created #### Verify the new configuration is working @@ -361,15 +361,16 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequests -n demo kfops-reconfigure-apply-combined +kubectl get kafkaopsrequests -n demo kfops-reconfigure-apply-combined +``` NAME TYPE STATUS AGE kfops-reconfigure-apply-combined Reconfigure Successful 55s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to reconfigure the cluster. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-reconfigure-apply-combined +kubectl describe kafkaopsrequest -n demo kfops-reconfigure-apply-combined +``` Name: kfops-reconfigure-apply-combined Namespace: demo Labels: @@ -472,15 +473,14 @@ Events: Normal RestartNodes 73s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 73s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 73s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-reconfigure-apply-combined -``` Now let's exec into one of the instance and run a `kafka-configs.sh` command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +kubectl exec -it -n demo kafka-dev-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +``` log.retention.hours=150 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=150, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=150 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=150, DEFAULT_CONFIG:log.retention.hours=168} -``` As we can see from the configuration of ready kafka, the value of `log.retention.hours` has been changed from `125` to `150`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/kafka/reconfigure/kafka-topology.md b/docs/guides/kafka/reconfigure/kafka-topology.md index 22b6e67ef9..baba0121ab 100644 --- a/docs/guides/kafka/reconfigure/kafka-topology.md +++ b/docs/guides/kafka/reconfigure/kafka-topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -77,9 +77,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-topology-custom-config.yaml -secret/kf-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-topology-custom-config.yaml ``` +secret/kf-topology-custom-config created > **Note:** @@ -121,31 +121,31 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-prod kubedb.com/v1 3.9.0 Ready 92s -``` Now, we will check if the kafka has started with the custom configuration we have provided. Exec into the Kafka pod and execute the following commands to see the configurations: ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- bash +kubectl exec -it -n demo kafka-prod-broker-0 -- bash +``` kafka@kafka-prod-broker-0:~$ kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep log.retention.hours log.retention.hours=100 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=100, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=100 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=100, DEFAULT_CONFIG:log.retention.hours=168} -``` Here, we can see that our given configuration is applied to the Kafka cluster for all brokers. `log.retention.hours` is set to `100` from the default value `168`. ### Reconfigure using new config secret @@ -184,9 +184,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/new-kafka-topology-custom-config.yaml -secret/new-kf-topology-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/new-kafka-topology-custom-config.yaml ``` +secret/new-kf-topology-custom-config created #### Create KafkaOpsRequest @@ -218,9 +218,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-update-topology.yaml -kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-update-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-topology created #### Verify the new configuration is working @@ -229,15 +229,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configur Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequests -n demo +kubectl get kafkaopsrequests -n demo +``` NAME TYPE STATUS AGE kfops-reconfigure-topology Reconfigure Successful 4m55s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-reconfigure-topology +kubectl describe kafkaopsrequest -n demo kfops-reconfigure-topology +``` Name: kfops-reconfigure-topology Namespace: demo Labels: @@ -378,15 +379,14 @@ Events: Normal RestartNodes 7s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 5s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-reconfigure-topology -``` Now let's exec one of the instance and run a kafka-configs.sh command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +``` log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=125 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=125, DEFAULT_CONFIG:log.retention.hours=168} -``` As we can see from the configuration of ready kafka, the value of `log.retention.hours` has been changed from `100` to `125`. So the reconfiguration of the cluster is successful. @@ -429,9 +429,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-apply-topology.yaml -kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-apply-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/reconfigure/kafka-reconfigure-apply-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-reconfigure-apply-topology created #### Verify the new configuration is working @@ -440,15 +440,16 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequests -n demo kfops-reconfigure-apply-topology +kubectl get kafkaopsrequests -n demo kfops-reconfigure-apply-topology +``` NAME TYPE STATUS AGE kfops-reconfigure-apply-topology Reconfigure Successful 55s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to reconfigure the cluster. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-reconfigure-apply-topology +kubectl describe kafkaopsrequest -n demo kfops-reconfigure-apply-topology +``` Name: kfops-reconfigure-apply-topology Namespace: demo Labels: @@ -591,15 +592,14 @@ Events: Normal RestartNodes 15s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 14s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 14s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-reconfigure-apply-topology -``` Now let's exec into one of the instance and run a `kafka-configs.sh` command to check the new configuration we have provided. ```bash -$ $ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'log.retention.hours' +``` log.retention.hours=150 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=150, DEFAULT_CONFIG:log.retention.hours=168} log.retention.hours=150 sensitive=false synonyms={STATIC_BROKER_CONFIG:log.retention.hours=150, DEFAULT_CONFIG:log.retention.hours=168} -``` As we can see from the configuration of ready kafka, the value of `log.retention.hours` has been changed from `125` to `150`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/kafka/restart/restart.md b/docs/guides/kafka/restart/restart.md index ec8229179e..7fe12a7c44 100644 --- a/docs/guides/kafka/restart/restart.md +++ b/docs/guides/kafka/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Kafka database via a KafkaOpsRequest. Restarting - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -89,9 +89,9 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restart/kafka.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restart/kafka.yaml ``` +kafka.kubedb.com/kafka-prod created ## Apply Restart opsRequest @@ -118,18 +118,21 @@ spec: Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restart/ops.yaml -kafkaopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restart/ops.yaml ``` +kafkaopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the controller pods, then broker of the referenced kafka. -```shell -$ kubectl get kfops -n demo +```bash +kubectl get kfops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 119s -$ kubectl get kfops -n demo restart -oyaml +```bash +kubectl get kfops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: KafkaOpsRequest metadata: @@ -230,7 +233,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/kafka/restproxy/overview.md b/docs/guides/kafka/restproxy/overview.md index 666e7333a0..208ff9e8bf 100644 --- a/docs/guides/kafka/restproxy/overview.md +++ b/docs/guides/kafka/restproxy/overview.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [examples/kafka/restproxy/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/restproxy) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,13 +48,12 @@ demo Active 9s When you install the KubeDB operator, it registers a CRD named [SchemaRegistryVersion](/docs/guides/kafka/concepts/schemaregistryversion.md). RestProxy uses SchemaRegistryVersions which distribution is `Aiven` to create a RestProxy instance. The installation process comes with a set of tested SchemaRegistryVersion objects. Let's check available SchemaRegistryVersions by, ```bash -$ kubectl get ksrversion - +kubectl get ksrversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE NAME VERSION DISTRIBUTION REGISTRY_IMAGE DEPRECATED AGE 2.5.11.final 2.5.11 Apicurio apicurio/apicurio-registry-kafkasql:2.5.11.Final 3d 3.15.0 3.15.0 Aiven ghcr.io/aiven-open/karapace:3.15.0 3d -``` > **Note**: Currently RestProxy is supported only for Aiven distribution. Use version with distribution `Aiven` to create Kafka Rest Proxy. @@ -92,26 +93,27 @@ Before create RestProxy, you have to deploy a `Kafka` cluster first. To deploy k Let's create the RestProxy CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-quickstart.yaml -restproxy.kafka.kubedb.com/restproxy-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-quickstart.yaml ``` +restproxy.kafka.kubedb.com/restproxy-quickstart created The RestProxy's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the RestProxy. ```bash -$ kubectl get restproxy -n demo -w +kubectl get restproxy -n demo -w +``` NAME TYPE VERSION STATUS AGE restproxy-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 2s restproxy-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 4s . . restproxy-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Ready 112s -``` Describe the `RestProxy` object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe restproxy -n demo restproxy-quickstart +kubectl describe restproxy -n demo restproxy-quickstart +``` Name: restproxy-quickstart Namespace: demo Labels: @@ -195,14 +197,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a RestProxy CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-quickstart' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/restproxy-quickstart-0 1/1 Running 0 117s pod/restproxy-quickstart-1 1/1 Running 0 79s @@ -216,7 +218,6 @@ secret/restproxy-quickstart-config Opaque 1 119s NAME AGE petset.apps.k8s.appscode.com/restproxy-quickstart 117s -``` - `PetSet` - a PetSet named after the RestProxy instance. - `Services` - For a RestProxy instance headless service is created with name `{RestProxy-name}-{pods}` and a primary service created with name `{RestProxy-name}`. @@ -230,17 +231,18 @@ You can access `Kafka` using the REST API. The RestProxy REST API is available a To access the RestProxy REST API, you can use `kubectl port-forward` command to forward the port to your local machine. ```bash -$ kubectl port-forward svc/restproxy-quickstart 8082:8082 -n demo +kubectl port-forward svc/restproxy-quickstart 8082:8082 -n demo +``` Forwarding from 127.0.0.1:8082 -> 8082 Forwarding from [::1]:8082 -> 8082 -``` In another terminal, you can use `curl` to list topics, produce and consume messages from the Kafka cluster. List topics: ```bash -$ curl localhost:8082/topics | jq +curl localhost:8082/topics | jq +``` [ "order_notification", "kafka-health", @@ -248,8 +250,6 @@ $ curl localhost:8082/topics | jq "kafkasql-journal" ] -``` - #### Produce a message to a topic `order_notification`(replace `order_notification` with your topic name): > Note: The topic must be created in the Kafka cluster before producing messages. @@ -291,9 +291,10 @@ To consume messages from a Kafka topic using the Kafka REST Proxy, you'll need t Create a Consumer Instance ```bash -$ curl -X POST http://localhost:8082/consumers/order_consumer \ +curl -X POST http://localhost:8082/consumers/order_consumer \ -H "Content-Type: application/vnd.kafka.v2+json" \ -d '{ +``` "name": "order_consumer_instance", "format": "json", "auto.offset.reset": "earliest" @@ -303,24 +304,23 @@ $ curl -X POST http://localhost:8082/consumers/order_consumer \ "base_uri": "http://restproxy-quickstart-0:8082/consumers/order_consumer/instances/order_consumer_instance", "instance_id": "order_consumer_instance" } -``` Subscribe the Consumer to a Topic ```bash -$ curl -X POST http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance/subscription \ +curl -X POST http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance/subscription \ -H "Content-Type: application/vnd.kafka.v2+json" \ -d '{ +``` "topics": ["order_notification"] }' -``` Consume Messages ```bash -$ curl -X GET http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance/records \ +curl -X GET http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance/records \ -H "Accept: application/vnd.kafka.json.v2+json" | jq - +``` [ { "key": null, @@ -365,12 +365,11 @@ $ curl -X GET http://localhost:8082/consumers/order_consumer/instances/order_con } } ] -``` Delete the Consumer Instance ```bash -$ curl -X DELETE http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance +curl -X DELETE http://localhost:8082/consumers/order_consumer/instances/order_consumer_instance ``` You can also list brokers, describe topics and more using the Kafka RestProxy. @@ -380,18 +379,24 @@ You can also list brokers, describe topics and more using the Kafka RestProxy. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo restproxy restproxy-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo restproxy restproxy-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` restproxy.kafka.kubedb.com/restproxy-quickstart patched -$ kubectl delete krp restproxy-quickstart -n demo +```bash +kubectl delete krp restproxy-quickstart -n demo +``` restproxy.kafka.kubedb.com "restproxy-quickstart" deleted -$ kubectl delete kafka kafka-quickstart -n demo +```bash +kubectl delete kafka kafka-quickstart -n demo +``` kafka.kubedb.com "kafka-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/kafka/restproxy/with-schema-registry.md b/docs/guides/kafka/restproxy/with-schema-registry.md index 5d0b96b512..63881f9384 100644 --- a/docs/guides/kafka/restproxy/with-schema-registry.md +++ b/docs/guides/kafka/restproxy/with-schema-registry.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [examples/kafka/restproxy/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/restproxy) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,12 +44,11 @@ demo Active 9s When you install the KubeDB operator, it registers a CRD named [SchemaRegistryVersion](/docs/guides/kafka/concepts/schemaregistryversion.md). RestProxy uses SchemaRegistryVersions which distribution is `Aiven` to create a RestProxy instance. The installation process comes with a set of tested SchemaRegistryVersion objects. Let's check available SchemaRegistryVersions by, ```bash -$ kubectl get ksrversion - +kubectl get ksrversion +``` NAME VERSION DISTRIBUTION REGISTRY_IMAGE DEPRECATED AGE 2.5.11.final 2.5.11 Apicurio apicurio/apicurio-registry-kafkasql:2.5.11.Final 3d 3.15.0 3.15.0 Aiven ghcr.io/aiven-open/karapace:3.15.0 3d -``` > **Note**: Currently RestProxy is supported only for Aiven distribution. Use version with distribution `Aiven` to create Kafka Rest Proxy. @@ -96,26 +97,27 @@ Before create RestProxy, you have to deploy a `Kafka` cluster first. To deploy k Let's create the RestProxy CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-internal-sr.yaml -restproxy.kafka.kubedb.com/restproxy-internal-sr created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-internal-sr.yaml ``` +restproxy.kafka.kubedb.com/restproxy-internal-sr created The RestProxy's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the RestProxy. ```bash -$ kubectl get restproxy -n demo -w +kubectl get restproxy -n demo -w +``` NAME TYPE VERSION KAFKA STATUS AGE restproxy-internal-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Provisioning 2s restproxy-internal-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Provisioning 4s . . restproxy-internal-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Ready 112s -``` Describe the `RestProxy` object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe restproxy -n demo restproxy-internal-sr +kubectl describe restproxy -n demo restproxy-internal-sr +``` Name: restproxy-internal-sr Namespace: demo Labels: @@ -201,14 +203,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a RestProxy CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-internal-sr' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-internal-sr' +``` NAME READY STATUS RESTARTS AGE pod/restproxy-internal-sr-0 1/1 Running 0 117s pod/restproxy-internal-sr-1 1/1 Running 0 79s @@ -222,7 +224,6 @@ secret/restproxy-internal-sr-config Opaque 1 119s NAME AGE petset.apps.k8s.appscode.com/restproxy-internal-sr 117s -``` - `PetSet` - a PetSet named after the RestProxy instance. - `Services` - For a RestProxy instance headless service is created with name `{RestProxy-name}-{pods}` and a primary service created with name `{RestProxy-name}`. @@ -265,26 +266,27 @@ Before create RestProxy, you have to deploy a `Kafka` cluster first. To deploy k Let's create the RestProxy CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-external-sr.yaml -restproxy.kafka.kubedb.com/restproxy-external-sr created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/restproxy/restproxy-external-sr.yaml ``` +restproxy.kafka.kubedb.com/restproxy-external-sr created The RestProxy's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the RestProxy. ```bash -$ kubectl get restproxy -n demo -w +kubectl get restproxy -n demo -w +``` NAME TYPE VERSION KAFKA STATUS AGE restproxy-external-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Provisioning 2s restproxy-external-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Provisioning 4s . . restproxy-external-sr kafka.kubedb.com/v1alpha1 3.15.0 kafka-quickstart Ready 112s -``` Describe the `RestProxy` object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe restproxy -n demo restproxy-external-sr +kubectl describe restproxy -n demo restproxy-external-sr +``` Name: restproxy-external-sr Namespace: demo Labels: @@ -371,14 +373,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a RestProxy CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-external-sr' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=restproxy-external-sr' +``` NAME READY STATUS RESTARTS AGE pod/restproxy-external-sr-0 1/1 Running 0 24s @@ -391,7 +393,6 @@ secret/restproxy-external-sr-config Opaque 1 25s NAME AGE petset.apps.k8s.appscode.com/restproxy-external-sr 24s -``` - `PetSet` - a PetSet named after the RestProxy instance. - `Services` - For a RestProxy instance headless service is created with name `{RestProxy-name}-{pods}` and a primary service created with name `{RestProxy-name}`. @@ -405,26 +406,26 @@ We are going to create schema first for message validation. There are many ways * If you are using internal SchemaRegistry, port forward the `restproxy-internal-sr` service to port `8082`, and export `SCHEMA_BASE_URL` like below: ```bash -$ kubectl port-forward svc/restproxy-internal-sr 8082:8082 -n demo +kubectl port-forward svc/restproxy-internal-sr 8082:8082 -n demo +``` Forwarding from 127.0.0.1:8082 -> 8082 Forwarding from [::1]:8082 -> 8082 Handling connection for 8082 -``` ```bash -$ export SCHEMA_BASE_URL=http://localhost:8082 +export SCHEMA_BASE_URL=http://localhost:8082 ``` * If you are using external SchemaRegistry, port forward the `schemaregistry-quickstart` service to port `8080`, and export `SCHEMA_BASE_URL` like below: ```bash -$ kubectl port-forward svc/schemaregistry-quickstart 8080:8080 -n demo +kubectl port-forward svc/schemaregistry-quickstart 8080:8080 -n demo +``` Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080 Handling connection for 8080 -```` ```bash -$ export SCHEMA_BASE_URL=http://localhost:8080/apis/ccompat/v7 +export SCHEMA_BASE_URL=http://localhost:8080/apis/ccompat/v7 ``` Schema: @@ -458,17 +459,18 @@ You can access `Kafka` using the REST API. The RestProxy REST API is available a To access the RestProxy REST API, you can use `kubectl port-forward` command to forward the port to your local machine. ```bash -$ kubectl port-forward svc/restproxy-internal-sr 8082:8082 -n demo +kubectl port-forward svc/restproxy-internal-sr 8082:8082 -n demo +``` Forwarding from 127.0.0.1:8082 -> 8082 Forwarding from [::1]:8082 -> 8082 -``` In another terminal, you can use `curl` to list topics, produce and consume messages from the Kafka cluster. List topics: ```bash -$ curl localhost:8082/topics | jq +curl localhost:8082/topics | jq +``` [ "rest-demo", "kafka-health", @@ -476,16 +478,16 @@ $ curl localhost:8082/topics | jq "__consumer_offsets", "kafkasql-journal" ] -``` #### Produce a message to a topic `rest-demo`(replace `rest-demo` with your topic name): > Note: The topic must be created in the Kafka cluster before producing messages. ```bash -$ curl -X POST http://localhost:8082/topics/rest-demo \ +curl -X POST http://localhost:8082/topics/rest-demo \ -H "Content-Type: application/vnd.kafka.avro.v2+json" \ -d '{ +``` "value_schema_id": 1, "records": [ {"value": {"id": 1, "name": "Alice", "email": {"string": "alice@example.com"}}}, @@ -511,7 +513,6 @@ $ curl -X POST http://localhost:8082/topics/rest-demo \ ], "value_schema_id": 1 } -``` Here, we have produced 3 messages to the topic `rest-demo` and used the value schema id `1` that we created earlier. #### Consume messages from a topic `order_notification`(replace `order_notification` with your topic name): @@ -521,9 +522,10 @@ To consume messages from a Kafka topic using the Kafka REST Proxy, you'll need t Create a Consumer Instance ```bash -$ curl -X POST http://localhost:8082/consumers/my_consumer_group \ + curl -X POST http://localhost:8082/consumers/my_consumer_group \ -H "Content-Type: application/vnd.kafka.v2+json" \ -d '{ +``` "name": "my_consumer", "format": "avro", "auto.offset.reset": "earliest" @@ -532,23 +534,22 @@ $ curl -X POST http://localhost:8082/consumers/my_consumer_group \ "base_uri": "http://restproxy-internal-sr-0:8082/consumers/my_consumer_group/instances/my_consumer", "instance_id": "my_consumer" } -``` Subscribe the Consumer to a Topic ```bash -$ curl -X POST http://localhost:8082/consumers/my_consumer_group/instances/my_consumer/subscription \ +curl -X POST http://localhost:8082/consumers/my_consumer_group/instances/my_consumer/subscription \ -H "Content-Type: application/vnd.kafka.v2+json" \ -d '{ +``` "topics": ["rest-demo"] }' -``` Consume Messages ```bash -$ curl -X GET -H "Accept: application/vnd.kafka.avro.v2+json" http://localhost:8082/consumers/my_consumer_group/instances/my_consumer/records | jq - +curl -X GET -H "Accept: application/vnd.kafka.avro.v2+json" http://localhost:8082/consumers/my_consumer_group/instances/my_consumer/records | jq +``` [ { "key": null, @@ -587,12 +588,11 @@ $ curl -X GET -H "Accept: application/vnd.kafka.avro.v2+json" http://localhost:8 } } ] -``` Delete the Consumer Instance ```bash -$ curl -X DELETE -H "Content-Type: application/vnd.kafka.v2+json" http://localhost:8082/consumers/my_consumer_group/instances/my_consumer +curl -X DELETE -H "Content-Type: application/vnd.kafka.v2+json" http://localhost:8082/consumers/my_consumer_group/instances/my_consumer ``` ## Cleaning up @@ -600,21 +600,29 @@ $ curl -X DELETE -H "Content-Type: application/vnd.kafka.v2+json" http://localho To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo restproxy restproxy-internal-sr -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo restproxy restproxy-internal-sr -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` restproxy.kafka.kubedb.com/restproxy-internal-sr patched -$ kubectl delete krp restproxy-internal-sr,restproxy-external-sr -n demo +```bash +kubectl delete krp restproxy-internal-sr,restproxy-external-sr -n demo +``` restproxy.kafka.kubedb.com "restproxy-internal-sr,restproxy-external-sr" deleted -$ kubectl delete ksr schemaregistry-quickstart -n demo +```bash +kubectl delete ksr schemaregistry-quickstart -n demo +``` schemaregistry.kafka.kubedb.com "schemaregistry-quickstart" deleted -$ kubectl delete kafka kafka-quickstart -n demo +```bash +kubectl delete kafka kafka-quickstart -n demo +``` kafka.kubedb.com "kafka-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/kafka/rotate-auth/kafka.md b/docs/guides/kafka/rotate-auth/kafka.md index ccd7f89efe..37b79edebf 100644 --- a/docs/guides/kafka/rotate-auth/kafka.md +++ b/docs/guides/kafka/rotate-auth/kafka.md @@ -29,9 +29,9 @@ This tutorial will show you how to use KubeDB to rotate authentication credentia - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -73,52 +73,55 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-prod.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-prod.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 9s . . kafka-prod kubedb.com/v1 3.9.0 Ready 2m10s -``` Now, we can exec one kafka broker pod and verify configuration that authentication is enabled. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep sasl.enabled.mechanism - +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep sasl.enabled.mechanism +``` listener.name.local.sasl.enabled.mechanisms=PLAIN sensitive=false synonyms={STATIC_BROKER_CONFIG:listener.name.local.sasl.enabled.mechanisms=PLAIN, STATIC_BROKER_CONFIG:sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256, DEFAULT_CONFIG:sasl.enabled.mechanisms=GSSAPI} sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256 sensitive=false synonyms={STATIC_BROKER_CONFIG:sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256, DEFAULT_CONFIG:sasl.enabled.mechanisms=GSSAPI} listener.name.local.sasl.enabled.mechanisms=PLAIN sensitive=false synonyms={STATIC_BROKER_CONFIG:listener.name.local.sasl.enabled.mechanisms=PLAIN, STATIC_BROKER_CONFIG:sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256, DEFAULT_CONFIG:sasl.enabled.mechanisms=GSSAPI} sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256 sensitive=false synonyms={STATIC_BROKER_CONFIG:sasl.enabled.mechanisms=PLAIN,SCRAM-SHA-256, DEFAULT_CONFIG:sasl.enabled.mechanisms=GSSAPI} -``` We can verify from the above output that authentication is enabled for this cluster. By default, KubeDB operator create default credentials for the Kafka cluster. The default credentials are stored in a secret named `-auth` in the same namespace as the Kafka cluster. You can find the secret by running the following command: ```bash -$ kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +``` "kafka-prod-auth" -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password}' | base64 -d -zvrFXkStB~9A!NTC +```bash +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password}' | base64 -d ``` +zvrFXkStB~9A!NTC You will find a new field `.spec.authSecret.activeFrom` in the `Kafka` CR. This field is used to track the active credentials. The value of this field is set the time when the secret (`.spec.authSecret.name`) is active for kafka cluster. The value of this field is updated when the authentication is rotated. ```bash -$ kubectl get kf -n demo kafka-prod -ojsonpath='{.spec.authSecret.activeFrom}' -2025-04-03T08:42:05Z +kubectl get kf -n demo kafka-prod -ojsonpath='{.spec.authSecret.activeFrom}' ``` +2025-04-03T08:42:05Z > **Note:** There is another field `.spec.authSecret.rotateAfter` in the `Kafka` CR. This field is used to track the time when the authentication will be rotated. When a user set this field, Recommendation Engine will generate a recommendation `RotateAuth` Ops Request after this time from `.spec.authSecret.activeFrom`(i.e. `activeFrom + rotateAfter`). You need `Recommendation Engine` to be installed in order to use this feature. @@ -152,22 +155,23 @@ Let's create the `KafkaOpsRequest` CR we have shown above, > **Note:** For combined kafka, you just need to refer kafka combined object in `databaseRef` field. To learn more about combined kafka, please visit [here](/docs/guides/kafka/clustering/combined-cluster/index.md). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-rotate-auth-generated.yaml -kafkaopsrequest.ops.kubedb.com/kfops-rotate-auth-generated created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-rotate-auth-generated.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-rotate-auth-generated created Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-rotate-auth-generated RotateAuth Successful 3m18s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-rotate-auth-generated +kubectl describe kafkaopsrequest -n demo kfops-rotate-auth-generated +``` Name: kfops-rotate-auth-generated Namespace: demo Labels: @@ -305,31 +309,37 @@ Events: Normal RestartNodes 55s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 55s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 55s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-rotate-auth-generated -``` #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +``` "kafka-prod-auth" -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password}' | base64 -d -al9jY2xvYW5pbmc= +```bash +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password}' | base64 -d ``` +al9jY2xvYW5pbmc= Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username.prev}' | base64 -d +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.username.prev}' | base64 -d +``` admin -$ kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password.prev}' | base64 -d -zvrFXkStB~9A!NTC + +```bash +kubectl get secret -n demo kafka-prod-auth -o=jsonpath='{.data.password.prev}' | base64 -d ``` +zvrFXkStB~9A!NTC The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. @@ -338,12 +348,12 @@ The above output shows that the password has been changed successfully. The prev At first, we need to create a secret with `kubernetes.io/basic-auth` type using custom `username` and `password`. Below is the command to create a secret with `kubernetes.io/basic-auth` type, ```bash -$ kubectl create secret generic kafka-user-auth -n demo \ +kubectl create secret generic kafka-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=kafka \ --from-literal=password=kafka-secret -secret/kafka-user-auth created ``` +secret/kafka-user-auth created Now create a Kafka Ops Request with `RotateAuth` type. Below is the YAML of the `KafkaOpsRequest` that we are going to create, @@ -376,23 +386,24 @@ Let's create the `KafkaOpsRequest` CR we have shown above, > **Note:** For combined kafka, you just need to refer kafka combined object in `databaseRef` field. To learn more about combined kafka, please visit [here](/docs/guides/kafka/clustering/combined-cluster/index.md). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-rotate-auth-user.yaml -kafkaopsrequest.ops.kubedb.com/kfops-rotate-auth-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/rotate-auth/kafka-rotate-auth-user.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-rotate-auth-user created Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CRO, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-rotate-auth-generated RotateAuth Successful 83m kfops-rotate-auth-user RotateAuth Successful 2m58s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-rotate-auth-user +kubectl describe kafkaopsrequest -n demo kfops-rotate-auth-user +``` Name: kfops-rotate-auth-user Namespace: demo Labels: @@ -533,31 +544,37 @@ Events: Normal RestartNodes 21s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 21s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 21s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-rotate-auth-user -``` #### Verify Password is changed Now, We can verify that the password has been changed. You can find the secret and its data by running the following command: ```bash -$ kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +kubectl get kf -n demo kafka-prod -ojson | jq .spec.authSecret.name +``` "kafka-user-auth" -$ kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` kafka -$ kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.password}' | base64 -d -kafka-secret +```bash +kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +kafka-secret Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: ```bash -$ kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.username.prev}' | base64 -d +kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.username.prev}' | base64 -d +``` admin -$ kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.password.prev}' | base64 -d -al9jY2xvYW5pbmc= + +```bash +kubectl get secret -n demo kafka-user-auth -o=jsonpath='{.data.password.prev}' | base64 -d ``` +al9jY2xvYW5pbmc= The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. diff --git a/docs/guides/kafka/scaling/horizontal-scaling/combined.md b/docs/guides/kafka/scaling/horizontal-scaling/combined.md index 665636ceb5..ac17d7a550 100644 --- a/docs/guides/kafka/scaling/horizontal-scaling/combined.md +++ b/docs/guides/kafka/scaling/horizontal-scaling/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the K To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -72,31 +72,33 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Let's check the number of replicas has from kafka object, number of pods the petset have, ```bash -$ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' ``` +2 We can see from both command that the cluster has 2 replicas. @@ -105,7 +107,8 @@ Also, we can verify the replicas of the combined from an internal kafka command Now let's exec to a instance and run a kafka internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-dev-0.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -236,7 +239,6 @@ kafka-dev-1.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 1 rack: null) -> ( AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` We can see from the above output that the kafka has 2 nodes. @@ -273,9 +275,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-up-combined.yaml -kafkaopsrequest.ops.kubedb.com/kfops-hscale-up-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-up-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-hscale-up-combined created #### Verify Combined cluster replicas scaled up successfully @@ -284,15 +286,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-hscale-up-combined HorizontalScaling Successful 106s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-hscale-up-combined +kubectl describe kafkaopsrequests -n demo kfops-hscale-up-combined +``` Name: kfops-hscale-up-combined Namespace: demo Labels: @@ -400,21 +403,23 @@ Events: Normal ScaleUpCombined 2m16s KubeDB Ops-manager Operator Successfully Scaled Up Server Node Normal Starting 2m16s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 2m16s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-hscale-up-combined -``` Now, we are going to verify the number of replicas this cluster has from the Kafka object, number of pods the petset have, ```bash -$ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' ``` +3 Now let's connect to a kafka instance and run a kafka internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-dev-0.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -610,7 +615,6 @@ kafka-dev-2.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 2 rack: null) -> ( AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` From all the above outputs we can see that the brokers of the combined kafka is `3`. That means we have successfully scaled up the replicas of the Kafka combined cluster. @@ -645,9 +649,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-down-combined.yaml -kafkaopsrequest.ops.kubedb.com/kfops-hscale-down-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-down-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-hscale-down-combined created #### Verify Combined cluster replicas scaled down successfully @@ -656,15 +660,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-hscale-down-combined HorizontalScaling Successful 2m32s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-hscale-down-combined +kubectl describe kafkaopsrequests -n demo kfops-hscale-down-combined +``` Name: kfops-hscale-down-combined Namespace: demo Labels: @@ -799,22 +804,24 @@ Events: Normal RestartNodes 20s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 20s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 20s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-hscale-down-combined -``` Now, we are going to verify the number of replicas this cluster has from the Kafka object, number of pods the petset have, ```bash -$ kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +kubectl get kafka -n demo kafka-dev -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-dev -o json | jq '.spec.replicas' ``` +2 Now let's connect to a kafka instance and run a kafka internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-dev-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-dev-0.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -945,7 +952,6 @@ kafka-dev-1.kafka-dev-pods.demo.svc.cluster.local:9092 (id: 1 rack: null) -> ( AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` From all the above outputs we can see that the replicas of the combined cluster is `2`. That means we have successfully scaled down the replicas of the Kafka combined cluster. diff --git a/docs/guides/kafka/scaling/horizontal-scaling/topology.md b/docs/guides/kafka/scaling/horizontal-scaling/topology.md index 21ddb2e71a..70f375a0a2 100644 --- a/docs/guides/kafka/scaling/horizontal-scaling/topology.md +++ b/docs/guides/kafka/scaling/horizontal-scaling/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the K To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -83,43 +83,47 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-prod kubedb.com/v1 3.9.0 Ready 92s -``` Let's check the number of replicas has from kafka object, number of pods the petset have, **Broker Replicas** ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +``` 2 -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' ``` +2 **Controller Replicas** ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.replicas' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.replicas' +``` 2 -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.replicas' ``` +2 We can see from commands that the cluster has 2 replicas for both broker and controller. @@ -130,7 +134,8 @@ Now let's exec to a broker instance and run a kafka internal command to check th **Broker** ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-prod-broker-0.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -261,14 +266,13 @@ kafka-prod-broker-1.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 1 rack: nul AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` **Controller** ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers -CurrentObservers: [0,1] +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers ``` +CurrentObservers: [0,1] We can see from the above output that the kafka has 2 nodes for broker and 2 nodes for controller. @@ -308,9 +312,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-up-topology.yaml -kafkaopsrequest.ops.kubedb.com/kfops-hscale-up-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-up-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-hscale-up-topology created > **Note:** If you want to scale down only broker or controller, you can specify the desired replicas for only broker or controller in the `KafkaOpsRequest` CR. You can specify one at a time. If you want to scale broker only, no node will need restart to apply the changes. But if you want to scale controller, all nodes will need restart to apply the changes. @@ -321,15 +325,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-hscale-up-topology HorizontalScaling Successful 106s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-hscale-up-topology +kubectl describe kafkaopsrequests -n demo kfops-hscale-up-topology +``` Name: kfops-hscale-up-topology Namespace: demo Labels: @@ -491,26 +496,28 @@ Events: Normal ScaleUpController 115s KubeDB Ops-manager Operator Successfully Scaled Up Controller Normal Starting 115s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 115s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-hscale-up-topology -``` Now, we are going to verify the number of replicas this cluster has from the Kafka object, number of pods the petset have, **Broker Replicas** ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +``` 3 -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' ``` +3 Now let's connect to a kafka instance and run a kafka internal command to check the number of replicas of topology cluster for both broker and controller., **Broker** ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-prod-broker-0.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -706,14 +713,13 @@ kafka-prod-broker-2.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 2 rack: nul AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` **Controller** ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers -CurrentObservers: [0,1,2] +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers ``` +CurrentObservers: [0,1,2] From all the above outputs we can see that the both brokers and controller of the topology kafka is `3`. That means we have successfully scaled up the replicas of the Kafka topology cluster. @@ -751,9 +757,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-down-topology.yaml -kafkaopsrequest.ops.kubedb.com/kfops-hscale-down-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/horizontal-scaling/kafka-hscale-down-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-hscale-down-topology created #### Verify Topology cluster replicas scaled down successfully @@ -762,15 +768,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ watch kubectl get kafkaopsrequest -n demo +watch kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-hscale-down-topology HorizontalScaling Successful 2m32s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequests -n demo kfops-hscale-down-topology +kubectl describe kafkaopsrequests -n demo kfops-hscale-down-topology +``` Name: kfops-hscale-down-topology Namespace: demo Labels: @@ -960,36 +967,40 @@ Events: Normal RestartNodes 5m35s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5m35s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 5m34s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-hscale-down-topology -``` Now, we are going to verify the number of replicas this cluster has from the Kafka object, number of pods the petset have, **Broker Replicas** ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.broker.replicas' +``` 2 -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.replicas' ``` +2 **Controller Replicas** ```bash -$ kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.replicas' +kubectl get kafka -n demo kafka-prod -o json | jq '.spec.topology.controller.replicas' +``` 2 -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.replicas' ``` +2 Now let's connect to a kafka instance and run a kafka internal command to check the number of replicas for both broker and controller nodes, **Broker** ```bash -$ kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +kubectl exec -it -n demo kafka-prod-broker-0 -- kafka-broker-api-versions.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties +``` kafka-prod-broker-0.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 0 rack: null) -> ( Produce(0): 0 to 9 [usable: 9], Fetch(1): 0 to 15 [usable: 15], @@ -1120,14 +1131,13 @@ kafka-prod-broker-1.kafka-prod-pods.demo.svc.cluster.local:9092 (id: 1 rack: nul AllocateProducerIds(67): UNSUPPORTED, ConsumerGroupHeartbeat(68): UNSUPPORTED ) -``` **Controller** ```bash -$ kubectl exec -it -n demo kafka-prod-controller-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers -CurrentObservers: [0,1] +kubectl exec -it -n demo kafka-prod-controller-0 -- kafka-metadata-quorum.sh --bootstrap-server localhost:9092 --command-config config/clientauth.properties describe --status | grep CurrentObservers ``` +CurrentObservers: [0,1] From all the above outputs we can see that the replicas of both broker and controller of the topology cluster is `2`. That means we have successfully scaled down the replicas of the Kafka topology cluster. diff --git a/docs/guides/kafka/scaling/vertical-scaling/combined.md b/docs/guides/kafka/scaling/vertical-scaling/combined.md index a2aaa40dc3..1eb5cbaafc 100644 --- a/docs/guides/kafka/scaling/vertical-scaling/combined.md +++ b/docs/guides/kafka/scaling/vertical-scaling/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -72,26 +72,27 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -101,7 +102,6 @@ $ kubectl get pod -n demo kafka-dev-0 -o json | jq '.spec.containers[].resources "memory": "1Gi" } } -``` This is the default resources of the Kafka combined cluster set by the `KubeDB` operator. We are now ready to apply the `KafkaOpsRequest` CR to update the resources of this database. @@ -146,9 +146,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/vertical-scaling/kafka-vertical-scaling-combined.yaml -kafkaopsrequest.ops.kubedb.com/kfops-vscale-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/vertical-scaling/kafka-vertical-scaling-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-vscale-combined created #### Verify Kafka Combined cluster resources updated successfully @@ -157,15 +157,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-vscale-combined VerticalScaling Successful 3m56s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-vscale-combined +kubectl describe kafkaopsrequest -n demo kfops-vscale-combined +``` Name: kfops-vscale-combined Namespace: demo Labels: @@ -268,12 +269,12 @@ Events: Normal RestartPods 40s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 40s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 40s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kfops-vscale-combined -``` Now, we are going to verify from one of the Pod yaml whether the resources of the combined cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo kafka-dev-1 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-dev-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -284,7 +285,6 @@ $ kubectl get pod -n demo kafka-dev-1 -o json | jq '.spec.containers[].resources "memory": "1288490188800m" } } -``` The above output verifies that we have successfully scaled up the resources of the Kafka combined cluster. diff --git a/docs/guides/kafka/scaling/vertical-scaling/topology.md b/docs/guides/kafka/scaling/vertical-scaling/topology.md index 05a1fa929d..7e537138e7 100644 --- a/docs/guides/kafka/scaling/vertical-scaling/topology.md +++ b/docs/guides/kafka/scaling/vertical-scaling/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -83,26 +83,27 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-prod kubedb.com/v1 3.9.0 Ready 92s -``` Let's check the Pod containers resources for both `broker` and `controller` of the Kafka topology cluster. Run the following command to get the resources of the `broker` and `controller` containers of the Kafka topology cluster ```bash -$ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -112,10 +113,10 @@ $ kubectl get pod -n demo kafka-prod-broker-0 -o json | jq '.spec.containers[].r "memory": "1Gi" } } -``` ```bash -$ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -125,7 +126,6 @@ $ kubectl get pod -n demo kafka-prod-controller-0 -o json | jq '.spec.containers "memory": "1Gi" } } -``` This is the default resources of the Kafka topology cluster set by the `KubeDB` operator. We are now ready to apply the `KafkaOpsRequest` CR to update the resources of this database. @@ -178,9 +178,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/vertical-scaling/kafka-vertical-scaling-topology.yaml -kafkaopsrequest.ops.kubedb.com/kfops-vscale-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/scaling/vertical-scaling/kafka-vertical-scaling-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kfops-vscale-topology created #### Verify Kafka Topology cluster resources updated successfully @@ -189,15 +189,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kfops-vscale-topology VerticalScaling Successful 3m56s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe kafkaopsrequest -n demo kfops-vscale-topology +kubectl describe kafkaopsrequest -n demo kfops-vscale-topology +``` Name: kfops-vscale-topology Namespace: demo Labels: @@ -345,11 +346,11 @@ Events: Normal RestartPods 2m18s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 2m18s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 2m18s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kfops-vscale-topology -``` Now, we are going to verify from one of the Pod yaml whether the resources of the topology cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo kafka-prod-broker-1 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo kafka-prod-broker-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -360,7 +361,10 @@ $ kubectl get pod -n demo kafka-prod-broker-1 -o json | jq '.spec.containers[].r "memory": "1288490188800m" } } -$ kubectl get pod -n demo kafka-prod-controller-1 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo kafka-prod-controller-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -371,7 +375,6 @@ $ kubectl get pod -n demo kafka-prod-controller-1 -o json | jq '.spec.containers "memory": "1181116006400m" } } -``` The above output verifies that we have successfully scaled up the resources of the Kafka topology cluster. diff --git a/docs/guides/kafka/schemaregistry/overview.md b/docs/guides/kafka/schemaregistry/overview.md index 07b9b38042..802b6c4ee9 100644 --- a/docs/guides/kafka/schemaregistry/overview.md +++ b/docs/guides/kafka/schemaregistry/overview.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [examples/kafka/schemaregistry/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/schemaregistry) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,13 +48,12 @@ demo Active 9s When you install the KubeDB operator, it registers a CRD named [SchemaRegistryVersion](/docs/guides/kafka/concepts/schemaregistryversion.md). The installation process comes with a set of tested SchemaRegistryVersion objects. Let's check available SchemaRegistryVersions by, ```bash -$ kubectl get ksrversion - +kubectl get ksrversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE NAME VERSION DISTRIBUTION REGISTRY_IMAGE DEPRECATED AGE 2.5.11.final 2.5.11 Apicurio apicurio/apicurio-registry-kafkasql:2.5.11.Final 3d 3.15.0 3.15.0 Aiven ghcr.io/aiven-open/karapace:3.15.0 3d -``` > **Note**: Currently Schema Registry is supported only for Apicurio distribution. Use version with distribution `Apicurio` to create Schema Registry. @@ -94,26 +95,27 @@ Before create SchemaRegistry, you have to deploy a `Kafka` cluster first. To dep Let's create the SchemaRegistry CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/schemaregistry/schemaregistry-apicurio.yaml -schemaregistry.kafka.kubedb.com/schemaregistry-quickstart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/schemaregistry/schemaregistry-apicurio.yaml ``` +schemaregistry.kafka.kubedb.com/schemaregistry-quickstart created The SchemaRegistry's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the SchemaRegistry. ```bash -$ kubectl get schemaregistry -n demo -w +kubectl get schemaregistry -n demo -w +``` NAME TYPE VERSION STATUS AGE schemaregistry-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 2s schemaregistry-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 4s . . schemaregistry-quickstart kafka.kubedb.com/v1alpha1 3.9.0 Ready 112s -``` Describe the `SchemaRegistry` object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe schemaregistry -n demo schemaregistry-quickstart +kubectl describe schemaregistry -n demo schemaregistry-quickstart +``` Name: schemaregistry-quickstart Namespace: demo Labels: @@ -197,14 +199,14 @@ Status: Type: Provisioned Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a SchemaRegistry CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=schemaregistry-quickstart' +kubectl get all,secret,petset -n demo -l 'app.kubernetes.io/instance=schemaregistry-quickstart' +``` NAME READY STATUS RESTARTS AGE pod/schemaregistry-quickstart-0 1/1 Running 0 4m14s pod/schemaregistry-quickstart-1 1/1 Running 0 3m28s @@ -218,7 +220,6 @@ secret/schemaregistry-quickstart-config Opaque 1 4m17s NAME AGE petset.apps.k8s.appscode.com/schemaregistry-quickstart 4m14s -``` - `PetSet` - a PetSet named after the SchemaRegistry instance. - `Services` - For a SchemaRegistry instance headless service is created with name `{SchemaRegistry-name}-{pods}` and a primary service created with name `{SchemaRegistry-name}`. @@ -232,21 +233,21 @@ You can access the Schema Registry using the REST API. The Schema Registry REST To access the Schema Registry REST API, you can use `kubectl port-forward` command to forward the port to your local machine. ```bash -$ kubectl port-forward service/schemaregistry-quickstart 8080:8080 -n demo +kubectl port-forward service/schemaregistry-quickstart 8080:8080 -n demo +``` Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080 -``` In another terminal, you can use `curl` to get, create or update schema using the Schema Registry REST API. Create a new schema with the following command: ```bash -$ curl -X POST -H "Content-Type: application/json; artifactType=AVRO" -H "X-Registry-ArtifactId: share-price" \ +curl -X POST -H "Content-Type: application/json; artifactType=AVRO" -H "X-Registry-ArtifactId: share-price" \ --data '{"type":"record","name":"price","namespace":"com.example", \ "fields":[{"name":"symbol","type":"string"},{"name":"price","type":"string"}]}' \ localhost:8080/apis/registry/v2/groups/quickstart-group/artifacts | jq - +``` { "createdBy": "", "createdOn": "2024-09-02T05:53:03+0000", @@ -261,12 +262,12 @@ $ curl -X POST -H "Content-Type: application/json; artifactType=AVRO" -H "X-Regi "contentId": 2, "references": [] } -``` Get all the groups: ```bash -$ curl localhost:8080/apis/registry/v2/groups | jq . +curl localhost:8080/apis/registry/v2/groups | jq . +``` { "groups": [ { @@ -278,12 +279,12 @@ $ curl localhost:8080/apis/registry/v2/groups | jq . ], "count": 1 } -``` Get all the artifacts in the group `quickstart-group`: ```bash -$ curl localhost:8080/apis/registry/v2/groups/quickstart-group/artifacts | jq +curl localhost:8080/apis/registry/v2/groups/quickstart-group/artifacts | jq +``` { "artifacts": [ { @@ -299,7 +300,6 @@ $ curl localhost:8080/apis/registry/v2/groups/quickstart-group/artifacts | jq ], "count": 1 } -``` > **Note**: You can also use Schema Registry with Confluent 7 compatible REST APIs. To use confluent compatible REST APIs, you have to add `apis/ccompat/v7` after url address.(e.g. `localhost:8081/subjects` -> `localhost:8080/apis/ccompat/v7/subjects`) @@ -321,18 +321,24 @@ From the UI, you can create, update, delete, and view the schema. Also add compa To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo schemaregistry schemaregistry-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo schemaregistry schemaregistry-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` schemaregistry.kafka.kubedb.com/schemaregistry-quickstart patched -$ kubectl delete ksr schemaregistry-quickstart -n demo +```bash +kubectl delete ksr schemaregistry-quickstart -n demo +``` schemaregistry.kafka.kubedb.com "schemaregistry-quickstart" deleted -$ kubectl delete kafka kafka-quickstart -n demo +```bash +kubectl delete kafka kafka-quickstart -n demo +``` kafka.kubedb.com "kafka-quickstart" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/kafka/tiered-storage/tiered-storage.md b/docs/guides/kafka/tiered-storage/tiered-storage.md index c71b23f19f..4025edad98 100644 --- a/docs/guides/kafka/tiered-storage/tiered-storage.md +++ b/docs/guides/kafka/tiered-storage/tiered-storage.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [examples/kafka/tiered-storage/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -56,9 +58,9 @@ stringData: Apply the secret: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-s3-tiered-secret.yaml -secret/aws-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-s3-tiered-secret.yaml ``` +secret/aws-secret created ## Create a Kafka Tiered Storage with S3 compatible storage @@ -115,24 +117,25 @@ Here, - `spec.tieredStorage.s3.prefix` specifies the prefix for the S3 objects. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-s3-tiered.yaml -kafka.kubedb.com/kafka-prod-tiered created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-s3-tiered.yaml ``` +kafka.kubedb.com/kafka-prod-tiered created ```bash -$ kubectl get kafka -n demo -w +kubectl get kafka -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 2s kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 4s . . kafka-prod-tiered kubedb.com/v1 4.0.0 Ready 112s -``` Exec one of the broker pods and run the following command to create a tiered storage enabled topic and insert some data into it: ```bash -$ kubectl exec -n demo -it kafka-prod-tiered-broker-0 -- bash +kubectl exec -n demo -it kafka-prod-tiered-broker-0 -- bash +``` root@kafka-prod-tiered-broker-0:/# kafka-topics.sh \ --bootstrap-server localhost:9092 \ --create \ @@ -158,7 +161,6 @@ root@kafka-prod-tiered-broker-0:/# kafka-producer-perf-test.sh \ 4998 records sent, 999.2 records/sec (0.49 MB/sec), 13.5 ms avg latency, 526.0 ms max latency. 10000 records sent, 999.3 records/sec (0.49 MB/sec), 8.51 ms avg latency, 526.00 ms max latency, 4 ms 50th, 50 ms 95th, 92 ms 99th, 92 ms 99.9th. -``` here, we created a topic with `local.retention.bytes=1` which will force kafka to offload segments to the remote tiered storage as soon as possible. You can check the S3 bucket to see the offloaded segments. @@ -282,19 +284,19 @@ Here, - `spec.tieredStorage.azure.storageAccount` specifies the azure storage account name. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-azure-tiered.yaml -kafka.kubedb.com/kafka-prod-tiered created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-azure-tiered.yaml ``` +kafka.kubedb.com/kafka-prod-tiered created ```bash -$ kubectl get kafka -n demo -w +kubectl get kafka -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 2s kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 4s . . kafka-prod-tiered kubedb.com/v1 4.0.0 Ready 112s -``` ## Create a Kafka Tiered Storage with GCS compatible storage @@ -347,19 +349,19 @@ Here, - `spec.tieredStorage.gcs.prefix` specifies the prefix for the gcs objects. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-gcs-tiered.yaml -kafka.kubedb.com/kafka-prod-tiered created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tiered-storage/kafka-gcs-tiered.yaml ``` +kafka.kubedb.com/kafka-prod-tiered created ```bash -$ kubectl get kafka -n demo -w +kubectl get kafka -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 2s kafka-prod-tiered kubedb.com/v1 4.0.0 Provisioning 4s . . kafka-prod-tiered kubedb.com/v1 4.0.0 Ready 112s -``` ## Next Steps diff --git a/docs/guides/kafka/tls/combined.md b/docs/guides/kafka/tls/combined.md index 5d3ffe6354..a098d7347b 100644 --- a/docs/guides/kafka/tls/combined.md +++ b/docs/guides/kafka/tls/combined.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Kafka. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml -issuer.cert-manager.io/kafka-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml ``` +issuer.cert-manager.io/kafka-ca-issuer created ## TLS/SSL encryption in Kafka Combined Cluster @@ -119,15 +119,15 @@ spec: ### Deploy Kafka Combined Cluster ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kafka-dev-tls.yaml -kafka.kubedb.com/kafka-dev-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kafka-dev-tls.yaml ``` +kafka.kubedb.com/kafka-dev-tls created Now, wait until `kafka-dev-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get mg -n demo - +watch kubectl get mg -n demo +``` Every 2.0s: kubectl get kafka -n demo aadee: Fri Sep 6 12:34:51 2024 NAME TYPE VERSION STATUS AGE kafka-dev-tls kubedb.com/v1 3.9.0 Provisioning 0s @@ -135,13 +135,12 @@ kafka-dev-tls kubedb.com/v1 3.9.0 Provisioning 12s . . kafka-dev-tls kubedb.com/v1 3.9.0 Ready 77s -``` ### Verify TLS/SSL in Kafka Combined Cluster ```bash -$ kubectl describe secret -n demo kafka-dev-tls-client-cert - +kubectl describe secret -n demo kafka-dev-tls-client-cert +``` Name: kafka-dev-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -168,12 +167,12 @@ ca.crt: 1184 bytes keystore.jks: 3245 bytes tls.crt: 1452 bytes tls.key: 1704 bytes -``` Now, Let's exec into a kafka broker pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo kafka-dev-tls-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo kafka-dev-tls-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=/var/private/ssl/server.keystore.jks sensitive=false synonyms={STATIC_BROKER_CONFIG:ssl.keystore.location=/var/private/ssl/server.keystore.jks} @@ -198,7 +197,6 @@ $ kubectl exec -it -n demo kafka-dev-tls-0 -- kafka-configs.sh --bootstrap-serve zookeeper.ssl.keystore.location=null sensitive=false synonyms={} zookeeper.ssl.keystore.password=null sensitive=true synonyms={} zookeeper.ssl.keystore.type=null sensitive=false synonyms={} -``` We can see from the above output that, keystore location is `/var/private/ssl/server.keystore.jks` which means that TLS is enabled. @@ -216,7 +214,8 @@ ssl.truststore.password=*********** Now, let's exec into the kafka pod and connect using this configuration to verify the TLS is enabled. ```bash -$ kubectl exec -it -n demo kafka-dev-tls-0 -- bash +kubectl exec -it -n demo kafka-dev-tls-0 -- bash +``` kafka@kafka-dev-tls-0:~$ kafka-metadata-quorum.sh --command-config config/clientauth.properties --bootstrap-server localhost:9092 describe --status ClusterId: 11ef-921c-f2a07f85765w LeaderId: 1 @@ -226,7 +225,6 @@ MaxFollowerLag: 0 MaxFollowerLagTimeMs: 16 CurrentVoters: [0,1,2] CurrentObservers: [] -``` From the above output, we can see that we are able to connect to the Kafka cluster using the TLS configuration. diff --git a/docs/guides/kafka/tls/connectcluster.md b/docs/guides/kafka/tls/connectcluster.md index 3d79bb2cd1..b80715a2c4 100644 --- a/docs/guides/kafka/tls/connectcluster.md +++ b/docs/guides/kafka/tls/connectcluster.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Kafka ConnectCluster. This tuto - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/connectcluster-issuer.yaml -issuer.cert-manager.io/connectcluster-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/connectcluster-issuer.yaml ``` +issuer.cert-manager.io/connectcluster-ca-issuer created ## TLS/SSL encryption in Kafka Topology Cluster @@ -124,15 +124,15 @@ Here, ### Deploy Kafka ConnectCluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/connectcluster-tls.yaml -connectcluster.kafka.kubedb.com/connectcluster-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/connectcluster-tls.yaml ``` +connectcluster.kafka.kubedb.com/connectcluster-tls created Now, wait until `connectcluster-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get connectcluster -n demo - +watch kubectl get connectcluster -n demo +``` Every 2.0s: kubectl get connectcluster -n demo aadee: Fri Sep 6 14:59:32 2024 NAME TYPE VERSION STATUS AGE @@ -141,13 +141,12 @@ connectcluster-tls kafka.kubedb.com/v1alpha1 3.9.0 Provisioning 34s . . connectcluster-tls kafka.kubedb.com/v1alpha1 3.9.0 Ready 2m -``` ### Verify TLS/SSL in Kafka ConnectCluster ```bash -$ kubectl describe secret -n demo connectcluster-tls-client-connect-cert - +kubectl describe secret -n demo connectcluster-tls-client-connect-cert +``` Name: connectcluster-tls-client-connect-cert Namespace: demo Labels: app.kubernetes.io/component=kafka @@ -172,15 +171,14 @@ Data ca.crt: 1184 bytes tls.crt: 1566 bytes tls.key: 1704 bytes -``` Now, Let's exec into a ConnectCluster pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it connectcluster-tls-0 -n demo -- bash +kubectl exec -it connectcluster-tls-0 -n demo -- bash +``` kafka@connectcluster-tls-0:~$ curl -u "$CONNECT_CLUSTER_USER:$CONNECT_CLUSTER_PASSWORD" http://localhost:8083 curl: (1) Received HTTP/0.9 when not allowed -``` From the above output, we can see that we are unable to connect to the Kafka cluster using the HTTP protocol. diff --git a/docs/guides/kafka/tls/topology.md b/docs/guides/kafka/tls/topology.md index c34ac2c0d5..4ab8a8fb6b 100644 --- a/docs/guides/kafka/tls/topology.md +++ b/docs/guides/kafka/tls/topology.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Kafka. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml -issuer.cert-manager.io/kafka-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kf-issuer.yaml ``` +issuer.cert-manager.io/kafka-ca-issuer created ## TLS/SSL encryption in Kafka Topology Cluster @@ -130,15 +130,15 @@ spec: ### Deploy Kafka Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kafka-prod-tls.yaml -kafka.kubedb.com/kafka-prod-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/tls/kafka-prod-tls.yaml ``` +kafka.kubedb.com/kafka-prod-tls created Now, wait until `kafka-prod-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get kafka -n demo - +watch kubectl get kafka -n demo +``` Every 2.0s: kubectl get kafka -n demo aadee: Fri Sep 6 12:34:51 2024 NAME TYPE VERSION STATUS AGE kafka-prod-tls kubedb.com/v1 3.9.0 Provisioning 17s @@ -146,13 +146,12 @@ kafka-prod-tls kubedb.com/v1 3.9.0 Provisioning 12s . . kafka-prod-tls kubedb.com/v1 3.9.0 Ready 2m1s -``` ### Verify TLS/SSL in Kafka Topology Cluster ```bash -$ kubectl describe secret kafka-prod-tls-client-cert -n demo - +kubectl describe secret kafka-prod-tls-client-cert -n demo +``` Name: kafka-prod-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -179,12 +178,12 @@ keystore.jks: 3254 bytes tls.crt: 1460 bytes tls.key: 1708 bytes truststore.jks: 891 bytes -``` Now, Let's exec into a kafka broker pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo kafka-prod-tls-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +kubectl exec -it -n demo kafka-prod-tls-broker-0 -- kafka-configs.sh --bootstrap-server localhost:9092 --command-config /opt/kafka/config/clientauth.properties --describe --entity-type brokers --all | grep 'ssl.keystore' +``` ssl.keystore.certificate.chain=null sensitive=true synonyms={} ssl.keystore.key=null sensitive=true synonyms={} ssl.keystore.location=/var/private/ssl/server.keystore.jks sensitive=false synonyms={STATIC_BROKER_CONFIG:ssl.keystore.location=/var/private/ssl/server.keystore.jks} @@ -201,7 +200,6 @@ $ kubectl exec -it -n demo kafka-prod-tls-broker-0 -- kafka-configs.sh --bootstr zookeeper.ssl.keystore.location=null sensitive=false synonyms={} zookeeper.ssl.keystore.password=null sensitive=true synonyms={} zookeeper.ssl.keystore.type=null sensitive=false synonyms={} -``` We can see from the above output that, keystore location is `/var/private/ssl/server.keystore.jks` which means that TLS is enabled. @@ -219,7 +217,8 @@ ssl.truststore.password=*********** Now, let's exec into the kafka pod and connect using this configuration to verify the TLS is enabled. ```bash -$ kubectl exec -it -n demo kafka-prod-broker-tls-0 -- bash +kubectl exec -it -n demo kafka-prod-broker-tls-0 -- bash +``` kafka@kafka-prod-broker-tls-0:~$ kafka-metadata-quorum.sh --command-config config/clientauth.properties --bootstrap-server localhost:9092 describe --status ClusterId: 11ef-921c-f2a07f85765w LeaderId: 1001 @@ -229,7 +228,6 @@ MaxFollowerLag: 0 MaxFollowerLagTimeMs: 18 CurrentVoters: [1000,1001] CurrentObservers: [0,1] -``` From the above output, we can see that we are able to connect to the Kafka cluster using the TLS configuration. diff --git a/docs/guides/kafka/update-version/update-version.md b/docs/guides/kafka/update-version/update-version.md index 7b634c4d10..98ccd30b52 100644 --- a/docs/guides/kafka/update-version/update-version.md +++ b/docs/guides/kafka/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/kafka](/docs/examples/kafka) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -96,21 +96,21 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/update-version/kafka.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/update-version/kafka.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` created has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.8.1 Provisioning 0s kafka-prod kubedb.com/v1 3.8.1 Provisioning 55s . . kafka-prod kubedb.com/v1 3.8.1 Ready 119s -``` We are now ready to apply the `KafkaOpsRequest` CR to update. @@ -149,9 +149,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/update-version/update-version-ops.yaml -kafkaopsrequest.ops.kubedb.com/kafka-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/update-version/update-version-ops.yaml ``` +kafkaopsrequest.ops.kubedb.com/kafka-update-version created #### Verify Kafka version updated successfully @@ -160,15 +160,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kafka-update-version UpdateVersion Successful 2m6s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe kafkaopsrequest -n demo kafka-update-version +kubectl describe kafkaopsrequest -n demo kafka-update-version +``` Name: kafka-update-version Namespace: demo Labels: @@ -302,20 +303,23 @@ Events: Normal RestartPods 62s KubeDB Ops-manager Operator Successfully Restarted Kafka nodes Normal Starting 62s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 61s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kafka-update-version -``` Now, we are going to verify whether the `Kafka` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get kf -n demo kafka-prod -o=jsonpath='{.spec.version}{"\n"}' +kubectl get kf -n demo kafka-prod -o=jsonpath='{.spec.version}{"\n"}' +``` 3.9.0 -$ kubectl get petset -n demo kafka-prod-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo kafka-prod-broker -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/kafka-kraft:3.9.0@sha256:e251d3c0ceee0db8400b689e42587985034852a8a6c81b5973c2844e902e6d11 -$ kubectl get pods -n demo kafka-prod-broker-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/kafka-kraft:3.9.0@sha256:e251d3c0ceee0db8400b689e42587985034852a8a6c81b5973c2844e902e6d11 +```bash +kubectl get pods -n demo kafka-prod-broker-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/kafka-kraft:3.9.0@sha256:e251d3c0ceee0db8400b689e42587985034852a8a6c81b5973c2844e902e6d11 You can see from above, our `Kafka` has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/kafka/volume-expansion/combined.md b/docs/guides/kafka/volume-expansion/combined.md index e2aa604185..6fd4344772 100644 --- a/docs/guides/kafka/volume-expansion/combined.md +++ b/docs/guides/kafka/volume-expansion/combined.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Kafka` combined using a supported version by `Ku At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -84,33 +84,35 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-combined.yaml -kafka.kubedb.com/kafka-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-combined.yaml ``` +kafka.kubedb.com/kafka-dev created Now, wait until `kafka-dev` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-dev kubedb.com/v1 3.9.0 Provisioning 0s kafka-dev kubedb.com/v1 3.9.0 Provisioning 24s . . kafka-dev kubedb.com/v1 3.9.0 Ready 92s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-23778f6015324895 1Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-1 longhorn 33s pvc-30b34f642f994e13 1Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-0 longhorn 58s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -148,9 +150,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-volume-expansion-combined.yaml -kafkaopsrequest.ops.kubedb.com/kf-volume-exp-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-volume-expansion-combined.yaml ``` +kafkaopsrequest.ops.kubedb.com/kf-volume-exp-combined created #### Verify Kafka Combined volume expanded successfully @@ -159,15 +161,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kf-volume-exp-combined VolumeExpansion Successful 2m4s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe kafkaopsrequest -n demo kf-volume-exp-combined +kubectl describe kafkaopsrequest -n demo kf-volume-exp-combined +``` Name: kf-volume-exp-combined Namespace: demo Labels: @@ -276,19 +279,20 @@ Events: Normal ReadyPetSets 23m KubeDB Ops-manager Operator PetSet is recreated Normal Starting 23m KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-dev Normal Successful 23m KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-dev for KafkaOpsRequest: kf-volume-exp-combined -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-dev -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-23778f6015324895 2Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-1 longhorn 7m2s pvc-30b34f642f994e13 2Gi RWO Delete Bound demo/kafka-dev-data-kafka-dev-0 longhorn 7m9s -``` The above output verifies that we have successfully expanded the volume of the Kafka. diff --git a/docs/guides/kafka/volume-expansion/topology.md b/docs/guides/kafka/volume-expansion/topology.md index 119ad87ee9..6089040cc7 100644 --- a/docs/guides/kafka/volume-expansion/topology.md +++ b/docs/guides/kafka/volume-expansion/topology.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/kafka](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/kafka) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Kafka` topology using a supported version by `Ku At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -95,38 +95,42 @@ spec: Let's create the `Kafka` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-topology.yaml -kafka.kubedb.com/kafka-prod created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-topology.yaml ``` +kafka.kubedb.com/kafka-prod created Now, wait until `kafka-prod` has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE kafka-prod kubedb.com/v1 3.9.0 Provisioning 0s kafka-prod kubedb.com/v1 3.9.0 Provisioning 9s . . kafka-prod kubedb.com/v1 3.9.0 Ready 2m10s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-3f177a92721440bb 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-0 longhorn 106s pvc-86ff354122324b1c 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-1 longhorn 78s pvc-9fa35d773aa74bd0 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-1 longhorn 75s pvc-ccf50adf179e4162 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-0 longhorn 106s -``` You can see the petsets have 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -168,9 +172,9 @@ Here, Let's create the `KafkaOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-volume-expansion-topology.yaml -kafkaopsrequest.ops.kubedb.com/kf-volume-exp-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/kafka/volume-expansion/kafka-volume-expansion-topology.yaml ``` +kafkaopsrequest.ops.kubedb.com/kf-volume-exp-topology created #### Verify Kafka Topology volume expanded successfully @@ -179,15 +183,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `KafkaOpsRequest` to be `Successful`. Run the following command to watch `KafkaOpsRequest` CR, ```bash -$ kubectl get kafkaopsrequest -n demo +kubectl get kafkaopsrequest -n demo +``` NAME TYPE STATUS AGE kf-volume-exp-topology VolumeExpansion Successful 3m1s -``` We can see from the above output that the `KafkaOpsRequest` has succeeded. If we describe the `KafkaOpsRequest` we will get an overview of the steps that were followed to expand the volume of kafka. ```bash -$ kubectl describe kafkaopsrequest -n demo kf-volume-exp-topology +kubectl describe kafkaopsrequest -n demo kf-volume-exp-topology +``` Name: kf-volume-exp-topology Namespace: demo Labels: @@ -316,24 +321,27 @@ Events: Normal ReadyPetSets 26s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 26s KubeDB Ops-manager Operator Resuming Kafka database: demo/kafka-prod Normal Successful 26s KubeDB Ops-manager Operator Successfully resumed Kafka database: demo/kafka-prod for KafkaOpsRequest: kf-volume-exp-topology -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo kafka-prod-broker -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "3Gi" -$ kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo kafka-prod-controller -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-3f177a92721440bb 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-0 longhorn 5m25s pvc-86ff354122324b1c 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-1 longhorn 4m51s pvc-9fa35d773aa74bd0 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-controller-1 longhorn 5m1s pvc-ccf50adf179e4162 1Gi RWO Delete Bound demo/kafka-prod-data-kafka-prod-broker-0 longhorn 5m30s -``` The above output verifies that we have successfully expanded the volume of the Kafka. diff --git a/docs/guides/mariadb/autoscaler/compute/cluster/index.md b/docs/guides/mariadb/autoscaler/compute/cluster/index.md index a6a5da99a0..a1abfed429 100644 --- a/docs/guides/mariadb/autoscaler/compute/cluster/index.md +++ b/docs/guides/mariadb/autoscaler/compute/cluster/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Cluster Database Here, we are going to deploy a `MariaDB` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `MariaDBAutoscaler` to set up autoscaling. @@ -79,22 +79,23 @@ spec: Let's create the `MariaDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/compute/cluster/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/compute/cluster/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 14m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -105,11 +106,11 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].reso "memory": "300Mi" } } -``` Let's check the MariaDB resources, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +``` { "limits": { "cpu": "200m", @@ -120,7 +121,6 @@ $ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spe "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mariadb. @@ -181,20 +181,23 @@ If a step doesn't finish within the specified timeout, the ops request will resu Let's create the `MariaDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/compute/cluster/examples/mdas-compute.yaml -mariadbautoscaler.autoscaling.kubedb.com/md-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/compute/cluster/examples/mdas-compute.yaml ``` +mariadbautoscaler.autoscaling.kubedb.com/md-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `mariadbautoscaler` resource is created successfully, ```bash -$ kubectl get mariadbautoscaler -n demo +kubectl get mariadbautoscaler -n demo +``` NAME AGE md-as-compute 5m56s -$ kubectl describe mariadbautoscaler md-as-compute -n demo +```bash +kubectl describe mariadbautoscaler md-as-compute -n demo +``` Name: md-as-compute Namespace: demo Labels: @@ -347,8 +350,6 @@ Status: Memory: 1Gi Vpa Name: sample-mariadb Events: - -``` So, the `mariadbautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -358,23 +359,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `mariadbopsrequest` in the demo namespace to see if any `mariadbopsrequest` object is created. After some time you'll see that a `mariadbopsrequest` will be created based on the recommendation. ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mdops-sample-mariadb-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mdops-vpa-sample-mariadb-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-vpa-sample-mariadb-z43wc8 +kubectl describe mariadbopsrequest -n demo mdops-vpa-sample-mariadb-z43wc8 +``` Name: mdops-sample-mariadb-6xc1kc Namespace: demo Labels: @@ -492,12 +494,12 @@ Events: Normal Starting 5m8s KubeDB Enterprise Operator Resuming MariaDB database: demo/sample-mariadb Normal Successful 5m8s KubeDB Enterprise Operator Successfully resumed MariaDB database: demo/sample-mariadb Normal Successful 5m8s KubeDB Enterprise Operator Controller has Successfully scaled the MariaDB database: demo/sample-mariadb -``` Now, we are going to verify from the Pod, and the MariaDB yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -509,7 +511,9 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].reso } } -$ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +```bash +kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +``` { "limits": { "cpu": "250m", @@ -520,7 +524,6 @@ $ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.podTemplate.spe "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the MariaDB replicaset database. diff --git a/docs/guides/mariadb/autoscaler/storage/cluster/index.md b/docs/guides/mariadb/autoscaler/storage/cluster/index.md index 73b9e44344..5fbd1509fb 100644 --- a/docs/guides/mariadb/autoscaler/storage/cluster/index.md +++ b/docs/guides/mariadb/autoscaler/storage/cluster/index.md @@ -37,20 +37,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Maria To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -85,30 +85,32 @@ spec: Let's create the `MariaDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/storage/cluster/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/storage/cluster/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-sample-mariadb-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-sample-mariadb-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -150,20 +152,23 @@ Here, Let's create the `MariaDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/storage/cluster/examples/mdas-storage.yaml -mariadbautoscaler.autoscaling.kubedb.com/md-as-st created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/autoscaler/storage/cluster/examples/mdas-storage.yaml ``` +mariadbautoscaler.autoscaling.kubedb.com/md-as-st created #### Storage Autoscaling is set up successfully Let's check that the `mariadbautoscaler` resource is created successfully, ```bash -$ kubectl get mariadbautoscaler -n demo +kubectl get mariadbautoscaler -n demo +``` NAME AGE md-as-st 33s -$ kubectl describe mariadbautoscaler md-as-st -n demo +```bash +kubectl describe mariadbautoscaler md-as-st -n demo +``` Name: md-as-st Namespace: demo Labels: @@ -185,7 +190,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `mariadbautoscaler` resource is created successfully. @@ -194,7 +198,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume(`var/lib/mysql`) using the following commands: ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 357M 658M 36% /var/lib/mysql @@ -205,30 +210,30 @@ root@sample-mariadb-0:/ dd if=/dev/zero of=/var/lib/mysql/file.img bs=500M count root@sample-mariadb-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 857M 158M 85% /var/lib/mysql -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 20%. Let's watch the `mariadbopsrequest` in the demo namespace to see if any `mariadbopsrequest` object is created. After some time you'll see that a `mariadbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-mariadb-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-mariadb-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mops-sample-mariadb-xojkua +kubectl describe mariadbopsrequest -n demo mops-sample-mariadb-xojkua +``` Name: mops-sample-mariadb-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -291,19 +296,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming MariaDB database: demo/sample-mariadb Normal Successful 103s KubeDB Enterprise Operator Successfully resumed MariaDB database: demo/sample-mariadb Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of MariaDB: demo/sample-mariadb -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-sample-mariadb-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-sample-mariadb-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the MariaDB replicaset database. diff --git a/docs/guides/mariadb/backup/kubestash/application-level/index.md b/docs/guides/mariadb/backup/kubestash/application-level/index.md index c42020536f..41a092a909 100644 --- a/docs/guides/mariadb/backup/kubestash/application-level/index.md +++ b/docs/guides/mariadb/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mariadb/backup/kubestash/application-level/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,32 +80,34 @@ spec: Create the above `MariaDB` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created KubeDB will deploy a `MariaDB` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get md -n demo sample-mariadb +kubectl get md -n demo sample-mariadb +``` NAME VERSION STATUS AGE sample-mariadb 11.1.3 Ready 5m1s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-mariadb-auth kubernetes.io/basic-auth 2 5m49s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mariadb +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mariadb +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mariadb ClusterIP 10.128.92.155 3306/TCP 62s sample-mariadb-pods ClusterIP None 3306/TCP 62s -``` Here, we have to use service `sample-mariadb` and secret `sample-mariadb-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mariadb/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. @@ -115,15 +117,15 @@ Here, we have to use service `sample-mariadb` and secret `sample-mariadb-auth` t Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-mariadb kubedb.com/mariadb 11.1.3 6m14s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mariadb -o yaml +kubectl get appbindings -n demo sample-mariadb -o yaml ``` ```yaml @@ -203,18 +205,18 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mariadb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mariadb" +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 2/2 Running 0 8m4s sample-mariadb-1 2/2 Running 0 8m3s sample-mariadb-2 2/2 Running 0 8m3s -``` Now, let’s exec into the pod and create a table, ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> create database hello; @@ -246,7 +248,6 @@ MariaDB [hello]> select count(*) from demo_table; +----------+ | 10 | +----------+ -``` Now, we are ready to backup the database. @@ -259,13 +260,19 @@ We are going to store our backup data into a `GCS` bucket. We have to create a ` Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -294,9 +301,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -327,9 +334,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -342,8 +349,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -399,27 +409,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mariadb-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mariadb-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mariadb-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mariadb-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mariadb` directory. @@ -430,20 +440,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mariadb-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mariadb-backup-frequent-backup-1726651003 BackupConfiguration sample-mariadb-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backup data has been stored in the backend. @@ -452,18 +462,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-mariadb-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mariadb-repo +kubectl get repository -n demo gcs-mariadb-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mariadb-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726651003 gcs-mariadb-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -476,7 +486,7 @@ gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726651003 gcs-mariad If we check the YAML of the `Snapshot`, we can find the information about the backup components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -581,9 +591,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -625,18 +635,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-mariadb created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE restore-sample-mariadb gcs-mariadb-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -646,10 +656,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `MariaDB` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get mariadb -n dev +kubectl get mariadb -n dev +``` NAME VERSION STATUS AGE sample-mariadb 11.1.3 Ready 5m18s -``` The output confirms that the `MariaDB` database has been successfully created with the same configuration as it had at the time of backup. @@ -661,26 +671,27 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get mariadb -n dev sample-mariadb +kubectl get mariadb -n dev sample-mariadb +``` NAME VERSION STATUS AGE sample-mariadb 11.1.3 Ready 5m18s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mariadb" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mariadb" +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 2/2 Running 0 12m sample-mariadb-1 2/2 Running 0 12m sample-mariadb-2 2/2 Running 0 12m -``` Now, lets exec one of the Pod and verify restored data. ```bash -$ kubectl exec -it -n dev sample-mariadb-0 -- bash +kubectl exec -it -n dev sample-mariadb-0 -- bash +``` mysql@restored-mariadb-0:/$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> use hello; @@ -691,7 +702,6 @@ MariaDB [hello]> select count(*) from demo_table; +----------+ | 10 | +----------+ -``` So, from the above output, we can see the `hello` database we had created in the original database `sample-mariadb` has been restored successfully. diff --git a/docs/guides/mariadb/backup/kubestash/auto-backup/index.md b/docs/guides/mariadb/backup/kubestash/auto-backup/index.md index 50e0f0b674..e062019932 100644 --- a/docs/guides/mariadb/backup/kubestash/auto-backup/index.md +++ b/docs/guides/mariadb/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mariadb/backup/kubestash/auto-backup/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -53,13 +53,19 @@ We are going to store our backup data into a `GCS` bucket. We have to create a ` Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -88,9 +94,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -121,9 +127,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -132,8 +138,11 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -196,9 +205,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/mariadb-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mariadb-default-backup-blueprint created Now, we are ready to backup our `MariaDB` databases using few annotations. @@ -238,24 +247,24 @@ Here, Let's create the `MariaDB` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MariaDB in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mariadb Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mariadb -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mariadb -o yaml ``` ```yaml @@ -362,10 +371,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mariadb-frequent-backup-1726637655 BackupConfiguration appbinding-sample-mariadb Succeeded 2m11s 3m15s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backup data has been stored in the backend. **Verify Backup:** @@ -373,18 +382,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-mariadb-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 3 1.559 KiB Ready 80s 7m32s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-samiadb-frequent-backup-1726637655 default-blueprint frequent-backup 2024-09-18T05:34:18Z Delete Succeeded 7m39s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -397,7 +406,7 @@ default-blueprint-appbinding-samiadb-frequent-backup-1726637655 default-bluepr If we check the YAML of the `Snapshot`, we can find the information about the backup components of the Database. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo default-blueprint-appbinding-samgres-frequent-backup-1725533628 -oyaml +kubectl get snapshot.storage.kubestash.com -n demo default-blueprint-appbinding-samgres-frequent-backup-1725533628 -oyaml ``` ```yaml @@ -544,9 +553,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/mariadb-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mariadb-customize-backup-blueprint created Now, we are ready to backup our `MariaDB` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -588,24 +597,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `MariaDB` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/sample-mariadb-2.yaml -mariadb.kubedb.com/sample-mariadb-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/auto-backup/examples/sample-mariadb-2.yaml ``` +mariadb.kubedb.com/sample-mariadb-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MariaDB in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mariadb-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mariadb-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mariadb-2 -o yaml ``` ```yaml @@ -714,10 +723,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mariadb-2-frequent-backup-1726640601 BackupConfiguration appbinding-sample-mariadb-2 Succeeded 2m6s 10m -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backup data has been stored in the backend. @@ -726,18 +735,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 2 1.021 MiB Ready 4m29s 11ms -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-sdb-2-frequent-backup-1726640601 customize-blueprint frequent-backup 2024-09-18T06:23:24Z Delete Succeeded 12m -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -751,7 +760,7 @@ customize-blueprint-appbinding-sdb-2-frequent-backup-1726640601 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backup components of the Database. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml +kubectl get snapshot.storage.kubestash.com -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml ``` ```yaml diff --git a/docs/guides/mariadb/backup/kubestash/customization/index.md b/docs/guides/mariadb/backup/kubestash/customization/index.md index bb0fca644b..a74e430c5d 100644 --- a/docs/guides/mariadb/backup/kubestash/customization/index.md +++ b/docs/guides/mariadb/backup/kubestash/customization/index.md @@ -311,13 +311,13 @@ spec: You can also restore a specific snapshot. At first, list the available snapshot as bellow, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725257849 gcs-mariadb-repo frequent-backup 2024-09-02T06:18:01Z Delete Succeeded 15m gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725258000 gcs-mariadb-repo frequent-backup 2024-09-02T06:20:00Z Delete Succeeded 13m gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725258300 gcs-mariadb-repo frequent-backup 2024-09-02T06:25:00Z Delete Succeeded 8m34s gcs-mariadb-repo-sample-mariadb-backup-frequent-backup-1725258600 gcs-mariadb-repo frequent-backup 2024-09-02T06:30:00Z Delete Succeeded 3m34s -``` The below example shows how you can pass a specific snapshot name in `.spec.dataSource` section. diff --git a/docs/guides/mariadb/backup/kubestash/logical/index.md b/docs/guides/mariadb/backup/kubestash/logical/index.md index 183db9517f..086551bd2a 100644 --- a/docs/guides/mariadb/backup/kubestash/logical/index.md +++ b/docs/guides/mariadb/backup/kubestash/logical/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mariadb/backup/kubestash/logical/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -83,32 +83,34 @@ spec: Create the above `MariaDB` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created KubeDB will deploy a `MariaDB` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get md -n demo sample-mariadb +kubectl get md -n demo sample-mariadb +``` NAME VERSION STATUS AGE mariadb.kubedb.com/sample-mariadb 11.1.3 Ready 5m4s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-mariadb-auth kubernetes.io/basic-auth 2 5m49s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mariadb +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mariadb +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mariadb ClusterIP 10.128.7.155 3306/TCP 6m28s sample-mariadb-pods ClusterIP None 3306/TCP 6m28s -``` Here, we have to use service `sample-mariadb` and secret `sample-mariadb-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mariadb/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. @@ -118,15 +120,15 @@ Here, we have to use service `sample-mariadb` and secret `sample-mariadb-auth` t Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-mariadb kubedb.com/mariadb 11.1.3 7m56s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mariadb -o yaml +kubectl get appbindings -n demo sample-mariadb -o yaml ``` ```yaml @@ -198,18 +200,18 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mariadb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mariadb" +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 2/2 Running 0 10m sample-mariadb-1 2/2 Running 0 10m sample-mariadb-2 2/2 Running 0 10m -``` Now, let’s exec into the pod and create a table, ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> create database hello; @@ -242,8 +244,6 @@ MariaDB [hello]> select count(*) from demo_table; | 10 | +----------+ -``` - Now, we are ready to backup the database. ### Prepare Backend @@ -255,13 +255,19 @@ We are going to store our backup data into a `GCS` bucket. We have to create a ` Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -290,9 +296,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -323,9 +329,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -338,8 +344,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -391,29 +400,28 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mariadb-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mariadb-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mariadb-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mariadb-repo true 1 1.096 KiB Ready 3m3s 3m13s -``` - KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mariadb` directory. **Verify CronJob:** @@ -423,20 +431,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mariadb-backup-frequent-backup */5 * * * * False 0 4m23s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mariadb-backup-frequent-backup-1725449400 BackupConfiguration sample-mariadb-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backup data has been stored in the backend. @@ -445,18 +453,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-mariadb-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mariadb-repo +kubectl get repository -n demo gcs-mariadb-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mariadb-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +kubectl get snapshot.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mariadb-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726569774 gcs-mariadb-repo frequent-backup 2024-09-17T10:43:04Z Delete Succeeded 41m -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -469,7 +477,7 @@ gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726569774 gcs-mariad If we check the YAML of the `Snapshot`, we can find the information about the backup components of the Database. ```bash -$ kubectl get snapshot.storage.kubestash.com -n demo gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726569774 -oyaml +kubectl get snapshot.storage.kubestash.com -n demo gcs-mariadb-repo-sample-mariadb-ckup-frequent-backup-1726569774 -oyaml ``` ```yaml @@ -584,17 +592,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/restored-mariadb.yaml -mariadb.kubedb.com/restored-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/restored-mariadb.yaml ``` +mariadb.kubedb.com/restored-mariadb created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get mariadb -n demo restored-mariadb +kubectl get mariadb -n demo restored-mariadb +``` NAME VERSION STATUS AGE restored-mariadb 11.1.3 Provisioning 110s -``` #### Create RestoreSession: @@ -635,17 +643,17 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-mariadb-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-mariadb-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-mariadb-restore gcs-mariadb-repo Succeeded 7s 116s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -656,25 +664,26 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get mariadb -n demo restored-mariadb +kubectl get mariadb -n demo restored-mariadb +``` NAME VERSION STATUS AGE restored-mariadb 11.1.3 Ready 6m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mariadb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mariadb" +``` NAME READY STATUS RESTARTS AGE restored-mariadb-0 2/2 Running 0 7m restored-mariadb-1 2/2 Running 0 7m restored-mariadb-2 2/2 Running 0 7m -``` Now, lets exec one of the `Pod` and verify restored data. ```bash -$ kubectl exec -it -n demo restored-mariadb-0 -- bash +kubectl exec -it -n demo restored-mariadb-0 -- bash +``` mysql@restored-mariadb-0:/$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> use hello; @@ -686,8 +695,6 @@ MariaDB [hello]> select count(*) from demo_table; | 10 | +----------+ -``` - So, from the above output, we can see the `hello` database we had created in the original database `sample-mariadb` has been restored in the `restored-mariadb` database. ## Cleanup diff --git a/docs/guides/mariadb/backup/stash/logical/cluster/index.md b/docs/guides/mariadb/backup/stash/logical/cluster/index.md index 55a824dcec..5ce2f1c7d0 100644 --- a/docs/guides/mariadb/backup/stash/logical/cluster/index.md +++ b/docs/guides/mariadb/backup/stash/logical/cluster/index.md @@ -35,9 +35,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created it yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MariaDB @@ -67,15 +67,16 @@ spec: deletionPolicy: WipeOut ``` -``` bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +```bash +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created This MariaDB object will create the necessary PetSet, Secret, Service etc for the database. You can easily view all the resources created by MariaDB object using [ketall](https://github.com/corneliusweig/ketall) `kubectl` plugin as below, ```bash -$ kubectl get-all -n demo -l app.kubernetes.io/instance=sample-mariadb +kubectl get-all -n demo -l app.kubernetes.io/instance=sample-mariadb +``` NAME NAMESPACE AGE endpoints/sample-mariadb demo 28m endpoints/sample-mariadb-pods demo 28m @@ -91,22 +92,22 @@ petset.apps/sample-mariadb demo 28m poddisruptionbudget.policy/sample-mariadb demo 28m rolebinding.rbac.authorization.k8s.io/sample-mariadb demo 28m role.rbac.authorization.k8s.io/sample-mariadb demo 28m -``` Now, wait for 3 database pods to go into `Running` state, ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=sample-mariadb +kubectl get pod -n demo -l app.kubernetes.io/instance=sample-mariadb +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 1/1 Running 0 2m7s sample-mariadb-1 1/1 Running 0 101s sample-mariadb-2 1/1 Running 0 81s -``` Once the database pod is in `Running` state, verify that all 3 nodes joined the cluster. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 26 @@ -126,7 +127,6 @@ MariaDB [(none)]> show status like 'wsrep_cluster_size'; MariaDB [(none)]> quit; Bye -``` From the above log, we can see that 3 nodes are ready to accept connections. @@ -137,7 +137,8 @@ Now, we are going to exec into the database pod and create some sample data. The Here, we are going to use the root user (`MYSQL_ROOT_USERNAME`) credential `MYSQL_ROOT_PASSWORD` to insert the sample data. Now, let's exec into one of the pods and insert some sample data, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -196,7 +197,6 @@ MariaDB [(none)]> select * from company.employees; MariaDB [(none)]> exit Bye -``` We have successfully deployed a MariaDB database and inserted some sample data into it. In the subsequent sections, we are going to backup these data using Stash. @@ -209,10 +209,10 @@ In this section, we are going to prepare the necessary resources (i.e. database When you install the Stash, it automatically installs all the official database addons. Verify that it has installed the MariaDB addons using the following command. ```bash -$ kubectl get tasks.stash.appscode.com | grep mariadb +kubectl get tasks.stash.appscode.com | grep mariadb +``` mariadb-backup-11.8.5 35s mariadb-restore-11.8.5 35s -``` ### Ensure AppBinding @@ -223,10 +223,10 @@ Stash expect your database Secret to have `username` and `password` keys. If you You don't need to worry about appbindings if you are using KubeDB. It creates an appbinding containing the necessary informations when you deploy the database. Let's ensure the appbinding create by `KubeDB` operator. ```bash -$ kubectl get appbinding -n demo +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE sample-mariadb kubedb.com/mariadb 11.8.5 62m -``` We have a appbinding named same as database name `sample-mariadb`. We will use this later for connecting into this database. @@ -239,15 +239,24 @@ We are going to store our backed up data into a GCS bucket. So, we need to creat At first, let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -270,9 +279,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database into our desired backend. @@ -313,19 +322,19 @@ Here, Let's create the `BackupConfiguration` object we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-mariadb-backup created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-mariadb-backup created ### Verify Backup Setup Successful If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-11.8.5 */5 * * * * Ready 11s -``` #### Verify CronJob @@ -334,10 +343,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * False 0 15s 17s -``` #### Wait for BackupSession @@ -346,12 +355,12 @@ The `sample-mariadb-backup` CronJob will trigger a backup on each scheduled slot Now, wait for a schedule to appear. Run the following command to watch for a `BackupSession` object, ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Running 24s sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Running 75s sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Succeeded 103s -``` Here, the phase `Succeeded` means that the backup process has been completed successfully. @@ -360,10 +369,10 @@ Here, the phase `Succeeded` means that the backup process has been completed suc Now, we are going to verify whether the backed up data is present in the backend or not. Once a backup is completed, Stash will update the respective `Repository` object to reflect the backup completion. Check that the repository `gcs-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo +kubectl get repository -n demo gcs-repo +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo true 1.327 MiB 1 60s 8m -``` Now, if we navigate to the GCS bucket, we will see the backed up data has been stored in `demo/mariadb/sample-mariadb` directory as specified by `.spec.backend.gcs.prefix` field of the `Repository` object.

@@ -388,38 +397,39 @@ At first, let's stop taking any further backup of the database so that no backup Let's pause the `sample-mariadb-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mariadb-backup patched +kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mariadb-backup patched Or you can use Stash `kubectl` plugin to pause the BackupConfiguration, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mariadb-backup +kubectl stash pause backup -n demo --backupconfig=sample-mariadb-backup +``` BackupConfiguration demo/sample-mariadb-backup has been paused successfully. -```` Verify that the `BackupConfiguration` has been paused, ```bash -$ kubectl get backupconfiguration -n demo sample-mariadb-backup +kubectl get backupconfiguration -n demo sample-mariadb-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-11.8.5 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the `BackupConfiguration` has been paused. Stash will also suspend the respective CronJob. ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * True 0 2m59s 20m -``` #### Simulate Disaster Now, let's simulate an accidental deletion scenario. Here, we are going to exec into the database pod and delete the `company` database we had created earlier. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -458,7 +468,6 @@ MariaDB [(none)]> show databases; MariaDB [(none)]> exit Bye -``` #### Create RestoreSession @@ -493,18 +502,18 @@ Here, Let's create the `RestoreSession` object object we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-mariadb-restore created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/cluster/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-mariadb-restore created Once, you have created the `RestoreSession` object, Stash will create a restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ kubectl get restoresession -n demo -w +kubectl get restoresession -n demo -w +``` NAME REPOSITORY PHASE AGE sample-mariadb-restore gcs-repo Running 15s sample-mariadb-restore gcs-repo Succeeded 18s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -513,7 +522,8 @@ The `Succeeded` phase means that the restore process has been completed successf Now, let's exec into the database pod and verify whether data actual data was restored or not, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -556,7 +566,6 @@ MariaDB [(none)]> select * from company.employees; MariaDB [(none)]> exit Bye -``` Hence, we can see from the above output that the deleted data has been restored successfully from the backup. @@ -564,30 +573,30 @@ Hence, we can see from the above output that the deleted data has been restored Since our data has been restored successfully we can now resume our usual backup process. Resume the `BackupConfiguration` using following command, ```bash -$ kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": false}}' -backupconfiguration.stash.appscode.com/sample-mariadb-backup patched +kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": false}}' ``` +backupconfiguration.stash.appscode.com/sample-mariadb-backup patched Or you can use the Stash `kubectl` plugin to resume the `BackupConfiguration`, ```bash -$ kubectl stash resume -n demo --backupconfig=sample-mariadb-backup -BackupConfiguration demo/sample-mariadb-backup has been resumed successfully. +kubectl stash resume -n demo --backupconfig=sample-mariadb-backup ``` +BackupConfiguration demo/sample-mariadb-backup has been resumed successfully. Verify that the `BackupConfiguration` has been resumed, ```bash -$ kubectl get backupconfiguration -n demo sample-mariadb-backup +kubectl get backupconfiguration -n demo sample-mariadb-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-11.8.5 */5 * * * * false Ready 29m -``` Here, `false` in the `PAUSED` column means the backup has been resume successfully. The CronJob also should be resumed now. ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * False 0 2m59s 29m -``` Here, `False` in the `SUSPEND` column means the CronJob is no longer suspended and will trigger in the next schedule. diff --git a/docs/guides/mariadb/backup/stash/logical/standalone/index.md b/docs/guides/mariadb/backup/stash/logical/standalone/index.md index e91137d60a..d2361f9d4f 100644 --- a/docs/guides/mariadb/backup/stash/logical/standalone/index.md +++ b/docs/guides/mariadb/backup/stash/logical/standalone/index.md @@ -35,9 +35,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created it yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MariaDB @@ -67,15 +67,16 @@ spec: deletionPolicy: WipeOut ``` -``` bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +```bash +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created This MariaDB objetc will create the necessary PetSet, Secret, Service etc. for the database. You can easily view all the resources created by MariaDB object using [ketall](https://github.com/corneliusweig/ketall) `kubectl` plugin as below, ```bash -$ kubectl get-all -n demo -l app.kubernetes.io/instance=sample-mariadb +kubectl get-all -n demo -l app.kubernetes.io/instance=sample-mariadb +``` NAME NAMESPACE AGE endpoints/sample-mariadb demo 28m endpoints/sample-mariadb-pods demo 28m @@ -91,25 +92,24 @@ petset.apps/sample-mariadb demo 28m poddisruptionbudget.policy/sample-mariadb demo 28m rolebinding.rbac.authorization.k8s.io/sample-mariadb demo 28m role.rbac.authorization.k8s.io/sample-mariadb demo 28m -``` Now, wait for the database pod `sample-mariadb-0` to go into `Running` state, ```bash -$ kubectl get pod -n demo sample-mariadb-0 +kubectl get pod -n demo sample-mariadb-0 +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 1/1 Running 0 29m -``` Once the database pod is in `Running` state, verify that the database is ready to accept the connections. ```bash -$ kubectl logs -n demo sample-mariadb-0 +kubectl logs -n demo sample-mariadb-0 +``` 2021-02-22 9:41:37 0 [Note] Reading of all Master_info entries succeeded 2021-02-22 9:41:37 0 [Note] Added new Master_info '' to hash table 2021-02-22 9:41:37 0 [Note] mysqld: ready for connections. Version: '11.8.5-MariaDB-1:11.8.5+maria~focal' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution -``` From the above log, we can see the database is ready to accept connections. @@ -120,7 +120,8 @@ Now, we are going to exec into the database pod and create some sample data. The Here, we are going to use the root user (`MYSQL_ROOT_USERNAME`) credential `MYSQL_ROOT_PASSWORD` to insert the sample data. Now, let's exec into the database pod and insert some sample data, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -179,7 +180,6 @@ MariaDB [(none)]> select * from company.employees; MariaDB [(none)]> exit Bye -``` We have successfully deployed a MariaDB database and inserted some sample data into it. In the subsequent sections, we are going to backup these data using Stash. @@ -192,10 +192,10 @@ In this section, we are going to prepare the necessary resources (i.e. database When you install the Stash, it automatically installs all the official database addons. Verify that it has installed the MariaDB addons using the following command. ```bash -$ kubectl get tasks.stash.appscode.com | grep mariadb +kubectl get tasks.stash.appscode.com | grep mariadb +``` mariadb-backup-10.6.23 35s mariadb-backup-10.6.23 35s -``` ### Ensure AppBinding @@ -206,10 +206,10 @@ Stash expect your database Secret to have `username` and `password` keys. If you You don't need to worry about appbindings if you are using KubeDB. It creates an appbinding containing the necessary informations when you deploy the database. Let's ensure the appbinding create by `KubeDB` operator. ```bash -$ kubectl get appbinding -n demo +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE sample-mariadb kubedb.com/mariadb 11.8.5 62m -``` We have a appbinding named same as database name `sample-mariadb`. We will use this later for connecting into this database. @@ -222,15 +222,24 @@ We are going to store our backed up data into a GCS bucket. So, we need to creat At first, let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -253,9 +262,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database into our desired backend. @@ -296,19 +305,19 @@ Here, Let's create the `BackupConfiguration` object we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-mariadb-backup created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-mariadb-backup created #### Verify Backup Setup Successful If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-10.6.23 */5 * * * * Ready 11s -``` #### Verify CronJob @@ -317,10 +326,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * False 0 15s 17s -``` #### Wait for BackupSession @@ -329,12 +338,12 @@ The `sample-mariadb-backup` CronJob will trigger a backup on each scheduled slot Now, wait for a schedule to appear. Run the following command to watch for a `BackupSession` object, ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Running 24s sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Running 75s sample-mariadb-backup-1606994706 BackupConfiguration sample-mariadb-backup Succeeded 103s -``` Here, the phase `Succeeded` means that the backup process has been completed successfully. @@ -343,10 +352,10 @@ Here, the phase `Succeeded` means that the backup process has been completed suc Now, we are going to verify whether the backed up data is present in the backend or not. Once a backup is completed, Stash will update the respective `Repository` object to reflect the backup completion. Check that the repository `gcs-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo +kubectl get repository -n demo gcs-repo +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo true 1.327 MiB 1 60s 8m -``` Now, if we navigate to the GCS bucket, we will see the backed up data has been stored in `demo/mariadb/sample-mariadb` directory as specified by `.spec.backend.gcs.prefix` field of the `Repository` object. @@ -371,40 +380,41 @@ At first, let's stop taking any further backup of the database so that no backup Let's pause the `sample-mariadb-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mariadb-backup--type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mgo-rs-backup patched +kubectl patch backupconfiguration -n demo sample-mariadb-backup--type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mgo-rs-backup patched Or you can use the Stash `kubectl` plugin to pause the `BackupConfiguration`, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mariadb-backup -BackupConfiguration demo/sample-mariadb-backup has been paused successfully. +kubectl stash pause backup -n demo --backupconfig=sample-mariadb-backup ``` +BackupConfiguration demo/sample-mariadb-backup has been paused successfully. Verify that the `BackupConfiguration` has been paused, ```bash -$ kubectl get backupconfiguration -n demo sample-mariadb-backup +kubectl get backupconfiguration -n demo sample-mariadb-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-10.6.23 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the `BackupConfiguration` has been paused. Stash will also suspend the respective CronJob. ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * True 0 2m59s 20m -``` #### Simulate Disaster Now, let's simulate an accidental deletion scenario. Here, we are going to exec into the database pod and delete the `company` database we had created earlier. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -443,7 +453,6 @@ MariaDB [(none)]> show databases; MariaDB [(none)]> exit Bye -``` #### Create RestoreSession @@ -481,18 +490,18 @@ Here, Let's create the `RestoreSession` object object we have shown above, ```bash -$ kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-mariadb-restore created +kubectl apply -f https://github.com/logical/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/backup/logical/standalone/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-mariadb-restore created Once, you have created the `RestoreSession` object, Stash will create a restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ kubectl get restoresession -n demo -w +kubectl get restoresession -n demo -w +``` NAME REPOSITORY PHASE AGE sample-mariadb-restore gcs-repo Running 15s sample-mariadb-restore gcs-repo Succeeded 18s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -501,7 +510,8 @@ The `Succeeded` phase means that the restore process has been completed successf Now, let's exec into the database pod and verify whether data actual data was restored or not, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 341 @@ -544,7 +554,6 @@ MariaDB [(none)]> select * from company.employees; MariaDB [(none)]> exit Bye -``` Hence, we can see from the above output that the deleted data has been restored successfully from the backup. @@ -552,30 +561,30 @@ Hence, we can see from the above output that the deleted data has been restored Since our data has been restored successfully we can now resume our usual backup process. Resume the `BackupConfiguration` using following command, ```bash -$ kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": false}}' -backupconfiguration.stash.appscode.com/sample-mariadb-backup patched +kubectl patch backupconfiguration -n demo sample-mariadb-backup --type="merge" --patch='{"spec": {"paused": false}}' ``` +backupconfiguration.stash.appscode.com/sample-mariadb-backup patched Or you can use the Stash `kubectl` plugin to resume the `BackupConfiguration`, ```bash -$ kubectl stash resume -n demo --backupconfig=sample-mariadb-backup -BackupConfiguration demo/sample-mariadb-backup has been resumed successfully. +kubectl stash resume -n demo --backupconfig=sample-mariadb-backup ``` +BackupConfiguration demo/sample-mariadb-backup has been resumed successfully. Verify that the `BackupConfiguration` has been resumed, ```bash -$ kubectl get backupconfiguration -n demo sample-mariadb-backup +kubectl get backupconfiguration -n demo sample-mariadb-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mariadb-backup mariadb-backup-10.6.23 */5 * * * * false Ready 29m -``` Here, `false` in the `PAUSED` column means the backup has been resume successfully. The CronJob also should be resumed now. ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE stash-backup-sample-mariadb-backup */5 * * * * False 0 2m59s 29m -``` Here, `False` in the `SUSPEND` column means the CronJob is no longer suspended and will trigger in the next schedule. diff --git a/docs/guides/mariadb/clustering/galera-cluster/index.md b/docs/guides/mariadb/clustering/galera-cluster/index.md index fef379677a..a28546d605 100644 --- a/docs/guides/mariadb/clustering/galera-cluster/index.md +++ b/docs/guides/mariadb/clustering/galera-cluster/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mariadb/clustering/galera-cluster/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/clustering/galera-cluster/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,9 +62,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/galera-cluster/examples/demo-1.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/galera-cluster/examples/demo-1.yaml ``` +mariadb.kubedb.com/sample-mariadb created Here, @@ -74,7 +74,8 @@ Here, KubeDB operator watches for `MariaDB` objects using Kubernetes API. When a `MariaDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MariaDB object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl get mariadb -n demo sample-mariadb -o yaml +kubectl get mariadb -n demo sample-mariadb -o yaml +``` apiVersion: kubedb.com/v1 kind: MariaDB metadata: @@ -138,8 +139,9 @@ status: observedGeneration: 2 phase: Ready - -$ kubectl get petset,svc,secret,pvc,pv,pod -n demo +```bash +kubectl get petset,svc,secret,pvc,pv,pod -n demo +``` NAME READY AGE petset.apps/sample-mariadb 3/3 116m @@ -166,15 +168,15 @@ NAME READY STATUS RESTARTS AGE pod/sample-mariadb-0 1/1 Running 0 116m pod/sample-mariadb-1 1/1 Running 0 116m pod/sample-mariadb-2 1/1 Running 0 116m -``` ## Connect with MariaDB database Once the database is in running state we can conncet to each of three nodes. We will use login credentials `MYSQL_ROOT_USERNAME` and `MYSQL_ROOT_PASSWORD` saved as container's environment variable. -```bash # First Node -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 26 @@ -195,9 +197,10 @@ MariaDB [(none)]> SELECT 1; MariaDB [(none)]> quit; Bye - # Second Node -$ kubectl exec -it -n demo sample-mariadb-1 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-1 -- bash +``` root@sample-mariadb-1:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 94 @@ -218,9 +221,10 @@ MariaDB [(none)]> SELECT 1; MariaDB [(none)]> quit; Bye - # Third Node -$ kubectl exec -it -n demo sample-mariadb-2 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-2 -- bash +``` root@sample-mariadb-2:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 78 @@ -240,14 +244,14 @@ MariaDB [(none)]> SELECT 1; MariaDB [(none)]> quit; Bye -``` ## Check the Cluster Status Now, we are ready to check newly created cluster status. Connect and run the following commands from any of the hosts and you will get the same result, that is the cluster size is three. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 137 @@ -264,7 +268,6 @@ MariaDB [(none)]> show status like 'wsrep_cluster_size'; | wsrep_cluster_size | 3 | +--------------------+-------+ 1 row in set (0.001 sec) -``` ## Data Availability @@ -273,7 +276,8 @@ In a MariaDB Galera Cluster, Each member can read and write. In this section, we > Read the comment written for the following commands. They contain the instructions and explanations of the commands. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 202 @@ -373,7 +377,6 @@ MariaDB [(none)]> quit Bye root@sample-mariadb-2:/# exit exit -``` ## Automatic Failover @@ -453,8 +456,11 @@ Bye Clean what we created in this tutorial. ```bash -$ kubectl delete mariadb -n demo sample-mariadb +kubectl delete mariadb -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/clustering/mariadb-replication/index.md b/docs/guides/mariadb/clustering/mariadb-replication/index.md index 187aa409b5..1a67dfde76 100644 --- a/docs/guides/mariadb/clustering/mariadb-replication/index.md +++ b/docs/guides/mariadb/clustering/mariadb-replication/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mariadb/clustering/mariadb-replication/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/clustering/mariadb-replication/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -71,9 +71,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/mariadb-replication/examples/demo-1.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/mariadb-replication/examples/demo-1.yaml ``` +mariadb.kubedb.com/sample-mariadb created Here, @@ -87,7 +87,8 @@ Here, KubeDB operator watches for `MariaDB` objects using Kubernetes API. When a `MariaDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MariaDB object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl get mariadb -n demo sample-mariadb -o yaml +kubectl get mariadb -n demo sample-mariadb -o yaml +``` apiVersion: kubedb.com/v1 kind: MariaDB metadata: @@ -227,9 +228,9 @@ status: observedGeneration: 2 phase: Ready - - -$ kubectl get petset,svc,secret,pvc,pv,pod -n demo +```bash +kubectl get petset,svc,secret,pvc,pv,pod -n demo +``` NAME AGE petset.apps.k8s.appscode.com/sample-mariadb 53s petset.apps.k8s.appscode.com/sample-mariadb-mx 56s @@ -271,14 +272,13 @@ pod/sample-mariadb-mx-0 1/1 Running 0 3m9s pod/sample-mariadb-mx-1 1/1 Running 0 3m9s pod/sample-mariadb-mx-2 1/1 Running 0 3m9s -``` - ## Check the Cluster Status Now, we are ready to check newly created cluster status. Connect to maxscale pod and run the following commands from any of the maxscale pod and you will get the same result. ```bash -$ kubectl exec -it -n demo svc/sample-mariadb-mx -- bash +kubectl exec -it -n demo svc/sample-mariadb-mx -- bash +``` bash-4.4$ maxctrl list servers ┌─────────┬─────────────────────────────────────────────────────────────┬──────┬─────────────┬─────────────────┬─────────┬────────────────────┐ │ Server │ Address │ Port │ Connections │ State │ GTID │ Monitor │ @@ -290,8 +290,6 @@ bash-4.4$ maxctrl list servers │ server3 │ sample-mariadb-2.sample-mariadb-pods.demo.svc.cluster.local │ 3306 │ 0 │ Slave, Running │ 0-1-125 │ ReplicationMonitor │ └─────────┴─────────────────────────────────────────────────────────────┴──────┴─────────────┴─────────────────┴─────────┴────────────────────┘ -``` - ## Connecting to MariaDB Database Once the database is in running state we can conncet to each of three nodes. We will use login credentials `MYSQL_ROOT_USERNAME` and `MYSQL_ROOT_PASSWORD` saved as container's environment variable. @@ -303,7 +301,8 @@ Writing to a slave replica may result in a binary log (binlog) conflict issue. I We recommend using a non-root user for production environments. The root user has extensive privileges, which can pose security risks. Therefore, it is advisable to create a dedicated user with appropriate permissions for production use. ```bash -$ kubectl exec -it -n demo svc/sample-mariadb -- bash +kubectl exec -it -n demo svc/sample-mariadb -- bash +``` mysql@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 11 @@ -328,12 +327,12 @@ MariaDB [(none)]> quit; Bye mysql@sample-mariadb-0:/ exit exit -``` ## Check Connectivity using Test User -```bash # Master Node -$ kubectl exec -it -n demo svc/sample-mariadb -- bash +```bash +kubectl exec -it -n demo svc/sample-mariadb -- bash +``` mysql@sample-mariadb-0:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 26 @@ -355,7 +354,9 @@ MariaDB [(none)]> quit; Bye # Slave Node -$ kubectl exec -it -n demo svc/sample-mariadb-standby -- bash +```bash +kubectl exec -it -n demo svc/sample-mariadb-standby -- bash +``` mysql@sample-mariadb-1:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 94 @@ -378,7 +379,6 @@ Bye MariaDB [(none)]> quit; Bye -``` ## Insert Data and Check Availability @@ -387,9 +387,10 @@ In a MariaDB Replication Cluster, Only master member can write, and slave member > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # master node -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` mysql@sample-mariadb-0:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 202 @@ -426,7 +427,9 @@ exit # check slave node data -$ kubectl exec -it -n demo sample-mariadb-1 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-1 -- bash +``` mysql@sample-mariadb-1:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 209 @@ -471,7 +474,6 @@ MariaDB [(none)]> quit Bye mysql@sample-mariadb-2:/# exit exit -``` ## Automatic Failover @@ -580,14 +582,14 @@ deployment.apps/ubuntu created Let's exec into the pod and install mariadb-client. ```bash -$ kubectl exec -it -n demo pod/ubuntu-bb47d8d6c-4vhjv -- bash 12:00 +kubectl exec -it -n demo pod/ubuntu-bb47d8d6c-4vhjv -- bash 12:00 +``` mysql@ubuntu-bb47d8d6c-4vhjv:/# apt update ... ... .. mysql@ubuntu-bb47d8d6c-4vhjv:/# apt install mariadb-client -y Reading package lists... Done ... .. ... mysql@ubuntu-bb47d8d6c-4vhjv:/# -``` Now let's try to connect with the Maxscale Proxy server through the `sample-mariadb-mx` service as the `testuser` user. @@ -748,13 +750,19 @@ After logging in, you will be greeted by an intuitive dashboard showcasing serve Let's clean up what we created in this tutorial. ```bash -$ kubectl delete mariadb.kubedb.com -n demo sample-mariadb +kubectl delete mariadb.kubedb.com -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete -n demo deployment.apps/ubuntu + +```bash +kubectl delete -n demo deployment.apps/ubuntu +``` deployment.apps "ubuntu" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/configuration/using-config-file/index.md b/docs/guides/mariadb/configuration/using-config-file/index.md index 4542ef1e79..35d39fd627 100644 --- a/docs/guides/mariadb/configuration/using-config-file/index.md +++ b/docs/guides/mariadb/configuration/using-config-file/index.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for MariaDB. This tutorial will s - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - $ kubectl get ns demo + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-config-file/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -66,9 +68,9 @@ Here, `read_buffer_size` is set to 1MB in bytes. Now, create a Secret with this configuration file. ```bash -$ kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf -secret/md-configuration created +kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf ``` +secret/md-configuration created Verify the Secret has the configuration file. @@ -90,9 +92,9 @@ metadata: Now, create MariaDB crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-config-file/examples/md-custom.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-config-file/examples/md-custom.yaml ``` +mariadb.kubedb.com/sample-mariadb created Below is the YAML for the MariaDB crd we just created. @@ -122,15 +124,17 @@ Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, serv Check that the petset's pod is running -```bash - $ kubectl get pod -n demo + ```bash + kubectl get pod -n demo + ``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 1/1 Running 0 21s -$ kubectl get mariadb -n demo +```bash +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 71s -``` We can see the database is in ready phase so it can accept conncetion. @@ -138,9 +142,10 @@ Now, we will check if the database has started with the custom configuration we > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # Connceting to the database - $ kubectl exec -it -n demo sample-mariadb-0 -- bash + ```bash + kubectl exec -it -n demo sample-mariadb-0 -- bash + ``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -170,15 +175,17 @@ MariaDB [(none)]> show variables like 'read_buffer_size'; MariaDB [(none)]> exit Bye -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb +kubectl delete mariadb -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/configuration/using-pod-template/index.md b/docs/guides/mariadb/configuration/using-pod-template/index.md index 90bef33493..8d4a1e2b27 100644 --- a/docs/guides/mariadb/configuration/using-pod-template/index.md +++ b/docs/guides/mariadb/configuration/using-pod-template/index.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for MariaDB via [PodTemplate](/do - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mariadb/configuration/using-pod-template/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-pod-template/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -95,24 +95,25 @@ spec: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-pod-template/examples/md-misc-config.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/configuration/using-pod-template/examples/md-misc-config.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `sample-mariadb` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 1/1 Running 0 96s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo sample-mariadb-0 +kubectl logs -f -n demo sample-mariadb-0 +``` 2021-03-18 06:06:17+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:11.8.5+maria~focal started. 2021-03-18 06:06:18+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' 2021-03-18 06:06:18+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:11.8.5+maria~focal started. @@ -120,14 +121,14 @@ $ kubectl logs -f -n demo sample-mariadb-0 ... 2021-03-18 6:06:33 0 [Note] mysqld: ready for connections. Version: '11.8.5-MariaDB-1:11.8.5+maria~focal' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution -``` Once we see `Note] mysqld: ready for connections.` in the log, the database is ready. Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 22 @@ -167,15 +168,17 @@ MariaDB [(none)]> show variables like 'char%'; MariaDB [(none)]> quit; Bye -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb +kubectl delete mariadb -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/custom-rbac/using-custom-rbac/index.md b/docs/guides/mariadb/custom-rbac/using-custom-rbac/index.md index 0369e0889a..2d740bb98a 100644 --- a/docs/guides/mariadb/custom-rbac/using-custom-rbac/index.md +++ b/docs/guides/mariadb/custom-rbac/using-custom-rbac/index.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo md-custom-serviceaccount -serviceaccount/md-custom-serviceaccount created +kubectl create serviceaccount -n demo md-custom-serviceaccount ``` +serviceaccount/md-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the MariaDB instance named `sample-mariadb`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-role.yaml -role.rbac.authorization.k8s.io/md-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-role.yaml ``` +role.rbac.authorization.k8s.io/md-custom-role created Below is the YAML for the Role we just created. @@ -98,16 +98,17 @@ This permission is required for MariaDB pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding md-custom-rolebinding --role=md-custom-role --serviceaccount=demo:md-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/md-custom-rolebinding created +kubectl create rolebinding md-custom-rolebinding --role=md-custom-role --serviceaccount=demo:md-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/md-custom-rolebinding created It should bind `md-custom-role` and `md-custom-serviceaccount` successfully. SO, All required resources for RBAC are created. ```bash -$ kubectl get serviceaccount,role,rolebindings -n demo +kubectl get serviceaccount,role,rolebindings -n demo +``` NAME SECRETS AGE serviceaccount/default 1 38m serviceaccount/md-custom-serviceaccount 1 36m @@ -117,14 +118,13 @@ role.rbac.authorization.k8s.io/md-custom-role 2021-03-18T05:13:27Z NAME ROLE AGE rolebinding.rbac.authorization.k8s.io/md-custom-rolebinding Role/md-custom-role 79s -``` Now, create a MariaDB crd specifying `spec.podTemplate.spec.serviceAccountName` field to `md-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-db.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-db.yaml ``` +mariadb.kubedb.com/sample-mariadb created Below is the YAML for the MariaDB crd we just created. @@ -155,15 +155,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, PetSet, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo sample-mariadb-0 +kubectl get pod -n demo sample-mariadb-0 +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 1/1 Running 0 2m44s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo sample-mariadb-0 +kubectl logs -f -n demo sample-mariadb-0 +``` 2021-03-18 05:35:13+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:11.8.5+maria~focal started. 2021-03-18 05:35:13+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' 2021-03-18 05:35:13+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:11.8.5+maria~focal started. @@ -173,7 +174,6 @@ $ kubectl logs -f -n demo sample-mariadb-0 2021-03-18 5:35:22 0 [Note] Added new Master_info '' to hash table 2021-03-18 5:35:22 0 [Note] mysqld: ready for connections. Version: '11.8.5-MariaDB-1:11.8.5+maria~focal' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution -``` Once we see `mysqld: ready for connections.` in the log, the database is ready. @@ -184,9 +184,9 @@ An existing service account can be reused in another MariaDB instance. No new ac Now, create MariaDB crd `another-mariadb` using the existing service account name `md-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-db-2.yaml -mariadb.kubedb.com/another-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/custom-rbac/using-custom-rbac/examples/md-custom-db-2.yaml ``` +mariadb.kubedb.com/another-mariadb created Below is the YAML for the MariaDB crd we just created. @@ -217,10 +217,10 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo another-mariadb-0 +kubectl get pod -n demo another-mariadb-0 +``` NAME READY STATUS RESTARTS AGE another-mariadb-0 1/1 Running 0 37s -``` Check the pod's log to see if the database is ready @@ -243,18 +243,33 @@ Version: '11.8.5-MariaDB-1:11.8.5+maria~focal' socket: '/run/mysqld/mysqld.sock To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb +kubectl delete mariadb -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete mariadb -n demo another-mariadb + +```bash +kubectl delete mariadb -n demo another-mariadb +``` mariadb.kubedb.com "another-mariadb" deleted -$ kubectl delete -n demo role md-custom-role + +```bash +kubectl delete -n demo role md-custom-role +``` role.rbac.authorization.k8s.io "md-custom-role" deleted -$ kubectl delete -n demo rolebinding md-custom-rolebinding + +```bash +kubectl delete -n demo rolebinding md-custom-rolebinding +``` rolebinding.rbac.authorization.k8s.io "md-custom-rolebinding" deleted -$ kubectl delete sa -n demo md-custom-serviceaccount + +```bash +kubectl delete sa -n demo md-custom-serviceaccount +``` serviceaccount "md-custom-serviceaccount" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/distributed/autoscaler/compute/cluster/index.md b/docs/guides/mariadb/distributed/autoscaler/compute/cluster/index.md index cdb078e873..68fe6697cf 100644 --- a/docs/guides/mariadb/distributed/autoscaler/compute/cluster/index.md +++ b/docs/guides/mariadb/distributed/autoscaler/compute/cluster/index.md @@ -38,9 +38,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Distributed Cluster Database @@ -85,9 +85,9 @@ Here, Apply the `PlacementPolicy` on the hub (`demo-controller`) cluster: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/placement-policy.yaml --context demo-controller -placementpolicy.apps.k8s.appscode.com/distributed-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/placement-policy.yaml --context demo-controller ``` +placementpolicy.apps.k8s.appscode.com/distributed-mariadb created ### Deploy Distributed MariaDB Cluster @@ -132,35 +132,38 @@ spec: Let's create the `MariaDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/sample-mariadb.yaml --context demo-controller -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/sample-mariadb.yaml --context demo-controller ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo --context demo-controller +kubectl get mariadb -n demo --context demo-controller +``` NAME VERSION STATUS AGE sample-mariadb 11.5.2 Ready 14m -``` The pods are distributed across clusters as defined by the `PlacementPolicy`: ```bash -$ kubectl get pod -n demo --context demo-controller +kubectl get pod -n demo --context demo-controller +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 3/3 Running 0 14m sample-mariadb-2 3/3 Running 0 14m -$ kubectl get pod -n demo --context demo-worker +```bash +kubectl get pod -n demo --context demo-worker +``` NAME READY STATUS RESTARTS AGE sample-mariadb-1 3/3 Running 0 14m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -171,11 +174,11 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '. "memory": "300Mi" } } -``` Let's check the MariaDB resources, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +``` { "limits": { "cpu": "200m", @@ -186,7 +189,6 @@ $ kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mariadb. @@ -248,20 +250,23 @@ If a step doesn't finish within the specified timeout, the ops request will resu Let's create the `MariaDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/mdas-compute.yaml --context demo-controller -mariadbautoscaler.autoscaling.kubedb.com/md-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/compute/cluster/examples/mdas-compute.yaml --context demo-controller ``` +mariadbautoscaler.autoscaling.kubedb.com/md-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `mariadbautoscaler` resource is created successfully, ```bash -$ kubectl get mariadbautoscaler -n demo --context demo-controller +kubectl get mariadbautoscaler -n demo --context demo-controller +``` NAME AGE md-as-compute 5m56s -$ kubectl describe mariadbautoscaler md-as-compute -n demo --context demo-controller +```bash +kubectl describe mariadbautoscaler md-as-compute -n demo --context demo-controller +``` Name: md-as-compute Namespace: demo Labels: @@ -364,8 +369,6 @@ Status: Memory: 1Gi Vpa Name: sample-mariadb Events: - -``` So, the `mariadbautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -375,23 +378,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `mariadbopsrequest` in the demo namespace to see if any `mariadbopsrequest` object is created. After some time you'll see that a `mariadbopsrequest` will be created based on the recommendation. ```bash -$ kubectl get mariadbopsrequest -n demo --context demo-controller +kubectl get mariadbopsrequest -n demo --context demo-controller +``` NAME TYPE STATUS AGE mdops-sample-mariadb-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mariadbopsrequest -n demo --context demo-controller +kubectl get mariadbopsrequest -n demo --context demo-controller +``` NAME TYPE STATUS AGE mdops-vpa-sample-mariadb-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-vpa-sample-mariadb-z43wc8 --context demo-controller +kubectl describe mariadbopsrequest -n demo mdops-vpa-sample-mariadb-z43wc8 --context demo-controller +``` Name: mdops-sample-mariadb-6xc1kc Namespace: demo ... @@ -420,12 +424,12 @@ Status: Type: VerticalScaling ... Phase: Successful -``` Now, we are going to verify from the Pod, and the MariaDB yaml whether the resources of the distributed cluster database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -437,7 +441,9 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json --context demo-worker | jq '. } } -$ kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +```bash +kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | jq '.spec.podTemplate.spec.containers[] | select(.name == "mariadb") | .resources' +``` { "limits": { "cpu": "250m", @@ -448,7 +454,6 @@ $ kubectl get mariadb -n demo sample-mariadb -o json --context demo-controller | "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the distributed MariaDB cluster. diff --git a/docs/guides/mariadb/distributed/autoscaler/storage/cluster/index.md b/docs/guides/mariadb/distributed/autoscaler/storage/cluster/index.md index 0d0d982b5a..b92ce813fe 100644 --- a/docs/guides/mariadb/distributed/autoscaler/storage/cluster/index.md +++ b/docs/guides/mariadb/distributed/autoscaler/storage/cluster/index.md @@ -40,29 +40,29 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a distr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Distributed Cluster Database At first verify that your clusters have a storage class that supports volume expansion. First let's check the storagclass of `Controler` cluster, ```bash -$ kubectl get storageclass --context demo-controller +kubectl get storageclass --context demo-controller +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 4d longhorn (default) driver.longhorn.io Delete Immediate true 24h longhorn-static driver.longhorn.io Delete Immediate true 24h -``` Then check the storageclass of `Worker` cluster, ```bash -$ kubectl get storageclass --context demo-worker +kubectl get storageclass --context demo-worker +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 4d longhorn (default) driver.longhorn.io Delete Immediate true 23h longhorn-static driver.longhorn.io Delete Immediate true 23h -``` We can see from the output the `longhorn (default)` and `longhorn-static` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install `longhorn` from [here](https://longhorn.io/docs/1.11.2/deploy/install/) @@ -118,9 +118,9 @@ Here, Apply the `PlacementPolicy` on the hub (`demo-controller`) cluster: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/placement-policy.yaml --context demo-controller -placementpolicy.apps.k8s.appscode.com/distributed-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/placement-policy.yaml --context demo-controller ``` +placementpolicy.apps.k8s.appscode.com/distributed-mariadb created > **Note:** Update the `monitoring.prometheus.url` values to match the actual Prometheus service endpoints in each of your spoke clusters. @@ -158,41 +158,45 @@ spec: Let's create the `MariaDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/sample-mariadb.yaml --context demo-controller -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/sample-mariadb.yaml --context demo-controller ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo --context demo-controller +kubectl get mariadb -n demo --context demo-controller +``` NAME VERSION STATUS AGE sample-mariadb 11.5.2 Ready 3m46s -``` The pods are distributed across clusters as defined by the `PlacementPolicy`: ```bash -$ kubectl get pod -n demo --context demo-controller +kubectl get pod -n demo --context demo-controller +``` NAME READY STATUS RESTARTS AGE sample-mariadb-0 3/3 Running 0 3m46s sample-mariadb-2 3/3 Running 0 3m46s -$ kubectl get pod -n demo --context demo-worker +```bash +kubectl get pod -n demo --context demo-worker +``` NAME READY STATUS RESTARTS AGE sample-mariadb-1 3/3 Running 0 3m46s -``` Let's check volume size from petset, and from the persistent volume on `demo-worker`, ```bash -$ kubectl get petset -n demo sample-mariadb -o json --context demo-worker | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json --context demo-worker | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo --context demo-worker +```bash +kubectl get pv -n demo --context demo-worker +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes is also 1GB. @@ -234,20 +238,23 @@ Here, Let's create the `MariaDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/mdas-storage.yaml --context demo-controller -mariadbautoscaler.autoscaling.kubedb.com/md-as-st created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/autoscaler/storage/cluster/examples/mdas-storage.yaml --context demo-controller ``` +mariadbautoscaler.autoscaling.kubedb.com/md-as-st created #### Storage Autoscaling is set up successfully Let's check that the `mariadbautoscaler` resource is created successfully, ```bash -$ kubectl get mariadbautoscaler -n demo --context demo-controller +kubectl get mariadbautoscaler -n demo --context demo-controller +``` NAME AGE md-as-st 33s -$ kubectl describe mariadbautoscaler md-as-st -n demo --context demo-controller +```bash +kubectl describe mariadbautoscaler md-as-st -n demo --context demo-controller +``` Name: md-as-st Namespace: demo Labels: @@ -268,7 +275,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `mariadbautoscaler` resource is created successfully. @@ -277,7 +283,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into a database pod on `demo-worker` and fill the database volume(`var/lib/mysql`) using the following commands: ```bash -$ kubectl exec -it -n demo sample-mariadb-0 --context demo-worker -- bash +kubectl exec -it -n demo sample-mariadb-0 --context demo-worker -- bash +``` root@sample-mariadb-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 357M 658M 36% /var/lib/mysql @@ -288,30 +295,30 @@ root@sample-mariadb-0:/ dd if=/dev/zero of=/var/lib/mysql/file.img bs=500M count root@sample-mariadb-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 857M 158M 85% /var/lib/mysql -``` So, from the above output we can see that the storage usage is 85%, which exceeded the `usageThreshold` 20%. Let's watch the `mariadbopsrequest` in the demo namespace to see if any `mariadbopsrequest` object is created. After some time you'll see that a `mariadbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get mariadbopsrequest -n demo --context demo-controller +kubectl get mariadbopsrequest -n demo --context demo-controller +``` NAME TYPE STATUS AGE mops-sample-mariadb-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mariadbopsrequest -n demo --context demo-controller +kubectl get mariadbopsrequest -n demo --context demo-controller +``` NAME TYPE STATUS AGE mops-sample-mariadb-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mops-sample-mariadb-xojkua --context demo-controller +kubectl describe mariadbopsrequest -n demo mops-sample-mariadb-xojkua --context demo-controller +``` Name: mops-sample-mariadb-xojkua Namespace: demo ... @@ -332,17 +339,19 @@ Status: Type: VolumeExpansion ... Phase: Successful -``` Now, we are going to verify from the `Petset` and the `Persistent Volume` whether the volume of the distributed replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-mariadb -o json --context demo-worker | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json --context demo-worker | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo --context demo-worker + +```bash +kubectl get pv -n demo --context demo-worker +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the distributed MariaDB cluster. diff --git a/docs/guides/mariadb/distributed/opsrequest/horizontal_scale.md b/docs/guides/mariadb/distributed/opsrequest/horizontal_scale.md index 3922dd8ff9..8a5385b6e1 100644 --- a/docs/guides/mariadb/distributed/opsrequest/horizontal_scale.md +++ b/docs/guides/mariadb/distributed/opsrequest/horizontal_scale.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` Opsrequest operator to horizontally To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Horizontal Scaling on Distributed Cluster @@ -90,9 +90,9 @@ Here, Apply the `PlacementPolicy` on the hub (`demo-controller`) cluster: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/placement-policy.yaml --context demo-controller -placementpolicy.apps.k8s.appscode.com/distributed-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/placement-policy.yaml --context demo-controller ``` +placementpolicy.apps.k8s.appscode.com/distributed-mariadb created ### Deploy Distributed MariaDB Cluster @@ -135,37 +135,39 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mariadb.yaml --context demo-controller -mariadb.kubedb.com/mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mariadb.yaml --context demo-controller ``` +mariadb.kubedb.com/mariadb created Now, wait until `mariadb` has status `Ready`: ```bash -$ kubectl get mariadb -n demo --context demo-controller +kubectl get mariadb -n demo --context demo-controller +``` NAME VERSION STATUS AGE mariadb 11.5.2 Ready 2m36s -``` Let's check the number of replicas this database has from the MariaDB object: ```bash -$ kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' -3 +kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' ``` +3 The pods are distributed across clusters as defined by the `PlacementPolicy`. Indices `0` and `2` land on `demo-controller`; index `1` lands on `demo-worker`: ```bash -$ kubectl get pods -n demo --context demo-controller +kubectl get pods -n demo --context demo-controller +``` NAME READY STATUS RESTARTS AGE mariadb-0 3/3 Running 0 2m30s mariadb-2 3/3 Running 0 2m30s -$ kubectl get pods -n demo --context demo-worker +```bash +kubectl get pods -n demo --context demo-worker +``` NAME READY STATUS RESTARTS AGE mariadb-1 3/3 Running 0 2m30s -``` @@ -202,9 +204,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mdops-upscale.yaml --context demo-controller -mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mdops-upscale.yaml --context demo-controller ``` +mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-up created ### Verify Cluster Replicas Scaled Up Successfully @@ -213,34 +215,35 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `MariaDBOpsRequest` to be `Successful`: ```bash -$ watch kubectl get mariadbopsrequest -n demo --context demo-controller +watch kubectl get mariadbopsrequest -n demo --context demo-controller +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdops-scale-horizontal-up HorizontalScaling Successful 18m -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, let's verify the number of replicas: ```bash -$ kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' -5 +kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' ``` +5 The two new pods are placed on the clusters according to the `PlacementPolicy` — index `4` on `demo-controller` and index `3` on `demo-worker`: ```bash -$ kubectl get pods -n demo --context demo-controller +kubectl get pods -n demo --context demo-controller +``` NAME READY STATUS RESTARTS AGE mariadb-0 3/3 Running 0 58m mariadb-2 3/3 Running 0 55m mariadb-4 3/3 Running 0 17m - -$ kubectl get pods -n demo --context demo-worker +```bash +kubectl get pods -n demo --context demo-worker +``` NAME READY STATUS RESTARTS AGE mariadb-1 3/3 Running 0 57m mariadb-3 3/3 Running 0 19m -``` From all the above outputs we can see that the cluster now has `5` replicas. We have successfully scaled up the distributed MariaDB cluster. @@ -275,9 +278,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mdops-downscale.yaml --context demo-controller -mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/distributed/opsrequest/examples/mdops-downscale.yaml --context demo-controller ``` +mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-down created ### Verify Cluster Replicas Scaled Down Successfully @@ -286,31 +289,33 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `MariaDBOpsRequest` to be `Successful`: ```bash -$ watch kubectl get mariadbopsrequest -n demo --context demo-controller +watch kubectl get mariadbopsrequest -n demo --context demo-controller +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdops-scale-horizontal-down HorizontalScaling Successful 2m32s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, let's verify the number of replicas: ```bash -$ kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' -3 +kubectl get mariadb -n demo mariadb -o json | jq '.spec.replicas' ``` +3 Pods `mariadb-3` and `mariadb-4` have been removed from their respective clusters: ```bash -$ kubectl get pods -n demo --context demo-controller +kubectl get pods -n demo --context demo-controller +``` NAME READY STATUS RESTARTS AGE mariadb-0 3/3 Running 0 20m mariadb-2 3/3 Running 0 20m -$ kubectl get pods -n demo --context demo-worker +```bash +kubectl get pods -n demo --context demo-worker +``` NAME READY STATUS RESTARTS AGE mariadb-1 3/3 Running 0 20m -``` From all the above outputs we can see that the cluster now has `3` replicas. We have successfully scaled down the distributed MariaDB cluster. @@ -320,7 +325,13 @@ From all the above outputs we can see that the cluster now has `3` replicas. We To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo mariadb --context demo-controller -$ kubectl delete mariadbopsrequest -n demo mdops-scale-horizontal-up mdops-scale-horizontal-down --context demo-controller -$ kubectl delete placementpolicy distributed-mariadb --context demo-controller +kubectl delete mariadb -n demo mariadb --context demo-controller +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-scale-horizontal-up mdops-scale-horizontal-down --context demo-controller +``` + +```bash +kubectl delete placementpolicy distributed-mariadb --context demo-controller ``` diff --git a/docs/guides/mariadb/distributed/overview/index.md b/docs/guides/mariadb/distributed/overview/index.md index 9724796982..e2f72ae4fd 100644 --- a/docs/guides/mariadb/distributed/overview/index.md +++ b/docs/guides/mariadb/distributed/overview/index.md @@ -51,7 +51,7 @@ Follow these steps to deploy a distributed MariaDB Galera cluster across multipl Ensure your `KUBECONFIG` is set up to switch between clusters. This guide uses two clusters: `demo-controller` (hub and spoke) and `demo-worker` (spoke). ```bash -$ kubectl config get-contexts +kubectl config get-contexts ``` **Output:** @@ -67,8 +67,11 @@ CURRENT NAME CLUSTER AUTHINFO NAMESPACE On the `demo-controller` cluster, initialize the OCM hub: ```bash -$ kubectl config use-context demo-controller -$ clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true +kubectl config use-context demo-controller +``` + +```bash +clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true ``` #### 3. Verify Hub Deployment @@ -76,7 +79,7 @@ $ clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true Check the pods in the `open-cluster-management-hub` namespace to ensure all components are running: ```bash -$ kubectl get pods -n open-cluster-management-hub +kubectl get pods -n open-cluster-management-hub ``` **Output:** @@ -98,7 +101,7 @@ All pods should be in the `Running` state with `1/1` readiness and no restarts, Obtain the join token from the hub cluster: ```bash -$ clusteradm get token +clusteradm get token ``` **Output:** @@ -112,8 +115,11 @@ clusteradm join --hub-token --hub-apiserver https:/ On the `demo-worker` cluster, join it to the hub. Include the `RawFeedbackJsonString` feature gate for resource feedback: ```bash -$ kubectl config use-context demo-worker -$ clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-worker --feature-gates=RawFeedbackJsonString=true +kubectl config use-context demo-worker +``` + +```bash +clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-worker --feature-gates=RawFeedbackJsonString=true ``` #### 5. Accept Spoke Cluster @@ -121,8 +127,11 @@ $ clusteradm join --hub-token --hub-apiserver https On the `demo-controller` cluster, accept the `demo-worker` cluster: ```bash -$ kubectl config use-context demo-controller -$ clusteradm accept --clusters demo-worker +kubectl config use-context demo-controller +``` + +```bash +clusteradm accept --clusters demo-worker ``` > **Note:** It may take a few attempts (e.g., retry every 10 seconds) if the cluster is not immediately available. @@ -141,7 +150,7 @@ Your managed cluster demo-worker has joined the Hub successfully. Confirm that a namespace for `demo-worker` was created on the hub cluster: ```bash -$ kubectl get ns +kubectl get ns ``` **Output:** @@ -162,15 +171,21 @@ open-cluster-management-hub Active 5m32s Repeat the join and accept process for `demo-controller` so it can also act as a spoke cluster: ```bash -$ kubectl config use-context demo-controller -$ clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-controller --feature-gates=RawFeedbackJsonString=true -$ clusteradm accept --clusters demo-controller +kubectl config use-context demo-controller +``` + +```bash +clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-controller --feature-gates=RawFeedbackJsonString=true +``` + +```bash +clusteradm accept --clusters demo-controller ``` Verify the namespace for `demo-controller`: ```bash -$ kubectl get ns +kubectl get ns ``` **Output:** @@ -193,18 +208,24 @@ open-cluster-management-hub Active 10m After registration, use these commands to confirm which cluster is the hub and which are spokes: -```bash # Hub: lists all registered spoke clusters -$ kubectl get managedclusters +```bash +kubectl get managedclusters +``` # Spoke: shows this cluster's registered name -$ kubectl get klusterlet klusterlet -o jsonpath='{.spec.clusterName}' +```bash +kubectl get klusterlet klusterlet -o jsonpath='{.spec.clusterName}' +``` # Hub components run only on the hub cluster -$ kubectl get pods -n open-cluster-management-hub +```bash +kubectl get pods -n open-cluster-management-hub +``` # Spoke agent runs on every spoke cluster -$ kubectl get pods -n open-cluster-management-agent +```bash +kubectl get pods -n open-cluster-management-agent ``` ### Step 2: Configure OCM WorkConfiguration @@ -216,7 +237,8 @@ Run this on **every spoke cluster** (`demo-controller` and `demo-worker`). This > **Why this matters:** KubeDB uses OCM's ManifestWork feedback mechanism to watch the status of MariaDB pods on remote spoke clusters. Without `RawFeedbackJsonString`, the KubeDB provisioner on the hub never receives pod status updates from spokes and the distributed MariaDB CR will stay in a non-Ready state indefinitely. The rate limits prevent the klusterlet agent from being API-throttled during initial cluster formation. ```bash -$ kubectl patch klusterlet klusterlet --type=merge -p '{ +kubectl patch klusterlet klusterlet --type=merge -p '{ +``` "spec": { "workConfiguration": { "featureGates": [{"feature": "RawFeedbackJsonString", "mode": "Enable"}], @@ -227,12 +249,11 @@ $ kubectl patch klusterlet klusterlet --type=merge -p '{ } } }' -``` Verify the configuration: ```bash -$ kubectl get klusterlet klusterlet -oyaml +kubectl get klusterlet klusterlet -oyaml ``` **Sample Output (abridged):** @@ -263,7 +284,7 @@ KubeSlice enables pod-to-pod communication across clusters. Install the KubeSlic On `demo-controller`, get the hub API server address first: ```bash -$ kubectl cluster-info | grep 'Kubernetes control plane' +kubectl cluster-info | grep 'Kubernetes control plane' ``` Use the IP and port from that output as the `endpoint` value. Create a `controller.yaml` file: @@ -280,7 +301,7 @@ kubeslice: Deploy the controller using Helm: ```bash -$ helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-controller \ +helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-controller \ --version v2026.1.15 \ -f controller.yaml \ --namespace kubeslice-controller \ @@ -292,7 +313,7 @@ $ helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-c Verify the installation: ```bash -$ kubectl get pods -n kubeslice-controller +kubectl get pods -n kubeslice-controller ``` **Output:** @@ -321,13 +342,13 @@ spec: Apply the project: ```bash -$ kubectl apply -f project.yaml +kubectl apply -f project.yaml ``` Verify: ```bash -$ kubectl get project -n kubeslice-controller +kubectl get project -n kubeslice-controller ``` **Output:** @@ -340,7 +361,7 @@ demo-distributed-mariadb 31s Check service accounts: ```bash -$ kubectl get sa -n kubeslice-demo-distributed-mariadb +kubectl get sa -n kubeslice-demo-distributed-mariadb ``` **Output:** @@ -358,16 +379,25 @@ Assign the `kubeslice.io/node-type=gateway` label to the node where the worker o On `demo-controller`: ```bash -$ kubectl get nodes -$ kubectl label node kubeslice.io/node-type=gateway +kubectl get nodes +``` + +```bash +kubectl label node kubeslice.io/node-type=gateway ``` On `demo-worker`: ```bash -$ kubectl config use-context demo-worker -$ kubectl get nodes -$ kubectl label node kubeslice.io/node-type=gateway +kubectl config use-context demo-worker +``` + +```bash +kubectl get nodes +``` + +```bash +kubectl label node kubeslice.io/node-type=gateway ``` #### 4. Register Clusters with KubeSlice @@ -375,7 +405,7 @@ $ kubectl label node kubeslice.io/node-type=gateway Identify the network interface for each cluster by running the following command **on the gateway node of each cluster**: ```bash -$ ip route get 8.8.8.8 | awk '{ print $5 }' +ip route get 8.8.8.8 | awk '{ print $5 }' ``` **Output (example):** @@ -443,13 +473,13 @@ spec: Apply on `demo-controller`: ```bash -$ kubectl apply -f registration.yaml +kubectl apply -f registration.yaml ``` Verify OCM is deploying the KubeSlice worker manifests to each cluster: ```bash -$ kubectl get managedclusteraddon -A +kubectl get managedclusteraddon -A ``` **Output:** @@ -462,9 +492,9 @@ demo-worker kubeslice Unknown True `PROGRESSING: True` means OCM is actively deploying. Wait until `kubeslice-operator` shows `2/2 Running` on both clusters before proceeding: -```bash # Run on each spoke cluster -$ kubectl get pods -n kubeslice-system --watch +```bash +kubectl get pods -n kubeslice-system --watch ``` **Expected output (after KubeSlice worker is fully deployed):** @@ -531,7 +561,7 @@ spec: Apply the `SliceConfig`: ```bash -$ kubectl apply -f sliceconfig.yaml +kubectl apply -f sliceconfig.yaml ``` After the SliceConfig is applied, a `vl3-slice-router` pod will appear in `kubeslice-system` on each cluster, indicating the slice VPN tunnel is being established. @@ -551,7 +581,7 @@ Update CoreDNS to forward `*.slice.local` traffic to the KubeSlice DNS service. Get the KubeSlice DNS service IP address on each cluster: ```bash -$ kubectl get svc -n kubeslice-system -owide -l 'app=kubeslice-dns' +kubectl get svc -n kubeslice-system -owide -l 'app=kubeslice-dns' ``` **Output:** @@ -574,7 +604,7 @@ slice.local:53 { Example of the full CoreDNS ConfigMap after editing: ```bash -$ kubectl get cm -n kube-system coredns -oyaml +kubectl get cm -n kube-system coredns -oyaml ``` **Output:** @@ -621,7 +651,7 @@ metadata: After editing the ConfigMap, restart CoreDNS to apply the change: ```bash -$ kubectl rollout restart deploy/coredns -n kube-system +kubectl rollout restart deploy/coredns -n kube-system ``` Repeat the DNS configuration steps on every cluster in the slice. @@ -634,18 +664,20 @@ Repeat the DNS configuration steps on every cluster in the slice. The KubeDB license is tied to the `kube-system` namespace UID of the hub cluster and has an expiry date. Get your cluster UID and verify the license before installing: -```bash # Get your cluster UID (required when requesting the license) -$ kubectl get ns kube-system -o jsonpath='{.metadata.uid}' +```bash +kubectl get ns kube-system -o jsonpath='{.metadata.uid}' +``` # Verify the license is not expired -$ openssl x509 -noout -enddate -in $HOME/Downloads/kubedb-license-.txt +```bash +openssl x509 -noout -enddate -in $HOME/Downloads/kubedb-license-.txt ``` If expired or not yet obtained, download a FREE license from the [AppsCode License Server](https://appscode.com/issue-license?p=kubedb) using the cluster UID above. ```bash -$ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ --version v2026.2.26 \ --namespace kubedb --create-namespace \ --set-file global.license=$HOME/Downloads/kubedb-license-.txt \ @@ -660,7 +692,7 @@ For additional details, refer to the [KubeDB Installation Guide](/docs/setup/). Verify that the pods are running: ```bash -$ kubectl get pods -n kubedb +kubectl get pods -n kubedb ``` **Output:** @@ -719,7 +751,7 @@ This policy schedules: Apply the policy on `demo-controller`: ```bash -$ kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubeconfig $HOME/.kube/config +kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubeconfig $HOME/.kube/config ``` ### Step 6: Create a Distributed MariaDB Instance @@ -727,7 +759,7 @@ $ kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubecon Create the `demo` namespace first: ```bash -$ kubectl create namespace demo +kubectl create namespace demo ``` Define a MariaDB custom resource with `spec.distributed` set to `true` and reference the `PlacementPolicy`. Create a `mariadb.yaml` file: @@ -759,7 +791,7 @@ spec: Apply the resource on `demo-controller`: ```bash -$ kubectl apply -f mariadb.yaml --context demo-controller --kubeconfig $HOME/.kube/config +kubectl apply -f mariadb.yaml --context demo-controller --kubeconfig $HOME/.kube/config ``` ### Step 7: Verify the Deployment @@ -767,7 +799,7 @@ $ kubectl apply -f mariadb.yaml --context demo-controller --kubeconfig $HOME/.ku #### 1. Check MariaDB Resource and Pods on `demo-controller` ```bash -$ kubectl get md,pods,secret -n demo --context demo-controller --kubeconfig $HOME/.kube/config +kubectl get md,pods,secret -n demo --context demo-controller --kubeconfig $HOME/.kube/config ``` **Output:** @@ -787,7 +819,7 @@ secret/mariadb-auth kubernetes.io/basic-auth 2 95s #### 2. Check Pods and Secrets on `demo-worker` ```bash -$ kubectl get pods,secrets -n demo --context demo-worker --kubeconfig $HOME/.kube/config +kubectl get pods,secrets -n demo --context demo-worker --kubeconfig $HOME/.kube/config ``` **Output:** @@ -805,9 +837,9 @@ secret/mariadb-auth kubernetes.io/basic-auth 2 95s Connect to a MariaDB pod and check the Galera cluster status. The primary service DNS follows the format `..svc`: ```bash -$ kubectl exec -it -n demo pod/mariadb-0 --context demo-controller -- bash -mariadb -uroot -p$MYSQL_ROOT_PASSWORD -hmariadb.demo.svc +kubectl exec -it -n demo pod/mariadb-0 --context demo-controller -- bash ``` +mariadb -uroot -p$MYSQL_ROOT_PASSWORD -hmariadb.demo.svc Run the following query: diff --git a/docs/guides/mariadb/failover/guide.md b/docs/guides/mariadb/failover/guide.md index a863e13201..67f2399bc1 100644 --- a/docs/guides/mariadb/failover/guide.md +++ b/docs/guides/mariadb/failover/guide.md @@ -57,9 +57,9 @@ using [kind](https://kind.sigs.k8s.io/docs/user/quick-start/). Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Deploy MariaDB Cluster The following is an example `MariaDB` object which creates a single-master MariaDB `standard replication` cluster with three members. @@ -96,9 +96,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/galera-cluster/examples/demo-1.yaml -mariadb.kubedb.com/ha-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/clustering/galera-cluster/examples/demo-1.yaml ``` +mariadb.kubedb.com/ha-mariadb created Here, @@ -117,8 +117,9 @@ watch kubectl get mariadb,petset,pods -n demo ``` See the database is ready. -```shell -$ kubectl get mariadb,petset,pods -n demo +```bash +kubectl get mariadb,petset,pods -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/ha-mariadb 11.8.5 Ready 3m27s @@ -134,23 +135,20 @@ pod/ha-mariadb-mx-0 1/1 Running 0 3m23s pod/ha-mariadb-mx-1 1/1 Running 0 3m23s pod/ha-mariadb-mx-2 1/1 Running 0 3m23s -``` - Inspect who is `Master` and who is `slave`. -```shell # you can inspect the role of the pods - -$ kubectl get pods -n demo --show-labels | grep role +```bash +kubectl get pods -n demo --show-labels | grep role +``` ha-mariadb-0 2/2 Running 0 4m9s app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mariadb,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mariadbs.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=ha-mariadb-598cd56869,kubedb.com/role=Master,statefulset.kubernetes.io/pod-name=ha-mariadb-0 ha-mariadb-1 2/2 Running 0 4m9s app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mariadb,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mariadbs.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=ha-mariadb-598cd56869,kubedb.com/role=Slave,statefulset.kubernetes.io/pod-name=ha-mariadb-1 ha-mariadb-2 2/2 Running 0 4m9s app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mariadb,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mariadbs.kubedb.com,apps.kubernetes.io/pod-index=2,controller-revision-hash=ha-mariadb-598cd56869,kubedb.com/role=Slave,statefulset.kubernetes.io/pod-name=ha-mariadb-2 - -``` The pod having `kubedb.com/role=Master` is the `Master` and `kubedb.com/role=Slave` are the slaves. You can also check it on the cluster status: -```shell -$ kubectl exec -it -n demo svc/ha-mariadb-mx -- bash +```bash +kubectl exec -it -n demo svc/ha-mariadb-mx -- bash +``` Defaulted container "maxscale" out of: maxscale, maxscale-init (init) bash-4.4$ maxctrl list servers ┌─────────┬─────────────────────────────────────────────────────────────┬──────┬─────────────┬─────────────────┬─────────┬────────────────────┐ @@ -162,8 +160,6 @@ bash-4.4$ maxctrl list servers ├─────────┼─────────────────────────────────────────────────────────────┼──────┼─────────────┼─────────────────┼─────────┼────────────────────┤ │ server3 │ ha-mariadb-2.ha-mariadb-pods.demo.svc.cluster.local │ 3306 │ 0 │ Slave, Running │ 0-1-217 │ ReplicationMonitor │ └─────────┴─────────────────────────────────────────────────────────────┴──────┴─────────────┴─────────────────┴─────────┴────────────────────┘ - -``` ## Verify Pod Reachability and Status Once the database is in running state we can connect to each of three nodes. We will use login credentials `MYSQL_ROOT_USERNAME` and `MYSQL_ROOT_PASSWORD` saved as container's environment variable. @@ -173,7 +169,8 @@ Writing to a slave replica can cause binlog conflicts. By default, slave-replica root user (with super privileges) can still make changes. For security, avoid using the root user in production and create a dedicated user with only the needed permissions instead. ```bash -$ kubectl exec -it -n demo svc/ha-mariadb -- bash +kubectl exec -it -n demo svc/ha-mariadb -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@ha-mariadb-0:/$ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -197,13 +194,12 @@ MariaDB [(none)]> quit Bye mysql@ha-mariadb-0:/$ exit exit - -``` ### Check Connectivity using Test User -```bash # Master Node -$ kubectl exec -it -n demo svc/ha-mariadb -- bash +```bash +kubectl exec -it -n demo svc/ha-mariadb -- bash +``` mysql@ha-mariadb-0:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 26 @@ -225,7 +221,9 @@ MariaDB [(none)]> quit; Bye # Slave Node -$ kubectl exec -it -n demo svc/ha-mariadb-standby -- bash +```bash +kubectl exec -it -n demo svc/ha-mariadb-standby -- bash +``` mysql@ha-mariadb-1:/ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 94 @@ -248,20 +246,19 @@ Bye MariaDB [(none)]> quit; Bye -``` ## Insert Data and Check Availability In a MariaDB Replication Cluster, Only master member can write, and slave member can read. In this section, we will insert data from master node, and we will see whether we can get the data from every other slave members. **Check which is the master pod** -```shell -$ kubectl get pods -n demo --show-labels | grep Master | awk '{ print $1 }' -ha-mariadb-0 - +```bash +kubectl get pods -n demo --show-labels | grep Master | awk '{ print $1 }' ``` +ha-mariadb-0 let's insert data in the master node ```bash -$ kubectl exec -it -n demo ha-mariadb-0 -- bash +kubectl exec -it -n demo ha-mariadb-0 -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@ha-mariadb-0:/$ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -293,7 +290,6 @@ MariaDB [(none)]> exit Bye mysql@ha-mariadb-0:/$ exit exit -``` You can read data from the slave nodes ```shell kubectl exec -it -n demo ha-mariadb-1 -- bash @@ -337,8 +333,8 @@ MaxScale: This process happens automatically, typically within seconds, ensuring minimal disruption. Lets open another terminal and monitor the state of all the pods: -```shell -$ watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" +```bash +watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" ``` You'll see: ```shell @@ -355,10 +351,10 @@ ha-mariadb-mx-2 Let's delete the current `Master` pod and see how the role change happens almost immediately. -```shell -$ kubectl delete pods -n demo ha-mariadb-0 -pod "ha-mariadb-0" deleted +```bash +kubectl delete pods -n demo ha-mariadb-0 ``` +pod "ha-mariadb-0" deleted You'll see the pods' status like that: ``` ha-mariadb-0 Down @@ -381,8 +377,9 @@ ha-mariadb-mx-2 Now we know how failover is done, let's check if the new `Master` is working. -```shell -$ kubectl exec -it -n demo ha-mariadb-1 -- bash +```bash +kubectl exec -it -n demo ha-mariadb-1 -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@ha-mariadb-1:/$ mariadb -utestuser -ptestpassword Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -413,12 +410,11 @@ Bye mysql@ha-mariadb-1:/$ exit exit -``` - Lets check if the new Slave(`ha-mariadb-0`) got the updated data from new `Master`, `ha-mariadb-1`. -```shell -$ kubectl exec -it -n demo ha-mariadb-0 -- bash +```bash + kubectl exec -it -n demo ha-mariadb-0 -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@ha-mariadb-0:/$ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -448,15 +444,13 @@ Bye mysql@ha-mariadb-0:/$ exit exit -``` - #### Case 2: Delete the current `Master` and One slave -```shell -$ kubectl delete pods -n demo ha-mariadb-1 ha-mariadb-2 +```bash +kubectl delete pods -n demo ha-mariadb-1 ha-mariadb-2 +``` pod "ha-mariadb-1" deleted pod "ha-mariadb-2" deleted -``` Again we can see the failover happened pretty quickly. ```shell ha-mariadb-0 Master @@ -477,8 +471,9 @@ ha-mariadb-mx-2 ``` Lets validate the cluster state from new `Master`(`ha-mariadb-0`). -```shell -$ kubectl exec -it -n demo ha-mariadb-0 -- bash +```bash +kubectl exec -it -n demo ha-mariadb-0 -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@ha-mariadb-0:/$ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -510,8 +505,6 @@ MariaDB [(none)]> exit Bye mysql@ha-mariadb-0:/$ exit exit - -``` Let's check whether the Slave nodes, `ha-mariadb-2` gets all the previous data ```shell kubectl exec -it -n demo ha-mariadb-2 -- bash @@ -580,13 +573,12 @@ ha-mariadb-mx-2 Let's delete all the pods. -```shell -$ kubectl delete pods -n demo ha-mariadb-0 ha-mariadb-1 ha-mariadb-2 +```bash +kubectl delete pods -n demo ha-mariadb-0 ha-mariadb-1 ha-mariadb-2 +``` pod "ha-mariadb-0" deleted pod "ha-mariadb-1" deleted pod "ha-mariadb-2" deleted - -``` ```shell ha-mariadb-0 Down ha-mariadb-1 Down @@ -611,8 +603,9 @@ ha-mariadb-mx-2 Lets verify the cluster state now. -```shell -$ kubectl exec -it -n demo svc/ha-mariadb-mx -- bash +```bash +kubectl exec -it -n demo svc/ha-mariadb-mx -- bash +``` Defaulted container "maxscale" out of: maxscale, maxscale-init (init) bash-4.4$ maxctrl list servers ┌─────────┬─────────────────────────────────────────────────────────────┬──────┬─────────────┬─────────────────┬──────────┬────────────────────┐ @@ -625,16 +618,17 @@ bash-4.4$ maxctrl list servers │ server3 │ ha-mariadb-2.ha-mariadb-pods.demo.svc.cluster.local │ 3306 │ 0 │ Slave, Running │ 0-1-3297 │ ReplicationMonitor │ └─────────┴─────────────────────────────────────────────────────────────┴──────┴─────────────┴─────────────────┴──────────┴────────────────────┘ -``` - ## CleanUp For cleaning up what we created in this tutorial follow the following command: -```shell -$ kubectl delete mariadb -n demo ha-mariadb +```bash +kubectl delete mariadb -n demo ha-mariadb +``` mariadb.kubedb.com "ha-mariadb" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/mariadb/gitops/gitops.md b/docs/guides/mariadb/gitops/gitops.md index b0da1af1d1..dd72311ba2 100644 --- a/docs/guides/mariadb/gitops/gitops.md +++ b/docs/guides/mariadb/gitops/gitops.md @@ -28,12 +28,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create MariaDB d - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mariadb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mariadb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -92,11 +94,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── MariaDB.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `MariaDB` CR is created in your cluster. @@ -104,18 +106,19 @@ Our `gitops` operator will create an actual `MariaDB` database CR in the cluster ```bash -$ kubectl get mariaDB.gitops.kubedb.com,mariaDB.kubedb.com -n demo +kubectl get mariaDB.gitops.kubedb.com,mariaDB.kubedb.com -n demo +``` NAME AGE mariadb.gitops.kubedb.com/mariadb-gitops 22m NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 22m -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` MariaDB. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/mariadb-gitops 22m @@ -133,7 +136,6 @@ service/mariadb-gitops-pods ClusterIP None 3306/TCP NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/mariadb-gitops kubedb.com/mariadb 11.8.5 22m -``` ## Update MariaDB Database using GitOps @@ -141,8 +143,9 @@ appbinding.appcatalog.appscode.com/mariadb-gitops kubedb.com/mariadb 11.8.5 Before scaling database resouces: -```shell -$ kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].resources' +```bash +kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1Gi" @@ -152,7 +155,6 @@ $ kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].res "memory": "1Gi" } } -``` Update the `MariaDB.yaml` with the following, ```yaml apiVersion: gitops.kubedb.com/v1alpha1 @@ -190,17 +192,18 @@ Resource Requests and Limits are updated to `600m` CPU and `1.2Gi` Memory. Commi Now, `gitops` operator will detect the resource changes and create a `MariaDBOpsRequest` to update the `MariaDB` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 39m NAME TYPE STATUS AGE mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 9m17s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "600m", @@ -211,7 +214,6 @@ $ kubectl get pod -n demo mariadb-gitops-0 -o json | jq '.spec.containers[0].res "memory": "1288490188800m" } } -``` ### Scale MariaDB Replicas Update the `MariaDB.yaml` with the following, @@ -250,25 +252,25 @@ Update the `replicas` to `5`. Commit the changes and push to your Git repository Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` MariaDBOpsRequest to update the `MariaDB` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 107m NAME TYPE STATUS AGE mariadbopsrequest.ops.kubedb.com/mariadb-gitops-horizontalscaling-m7iex7 HorizontalScaling Successful 63m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 76m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +``` NAME READY STATUS RESTARTS AGE mariadb-gitops-0 2/2 Running 0 76m mariadb-gitops-1 2/2 Running 0 75m mariadb-gitops-2 2/2 Running 0 73m mariadb-gitops-3 2/2 Running 0 63m mariadb-gitops-4 2/2 Running 0 62m -``` We can also scale down the replicas by updating the `replicas` fields. @@ -311,7 +313,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` MariaDBOpsRequest to update the `MariaDB` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 111m @@ -319,18 +322,17 @@ NAME TYPE mariadbopsrequest.ops.kubedb.com/mariadb-gitops-horizontalscaling-m7iex7 HorizontalScaling Successful 68m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 81m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 115s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mariadb-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-mariadb-gitops-0 Bound pvc-f1a49c53-d095-43a7-b62f-e91a5a9f5496 2Gi RWO longhorn 116m data-mariadb-gitops-1 Bound pvc-79d99636-e0d7-413f-a6a6-559e908ed817 2Gi RWO longhorn 116m data-mariadb-gitops-2 Bound pvc-f66ccf56-63b6-4ac6-a7f9-09f573466266 2Gi RWO longhorn 116m data-mariadb-gitops-3 Bound pvc-b7744652-611a-4c10-a06f-c93f030fb90f 2Gi RWO longhorn 72m data-mariadb-gitops-4 Bound pvc-dee1c10d-0456-4935-9306-0d86c3db54d0 2Gi RWO longhorn 71m -``` ## Reconfigure MariaDB @@ -353,12 +355,12 @@ type: Opaque Now, we will add this file to `kubedb/md-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── md-configuration.yaml │ └── mariadb.yaml 1 directories, 2 files -``` Update the `MariaDB.yaml` with the following, ```yaml @@ -399,7 +401,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` MariaDBOpsRequest to update the `MariaDB` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 17h @@ -408,7 +411,6 @@ mariadbopsrequest.ops.kubedb.com/mariadb-gitops-horizontalscaling-m7iex7 Horiz mariadbopsrequest.ops.kubedb.com/mariadb-gitops-reconfigure-1leaj8 Reconfigure Successful 17h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 19h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 18h -``` ### Rotate MariaDB Auth @@ -431,13 +433,13 @@ stringData: Let's add that to our `kubedb/md-auth.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── md-configuration.yaml │ ├── md-auth.yaml │ └── MariaDB.yaml 1 directories, 3 files -``` @@ -484,7 +486,8 @@ Change the `authSecret` field to `mdauth`. Commit the changes and push to your G Now, `gitops` operator will detect the auth changes and create a `RotateAuth` MariaDBOpsRequest to update the `MariaDB` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 18h @@ -494,7 +497,6 @@ mariadbopsrequest.ops.kubedb.com/mariadb-gitops-reconfigure-1leaj8 Recon mariadbopsrequest.ops.kubedb.com/mariadb-gitops-rotate-auth-1xy3d7 RotateAuth Successful 12m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 19h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 18h -``` ### TLS configuration @@ -506,17 +508,17 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls md-ca \ +kubectl create secret tls md-ca \ --cert=ca.crt \ --key=ca.key \ -n demo @@ -544,7 +546,8 @@ issuer.cert-manager.io/md-issuer created Let's add that to our `kubedb/md-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── md-configuration.yaml │ ├── md-auth.yaml @@ -552,7 +555,6 @@ $ tree . │ ├── md-issuer.yaml │ └── MariaDB.yaml 1 directories, 5 files -``` Update the `MariaDB.yaml` with the following, ```yaml @@ -611,7 +613,8 @@ Add `requireSSL` as `true` and `tls` fields in the spec. Commit the changes and Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` MariaDBOpsRequest to update the `MariaDB` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo + kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 11.8.5 Ready 18h @@ -622,7 +625,6 @@ mariadbopsrequest.ops.kubedb.com/mariadb-gitops-reconfiguretls-ftyfdq Recon mariadbopsrequest.ops.kubedb.com/mariadb-gitops-rotate-auth-1xy3d7 RotateAuth Successful 35m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 20h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 18h -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for MariaDB. @@ -690,7 +692,8 @@ Update the `version` field to `12.1.2`. Commit the changes and push to your Git Now, `gitops` operator will detect the version changes and create a `VersionUpdate` MariaDBOpsRequest to update the `MariaDB` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 12.1.2 Ready 18h @@ -702,19 +705,24 @@ mariadbopsrequest.ops.kubedb.com/mariadb-gitops-rotate-auth-1xy3d7 Rotat mariadbopsrequest.ops.kubedb.com/mariadb-gitops-versionupdate-ksli15 UpdateVersion Successful 10m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 20h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 19h -``` Now, we are going to verify whether the `MariaDB`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get MariaDB -n demo mariadb-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get MariaDB -n demo mariadb-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` 12.1.2 -$ kubectl get petset -n demo mariadb-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/mariadb:12.1.2-noble@sha256:843852d8651b3f321896a4a91f8118605d988d70703e520927c8d2c9313aded4 -$ kubectl get pod -n demo mariadb-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get petset -n demo mariadb-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/mariadb:12.1.2-noble@sha256:843852d8651b3f321896a4a91f8118605d988d70703e520927c8d2c9313aded4 + +```bash +kubectl get pod -n demo mariadb-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/mariadb:12.1.2-noble@sha256:843852d8651b3f321896a4a91f8118605d988d70703e520927c8d2c9313aded4 ### Enable Monitoring @@ -783,7 +791,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` MariaDBOpsRequest to add the `MariaDB` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get md,mariadbopsrequest -n demo +kubectl get md,mariadbopsrequest -n demo +``` NAME VERSION STATUS AGE mariadb.kubedb.com/mariadb-gitops 12.1.2 Ready 19h @@ -796,7 +805,6 @@ mariadbopsrequest.ops.kubedb.com/mariadb-gitops-rotate-auth-1xy3d7 Rotat mariadbopsrequest.ops.kubedb.com/mariadb-gitops-versionupdate-ksli15 UpdateVersion Successful 26m mariadbopsrequest.ops.kubedb.com/mariadb-gitops-verticalscaling-rjs268 VerticalScaling Successful 20h mariadbopsrequest.ops.kubedb.com/mariadb-gitops-volumeexpansion-01m39b VolumeExpansion Successful 19h -``` Verify the monitoring is enabled by checking the prometheus targets. diff --git a/docs/guides/mariadb/initialization/git-sync.md b/docs/guides/mariadb/initialization/git-sync.md index 80c1b8adf7..527f14e31a 100644 --- a/docs/guides/mariadb/initialization/git-sync.md +++ b/docs/guides/mariadb/initialization/git-sync.md @@ -25,9 +25,9 @@ In this example, we will initialize MariaDB using a `.sql` script from the GitHu To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## From Public Git Repository @@ -78,10 +78,10 @@ The `--link` argument creates a symlink that always points to the latest synced Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 5m -``` Next, we will connect to the MariaDB database and verify the data inserted from the `*.sql` script stored in the Git repository. @@ -132,7 +132,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -145,7 +145,7 @@ Use the `kubectl create secret` command to create a secret from your local SSH k This secret will be used by git-sync to authenticate with the Git repository. ```bash -$ kubectl create secret generic -n demo git-creds \ +kubectl create secret generic -n demo git-creds \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -198,7 +198,7 @@ First, create a `Personal Access Token (PAT)` on your Git host server with the r Then create a Kubernetes secret using the `Personal Access Token (PAT)`: ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -248,7 +248,13 @@ Once the database reaches the `Ready` state, you can verify the data using the m To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/mariadb/initialization/using-script/index.md b/docs/guides/mariadb/initialization/using-script/index.md index 8af5a7641d..11e2587424 100644 --- a/docs/guides/mariadb/initialization/using-script/index.md +++ b/docs/guides/mariadb/initialization/using-script/index.md @@ -27,10 +27,10 @@ In this tutorial we will use .sql script stored in GitHub repository [kubedb/mys - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo + ```bash + kubectl create ns demo + ``` namespace/demo created -``` ## Prepare Initialization Scripts @@ -43,10 +43,10 @@ At first, we will create a ConfigMap from `init.sql` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo md-init-script \ +kubectl create configmap -n demo md-init-script \ --from-literal=init.sql="$(curl -fsSL https://github.com/kubedb/mysql-init-scripts/raw/master/init.sql)" -configmap/md-init-script created ``` +configmap/md-init-script created ## Create a MariaDB database with Init-Script @@ -75,9 +75,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/initialization/using-script/example/demo-1.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/initialization/using-script/example/demo-1.yaml ``` +mariadb.kubedb.com/sample-mariadb created Here, @@ -123,9 +123,10 @@ KubeDB operator sets the `status.phase` to `Ready` once the database is successf Now, we will connect to this database and check the data inserted by the initlization script. -```bash # Connecting to the database -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +```bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 40 @@ -154,15 +155,16 @@ MariaDB [mysql]> select * from kubedb_table; MariaDB [mysql]> quit; Bye -``` - ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb +kubectl delete mariadb -n demo sample-mariadb +``` mariadb.kubedb.com "sample-mariadb" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/migration/databaseMigration.md b/docs/guides/mariadb/migration/databaseMigration.md index 5da40fbed6..7377e50931 100644 --- a/docs/guides/mariadb/migration/databaseMigration.md +++ b/docs/guides/mariadb/migration/databaseMigration.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` Migration to migrate an existing `M To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Source Database @@ -77,7 +77,7 @@ See the official [MariaDB Binary Log](https://mariadb.com/kb/en/binary-log/) doc ### Verify prerequisites ```bash -$ mysql -h .rds.amazonaws.com -u admin -p +mysql -h .rds.amazonaws.com -u admin -p ``` ```sql @@ -162,7 +162,7 @@ SELECT * FROM orders; First, create an authentication secret using the `migrator` user credentials: ```bash -$ kubectl create secret generic source-mariadb-auth -n demo \ +kubectl create secret generic source-mariadb-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=migrator \ --from-literal=password= @@ -230,9 +230,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/migration/target-mariadb.yaml -mariadb.kubedb.com/target-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/migration/target-mariadb.yaml ``` +mariadb.kubedb.com/target-mariadb created > Note: Adjust the `resources.requests.storage` based on the source database size. @@ -284,9 +284,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/migration/mariadb-migrate.yaml -migration.courier.kubedb.com/mariadb-migrate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/migration/mariadb-migrate.yaml ``` +migration.courier.kubedb.com/mariadb-migrate created Here we scope the migration to the `shop` database (`schema.database: [shop]`), enable both the bulk snapshot and CDC streaming phases, and cap connections at 100 on each side. For a full description of every field, see the [Migration CRD reference](/docs/guides/mariadb/concepts/migrator/). @@ -306,7 +306,7 @@ mariadb-migrate Running mariadb Streaming 0B 100% 4h36m Once the migration reaches the `Streaming` stage, exec into the KubeDB target pod and confirm all seed rows were copied over: ```bash -$ kubectl exec -it -n demo target-mariadb-0 -- mysql -u root -p +kubectl exec -it -n demo target-mariadb-0 -- mysql -u root -p ``` ```sql @@ -327,7 +327,7 @@ SELECT * FROM orders; With the migration still running, connect to the **source RDS** instance and run some DML: ```bash -$ mysql -h .rds.amazonaws.com -u migrator -p +mysql -h .rds.amazonaws.com -u migrator -p ``` ```sql @@ -366,8 +366,8 @@ Once the `LAG` drops to near zero, stop all writes to the source database. Wait Now delete the `Migration` CR to stop the migration process: ```bash -$ kubectl delete migration -n demo mariadb-migrate -migration.courier.kubedb.com "mariadb-migrate" deleted +kubectl delete migration -n demo mariadb-migrate ``` +migration.courier.kubedb.com "mariadb-migrate" deleted Finally, update your application's connection string to point to the target KubeDB-managed `MariaDB` database. The migration is complete. diff --git a/docs/guides/mariadb/monitoring/builtin-prometheus/index.md b/docs/guides/mariadb/monitoring/builtin-prometheus/index.md index d0babe67ca..c27e4bde01 100644 --- a/docs/guides/mariadb/monitoring/builtin-prometheus/index.md +++ b/docs/guides/mariadb/monitoring/builtin-prometheus/index.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor MariaDB database using builtin [Prome - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mariadb/monitoring/builtin-prometheus/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/builtin-prometheus/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the MariaDB crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/builtin-prometheus/examples/builtin-prom-md.yaml -mariadb.kubedb.com/builtin-prom-md created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/builtin-prometheus/examples/builtin-prom-md.yaml ``` +mariadb.kubedb.com/builtin-prom-md created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get mariadb -n demo builtin-prom-md +kubectl get mariadb -n demo builtin-prom-md +``` NAME VERSION STATUS AGE builtin-prom-md 11.8.5 Ready 76s -``` KubeDB will create a separate stats service with name `{MariaDB crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-md" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-md" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-md ClusterIP 10.106.32.194 3306/TCP 2m3s builtin-prom-md-pods ClusterIP None 3306/TCP 2m3s builtin-prom-md-stats ClusterIP 10.109.106.92 56790/TCP 2m2s -``` Here, `builtin-prom-md-stats ` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-md-stats +kubectl describe svc -n demo builtin-prom-md-stats +``` Name: builtin-prom-md-stats Namespace: demo Labels: app.kubernetes.io/instance=builtin-prom-md @@ -113,7 +116,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.34:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -277,20 +279,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/builtin-prometheus/examples/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/builtin-prometheus/examples/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -301,9 +303,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -312,18 +314,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-5dff66b455-cz9td 1/1 Running 0 42s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-md-stats` service as one of the targets. diff --git a/docs/guides/mariadb/monitoring/prometheus-operator/index.md b/docs/guides/mariadb/monitoring/prometheus-operator/index.md index 226b660691..a0b7fdcd7d 100644 --- a/docs/guides/mariadb/monitoring/prometheus-operator/index.md +++ b/docs/guides/mariadb/monitoring/prometheus-operator/index.md @@ -25,9 +25,9 @@ section_menu_id: guides - To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -42,10 +42,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE default prometheus 1 2m19s -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -94,9 +94,9 @@ KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add l Let's add label `prometheus: prometheus` to `demo` namespace, ```bash -$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' -namespace/demo patched +kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' ``` +namespace/demo patched ## Deploy MariaDB with Monitoring Enabled @@ -138,27 +138,27 @@ Here, Let's create the MariaDB object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/prometheus-operator/examples/prom-operator-md.yaml -mariadb.kubedb.com/coreos-prom-md created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/monitoring/prometheus-operator/examples/prom-operator-md.yaml ``` +mariadb.kubedb.com/coreos-prom-md created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get mariadb -n demo coreos-prom-md +kubectl get mariadb -n demo coreos-prom-md +``` NAME VERSION STATUS AGE coreos-prom-md 10.5.23 Ready 59s -``` KubeDB will create a separate stats service with name `{MariaDB crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-md" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-md" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-md ClusterIP 10.99.96.226 3306/TCP 107s coreos-prom-md-pods ClusterIP None 3306/TCP 107s coreos-prom-md-stats ClusterIP 10.101.190.67 56790/TCP 107s -``` Here, `coreos-prom-md-stats` service has been created for monitoring purpose. @@ -188,10 +188,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-md-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-md-stats 4m8s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of MariaDB crd. @@ -278,20 +278,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n default -l=app=prometheus +kubectl get pod -n default -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 16m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n default prometheus-prometheus-0 9090 +kubectl port-forward -n default prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-md-stats` service as one of the targets. diff --git a/docs/guides/mariadb/pitr/nfs/index.md b/docs/guides/mariadb/pitr/nfs/index.md index 62c8d3d47a..3f81ca3e3b 100644 --- a/docs/guides/mariadb/pitr/nfs/index.md +++ b/docs/guides/mariadb/pitr/nfs/index.md @@ -29,9 +29,9 @@ To install `External-snapshotter` in your cluster following the steps [here](ht To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mariadb/pitr/nfs/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/remote-replica/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## continuous archiving @@ -40,11 +40,10 @@ Continuous archiving involves making regular copies (or "archives") of the Maria ## Ensure volumeSnapshotClass ```bash -$ kubectl get volumesnapshotclasses +kubectl get volumesnapshotclasses +``` NAME DRIVER DELETIONPOLICY AGE longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h - -``` If not any, try using `longhorn` or any other [volumeSnapshotClass](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/). ### Install Longhorn Longhorn is a distributed block storage system for Kubernetes that manages persistent storage. @@ -81,9 +80,9 @@ parameters: ``` ```bash -$ kubectl apply -f volumesnapshotclass.yaml - volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged +kubectl apply -f volumesnapshotclass.yaml ``` + volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged ### Install CSI driver for NFS Install CSI driver for creating nfs volume from [here](https://github.com/kubernetes-csi/csi-driver-nfs/tree/master/charts). @@ -229,15 +228,15 @@ spec: fsGroup: 999 runAsUser: 999 ``` -```bash - $ kubectl apply -f nfs-pvc.yaml + ```bash + kubectl apply -f nfs-pvc.yaml + ``` persistentvolumeclaim/nfs-pvc created -``` -```bash - $ kubectl apply -f backupstorage.yaml + ```bash + kubectl apply -f backupstorage.yaml + ``` backupstorage.storage.kubestash.com/linode-storage created -``` ### Retention policy RetentionPolicy is a custom resource(CR) provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -256,9 +255,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/retentionPolicy.yaml -retentionpolicy.storage.kubestash.com/mariadb-retention-policy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/retentionPolicy.yaml ``` +retentionpolicy.storage.kubestash.com/mariadb-retention-policy created ### EncryptionSecret ```yaml @@ -272,8 +271,7 @@ stringData: RESTIC_PASSWORD: "changeit" ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/encryptionSecret.yaml - +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/encryptionSecret.yaml ``` ### MariaDBArchiver @@ -336,10 +334,10 @@ spec: -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/mariadbarchiver.yaml - mariadbarchiver.archiver.kubedb.com/mariadbarchiver-sample created + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/nfs/yamls/mariadbarchiver.yaml ``` + mariadbarchiver.archiver.kubedb.com/mariadbarchiver-sample created @@ -382,7 +380,8 @@ spec: ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mariadb-0 2/2 Running 0 4m12s mariadb-1 2/2 Running 0 4m12s @@ -392,7 +391,6 @@ mariadb-backup-manifest-backup-1726549703-fx9kx 0/1 Comple mariadb-sidekick 1/1 Running retention-policy-mariadb-backup-full-backup-1726549703-wg7wt 0/1 Completed 0 3m42s retention-policy-mariadb-backup-manifest-backup-17265497038pvjd 0/1 Completed 0 3m55s -``` `mariadb-sidekick` is responsible for uploading binlog files @@ -403,13 +401,14 @@ retention-policy-mariadb-backup-manifest-backup-17265497038pvjd 0/1 Comple ### validate BackupConfiguration and VolumeSnapshots ```bash - -$ kubectl get backupconfigurations -n demo - +kubectl get backupconfigurations -n demo +``` NAME PHASE PAUSED AGE mariadb-backup Ready 2m43s -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mariadb-backup-full-backup-1726549703 BackupConfiguration mariadb-backup Succeeded 33s 11m mariadb-backup-manifest-backup-1726549703 BackupConfiguration mariadb-backup Succeeded 20s 11m @@ -417,14 +416,13 @@ mariadb-backup-manifest-backup-1726549703 BackupConfiguration mariadb-bac kubectl get volumesnapshots -n demo NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE mariadb-1726549985 true data-mariadb-0 10Gi longhorn-snapshot-vsc snapcontent-317aaac9-ae4f-438b-9763-4eb81ff828af 11m 11m -``` ## Data Insert and Switch Binlog File After each and every binlog switch the binlog files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> create database hello; @@ -465,8 +463,6 @@ MariaDB [hello]> select count(*) from demo_table; | 10 | +----------+ -``` - > At this point We have 10 rows in our newly created table `demo_table` on database `hello` ## Point-in-time Recovery @@ -474,13 +470,11 @@ Point-In-Time Recovery allows you to restore a MariaDB database to a specific po Let's say accidentally our dba drops the table demo_table and we want to restore. ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` MariaDB [hello]> drop table demo_table; MariaDB [hello]> flush logs; - -``` We can't restore from a full backup since at this point no full backup was perform. so we can choose a specific time in which time we want to restore.We can get the specfice time from the binlog that archived in the backup storage . Go to the binlog file and find where to store. You can parse binlog-files using `mariadbbinlog`. @@ -534,33 +528,33 @@ spec: ``` ```bash -$ kubectl apply -f mariadbrestore.yaml -mariadb.kubedb.com/restore-mariadb created +kubectl apply -f mariadbrestore.yaml ``` +mariadb.kubedb.com/restore-mariadb created **check for Restored MariaDB** ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` restore-mariadb-0 1/1 Running 0 44s restore-mariadb-1 1/1 Running 0 42s restore-mariadb-2 1/1 Running 0 41s restore-mariadb-restorer-z4brz 0/2 Completed 0 113s restore-mariadb-restoresession-lk6jq 0/1 Completed 0 2m6s -``` - ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE mariadb 11.1.3 Ready 14m restore-mariadb 11.1.3 Ready 5m37s -``` **Validating data on Restored MariaDB** ```bash -$ kubectl exec -it -n demo restore-mariadb-0 -- bash +kubectl exec -it -n demo restore-mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD mariadb> use hello @@ -573,8 +567,6 @@ MariaDB [hello]> select count(*) from demo_table; +----------+ 1 row in set (0.00 sec) -``` - **so we are able to successfully recover from a disaster** ## Cleaning up @@ -582,11 +574,23 @@ MariaDB [hello]> select count(*) from demo_table; To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo mariadb/mariadb -$ kubectl delete -n demo mariadb/restore-mariadb -$ kubectl delete -n demo backupstorage -$ kubectl delete -n demo mariadbarchiver -$ kubectl delete ns demo +kubectl delete -n demo mariadb/mariadb +``` + +```bash +kubectl delete -n demo mariadb/restore-mariadb +``` + +```bash +kubectl delete -n demo backupstorage +``` + +```bash +kubectl delete -n demo mariadbarchiver +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mariadb/pitr/overview/index.md b/docs/guides/mariadb/pitr/overview/index.md index 4a53d1e9aa..ef14b94b68 100644 --- a/docs/guides/mariadb/pitr/overview/index.md +++ b/docs/guides/mariadb/pitr/overview/index.md @@ -29,9 +29,9 @@ To install `External-snapshotter` in your cluster following the steps [here](ht To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mariadb/pitr/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/remote-replica/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## continuous archiving @@ -63,10 +63,10 @@ spec: deletionPolicy: WipeOut ``` -```bash - $ kubectl apply -f backupstorage.yaml + ```bash + kubectl apply -f backupstorage.yaml + ``` backupstorage.storage.kubestash.com/linode-storage created -``` ### secrets for backup-storage ```yaml @@ -82,10 +82,10 @@ stringData: AWS_ENDPOINT: https://ap-south-1.linodeobjects.com ``` -```bash - $ kubectl apply -f storage-secret.yaml + ```bash + kubectl apply -f storage-secret.yaml + ``` secret/storage created -``` ### Retention policy RetentionPolicy is a custom resource(CR) provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -104,9 +104,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/retention-policy.yaml -retentionpolicy.storage.kubestash.com/mariadb-retention-policy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/retention-policy.yaml ``` +retentionpolicy.storage.kubestash.com/mariadb-retention-policy created ### MariaDBArchiver MariaDBArchiver is a custom resource(CR) provided by KubeDB for managing the archiving of MariaDB binlog files and performing volume-level backups @@ -170,20 +170,22 @@ stringData: RESTIC_PASSWORD: "changeit" ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/mariadbarchiver.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/mariadbarchiver.yaml + ``` mariadbarchiver.archiver.kubedb.com/mariadbarchiver-sample created - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/encryptionSecret.yaml -``` + + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/pitr/overview/yamls/encryptionSecret.yaml + ``` ## Ensure volumeSnapshotClass ```bash -$ kubectl get volumesnapshotclasses +kubectl get volumesnapshotclasses +``` NAME DRIVER DELETIONPOLICY AGE longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h - -``` If not any, try using `longhorn` or any other [volumeSnapshotClass](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/). ```yaml kind: VolumeSnapshotClass @@ -198,11 +200,13 @@ parameters: ``` ```bash -$ helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +``` -$ kubectl apply -f volumesnapshotclass.yaml - volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged +```bash +kubectl apply -f volumesnapshotclass.yaml ``` + volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged # Deploy MariaDB So far we are ready with setup for continuously archive MariaDB, We deploy a mariadb referring the MariaDB archiver object.To properly configure MariaDB for archiving, you need to pass specific arguments to the MariaDB container in the `spec.podTemplate.containers["mariadb"].args` field. Below is an example of a YAML configuration for a MariaDB instance managed by KubeDB, with archiving enabled. @@ -243,7 +247,8 @@ spec: ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mariadb-0 2/2 Running 0 4m12s mariadb-1 2/2 Running 0 4m12s @@ -253,7 +258,6 @@ mariadb-backup-manifest-backup-1726549703-fx9kx 0/1 Comple mariadb-sidekick 1/1 Running retention-policy-mariadb-backup-full-backup-1726549703-wg7wt 0/1 Completed 0 3m42s retention-policy-mariadb-backup-manifest-backup-17265497038pvjd 0/1 Completed 0 3m55s -``` `mariadb-sidekick` is responsible for uploading binlog files @@ -264,13 +268,14 @@ retention-policy-mariadb-backup-manifest-backup-17265497038pvjd 0/1 Comple ### validate BackupConfiguration and VolumeSnapshots ```bash - -$ kubectl get backupconfigurations -n demo - +kubectl get backupconfigurations -n demo +``` NAME PHASE PAUSED AGE mariadb-backup Ready 2m43s -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mariadb-backup-full-backup-1726549703 BackupConfiguration mariadb-backup Succeeded 33s 11m mariadb-backup-manifest-backup-1726549703 BackupConfiguration mariadb-backup Succeeded 20s 11m @@ -278,14 +283,13 @@ mariadb-backup-manifest-backup-1726549703 BackupConfiguration mariadb-bac kubectl get volumesnapshots -n demo NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE mariadb-1726549985 true data-mariadb-0 10Gi longhorn-snapshot-vsc snapcontent-317aaac9-ae4f-438b-9763-4eb81ff828af 11m 11m -``` ## Data Insert and Switch Binlog File After each and every binlog switch the binlog files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD MariaDB> create database hello; @@ -326,8 +330,6 @@ MariaDB [hello]> select count(*) from demo_table; | 10 | +----------+ -``` - > At this point We have 10 rows in our newly created table `demo_table` on database `hello` ## Point-in-time Recovery @@ -335,13 +337,11 @@ Point-In-Time Recovery allows you to restore a MariaDB database to a specific po Let's say accidentally our dba drops the table demo_table and we want to restore. ```bash -$ kubectl exec -it -n demo mariadb-0 -- bash - +kubectl exec -it -n demo mariadb-0 -- bash +``` MariaDB [hello]> drop table demo_table; MariaDB [hello]> flush logs; - -``` We can't restore from a full backup since at this point no full backup was perform. so we can choose a specific time in which time we want to restore.We can get the specfice time from the binlog that archived in the backup storage . Go to the binlog file and find where to store. You can parse binlog-files using `mariadbbinlog`. @@ -395,33 +395,33 @@ spec: ``` ```bash -$ kubectl apply -f mariadbrestore.yaml -mariadb.kubedb.com/restore-mariadb created +kubectl apply -f mariadbrestore.yaml ``` +mariadb.kubedb.com/restore-mariadb created **check for Restored MariaDB** ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` restore-mariadb-0 1/1 Running 0 44s restore-mariadb-1 1/1 Running 0 42s restore-mariadb-2 1/1 Running 0 41s restore-mariadb-restorer-z4brz 0/2 Completed 0 113s restore-mariadb-restoresession-lk6jq 0/1 Completed 0 2m6s -``` - ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE mariadb 11.1.3 Ready 14m restore-mariadb 11.1.3 Ready 5m37s -``` **Validating data on Restored MariaDB** ```bash -$ kubectl exec -it -n demo restore-mariadb-0 -- bash +kubectl exec -it -n demo restore-mariadb-0 -- bash +``` bash-4.4$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD mariadb> use hello @@ -434,8 +434,6 @@ MariaDB [hello]> select count(*) from demo_table; +----------+ 1 row in set (0.00 sec) -``` - **so we are able to successfully recover from a disaster** ## Cleaning up @@ -443,11 +441,23 @@ MariaDB [hello]> select count(*) from demo_table; To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo mariadb/mariadb -$ kubectl delete -n demo mariadb/restore-mariadb -$ kubectl delete -n demo backupstorage -$ kubectl delete -n demo mariadbarchiver -$ kubectl delete ns demo +kubectl delete -n demo mariadb/mariadb +``` + +```bash +kubectl delete -n demo mariadb/restore-mariadb +``` + +```bash +kubectl delete -n demo backupstorage +``` + +```bash +kubectl delete -n demo mariadbarchiver +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mariadb/private-registry/quickstart/index.md b/docs/guides/mariadb/private-registry/quickstart/index.md index 0017ce57df..b7353dd937 100644 --- a/docs/guides/mariadb/private-registry/quickstart/index.md +++ b/docs/guides/mariadb/private-registry/quickstart/index.md @@ -27,7 +27,8 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/u/kubedb) into your private registry. For mariadb, push `DB_IMAGE`, `EXPORTER_IMAGE`, `INITCONTAINER_IMAGE` of following MariaDBVersions, where `deprecated` is not true, to your private registry. ```bash -$ kubectl get mariadbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +kubectl get mariadbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +``` NAME VERSION DB_IMAGE EXPORTER_IMAGE INITCONTAINER_IMAGE DEPRECATED 10.10.7 10.10.7 ghcr.io/appscode-images/mariadb:10.10.7-jammy docker.io/prom/mysqld-exporter:v0.18.0 ghcr.io/kubedb/mariadb-init:0.8.0 10.11.6 10.11.6 ghcr.io/appscode-images/mariadb:10.11.6-jammy docker.io/prom/mysqld-exporter:v0.18.0 ghcr.io/kubedb/mariadb-init:0.8.0 @@ -43,7 +44,6 @@ NAME VERSION DB_IMAGE EXPORTER_IMA 11.6.2 11.6.2 ghcr.io/appscode-images/mariadb:11.6.2-noble docker.io/prom/mysqld-exporter:v0.18.0 ghcr.io/kubedb/mariadb-init:0.8.0 11.8.5 11.8.5 ghcr.io/appscode-images/mariadb:11.8.5-noble docker.io/prom/mysqld-exporter:v0.18.0 ghcr.io/kubedb/mariadb-init:0.8.0 12.1.2 12.1.2 ghcr.io/appscode-images/mariadb:12.1.2-noble docker.io/prom/mysqld-exporter:v0.18.0 ghcr.io/kubedb/mariadb-init:0.8.0 -``` Docker hub repositories: @@ -79,9 +79,9 @@ Docker hub repositories: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - ``` ## Create ImagePullSecret @@ -90,13 +90,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -136,25 +136,28 @@ spec: Now run the command to deploy this `MariaDB` object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/private-registry/quickstart/examples/demo.yaml -mariadb.kubedb.com/md-pvt-reg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/private-registry/quickstart/examples/demo.yaml ``` +mariadb.kubedb.com/md-pvt-reg created To check if the images pulled successfully from the repository, see if the `MariaDB` is in running state: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE md-pvt-reg-0 1/1 Running 0 56s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo md-pvt-reg +kubectl delete mariadb -n demo md-pvt-reg +``` mariadb.kubedb.com "md-pvt-reg" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/mariadb/quickstart/overview/index.md b/docs/guides/mariadb/quickstart/overview/index.md index f2a3ec03ee..3adb7e2202 100644 --- a/docs/guides/mariadb/quickstart/overview/index.md +++ b/docs/guides/mariadb/quickstart/overview/index.md @@ -31,10 +31,10 @@ This tutorial will show you how to use KubeDB to run a MariaDB database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash -$ kubectl get storageclasses +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m -``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. @@ -48,7 +48,8 @@ namespace/demo created When you have installed KubeDB, it has created `MariaDBVersion` crd for all supported MariaDB versions. Check it by using the following command, ```bash -$ kubectl get mariadbversions +kubectl get mariadbversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 10.10.7 10.10.7 ghcr.io/appscode-images/mariadb:10.10.7-jammy 12d 10.11.6 10.11.6 ghcr.io/appscode-images/mariadb:10.11.6-jammy 12d @@ -70,8 +71,6 @@ NAME VERSION DB_IMAGE DEPRECATED KubeDB implements a `MariaDB` CRD to define the specification of a MariaDB database. Below is the `MariaDB` object created in this tutorial. `Note`: If your `KubeDB version` is less or equal to `v2024.6.4`, You have to use `v1alpha2` apiVersion. - -```yaml apiVersion: kubedb.com/v1 kind: MariaDB metadata: diff --git a/docs/guides/mariadb/reconfigure-tls/cluster/index.md b/docs/guides/mariadb/reconfigure-tls/cluster/index.md index 7f2665bec3..62f12cfc13 100644 --- a/docs/guides/mariadb/reconfigure-tls/cluster/index.md +++ b/docs/guides/mariadb/reconfigure-tls/cluster/index.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Add TLS to a MariaDB Cluster @@ -63,26 +63,31 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 9m17s -``` ```bash -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d +``` U6(h_pYrekLZ2OOd -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +```bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 108 @@ -109,8 +114,6 @@ MariaDB [(none)]> show variables like '%ssl%'; +---------------------+-----------------------------+ 10 rows in set (0.001 sec) -``` - We can verify from the above output that TLS is disabled for this database. ### Create Issuer/ ClusterIssuer @@ -120,12 +123,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -199,19 +202,19 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-add-tls.yaml -mariadbopsrequest.ops.kubedb.com/mdops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-add-tls.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CRO, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-add-tls ReconfigureTLS Successful 6m6s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. @@ -220,7 +223,8 @@ Now, we are going to connect to the database for verifying the `MariaDB` server Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ ls /etc/mysql/certs/client ca.crt tls.crt tls.key root@sample-mariadb-0:/ ls /etc/mysql/certs/server @@ -261,7 +265,6 @@ MariaDB [(none)]> show variables like '%require_secure_transport%'; MariaDB [(none)]> quit; Bye -``` We can see from the above output that, `have_ssl` is set to `ture`. So, database TLS is enabled successfully to this database. @@ -272,12 +275,12 @@ We can see from the above output that, `have_ssl` is set to `ture`. So, 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 exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ apt update root@sample-mariadb-0:/ apt install openssl root@sample-mariadb-0:/ openssl x509 -in /etc/mysql/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Apr 13 05:18:43 2022 GMT -``` So, the certificate will expire on this time `Apr 13 05:18:43 2022 GMT`. @@ -308,29 +311,29 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-rotate-tls.yaml -mariadbopsrequest.ops.kubedb.com/mdops-rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-rotate-tls.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-rotate-tls created #### Verify Certificate Rotated Successfully Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CRO, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-rotate-tls ReconfigureTLS Successful 3m -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ apt update root@sample-mariadb-0:/ apt install openssl root@sample-mariadb-0:/# openssl x509 -in /etc/mysql/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Apr 13 06:04:50 2022 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -340,7 +343,8 @@ Now, we are going to update the server certificate. - Let's describe the server certificate `sample-mariadb-server-cert` ```bash -$ kubectl describe certificate -n demo sample-mariadb-server-cert +kubectl describe certificate -n demo sample-mariadb-server-cert +``` Name: sample-mariadb-server-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -409,7 +413,6 @@ Events: Normal Requested 19m cert-manager Created new CertificateRequest resource "sample-mariadb-server-cert-p5287" Normal Reused 19m (x5 over 22m) cert-manager Reusing private key stored in existing Secret resource "sample-mariadb-server-cert" Normal Issuing 19m (x6 over 65m) cert-manager The certificate has been successfully issued -``` We want to add `subject` and `emailAddresses` in the spec of server sertificate. @@ -448,34 +451,33 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-update-tls.yaml -mariadbopsrequest.ops.kubedb.com/mdops-update-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-update-tls.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-update-tls created #### Verify certificate is updated successfully Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CRO, ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdops-update-tls ReconfigureTLS Successful 7m -``` - We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ apt update root@sample-mariadb-0:/ apt install openssl root@sample-mariadb-0:/ openssl x509 -in /etc/mysql/certs/server/tls.crt -inform PEM -subject -email -nameopt RFC2253 -noout subject=CN=sample-mariadb.demo.svc,O=kubedb:server kubedb@appscode.com -``` We can see from the above output that, the subject name and email address match with the new ca certificate that we have created. So, the issuer is changed successfully. @@ -510,26 +512,27 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-remove-tls.yaml -mariadbopsrequest.ops.kubedb.com/mdops-remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure-tls/cluster/examples/mdops-remove-tls.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-remove-tls created #### Verify TLS Removed Successfully Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CRO, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-remove-tls ReconfigureTLS Successful 6m27s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed. Now, Let's exec into the database and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 108 @@ -556,8 +559,6 @@ MariaDB [(none)]> show variables like '%ssl%'; +---------------------+-----------------------------+ 10 rows in set (0.001 sec) -``` - So, we can see from the above that, output that tls is disabled successfully. ## Cleaning up @@ -565,8 +566,17 @@ So, we can see from the above that, output that tls is disabled successfully. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo --all -$ kubectl delete issuer -n demo --all -$ kubectl delete mariadbopsrequest -n demo --all -$ kubectl delete ns demo +kubectl delete mariadb -n demo --all +``` + +```bash +kubectl delete issuer -n demo --all +``` + +```bash +kubectl delete mariadbopsrequest -n demo --all +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mariadb/reconfigure/cluster/index.md b/docs/guides/mariadb/reconfigure/cluster/index.md index b3bcc1d594..9d180ca76f 100644 --- a/docs/guides/mariadb/reconfigure/cluster/index.md +++ b/docs/guides/mariadb/reconfigure/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `MariaDB` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `MariaDBOpsRequest` to reconfigure its configuration. @@ -57,9 +57,9 @@ Here, `max_connections` is set to `200`, whereas the default value is `151`. Lik Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf -secret/md-configuration created +kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf ``` +secret/md-configuration created In this section, we are going to create a MariaDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MariaDB` CR that we are going to create, @@ -88,34 +88,37 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/sample-mariadb-config.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/sample-mariadb-config.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 71s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mariadb instance, ```bash -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -145,7 +148,6 @@ MariaDB [(none)]> show variables like 'read_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration of ready mariadb, the value of `max_connections` has been set to `200` and `read_buffer_size` has been set to `1048576`. @@ -165,9 +167,9 @@ read_buffer_size = 122880 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-md-configuration --from-file=./new-md-config.cnf -secret/new-md-configuration created +kubectl create secret generic -n demo new-md-configuration --from-file=./new-md-config.cnf ``` +secret/new-md-configuration created #### Create MariaDBOpsRequest @@ -197,9 +199,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/reconfigure-using-secret.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/reconfigure-using-secret.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-config created #### Verify the new configuration is working @@ -208,15 +210,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configura Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-reconfigure-config Reconfigure Successful 3m8s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-reconfigure-config +kubectl describe mariadbopsrequest -n demo mdops-reconfigure-config +``` Name: mdops-reconfigure-config Namespace: demo Labels: @@ -264,12 +267,11 @@ Status: Observed Generation: 3 Phase: Successful -``` - Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -299,7 +301,6 @@ MariaDB [(none)]> show variables like 'read_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration has changed, the value of `max_connections` has been changed from `200` to `250` and and the `read_buffer_size` has been changed `1048576` to `122880`. So the reconfiguration of the database is successful. @@ -338,7 +339,8 @@ Here, Before applying this yaml we are going to check the existing value of our new field, ```bash -$ kubectl exec -it sample-mariadb-0 -n demo -c mariadb -- bash +kubectl exec -it sample-mariadb-0 -n demo -c mariadb -- bash +``` root@sample-mariadb-0:/# mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -358,15 +360,14 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` Here, we can see the default value for `innodb_log_buffer_size` is `16777216`. Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/mdops-reconfigure-apply-config.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/mdops-reconfigure-apply-config.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-apply-config created #### Verify the new configuration is working @@ -376,15 +377,16 @@ If everything goes well, `KubeDB` operator will update the `configuration.secre Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest mdops-reconfigure-apply-config -n demo +kubectl get mariadbopsrequest mdops-reconfigure-apply-config -n demo +``` NAME TYPE STATUS AGE mdops-reconfigure-apply-config Reconfigure Successful 4m59s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-reconfigure-apply-config +kubectl describe mariadbopsrequest -n demo mdops-reconfigure-apply-config +``` Name: mdops-reconfigure-apply-config Namespace: demo Labels: @@ -443,12 +445,12 @@ Status: Type: Successful Observed Generation: 3 Phase: Successful -``` Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -487,7 +489,6 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from above the configuration has been changed, the value of `max_connections` has been changed from `250` to `230` and the `read_buffer_size` has been changed `122880` to `1064960` also, `innodb_log_buffer_size` has been changed from `16777216` to `17408000`. So the reconfiguration of the `sample-mariadb` database is successful. @@ -523,9 +524,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/reconfigure-remove.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/cluster/examples/reconfigure-remove.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-remove created #### Verify the new configuration is working @@ -534,15 +535,16 @@ If everything goes well, `KubeDB` operator will update the `configuration.secre Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-reconfigure-remove Reconfigure Successful 2m1s -``` Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 23 @@ -581,7 +583,6 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `MariaDBOpsRequest` is successful. @@ -590,7 +591,13 @@ As we can see from the configuration has changed to its default value. So remova To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo mdops-reconfigure-config mdops-reconfigure-apply-config mdops-reconfigure-remove -$ kubectl delete ns demo +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-reconfigure-config mdops-reconfigure-apply-config mdops-reconfigure-remove +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mariadb/reconfigure/standalone/index.md b/docs/guides/mariadb/reconfigure/standalone/index.md index 8a8d3411c3..bf686ad880 100644 --- a/docs/guides/mariadb/reconfigure/standalone/index.md +++ b/docs/guides/mariadb/reconfigure/standalone/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `MariaDB` Standalone using a supported version by `KubeDB` operator. Then we are going to apply `MariaDBOpsRequest` to reconfigure its configuration. @@ -56,9 +56,9 @@ Here, `max_connections` is set to `200`, whereas the default value is `151`. Lik Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf -secret/md-configuration created +kubectl create secret generic -n demo md-configuration --from-file=./md-config.cnf ``` +secret/md-configuration created In this section, we are going to create a MariaDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MariaDB` CR that we are going to create, @@ -86,34 +86,37 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/sample-mariadb-config.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/sample-mariadb-config.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 61s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mariadb instance, ```bash -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d -PlWA6JNLkNFudl4I +```bash +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d ``` +PlWA6JNLkNFudl4I Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/# mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 11 @@ -141,7 +144,6 @@ MariaDB [(none)]> show variables like 'read_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration of ready mariadb, the value of `max_connections` has been set to `200` and `read_buffer_size` has been set to `1048576`. @@ -161,9 +163,9 @@ read_buffer_size = 122880 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-md-configuration --from-file=./new-md-config.cnf -secret/new-md-configuration created +kubectl create secret generic -n demo new-md-configuration --from-file=./new-md-config.cnf ``` +secret/new-md-configuration created #### Create MariaDBOpsRequest @@ -193,9 +195,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/reconfigure-using-secret.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/reconfigure-using-secret.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-config created #### Verify the new configuration is working @@ -204,15 +206,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-reconfigure-config Reconfigure Successful 2m8s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-reconfigure-config +kubectl describe mariadbopsrequest -n demo mdops-reconfigure-config +``` Name: mdops-reconfigure-config Namespace: demo Labels: @@ -259,12 +262,12 @@ Status: Type: Successful Observed Generation: 3 Phase: Successful -``` Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/# mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 21 @@ -292,7 +295,6 @@ MariaDB [(none)]> show variables like 'read_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration has changed, the value of `max_connections` has been changed from `200` to `250` and and the `read_buffer_size` has been changed `1048576` to `122880`. So the reconfiguration of the database is successful. @@ -331,7 +333,8 @@ Here, Before applying this yaml we are going to check the existing value of our new field, ```bash -$ kubectl exec -it sample-mariadb-0 -n demo -c mariadb -- bash +kubectl exec -it sample-mariadb-0 -n demo -c mariadb -- bash +``` root@sample-mariadb-0:/# mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 21 @@ -351,15 +354,14 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` Here, we can see the default value for `innodb_log_buffer_size` is `16777216`. Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/mdops-reconfigure-apply-config.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/mdops-reconfigure-apply-config.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-apply-config created #### Verify the new configuration is working @@ -369,15 +371,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest mdops-reconfigure-apply-config -n demo +kubectl get mariadbopsrequest mdops-reconfigure-apply-config -n demo +``` NAME TYPE STATUS AGE mdops-reconfigure-apply-config Reconfigure Successful 3m11s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mariadbopsrequest -n demo mdops-reconfigure-apply-config +kubectl describe mariadbopsrequest -n demo mdops-reconfigure-apply-config +``` Name: mdops-reconfigure-apply-config Namespace: demo Labels: @@ -436,12 +439,12 @@ Status: Type: Successful Observed Generation: 3 Phase: Successful -``` Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/# mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 24 @@ -477,7 +480,6 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from above the configuration has been changed, the value of `max_connections` has been changed from `250` to `230` and the `read_buffer_size` has been changed `122880` to `1064960` also, `innodb_log_buffer_size` has been changed from `16777216` to `17408000`. So the reconfiguration of the `sample-mariadb` database is successful. @@ -514,9 +516,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/reconfigure-remove.yaml -mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/reconfigure/standalone/examples/reconfigure-remove.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-reconfigure-remove created #### Verify the new configuration is working @@ -525,15 +527,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest --all-namespaces +kubectl get mariadbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo mdops-reconfigure-remove Reconfigure Successful 2m5s -``` Now let's connect to a mariadb instance and run a mariadb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -- bash +kubectl exec -it -n demo sample-mariadb-0 -- bash +``` root@sample-mariadb-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 8 @@ -572,7 +575,6 @@ MariaDB [(none)]> show variables like 'innodb_log_buffer_size'; MariaDB [(none)]> exit Bye -``` As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `MariaDBOpsRequest` is successful. @@ -581,7 +583,13 @@ As we can see from the configuration has changed to its default value. So remova To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo mdops-reconfigure-config mdops-reconfigure-apply-config mdops-reconfigure-remove -$ kubectl delete ns demo +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-reconfigure-config mdops-reconfigure-apply-config mdops-reconfigure-remove +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/mariadb/restart/restart.md b/docs/guides/mariadb/restart/restart.md index 7215e17406..6a3946e5e9 100644 --- a/docs/guides/mariadb/restart/restart.md +++ b/docs/guides/mariadb/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the MariaDB database via a `MariaDBOpsRequest`. Resta - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo + ```bash + kubectl create ns demo + ``` namespace/demo created -``` > Note: YAML files used in this tutorial are stored in [docs/examples/MariaDB](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mariadb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -57,9 +57,9 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/restart/MariaDB.yaml -MariaDB.kubedb.com/mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/restart/MariaDB.yaml ``` +MariaDB.kubedb.com/mariadb created ## Apply Restart opsRequest @@ -89,19 +89,21 @@ Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/restart/ops.yaml -MariaDBopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/restart/ops.yaml ``` +MariaDBopsrequest.ops.kubedb.com/restart created In `MariaDB`, all pods act as primary, so the Ops-manager operator will restart the pods one by one in sequence. -```shell -$ kubectl get mariaops -n demo restart +```bash +kubectl get mariaops -n demo restart +``` NAME TYPE STATUS AGE restart Restart Successful 3m25s - -$ kubectl get mariaops -n demo restart -oyaml +```bash +kubectl get mariaops -n demo restart -oyaml +``` kubectl get mariaops -n demo restart -oyaml apiVersion: ops.kubedb.com/v1alpha1 kind: MariaDBOpsRequest @@ -174,8 +176,6 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning up diff --git a/docs/guides/mariadb/rotate-auth/rotateauth.md b/docs/guides/mariadb/rotate-auth/rotateauth.md index 37462b2374..eb5a15896f 100644 --- a/docs/guides/mariadb/rotate-auth/rotateauth.md +++ b/docs/guides/mariadb/rotate-auth/rotateauth.md @@ -29,9 +29,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Create a MariaDB database @@ -59,17 +59,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/quickstart/overview/examples/sample-mariadb-v1.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/quickstart/overview/examples/sample-mariadb-v1.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until sample-mariadb has status Ready. i.e, -```shell -$ kubectl get mariadb -n demo -w +```bash +kubectl get mariadb -n demo -w +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 30m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the Secret. @@ -82,8 +82,9 @@ $ kubectl get secret -n demo sample-mariadb-auth -o=jsonpath='{.data.password}' s)cJQ*iL8wHySpvT⏎ ```` Now, you can exec into the pod `sample-mariadb` and connect to database using `username` and `password` -```shell -$ kubectl exec -it -n demo sample-mariadb-0 -- mariadb -u root --password='s)cJQ*iL8wHySpvT' +```bash +kubectl exec -it -n demo sample-mariadb-0 -- mariadb -u root --password='s)cJQ*iL8wHySpvT' +``` Defaulted container "mariadb" out of: mariadb, mariadb-init (init) Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 207 @@ -118,9 +119,6 @@ MariaDB [(none)]> show databases; | performance_schema | +--------------------+ 5 rows in set (0.000 sec) - - -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth MariaDBOpsRequest @@ -149,19 +147,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on MariaDB. Let's create the `MariaDBOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/rotate-auth/overview/examples/Mariadb-rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/rotate-auth/overview/examples/Mariadb-rotate-auth-generated.yaml + ``` mariadbopsrequest.ops.kubedb.com/mdops-rotate-auth-generated created -``` Let's wait for `MariaDBOpsrequest` to be `Successful`. Run the following command to watch `MariaDBOpsrequest` CRO -```shell -$ kubectl get Mariadbopsrequest -n demo +```bash +kubectl get Mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mdops-rotate-auth-generated RotateAuth Successful 6m28s -``` If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Mariadbopsrequest -n demo mdops-rotate-auth-generated +```bash +kubectl describe Mariadbopsrequest -n demo mdops-rotate-auth-generated +``` Name: mdops-rotate-auth-generated Namespace: demo Labels: @@ -239,25 +238,32 @@ Events: Normal Starting 8m26s KubeDB Ops-manager Operator Resuming MariaDB database: demo/sample-mariadb Normal Successful 8m26s KubeDB Ops-manager Operator Successfully resumed MariaDB database: demo/sample-mariadb Normal Successful 8m26s KubeDB Ops-manager Operator Controller has successfully rotate MariaDB auth secret - -``` **Verify Auth is rotated** -```shell -$ kubectl get mariadb -n demo sample-mariadb -ojson | jq .spec.authSecret.name +```bash +kubectl get mariadb -n demo sample-mariadb -ojson | jq .spec.authSecret.name +``` "sample-mariadb-auth" -$ kubectl get secret -n demo sample-mariadb-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo sample-mariadb-auth -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mariadb-auth -o=jsonpath='{.data.password}' | base64 -d -gTJJMdgpKy9U(Eqi⏎ + +```bash +kubectl get secret -n demo sample-mariadb-auth -o=jsonpath='{.data.password}' | base64 -d ``` +gTJJMdgpKy9U(Eqi⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo sample-mariadb-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo sample-mariadb-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mariadb-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -s)cJQ*iL8wHySpvT⏎ + +```bash +kubectl get secret -n demo sample-mariadb-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +s)cJQ*iL8wHySpvT⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials @@ -265,13 +271,13 @@ At first, we need to create a secret with kubernetes.io/basic-auth type using cu > Note: You cannot change the database `username`, but you can update the `password` while keeping the existing `username`. -```shell -$ kubectl create secret generic sample-mariadb-auth-user -n demo \ +```bash +kubectl create secret generic sample-mariadb-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=root \ --from-literal=password=testpassword -secret/sample-mariadb-auth-user created ``` +secret/sample-mariadb-auth-user created Now create a `MariaDBOpsRequest` with `RotateAuth` type. Below is the YAML of the `MariaDBOpsRequest` that we are going to create, ```shell @@ -299,21 +305,22 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/rotate-auth/overview/examples/rotate-auth-user.yaml -mariadbopsrequest.ops.kubedb.com/mdops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/rotate-auth/overview/examples/rotate-auth-user.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-rotate-auth-user created Let’s wait for `MariaDBOpsRequest` to be Successful. Run the following command to watch `MariaDBOpsRequest` CRO: -```shell -$ kubectl get Mariadbopsrequest -n demo +```bash +kubectl get Mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE mdops-rotate-auth-generated RotateAuth Successful 100s mdops-rotate-auth-user RotateAuth Successful 62s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Mariadbopsrequest -n demo mdops-rotate-auth-user +```bash + kubectl describe Mariadbopsrequest -n demo mdops-rotate-auth-user +``` Name: mdops-rotate-auth-user Namespace: demo Labels: @@ -393,24 +400,31 @@ Events: Normal Starting 63s KubeDB Ops-manager Operator Resuming MariaDB database: demo/sample-mariadb Normal Successful 63s KubeDB Ops-manager Operator Successfully resumed MariaDB database: demo/sample-mariadb Normal Successful 63s KubeDB Ops-manager Operator Controller has successfully rotate MariaDB auth secret - -``` **Verify auth is rotate** -```shell -$ kubectl get mariadb -n demo sample-mariadb -ojson | jq .spec.authSecret.name +```bash +kubectl get mariadb -n demo sample-mariadb -ojson | jq .spec.authSecret.name +``` "sample-mariadb-auth-user" -$ kubectl get secret -n demo sample-mariadb-auth-user -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo sample-mariadb-auth-user -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mariadb-auth-user -o=jsonpath='{.data.password}' | base64 -d -testpassword⏎ + +```bash +kubectl get secret -n demo sample-mariadb-auth-user -o=jsonpath='{.data.password}' | base64 -d ``` +testpassword⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo sample-mariadb-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo sample-mariadb-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mariadb-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d -gTJJMdgpKy9U(Eqi⏎ + +```bash +kubectl get secret -n demo sample-mariadb-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +gTJJMdgpKy9U(Eqi⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -419,15 +433,21 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Mariadbopsrequest mdops-rotate-auth-generated mdops-rotate-auth-user -n demo +```bash +kubectl delete Mariadbopsrequest mdops-rotate-auth-generated mdops-rotate-auth-user -n demo +``` mariadbopsrequest.ops.kubedb.com "mdops-rotate-auth-generated" deleted mariadbopsrequest.ops.kubedb.com "mdops-rotate-auth-user" deleted -$ kubectl delete secret -n demo sample-mariadb-auth-user + +```bash +kubectl delete secret -n demo sample-mariadb-auth-user +``` secret "sample-mariadb-auth-user" deleted -$ kubectl delete secret -n demo sample-mariadb-auth -secret "sample-mariadb-auth" deleted + +```bash +kubectl delete secret -n demo sample-mariadb-auth ``` +secret "sample-mariadb-auth" deleted ## Next Steps diff --git a/docs/guides/mariadb/scaling/horizontal-scaling/cluster/index.md b/docs/guides/mariadb/scaling/horizontal-scaling/cluster/index.md index cc0dafe8b6..a999e92500 100644 --- a/docs/guides/mariadb/scaling/horizontal-scaling/cluster/index.md +++ b/docs/guides/mariadb/scaling/horizontal-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to scale the cl To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Horizontal Scaling on Cluster @@ -70,26 +70,29 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 2m36s -``` Let's check the number of replicas this database has from the MariaDB object, number of pods the petset have, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' -3 -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' +kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' +``` 3 + +```bash +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' ``` +3 We can see from both command that the database has 3 replicas in the cluster. @@ -97,17 +100,20 @@ Also, we can verify the replicas of the replicaset from an internal mariadb comm First we need to get the username and password to connect to a mariadb instance, ```bash -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo sample-mariadb-auth -o jsonpath='{.data.password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now let's connect to a mariadb instance and run a mariadb internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash + kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | @@ -115,8 +121,6 @@ root@sample-mariadb-0:/ mariadb -uroot -p$MYSQL_ROOT_PASSWORD -e "show status li | wsrep_cluster_size | 3 | +--------------------+-------+ -``` - We can see from the above output that the cluster has 3 nodes. We are now ready to apply the `MariaDBOpsRequest` CR to scale this database. @@ -152,9 +156,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/mdops-upscale.yaml -mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/mdops-upscale.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-up created #### Verify Cluster replicas scaled up successfully @@ -163,32 +167,35 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ watch kubectl get mariadbopsrequest -n demo +watch kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdps-scale-horizontal HorizontalScaling Successful 106s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the MariaDB object, number of pods the petset have, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' -5 -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' +kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' +``` 5 + +```bash +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' ``` +5 Now let's connect to a mariadb instance and run a mariadb internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 5 | +--------------------+-------+ -``` From all the above outputs we can see that the replicas of the cluster is `5`. That means we have successfully scaled up the replicas of the MariaDB replicaset. @@ -223,9 +230,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/mdops-downscale.yaml -mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/horizontal-scaling/cluster/example/mdops-downscale.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-scale-horizontal-down created #### Verify Cluster replicas scaled down successfully @@ -234,31 +241,34 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ watch kubectl get mariadbopsrequest -n demo +watch kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mops-hscale-down-replicaset HorizontalScaling Successful 2m32s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the MariaDB object, number of pods the petset have, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' -3 -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' +kubectl get mariadb -n demo sample-mariadb -o json | jq '.spec.replicas' +``` 3 + +```bash +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.replicas' ``` +3 Now let's connect to a mariadb instance and run a mariadb internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +kubectl exec -it -n demo sample-mariadb-0 -c mariadb -- bash +``` root@sample-mariadb-0:/ mariadb -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 3 | +--------------------+-------+ -``` From all the above outputs we can see that the replicas of the cluster is `3`. That means we have successfully scaled down the replicas of the MariaDB replicaset. @@ -267,6 +277,9 @@ From all the above outputs we can see that the replicas of the cluster is `3`. T To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo mdops-scale-horizontal-up mdops-scale-horizontal-down +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-scale-horizontal-up mdops-scale-horizontal-down ``` \ No newline at end of file diff --git a/docs/guides/mariadb/scaling/horizontal-scaling/maxscale.md b/docs/guides/mariadb/scaling/horizontal-scaling/maxscale.md index 0769776be9..41b76cd5fc 100644 --- a/docs/guides/mariadb/scaling/horizontal-scaling/maxscale.md +++ b/docs/guides/mariadb/scaling/horizontal-scaling/maxscale.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale MaxSc To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Horizontal Scaling on MaxScale Server @@ -77,26 +77,29 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/md-replication.yaml -mariadb.kubedb.com/md-replication created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/md-replication.yaml ``` +mariadb.kubedb.com/md-replication created Now, wait until `md-replication` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE md-replication 11.8.5 Ready 2m8s -``` Let's check the number of replicas `Maxscale` has from the MariaDB object, also the number of replicas the petset have, ```bash -$ kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' -3 -$ kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' +kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' +``` 3 + +```bash +kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' ``` +3 We can see from both command that the `MaxScale` has 3 replicas in the cluster. @@ -133,9 +136,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/horizontal-scaling/mx-hscale-up.yaml -mariadbopsrequest.ops.kubedb.com/maxscale-horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/horizontal-scaling/mx-hscale-up.yaml ``` +mariadbopsrequest.ops.kubedb.com/maxscale-horizontal-scale-up created #### Verify Cluster replicas scaled up successfully @@ -144,20 +147,23 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ watch kubectl get mariadbopsrequest -n demo +watch kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE maxscale-horizontal-scale-up HorizontalScaling Successful 2m31s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the MariaDB object, number of pods the petset have, ```bash -$ kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' +kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' +``` 4 -$ kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' -4 + +```bash +kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' ``` +4 From all the above outputs we can see that the replicas of the `MaxScale` server is `4`. That means we have successfully scaled up the replicas of the MaxScale server. @@ -194,9 +200,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/horizontal-scaling/mx-hscale-down.yaml -mariadbopsrequest.ops.kubedb.com/maxscale-horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/horizontal-scaling/mx-hscale-down.yaml ``` +mariadbopsrequest.ops.kubedb.com/maxscale-horizontal-scale-down created #### Verify Cluster replicas scaled down successfully @@ -205,20 +211,23 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ watch kubectl get mariadbopsrequest -n demo +watch kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE maxscale-horizontal-scale-down HorizontalScaling Successful 55s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas `MaxScale` server has from the MariaDB object, number of pods the petset have, ```bash -$ kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' -3 -$ kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' +kubectl get mariadb -n demo md-replication -o json | jq '.spec.topology.maxscale.replicas' +``` 3 + +```bash +kubectl get petset -n demo md-replication-mx -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the cluster is `3`. That means we have successfully scaled down the replicas of the MaxScale server. @@ -227,7 +236,13 @@ From all the above outputs we can see that the replicas of the cluster is `3`. T To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo md-replication -$ kubectl delete mariadbopsrequest -n demo maxscale-horizontal-scale-up maxscale-horizontal-scale-down -$ kubectl delete ns demo +kubectl delete mariadb -n demo md-replication +``` + +```bash +kubectl delete mariadbopsrequest -n demo maxscale-horizontal-scale-up maxscale-horizontal-scale-down +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/mariadb/scaling/vertical-scaling/cluster/index.md b/docs/guides/mariadb/scaling/vertical-scaling/cluster/index.md index 54aab2dbd2..4fc5c1251e 100644 --- a/docs/guides/mariadb/scaling/vertical-scaling/cluster/index.md +++ b/docs/guides/mariadb/scaling/vertical-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Vertical Scaling on Cluster @@ -71,22 +71,23 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/vertical-scaling/cluster/example/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/vertical-scaling/cluster/example/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 3m46s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -97,7 +98,6 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].reso "memory": "1Gi" } } -``` You can see the Pod has the default resources which is assigned by KubeDB operator. @@ -141,9 +141,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/vertical-scaling/cluster/example/mdops-vscale.yaml -mariadbopsrequest.ops.kubedb.com/mdops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/scaling/vertical-scaling/cluster/example/mdops-vscale.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-vscale created #### Verify MariaDB Cluster resources updated successfully @@ -152,16 +152,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdops-vscale VerticalScaling Successful 3m56s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -172,7 +173,6 @@ $ kubectl get pod -n demo sample-mariadb-0 -o json | jq '.spec.containers[].reso "memory": "1288490188800m" } } -``` The above output verifies that we have successfully scaled up the resources of the MariaDB database. @@ -181,6 +181,9 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo mdops-vscale +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-vscale ``` \ No newline at end of file diff --git a/docs/guides/mariadb/scaling/vertical-scaling/maxscale.md b/docs/guides/mariadb/scaling/vertical-scaling/maxscale.md index 8b43122c9e..722ab98ca6 100644 --- a/docs/guides/mariadb/scaling/vertical-scaling/maxscale.md +++ b/docs/guides/mariadb/scaling/vertical-scaling/maxscale.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Vertical Scaling on MaxScale Server @@ -77,22 +77,23 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/md-replication.yaml -mariadb.kubedb.com/md-replication created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/md-replication.yaml ``` +mariadb.kubedb.com/md-replication created Now, wait until `md-replication` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE md-replication 11.8.5 Ready 2m39s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "512Mi" @@ -102,7 +103,6 @@ $ kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].r "memory": "256Mi" } } -``` You can see the Pod has the default resources which is assigned by KubeDB operator. @@ -145,9 +145,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/vertical-scaling/mx-vscale.yaml -mariadbopsrequest.ops.kubedb.com/maxscale-vertical-scale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/scaling/vertical-scaling/mx-vscale.yaml ``` +mariadbopsrequest.ops.kubedb.com/maxscale-vertical-scale created #### Verify MaxScale server resources updated successfully @@ -156,18 +156,18 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ watch kubectl get mariadbopsrequest -n demo +watch kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE maxscale-vertical-scale VerticalScaling Successful 3m8s -``` - We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of maxscale server has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -178,7 +178,6 @@ $ kubectl get pod -n demo md-replication-mx-0 -o json | jq '.spec.containers[].r "memory": "512Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the MariaDB database. @@ -187,7 +186,13 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo md-replication -$ kubectl delete mariadbopsrequest -n demo maxscale-vertical-scale -$ kubectl delete ns demo +kubectl delete mariadb -n demo md-replication +``` + +```bash +kubectl delete mariadbopsrequest -n demo maxscale-vertical-scale +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mariadb/tls/configure/index.md b/docs/guides/mariadb/tls/configure/index.md index 82952d8617..b9fcff8ca2 100644 --- a/docs/guides/mariadb/tls/configure/index.md +++ b/docs/guides/mariadb/tls/configure/index.md @@ -27,9 +27,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mariadb/tls/configure/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mariadb/tls/configure/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,12 +44,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mariadb/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -133,23 +133,25 @@ You can found more details from [here](/docs/guides/mariadb/concepts/mariadb/#sp Let’s create the `MariaDB` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/tls/configure/examples/tls-standalone.yaml -mariadb.kubedb.com/md-standalone-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/tls/configure/examples/tls-standalone.yaml ``` +mariadb.kubedb.com/md-standalone-tls created **Wait for the database to be ready:** Now, wait for `MariaDB` going on `Running` state and also wait for `PetSet` and its pod to be created and going to `Running` state, ```bash -$ kubectl get mariadb -n demo md-standalone-tls +kubectl get mariadb -n demo md-standalone-tls +``` NAME VERSION STATUS AGE md-standalone-tls 11.8.5 Ready 5m48s -$ kubectl get petset -n demo md-standalone-tls +```bash +kubectl get petset -n demo md-standalone-tls +``` NAME READY AGE md-standalone-tls 1/1 7m5s -``` **Verify tls-secrets created successfully:** @@ -160,14 +162,14 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secrets -n demo | grep md-standalone-tls +kubectl get secrets -n demo | grep md-standalone-tls +``` md-standalone-tls-archiver-cert kubernetes.io/tls 3 7m53s md-standalone-tls-auth kubernetes.io/basic-auth 2 7m54s md-standalone-tls-metrics-exporter-cert kubernetes.io/tls 3 7m53s md-standalone-tls-metrics-exporter-config Opaque 1 7m54s md-standalone-tls-server-cert kubernetes.io/tls 3 7m53s md-standalone-tls-token-7hhg2 -``` **Verify MariaDB Standalone configured with TLS/SSL:** @@ -176,8 +178,8 @@ Now, we are going to connect to the database for verifying the `MariaDB` server Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo md-standalone-tls-0 -- bash - +kubectl exec -it -n demo md-standalone-tls-0 -- bash +``` root@md-standalone-tls-0:/ ls /etc/mysql/certs/client ca.crt tls.crt tls.key root@md-standalone-tls-0:/ ls /etc/mysql/certs/server @@ -219,7 +221,6 @@ MariaDB [(none)]> show variables like '%require_secure_transport%'; MariaDB [(none)]> quit; Bye -``` The above output shows that the `MariaDB` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/etc/mysql/certs/client/` and `/etc/mysql/certs/server/` directory for client and server respectively. @@ -230,7 +231,8 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, ```bash -$ kubectl exec -it -n demo md-standalone-tls-0 -- bash +kubectl exec -it -n demo md-standalone-tls-0 -- bash +``` root@md-standalone-tls-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 92 @@ -265,7 +267,6 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> exit Bye -``` From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/mysql/certs/client/` directory. @@ -320,15 +321,17 @@ mariadb.kubedb.com/md-cluster-tls created Now, wait for `MariaDB` going on `Running` state and also wait for `PetSet` and its pods to be created and going to `Running` state, ```bash -$ kubectl get mariadb -n demo md-cluster-tls +kubectl get mariadb -n demo md-cluster-tls +``` NAME VERSION STATUS AGE md-cluster-tls 11.8.5 Ready 2m49s -$ kubectl get pod -n demo | grep md-cluster-tls +```bash +kubectl get pod -n demo | grep md-cluster-tls +``` md-cluster-tls-0 1/1 Running 0 3m29s md-cluster-tls-1 1/1 Running 0 3m9s md-cluster-tls-2 1/1 Running 0 2m49s -``` **Verify tls-secrets created successfully :** @@ -339,14 +342,14 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secrets -n demo | grep md-cluster-tls +kubectl get secrets -n demo | grep md-cluster-tls +``` md-cluster-tls-archiver-cert kubernetes.io/tls 3 6m20s md-cluster-tls-auth kubernetes.io/basic-auth 2 6m22s md-cluster-tls-metrics-exporter-cert kubernetes.io/tls 3 6m20s md-cluster-tls-metrics-exporter-config Opaque 1 6m21s md-cluster-tls-server-cert kubernetes.io/tls 3 6m21s md-cluster-tls-token-nrs75 -``` **Verify MariaDB Cluster configured with TLS/SSL:** @@ -355,8 +358,8 @@ Now, we are going to connect to the database for verifying the `MariaDB` server Let's exec into the first pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo md-cluster-tls-0 -- bash - +kubectl exec -it -n demo md-cluster-tls-0 -- bash +``` root@md-cluster-tls-0:/ ls /etc/mysql/certs/client ca.crt tls.crt tls.key root@md-cluster-tls-0:/ ls /etc/mysql/certs/server @@ -398,12 +401,12 @@ MariaDB [(none)]> show variables like '%require_secure_transport%'; MariaDB [(none)]> quit; Bye -``` Now let's check for the second database server, ```bash -$ kubectl exec -it -n demo md-cluster-tls-1 -- bash +kubectl exec -it -n demo md-cluster-tls-1 -- bash +``` root@md-cluster-tls-1:/ ls /etc/mysql/certs/client ca.crt tls.crt tls.key root@md-cluster-tls-1:/ ls /etc/mysql/certs/server @@ -444,7 +447,6 @@ MariaDB [(none)]> show variables like '%require_secure_transport%'; MariaDB [(none)]> quit; Bye -``` The above output shows that the `MariaDB` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/etc/mysql/certs/client/` and `/etc/mysql/certs/server/` directory for client and server respectively. @@ -455,7 +457,8 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, ```bash -$ kubectl exec -it -n demo md-cluster-tls-0 -- bash +kubectl exec -it -n demo md-cluster-tls-0 -- bash +``` root@md-cluster-tls-0:/ mariadb -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 92 @@ -490,7 +493,6 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> exit Bye -``` From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/mysql/certs/client/` directory. @@ -499,10 +501,16 @@ From the above output, you can see that only using client certificate we can acc To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb demo md-standalone-tls +kubectl delete mariadb demo md-standalone-tls +``` mariadb.kubedb.com "md-standalone-tls" deleted -$ kubectl delete mariadb demo md-cluster-tls + +```bash +kubectl delete mariadb demo md-cluster-tls +``` mariadb.kubedb.com "md-cluster-tls" deleted -$ kubectl delete ns demo -namespace "demo" deleted -``` \ No newline at end of file + +```bash +kubectl delete ns demo +``` +namespace "demo" deleted \ No newline at end of file diff --git a/docs/guides/mariadb/update-version/cluster/index.md b/docs/guides/mariadb/update-version/cluster/index.md index 24ef9c892d..489a9ae607 100644 --- a/docs/guides/mariadb/update-version/cluster/index.md +++ b/docs/guides/mariadb/update-version/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MariaDB Cluster @@ -69,17 +69,17 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/update-version/cluster/examples/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/update-version/cluster/examples/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` created has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 3m15s -``` We are now ready to apply the `MariaDBOpsRequest` CR to update this database. @@ -114,9 +114,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/update-version/cluster/examples/mdops-update.yaml -mariadbopsrequest.ops.kubedb.com/mdops-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/update-version/cluster/examples/mdops-update.yaml ``` +mariadbopsrequest.ops.kubedb.com/mdops-update created #### Verify MariaDB version updated successfully @@ -125,26 +125,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` Every 2.0s: kubectl get mariadbopsrequest -n demo NAME TYPE STATUS AGE mdops-update UpdateVersion Successful 84s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. Now, we are going to verify whether the `MariaDB` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get mariadb -n demo sample-mariadb -o=jsonpath='{.spec.version}{"\n"}' +kubectl get mariadb -n demo sample-mariadb -o=jsonpath='{.spec.version}{"\n"}' +``` 12.1.2 -$ kubectl get petset -n demo sample-mariadb -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo sample-mariadb -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mariadb:12.1.2 -$ kubectl get pods -n demo sample-mariadb-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mariadb:12.1.2 +```bash +kubectl get pods -n demo sample-mariadb-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mariadb:12.1.2 You can see from above, our `MariaDB` cluster database has been updated with the new version. So, the update process is successfully completed. @@ -153,6 +157,9 @@ You can see from above, our `MariaDB` cluster database has been updated with the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo mdops-update +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo mdops-update ``` \ No newline at end of file diff --git a/docs/guides/mariadb/volume-expansion/maxscale.md b/docs/guides/mariadb/volume-expansion/maxscale.md index 2cc78eb276..85e318fe01 100644 --- a/docs/guides/mariadb/volume-expansion/maxscale.md +++ b/docs/guides/mariadb/volume-expansion/maxscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of MaxScale @@ -46,12 +46,12 @@ Here, we are going to deploy a `MariaDB` cluster in replication mode using a su At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path rancher.io/local-path Delete WaitForFirstConsumer false 46h standard driver.standard.io Delete Immediate true 2m27s standard-static driver.standard.io Delete Immediate true 2m24s -``` We can see from the output that `standard` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. @@ -98,25 +98,28 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/volume-expansion/md-replication.yaml -mariadb.kubedb.com/md-replication created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/volume-expansion/md-replication.yaml ``` +mariadb.kubedb.com/md-replication created Now, wait until `md-replication` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE md-replication 11.8.5 Ready 2m30s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo md-replication-mx -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo md-replication-mx -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "50Mi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-27e4f4b2-289b-44bb-97a2-729d9420f668 1Gi RWO Delete Bound demo/data-md-replication-2 standard 3m48s pvc-2df9a141-5d32-4c92-b0ec-a8043975c2ae 1Gi RWO Delete Bound demo/data-md-replication-1 standard 3m48s @@ -125,8 +128,6 @@ pvc-96449ed7-305e-4857-a2b6-6eda33c99207 50Mi RWO Delete pvc-c1424029-4a52-4ff4-9888-14d5e7b4fb61 50Mi RWO Delete Bound demo/data-md-replication-mx-0 standard 3m51s pvc-d12d301c-58bd-4c59-bd5a-d9167df2b53d 50Mi RWO Delete Bound demo/data-md-replication-mx-1 standard 3m51s -``` - You can see that `MaxScale` petset has 50Mi storage, and the capacity of the `MaxScale` persistent volumes are also 50Mi. We are now ready to apply the `MariaDBOpsRequest` CR to expand the volume of this database. @@ -165,9 +166,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/volume-expansion/maxscale-volume-expansion.yaml -mariadbopsrequest.ops.kubedb.com/maxscale-volume-expansion created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mariadb/volume-expansion/maxscale-volume-expansion.yaml ``` +mariadbopsrequest.ops.kubedb.com/maxscale-volume-expansion created #### Verify MaxScale volume expanded successfully @@ -176,15 +177,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE maxscale-volume-expansion VolumeExpansion Successful 3m -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mariadbopsrequest -n demo maxscale-volume-expansion +kubectl describe mariadbopsrequest -n demo maxscale-volume-expansion +``` Name: maxscale-volume-expansion Namespace: demo Labels: @@ -271,15 +273,16 @@ Events: Normal Successful 14m KubeDB Ops-manager Operator Successfully resumed MariaDB database: demo/md-replication Normal Successful 14m KubeDB Ops-manager Operator Controller has Successfully expand the volume of MaxScale: demo/md-replication -``` - Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo md-replication-mx -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo md-replication-mx -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "100Mi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-27e4f4b2-289b-44bb-97a2-729d9420f668 1Gi RWO Delete Bound demo/data-md-replication-2 standard 34m pvc-2df9a141-5d32-4c92-b0ec-a8043975c2ae 1Gi RWO Delete Bound demo/data-md-replication-1 standard 34m @@ -288,8 +291,6 @@ pvc-96449ed7-305e-4857-a2b6-6eda33c99207 100Mi RWO Delete pvc-c1424029-4a52-4ff4-9888-14d5e7b4fb61 100Mi RWO Delete Bound demo/data-md-replication-mx-0 standard 34m pvc-d12d301c-58bd-4c59-bd5a-d9167df2b53d 100Mi RWO Delete Bound demo/data-md-replication-mx-1 standard 34m -``` - The above output verifies that we have successfully expanded the volume of the MariaDB database. ## Cleaning Up @@ -297,7 +298,13 @@ The above output verifies that we have successfully expanded the volume of the M To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo md-replication -$ kubectl delete mariadbopsrequest -n demo maxscale-volume-expansion -$ kubectl delete ns demo +kubectl delete mariadb -n demo md-replication +``` + +```bash +kubectl delete mariadbopsrequest -n demo maxscale-volume-expansion +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mariadb/volume-expansion/volume-expansion/index.md b/docs/guides/mariadb/volume-expansion/volume-expansion/index.md index 5d7a0b8e10..f188d724bb 100644 --- a/docs/guides/mariadb/volume-expansion/volume-expansion/index.md +++ b/docs/guides/mariadb/volume-expansion/volume-expansion/index.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to expand the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of MariaDB @@ -45,13 +45,12 @@ Here, we are going to deploy a `MariaDB` cluster using a supported version by ` At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 69s topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 37s -``` - We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. You can install topolvm from [here](https://github.com/topolvm/topolvm). Now, we are going to deploy a `MariaDB` database of 3 replicas with version `12.1.2`. @@ -84,30 +83,32 @@ spec: Let's create the `MariaDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/volume-expansion/volume-expansion/example/sample-mariadb.yaml -mariadb.kubedb.com/sample-mariadb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/volume-expansion/volume-expansion/example/sample-mariadb.yaml ``` +mariadb.kubedb.com/sample-mariadb created Now, wait until `sample-mariadb` has status `Ready`. i.e, ```bash -$ kubectl get mariadb -n demo +kubectl get mariadb -n demo +``` NAME VERSION STATUS AGE sample-mariadb 11.8.5 Ready 5m4s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 1Gi RWO Delete Bound demo/data-sample-mariadb-0 topolvm-provisioner 63s pvc-b90179f8-c40a-4273-ad77-74ca8470b782 1Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 62s pvc-f72411a4-80d5-4d32-b713-cb30ec662180 1Gi RWO Delete Bound demo/data-sample-mariadb-2 topolvm-provisioner 62s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -148,9 +149,9 @@ Here, Let's create the `MariaDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/volume-expansion/volume-expansion/example/online-volume-expansion.yaml -mariadbopsrequest.ops.kubedb.com/md-online-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mariadb/volume-expansion/volume-expansion/example/online-volume-expansion.yaml ``` +mariadbopsrequest.ops.kubedb.com/md-online-volume-expansion created #### Verify MariaDB volume expanded successfully @@ -159,15 +160,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the volume siz Let's wait for `MariaDBOpsRequest` to be `Successful`. Run the following command to watch `MariaDBOpsRequest` CR, ```bash -$ kubectl get mariadbopsrequest -n demo +kubectl get mariadbopsrequest -n demo +``` NAME TYPE STATUS AGE md-online-volume-expansion VolumeExpansion Successful 96s -``` We can see from the above output that the `MariaDBOpsRequest` has succeeded. If we describe the `MariaDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mariadbopsrequest -n demo md-online-volume-expansion +kubectl describe mariadbopsrequest -n demo md-online-volume-expansion +``` Name: md-online-volume-expansion Namespace: demo Labels: @@ -216,21 +218,21 @@ Events: Normal Starting 41s KubeDB Enterprise Operator Resuming MariaDB database: demo/sample-mariadb Normal Successful 41s KubeDB Enterprise Operator Successfully resumed MariaDB database: demo/sample-mariadb Normal Successful 41s KubeDB Enterprise Operator Controller has Successfully expand the volume of MariaDB: demo/sample-mariadb - -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mariadb -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 2Gi RWO Delete Bound demo/data-sample-mariadb-0 topolvm-provisioner 12m pvc-b90179f8-c40a-4273-ad77-74ca8470b782 2Gi RWO Delete Bound demo/data-sample-mariadb-1 topolvm-provisioner 12m pvc-f72411a4-80d5-4d32-b713-cb30ec662180 2Gi RWO Delete Bound demo/data-sample-mariadb-2 topolvm-provisioner 12m -``` The above output verifies that we have successfully expanded the volume of the MariaDB database. @@ -239,6 +241,9 @@ The above output verifies that we have successfully expanded the volume of the M To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mariadb -n demo sample-mariadb -$ kubectl delete mariadbopsrequest -n demo md-online-volume-expansion +kubectl delete mariadb -n demo sample-mariadb +``` + +```bash +kubectl delete mariadbopsrequest -n demo md-online-volume-expansion ``` diff --git a/docs/guides/memcached/autoscaler/compute/compute-autoscale.md b/docs/guides/memcached/autoscaler/compute/compute-autoscale.md index 3937030afd..78d00acf99 100644 --- a/docs/guides/memcached/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/memcached/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached](/docs/examples/memcached) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,22 +73,23 @@ spec: Let's create the `Memcached` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/auto-scaler/memcached.yaml -Memcached.kubedb.com/mc-autoscaler-compute created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/auto-scaler/memcached.yaml ``` +Memcached.kubedb.com/mc-autoscaler-compute created Now, wait until `mc-autoscaler-compute` has status `Ready`. i.e, ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE mc-autoscaler-compute 1.6.40 Ready 2m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "100m", @@ -99,11 +100,11 @@ $ kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers "memory": "100Mi" } } -``` Let's check the Memcached resources, ```bash -$ kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "memcached") | .resources' +kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "memcached") | .resources' +``` { "limits": { "cpu": "100m", @@ -114,7 +115,6 @@ $ kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTem "memory": "100Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the Memcached. @@ -171,20 +171,23 @@ Here, Let's create the `MemcachedAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/auto-scaler/memcached-autoscaler-compute.yaml -Memcachedautoscaler.autoscaling.kubedb.com/mc-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/auto-scaler/memcached-autoscaler-compute.yaml ``` +Memcachedautoscaler.autoscaling.kubedb.com/mc-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `Memcachedautoscaler` resource is created successfully, ```bash -$ kubectl get memcachedautoscaler -n demo +kubectl get memcachedautoscaler -n demo +``` NAME AGE mc-autoscaler 16m -$ kubectl describe memcachedautoscaler mc-autoscaler -n demo +```bash +kubectl describe memcachedautoscaler mc-autoscaler -n demo +``` Name: mc-autoscaler Namespace: demo Labels: @@ -271,7 +274,6 @@ Status: Memory: 1Gi Vpa Name: mc-autoscaler-compute Events: -``` So, the `Memcachedautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `Memcachedopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -279,26 +281,27 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `Memcachedopsrequest` in the demo namespace to see if any `Memcachedopsrequest` object is created. After some time you'll see that a `Memcachedopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo NAME TYPE STATUS AGE mcops-mc-autoscaler-compute-p1usdl VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo NAME TYPE STATUS AGE mcops-mc-autoscaler-compute-p1usdl VerticalScaling Successful 1m -``` We can see from the above output that the `memcachedOpsRequest` has succeeded. ```bash -$ kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -310,7 +313,9 @@ $ kubectl get pod -n demo mc-autoscaler-compute-0 -o json | jq '.spec.containers } } -$ kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "memcached") | .resources' +```bash +kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "memcached") | .resources' +``` { "limits": { "cpu": "400m", @@ -321,7 +326,6 @@ $ kubectl get Memcached -n demo mc-autoscaler-compute -o json | jq '.spec.podTem "memory": "400Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the Memcached database. @@ -330,12 +334,16 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mc/mc-autoscaler-compute -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/mc-autoscaler-compute -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/mc-autoscaler-compute patched -$ kubectl delete mc -n demo mc-autoscaler-compute +```bash +kubectl delete mc -n demo mc-autoscaler-compute +``` memcached.kubedb.com "mc-autoscaler-compute" deleted -$ kubectl delete memcachedautoscaler -n demo mc-autoscaler -memcachedautoscaler.autoscaling.kubedb.com "mc-autoscaler" deleted -``` \ No newline at end of file +```bash +kubectl delete memcachedautoscaler -n demo mc-autoscaler +``` +memcachedautoscaler.autoscaling.kubedb.com "mc-autoscaler" deleted \ No newline at end of file diff --git a/docs/guides/memcached/cli/cli.md b/docs/guides/memcached/cli/cli.md index 9f546e27d9..256f205506 100644 --- a/docs/guides/memcached/cli/cli.md +++ b/docs/guides/memcached/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a Memcached object as specified in `memcached.yaml`. ```bash -$ kubectl create -f memcached-demo.yaml -memcached.kubedb.com/memcached-demo created +kubectl create -f memcached-demo.yaml ``` +memcached.kubedb.com/memcached-demo created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f memcached-demo.yaml --namespace=kube-system -memcached.kubedb.com/memcached-demo created +kubectl create -f memcached-demo.yaml --namespace=kube-system ``` +memcached.kubedb.com/memcached-demo created `kubectl create` command also considers `stdin` as input. @@ -45,13 +45,13 @@ cat memcached-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all Memcached objects in `default` namespace, run the following command: ```bash -$ kubectl get memcached +kubectl get memcached +``` NAME VERSION STATUS AGE memcached-demo 1.6.40 Running 40s memcached-dev 1.6.40 Running 40s memcached-prod 1.6.40 Running 40s memcached-qa 1.6.40 Running 40s -``` To get YAML of an object, use `--output=yaml` flag. @@ -102,13 +102,13 @@ kubectl get memcached memcached-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get all -o wide +kubectl get all -o wide +``` NAME VERSION STATUS AGE mc/memcached-demo 1.6.40 Running 3h mc/memcached-dev 1.6.40 Running 3h mc/memcached-prod 1.6.40 Running 3h mc/memcached-qa 1.6.40 Running 3h -``` Flag `--output=wide` is used to print additional information. @@ -119,27 +119,28 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Memcached with their corresponding labels. ```bash -$ kubectl get mc --show-labels +kubectl get mc --show-labels +``` NAME VERSION STATUS AGE LABELS memcached-demo 1.6.40 Running 2m kubedb=cli-demo -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` memcached/memcached-demo memcached/memcached-dev memcached/memcached-prod memcached/memcached-qa -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe Memcached server `memcached-demo` with relevant information. ```bash -$ kubectl dba describe mc memcached-demo +kubectl dba describe mc memcached-demo +``` Name: memcached-demo Namespace: default CreationTimestamp: Thu, 04 Oct 2018 11:58:57 +0600 @@ -180,7 +181,6 @@ Events: Normal Successful 2m Memcached operator Successfully created Memcached Normal Successful 2m Memcached operator Successfully patched PetSet Normal Successful 2m Memcached operator Successfully patched Memcached -``` `kubectl dba describe` command provides following basic information about a Memcached server. @@ -223,14 +223,13 @@ To learn about various options of `describe` command, please visit [here](/docs/ Let's edit an existing running Memcached object to setup [Monitoring](/docs/guides/memcached/monitoring/using-builtin-prometheus.md). The following command will open Memcached `memcached-demo` in editor. ```bash -$ kubectl edit mc memcached-demo - +kubectl edit mc memcached-demo +``` #spec: # monitor: # agent: prometheus.io/builtin memcached "memcached-demo" edited -``` #### Edit Restrictions @@ -253,16 +252,16 @@ If Deployment exists for a Memcached server, following fields can't be modified `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a Memcached `memcached-dev` in default namespace ```bash -$ kubectl delete memcached memcached-dev -memcached.kubedb.com "memcached-dev" deleted +kubectl delete memcached memcached-dev ``` +memcached.kubedb.com "memcached-dev" deleted You can also use YAML files to delete objects. The following command will delete a memcached using the type and name specified in `memcached.yaml`. ```bash -$ kubectl delete -f memcached-demo.yaml -memcached.kubedb.com "memcached-dev" deleted +kubectl delete -f memcached-demo.yaml ``` +memcached.kubedb.com "memcached-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -280,13 +279,18 @@ kubectl delete memcached -l memcached.app.kubernetes.io/instance=memcached-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # List objects -$ kubectl get memcached -$ kubectl get memcached.kubedb.com +```bash +kubectl get memcached +``` + +```bash +kubectl get memcached.kubedb.com +``` # Delete objects -$ kubectl delete memcached +```bash +kubectl delete memcached ``` ## Next Steps diff --git a/docs/guides/memcached/custom-configuration/using-config-file.md b/docs/guides/memcached/custom-configuration/using-config-file.md index fc0be06c42..f683ebacd4 100644 --- a/docs/guides/memcached/custom-configuration/using-config-file.md +++ b/docs/guides/memcached/custom-configuration/using-config-file.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for Memcached. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - - $ kubectl get ns demo + + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > 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). @@ -61,10 +63,10 @@ metadata: Here, --con-limit means max simultaneous connections which is default value is 1024. and --memory-limit means item memory in megabytes which default value is 64. -```bash - $ kubectl apply -f mc-configuration.yaml + ```bash + kubectl apply -f mc-configuration.yaml + ``` secret/mc-configuration created -``` Let's get the mc-configuration `secret` with custom configuration: @@ -89,9 +91,9 @@ type: Opaque Now, create Memcached crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/custom-memcached.yaml -memcached.kubedb.com/custom-memcached created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/custom-memcached.yaml ``` +memcached.kubedb.com/custom-memcached created Below is the YAML for the Memcached crd we just created. @@ -125,25 +127,26 @@ Now, wait a few minutes. KubeDB operator will create necessary petset, services Check if the database is ready ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE custom-memcached 1.6.40 Ready 17m -``` Now, we will check if the database has started with the custom configuration we have provided. We will use [stats](https://github.com/memcached/memcached/wiki/ConfiguringServer#inspecting-running-configuration) command to check the configuration. We will connect to `custom-memcached-0` pod from local-machine using port-frowarding. ```bash -$ kubectl port-forward -n demo custom-memcached-0 11211 +kubectl port-forward -n demo custom-memcached-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 -``` Now, connect to the memcached server from a different terminal through `telnet`. ```bash -$ telnet 127.0.0.1 11211 +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -160,7 +163,6 @@ STAT max_connections 500 STAT limit_maxbytes 536870912 ... END -``` Here, `limit_maxbytes` is represented in bytes. diff --git a/docs/guides/memcached/custom-configuration/using-podtemplate.md b/docs/guides/memcached/custom-configuration/using-podtemplate.md index dac69dcaf1..051e3a3939 100644 --- a/docs/guides/memcached/custom-configuration/using-podtemplate.md +++ b/docs/guides/memcached/custom-configuration/using-podtemplate.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Memcached via [PodTemplate](/ - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + 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). @@ -86,30 +86,30 @@ spec: ``` ```bash -$ 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 +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. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE custom-memcached-0 1/1 Running 0 30s -``` 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 +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 @@ -135,8 +135,11 @@ 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 +docker build -t repository_name/custom_filebeat:latest . +``` + +```bash +docker push repository_name/custom_filebeat:latest ``` 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 @@ -171,20 +174,19 @@ spec: 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 +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 +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 @@ -292,31 +294,32 @@ So, we have successfully checked our sidecar filebeat container in Memcached dat 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -332,7 +335,6 @@ Labels: beta.kubernetes.io/arch=amd64 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: @@ -352,24 +354,24 @@ spec: 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 +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 +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 +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 @@ -377,28 +379,33 @@ We can successfully verify that our pod was scheduled to our desired node. 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key2=node2:NoSchedule +```bash +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 +```bash +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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -423,7 +430,6 @@ lke212553-307295-5b53c5520000 "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 @@ -437,20 +443,21 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/without-toleration.yaml -memcached.kubedb.com/memcached-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/without-toleration.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 +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 +kubectl describe pods -n demo memcached-without-tolerations-0 +``` Name: memcached-without-tolerations-0 Namespace: demo Priority: 0 @@ -533,7 +540,6 @@ Events: 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, @@ -557,24 +563,24 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/with-tolerations.yaml -memcached.kubedb.com/memcached-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-config/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 +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 +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 diff --git a/docs/guides/memcached/custom-rbac/using-custom-rbac.md b/docs/guides/memcached/custom-rbac/using-custom-rbac.md index 60e5b96a51..1680a2b457 100644 --- a/docs/guides/memcached/custom-rbac/using-custom-rbac.md +++ b/docs/guides/memcached/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +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). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the Memcached instance named `quick-memcached`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -98,10 +98,9 @@ This permission is required for Memcached pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -130,9 +129,9 @@ subjects: Now, create a Memcached crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-db.yaml -memcached.kubedb.com/quick-memcached created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-db.yaml ``` +memcached.kubedb.com/quick-memcached created Below is the YAML for the Memcached crd we just created. @@ -166,10 +165,10 @@ Now, wait a few minutes. the KubeDB operator will create necessary petset, servi Check that the pod is running: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE quick-memcached-0 1/1 Running 0 5m52s -``` ## Reusing Service Account @@ -178,9 +177,9 @@ An existing service account can be reused in another Memcached instance. No new Now, create Memcached crd `minute-memcached` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-db-two.yaml -memcached.kubedb.com/minute-memcached created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/custom-rbac/mc-custom-db-two.yaml ``` +memcached.kubedb.com/minute-memcached created Below is the YAML for the Memcached crd we just created. @@ -214,40 +213,54 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the pod is running: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE minute-memcached-0 1/1 Running 0 5m52s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mc/quick-memcached -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/quick-memcached -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/quick-memcached patched -$ kubectl delete -n demo mc/quick-memcached +```bash +kubectl delete -n demo mc/quick-memcached +``` memcached.kubedb.com "quick-memcached" deleted -$ kubectl patch -n demo mc/minute-memcached -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo mc/minute-memcached -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/minute-memcached patched -$ kubectl delete -n demo mc/minute-memcached +```bash +kubectl delete -n demo mc/minute-memcached +``` memcached.kubedb.com "minute-memcached" deleted -$ kubectl delete -n demo role my-custom-role +```bash +kubectl delete -n demo role my-custom-role +``` role.rbac.authorization.k8s.io "my-custom-role" deleted -$ kubectl delete -n demo rolebinding my-custom-rolebinding +```bash +kubectl delete -n demo rolebinding my-custom-rolebinding +``` rolebinding.rbac.authorization.k8s.io "my-custom-rolebinding" deleted -$ kubectl delete sa -n demo my-custom-serviceaccount +```bash +kubectl delete sa -n demo my-custom-serviceaccount +``` serviceaccount "my-custom-serviceaccount" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted If you would like to uninstall the KubeDB operator, please follow the steps [here](/docs/setup/README.md). diff --git a/docs/guides/memcached/monitoring/using-builtin-prometheus.md b/docs/guides/memcached/monitoring/using-builtin-prometheus.md index 1ccc9adef1..22d30406ee 100644 --- a/docs/guides/memcached/monitoring/using-builtin-prometheus.md +++ b/docs/guides/memcached/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Memcached server using builtin [Prome - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```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). @@ -74,32 +76,33 @@ Here, Let's create the Memcached crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/monitoring/builtin-prom-memcd.yaml -memcached.kubedb.com/builtin-prom-memcd created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/monitoring/builtin-prom-memcd.yaml ``` +memcached.kubedb.com/builtin-prom-memcd created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get mc -n demo builtin-prom-memcd +kubectl get mc -n demo builtin-prom-memcd +``` NAME VERSION STATUS AGE builtin-prom-memcd 1.6.40 Ready 30s -``` KubeDB will create a separate stats service with name `{Memcached crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-memcd" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-memcd" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-memcd ClusterIP 10.96.168.132 11211/TCP 20s builtin-prom-memcd-pods ClusterIP None 11211/TCP 20s builtin-prom-memcd-stats ClusterIP 10.96.40.60 56790/TCP 20s -``` Here, `builtin-prom-memcd-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-memcd-stats +kubectl describe svc -n demo builtin-prom-memcd-stats +``` Name: builtin-prom-memcd-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -123,7 +126,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.186:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -278,20 +280,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -302,9 +304,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -313,18 +315,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-d64b668fb-4jq99 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-d64b668fb-4jq99` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-d64b668fb-4jq99 9090 +kubectl port-forward -n monitoring prometheus-d64b668fb-4jq99 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoints of `builtin-prom-memcd-stats` service as targets. @@ -341,16 +343,31 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo mc/builtin-prom-memcd +kubectl delete -n demo mc/builtin-prom-memcd +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/memcached/monitoring/using-prometheus-operator.md b/docs/guides/memcached/monitoring/using-prometheus-operator.md index cb2c386549..15c5f16945 100644 --- a/docs/guides/memcached/monitoring/using-prometheus-operator.md +++ b/docs/guides/memcached/monitoring/using-prometheus-operator.md @@ -34,12 +34,14 @@ The following diagram shows how KubeDB Provisioner operator monitor `Memcached` - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```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). @@ -50,12 +52,11 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 3m -``` - > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. @@ -216,27 +217,27 @@ Here, Let's create the Memcached object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/monitoring/memcached.yaml -memcached.kubedb.com/memcached created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/monitoring/memcached.yaml ``` +memcached.kubedb.com/memcached created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get mc -n demo memcached +kubectl get mc -n demo memcached +``` NAME VERSION STATUS AGE memcached 1.6.40 Ready 2m -``` KubeDB will create a separate stats service with name `{Memcached crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=memcached" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=memcached" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE memcached ClusterIP 10.96.91.51 11211/TCP 3m9s memcached-pods ClusterIP None 11211/TCP 3m9s memcached-stats ClusterIP 10.96.50.21 56790/TCP 3m9s -``` Here, `memcached-stats` service has been created for monitoring purpose. @@ -270,10 +271,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `memcached-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE memcached-stats 5m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Memcached crd. @@ -327,20 +328,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 16m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `memcached-stats` service as one of the targets. diff --git a/docs/guides/memcached/private-registry/using-private-registry.md b/docs/guides/memcached/private-registry/using-private-registry.md index 53ea22e94d..81454d651c 100644 --- a/docs/guides/memcached/private-registry/using-private-registry.md +++ b/docs/guides/memcached/private-registry/using-private-registry.md @@ -27,12 +27,12 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For memcached, push `DB_IMAGE`, `EXPORTER_IMAGE` of following MemcachedVersions, where `deprecated` is not true, to your private registry. ```bash - $ kubectl get memcachedversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + kubectl get memcachedversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + ``` NAME VERSION DB_IMAGE EXPORTER_IMAGE DEPRECATED 1.5.22 1.5.22 ghcr.io/appscode-images/memcached:1.5.22-alpine prom/memcached-exporter:v0.14.2 1.6.40 1.6.40 ghcr.io/appscode-images/memcached:1.6.40-alpine ghcr.io/appscode-images/memcached_exporter:v0.14.3-ac 1.6.29 1.6.29 ghcr.io/appscode-images/memcached:1.6.29-alpine ghcr.io/appscode-images/memcached_exporter:v0.14.3-ac - ``` Docker hub repositories: @@ -62,9 +62,9 @@ KubeDB operator supports using private Docker registry. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - ``` ## Create ImagePullSecret @@ -73,13 +73,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -121,14 +121,15 @@ spec: Now run the command to deploy this `Memcached` object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/private-registry/demo-2.yaml -memcached.kubedb.com/memcd-pvt-reg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/private-registry/demo-2.yaml ``` +memcached.kubedb.com/memcd-pvt-reg created To check if the images pulled successfully from the repository, see if the `Memcached` is in running state: ```bash -$ kubectl get pods -n demo -w +kubectl get pods -n demo -w +``` NAME READY STATUS RESTARTS AGE memcd-pvt-reg-694d4d44df-bwtk8 0/1 ContainerCreating 0 18s memcd-pvt-reg-694d4d44df-tkqc4 0/1 ContainerCreating 0 17s @@ -137,28 +138,35 @@ memcd-pvt-reg-694d4d44df-bwtk8 1/1 Running 0 25s memcd-pvt-reg-694d4d44df-zhj4l 1/1 Running 0 26s memcd-pvt-reg-694d4d44df-tkqc4 1/1 Running 0 27s -$ kubectl get mc -n demo +```bash +kubectl get mc -n demo +``` NAME VERSION STATUS AGE memcd-pvt-reg 1.6.40 Running 59s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mc/memcd-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/memcd-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/memcd-pvt-reg patched -$ kubectl delete -n demo mc/memcd-pvt-reg +```bash +kubectl delete -n demo mc/memcd-pvt-reg +``` memcached.kubedb.com "memcd-pvt-reg" deleted -$ kubectl delete -n demo secret myregistrykey +```bash +kubectl delete -n demo secret myregistrykey +``` secret "myregistrykey" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/memcached/quickstart/quickstart.md b/docs/guides/memcached/quickstart/quickstart.md index e72c95dbdb..cb10ef16c4 100644 --- a/docs/guides/memcached/quickstart/quickstart.md +++ b/docs/guides/memcached/quickstart/quickstart.md @@ -31,25 +31,27 @@ This tutorial will show you how to use KubeDB to run a Memcached server. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 1s -``` ## Find Available MemcachedVersion When you have installed KubeDB, it has created `MemcachedVersion` crd for all supported Memcached versions. Check 0 ```bash -$ kubectl get memcachedversions +kubectl get memcachedversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.5.22 1.5.22 ghcr.io/appscode-images/memcached:1.5.22-alpine 2h 1.6.40 1.6.40 ghcr.io/appscode-images/memcached:1.6.40-alpine 2h 1.6.29 1.6.29 ghcr.io/appscode-images/memcached:1.6.29-alpine 2h -``` ## Create a Memcached server @@ -81,9 +83,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1.yaml ``` +memcached.kubedb.com/memcd-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -107,9 +109,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1alpha2.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1alpha2.yaml ``` +memcached.kubedb.com/memcd-quickstart created Here, @@ -120,11 +122,14 @@ Here, KubeDB operator watches for `Memcached` objects using Kubernetes api. When a `Memcached` object is created, KubeDB operator will create a new PetSet and a Service with the matching Memcached object name. ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 2m -$ kubectl describe mc -n demo memcd-quickstart +```bash +kubectl describe mc -n demo memcd-quickstart +``` Name: memcd-quickstart Namespace: demo Labels: @@ -223,15 +228,18 @@ Events: Normal Successful 5m18s KubeDB Operator Successfully patched PetSet Normal Successful 5m18s KubeDB Operator Successfully patched Memcached -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME AGE memcd-quickstart 8m15s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE memcd-quickstart ClusterIP 10.96.115.90 11211/TCP 9m7s memcd-quickstart-pods ClusterIP None 11211/TCP 9m7s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified Memcached object: @@ -327,12 +335,14 @@ By default, KubeDB enables authentication for Memcached. The credentials are sto Retrieve the credentials from the auth secret. They are stored in the `authData` key in the `username:password` format. ```bash -$ kubectl get memcached -n demo memcd-quickstart -o=jsonpath='{.spec.authSecret.name}' +kubectl get memcached -n demo memcd-quickstart -o=jsonpath='{.spec.authSecret.name}' +``` memcd-quickstart-auth -$ kubectl get secret -n demo memcd-quickstart-auth -o=jsonpath='{.data.authData}' | base64 -d -user:tysiujogcmzapyhz +```bash +kubectl get secret -n demo memcd-quickstart-auth -o=jsonpath='{.data.authData}' | base64 -d ``` +user:tysiujogcmzapyhz Here, `username` is `user` and `password` is `tysiujogcmzapyhz`. @@ -340,12 +350,15 @@ Now, you can connect to this database using `telnet`. Here, we will connect to Memcached server from local-machine through port-forwarding. ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE memcd-quickstart-0 1/1 Running 1 (26m ago) 15h # We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding. -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +```bash +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 @@ -384,7 +397,6 @@ END # Exit quit -``` ## Database DeletionPolicy @@ -395,9 +407,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete mc memcd-quickstart -n demo -Error from server (Forbidden): admission webhook "memcachedwebhook.validators.kubedb.com" denied the request: memcached demo/memcd-quickstart can't be terminated. To delete, change spec.deletionPolicy +kubectl delete mc memcd-quickstart -n demo ``` +Error from server (Forbidden): admission webhook "memcachedwebhook.validators.kubedb.com" denied the request: memcached demo/memcd-quickstart can't be terminated. To delete, change spec.deletionPolicy Learn details of all `DeletionPolicy` [here](/docs/guides/memcached/concepts/memcached.md#specdeletionpolicy). **Delete:** @@ -409,18 +421,18 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete -n demo mc/memcd-quickstart -memcached.kubedb.com "memcd-quickstart" deleted +kubectl delete -n demo mc/memcd-quickstart ``` +memcached.kubedb.com "memcd-quickstart" deleted Now, run the following command to get all memcached resources in `demo` namespaces, ```bash -$ kubectl get petsets,svc,secret,pvc -n demo +kubectl get petsets,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE auth-secret Opaque 1 3h mc-configuration Opaque 1 3h -``` From the above output, you can see that all memcached resources(`PetSet`, `Service` etc.) are deleted except `Secret`. @@ -440,9 +452,9 @@ memcached.kubedb.com "memcd-quickstart" deleted Now, run the following command to get all memcached resources in `demo` namespaces, ```bash -$ kubectl get petsets,svc,secret -n demo -No resources found in demo namespace. +kubectl get petsets,svc,secret -n demo ``` +No resources found in demo namespace. From the above output, you can see that all memcached resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. @@ -454,15 +466,19 @@ From the above output, you can see that all memcached resources are deleted. the To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/memcd-quickstart patched -$ kubectl delete -n demo mc/memcd-quickstart +```bash +kubectl delete -n demo mc/memcd-quickstart +``` memcached.kubedb.com "memcd-quickstart" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md index e5fd9f789f..1d48b97542 100644 --- a/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/memcached/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. `add, remove, update and rotation of TLS/SSL ce - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + 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). @@ -57,28 +57,31 @@ spec: 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 +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 +watch kubectl get mc -n demo +``` Every 2.0s: kubectl get mc -n demo NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 26s -``` 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 +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 +```bash +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -110,7 +113,6 @@ ssl_ca_cert NULL END quit -``` We can verify from the above output that TLS is disabled for this database. @@ -121,23 +123,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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" +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 \ +kubectl create secret tls memcached-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/memcached-ca created ``` +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: @@ -155,9 +157,9 @@ 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/issuer.yaml -issuer.cert-manager.io/memcached-ca-issuer created +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 @@ -197,25 +199,26 @@ 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-add-tls.yaml -Memcachedopsrequest.ops.kubedb.com/mc-add-tls created +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/mc-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 +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. If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mcops -n demo mc-add-tls +kubectl describe mcops -n demo mc-add-tls +``` Name: mc-add-tls Namespace: demo Labels: @@ -304,12 +307,11 @@ Status: Phase: Successful Events: -``` - Now, let's describe the client.crt of running Memcached database. ```bash -$ kubectl describe secret -n demo memcd-quickstart-client-cert +kubectl describe secret -n demo memcd-quickstart-client-cert +``` Name: memcd-quickstart-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -336,17 +338,19 @@ 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 -$ kc port-forward -n demo memcd-quickstart-0 11211 +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 +```bash +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -378,19 +382,20 @@ ssl_ca_cert /usr/certs/ca.crt END quit -``` ## Rotate Certificate 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 +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 +```bash +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 Feb 16 04:58:37 2025 GMT. ### Create MemcachedOpsRequest @@ -419,25 +424,26 @@ 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-rotate.yaml -memcachedopsrequest.ops.kubedb.com/mc-ops-rotate created +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 +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. 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 +kubectl describe mcops -n demo mc-ops-rotate +``` Name: mc-ops-rotate Namespace: demo Labels: @@ -522,17 +528,17 @@ Status: Phase: Successful Events: -``` - Now, let’s check the expiration date of the certificate: ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +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 +```bash +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 @@ -542,23 +548,23 @@ 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" +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 \ +kubectl create secret tls memcached-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/memcached-new-ca created ``` +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: @@ -576,9 +582,9 @@ 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/mc-new-issuer.yaml -issuer.cert-manager.io/mc-new-issuer created +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 ### Create MemcachedOpsRequest @@ -610,25 +616,26 @@ 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-change-issuer.yaml -Memcachedopsrequest.ops.kubedb.com/mc-change-issuer created +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 +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 `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 +kubectl describe mcops -n demo mc-change-issuer +``` Name: mc-change-issuer Namespace: demo Labels: @@ -744,18 +751,19 @@ Events: 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 +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 +```bash +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 @@ -789,25 +797,26 @@ 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-tls-remove.yaml -memcachedopsrequest.ops.kubedb.com/mc-ops-tls-remove created +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-tls-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 +kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo 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-tls-remove +kubectl describe mcops -n demo mc-ops-tls-remove +``` Name: mc-ops-tls-remove Namespace: demo Labels: @@ -864,16 +873,18 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Lets check Memcached TLS is disabled or not. ```bash -$ kc port-forward -n demo memcd-quickstart-0 11211 +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 +```bash +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -894,7 +905,6 @@ ssl_ca_cert NULL END quit -``` So, we can see from the above that, output that tls is disabled successfully. @@ -903,22 +913,28 @@ So, we can see from the above that, output that tls is disabled successfully. 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" +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 +```bash +kubectl delete memcached -n demo memcd-quickstart +``` memcached.kubedb.com/memcd-quickstart deleted -$ kubectl delete issuer -n demo memcached-ca-issuer mc-new-issuer +```bash +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-tls-remove mc-ops-rotate mc-change-issuer +```bash +kubectl delete memcachedopsrequest -n demo mc-add-tls mc-ops-tls-remove mc-ops-rotate mc-change-issuer +``` memcachedopsrequest.ops.kubedb.com "mc-add-tls" deleted memcachedopsrequest.ops.kubedb.com "mc-ops-tls-remove" deleted memcachedopsrequest.ops.kubedb.com "mc-ops-rotate" deleted memcachedopsrequest.ops.kubedb.com "mc-change-issuer" deleted -``` ## Next Steps diff --git a/docs/guides/memcached/reconfigure/reconfigure.md b/docs/guides/memcached/reconfigure/reconfigure.md index 73716e3d95..113294c2df 100644 --- a/docs/guides/memcached/reconfigure/reconfigure.md +++ b/docs/guides/memcached/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached](/docs/examples/memcached) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -61,9 +61,9 @@ Here, `maxclients` is set to `500`, whereas the default value is `1024`. Now, we will apply the secret with custom configuration. ```bash -$ kubectl create -f mc-configuration -secret/mc-configuration created +kubectl create -f mc-configuration ``` +secret/mc-configuration created In this section, we are going to create a Memcached object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Memcahced` CR that we are going to create, @@ -84,32 +84,33 @@ spec: 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/memcached-config.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure/memcached-config.yaml ``` +memcached.kubedb.com/memcd-quickstart created Now, wait until `memcd-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 -``` Now, connect to the memcached server from a different terminal through `telnet`. ```bash -$ telnet 127.0.0.1 11211 +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -123,7 +124,6 @@ stats STAT max_connections 500 ... END -``` As we can see from the configuration of running memcached, the value of `maxclients` has been set to `500`. @@ -148,9 +148,9 @@ Here, `maxclients` is set to `2000`. Now, we will apply the secret with custom configuration. ```bash -$ kubectl create -f new-configuration -secret/new-configuration created +kubectl create -f new-configuration ``` +secret/new-configuration created #### Create MemcachedOpsRequest @@ -180,9 +180,9 @@ 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/config-secret-reconfigure.yaml -memcachedopsrequest.ops.kubedb.com/memcd-reconfig created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure/config-secret-reconfigure.yaml ``` +memcachedopsrequest.ops.kubedb.com/memcd-reconfig created #### Verify the new configuration is working @@ -191,16 +191,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcahcedOpsRequest` CR, ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo NAME TYPE STATUS AGE memcd-reconfig Reconfigure Successful 1m -``` 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 to reconfigure the database. ```bash -$ kubectl describe memcachedopsrequest -n demo memcd-reconfig +kubectl describe memcachedopsrequest -n demo memcd-reconfig +``` Name: memcd-reconfig Namespace: demo Labels: @@ -272,32 +273,31 @@ Events: Normal ResumeDatabase 38s KubeDB Ops-manager Operator Successfully resumed Memcached demo/memcd-quickstart Normal Successful 38s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` - Now need to check the new configuration we have provided. Now, wait until `memcd-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 20s -``` Now, we will check if the database has started with the custom configuration we have provided. We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 -``` Now, connect to the memcached server from a different terminal through `telnet`. ```bash -$ telnet 127.0.0.1 11211 +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -311,7 +311,6 @@ stats STAT max_connections 2000 ... END -``` As we can see from the configuration of running memcached, the value of `maxclients` has been updated to `2000`. @@ -351,9 +350,9 @@ 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/apply-config-reconfigure.yaml -memcachedopsrequest.ops.kubedb.com/memcd-reconfig created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/reconfigure/apply-config-reconfigure.yaml ``` +memcachedopsrequest.ops.kubedb.com/memcd-reconfig created #### Verify the new configuration is working @@ -362,16 +361,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CR, ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo NAME TYPE STATUS AGE memcd-apply-reconfig Reconfigure Successful 38s -``` We can see from the above output that the `MemcachedOpsRequest` has succeeded. If we describe the `MemcahcedOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe memcachedopsrequest -n demo memcd-apply-reconfig +kubectl describe memcachedopsrequest -n demo memcd-apply-reconfig +``` Name: memcd-apply-reconfig Namespace: demo Labels: @@ -444,22 +444,21 @@ Events: Normal ResumeDatabase 13s KubeDB Ops-manager Operator Successfully resumed Memcached demo/memcd-quickstart Normal Successful 13s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` - Now let's check the new configuration we have provided. We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 -``` Now, connect to the memcached server from a different terminal through `telnet`. ```bash -$ telnet 127.0.0.1 11211 +telnet 127.0.0.1 11211 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -473,7 +472,6 @@ stats STAT max_connections 3000 ... END -``` As we can see from the configuration of running memcached, the value of `maxclients` has been changed from `2000` to `3000`. So, the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/memcached/restart/restart.md b/docs/guides/memcached/restart/restart.md index 8807dd2d72..b314aa19f2 100644 --- a/docs/guides/memcached/restart/restart.md +++ b/docs/guides/memcached/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Memcached database via a MemcachedOpsRequest. Res - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```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). @@ -61,9 +61,9 @@ spec: 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 +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 @@ -86,18 +86,21 @@ spec: 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 +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 +```bash +kubectl get mcops -n demo restart +``` NAME TYPE STATUS AGE restart Restart Successful 3m25s -$ kubectl get mcops -n demo restart -oyaml +```bash +kubectl get mcops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: MemcachedOpsRequest metadata: @@ -152,7 +155,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/memcached/rotate-auth/rotateauth.md b/docs/guides/memcached/rotate-auth/rotateauth.md index 6f0fa82f8c..352cdbb0ac 100644 --- a/docs/guides/memcached/rotate-auth/rotateauth.md +++ b/docs/guides/memcached/rotate-auth/rotateauth.md @@ -30,20 +30,23 @@ existing secretwith the new credential, and does not provide the secretdetails d - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 1s -``` ## Find Available MemcachedVersion When you have installed KubeDB, it has created `MemcachedVersion` crd for all supported Memcached versions. Check 0 ```bash -$ kubectl get memcachedversions +kubectl get memcachedversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.5 1.5 ghcr.io/kubedb/memcached:1.5 true 5d19h 1.5-v1 1.5 ghcr.io/kubedb/memcached:1.5-v1 true 5d19h @@ -53,7 +56,6 @@ NAME VERSION DB_IMAGE DEPRECATE 1.6.40 1.6.40 ghcr.io/appscode-images/memcached:1.6.40-alpine 5d19h 1.6.29 1.6.29 ghcr.io/appscode-images/memcached:1.6.29-alpine 5d19h 1.6.33 1.6.33 ghcr.io/appscode-images/memcached:1.6.33-alpine 5d19h -``` > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached/rotate-auth](/docs/examples/memcached/rotate-auth) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -87,17 +89,17 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/quickstart/demo-v1.yaml ``` +memcached.kubedb.com/memcd-quickstart created Now, wait until memcd-quickstart has status Ready. i.e, -```shell -$ kubectl get mc -n demo -w +```bash + kubectl get mc -n demo -w +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 17h -``` ## Verify Authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an example showing how to retrieve the credentials from the Secret. @@ -114,10 +116,10 @@ Here, `username`is `user` and `password` is `ikbkjbodeewenrgj` Here, we will connect to Memcached server from local-machine through port-forwarding. We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding and it must be running in separate terminal. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 -``` Now, you can connect to this database using `telnet`.Connect to Memcached from local-machine through telnet. ```shell @@ -173,19 +175,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Memcached. Let's create the `MemcachedOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/memcached/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/memcached/rotate-auth/rotate-auth-generated.yaml + ``` Memcachedopsrequest.ops.kubedb.com/mcops-rotate-auth-generated created -``` Let's wait for `MemcachedOpsrequest` to be `Successful`. Run the following command to watch `MemcachedOpsrequest` CRO -```shell - $ kubectl get Memcachedopsrequest -n demo + ```bash + kubectl get Memcachedopsrequest -n demo + ``` NAME TYPE STATUS AGE mcops-rotate-auth-generated RotateAuth Successful 7m47s -``` If we describe the `MemcachedOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe MemcachedopsRequest -n demo mcops-rotate-auth-generated +```bash +kubectl describe MemcachedopsRequest -n demo mcops-rotate-auth-generated +``` Name: mcops-rotate-auth-generated Namespace: demo Labels: @@ -265,28 +268,29 @@ Events: Normal ResumeDatabase 98s KubeDB Ops-manager Operator Resuming Memcached demo/memcd-quickstart Normal ResumeDatabase 98s KubeDB Ops-manager Operator Successfully resumed Memcached demo/memcd-quickstart Normal Successful 98s KubeDB Ops-manager Operator Successfully Rotated Memcached Auth secretfor demo/memcd-quickstart -``` **Verify Auth is rotated** -```shell -$ kubectl get mc -n demo memcd-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get mc -n demo memcd-quickstart -ojson | jq .spec.authSecret.name +``` "memcd-quickstart-auth" -$ kubectl get secret -n demo memcd-quickstart-auth -o=jsonpath='{.data.authData}' | base64 -d -user:yjf3Oc;ZlSs.iMVO + +```bash +kubectl get secret -n demo memcd-quickstart-auth -o=jsonpath='{.data.authData}' | base64 -d ``` +user:yjf3Oc;ZlSs.iMVO **Let's verify whether the credential is working or not:** We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding and it must be running in separate terminal. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 - -``` Now, you can connect to this database using `telnet`.Connect to Memcached from local-machine through telnet. -```shell - -$ telnet 127.0.0.1 11211 +```bash +telnet 127.0.0.1 11211 +``` #Output Trying 127.0.0.1... Connected to 127.0.0.1. @@ -308,14 +312,13 @@ VERSION 1.6.40 #output quit Connection closed by foreign host. -``` Your credentials have been rotated successfully, so everything’s working. Also, there will be two more new keys in the secretthat stores the previous credentials. The key is `authData.prev`. You can find the secretand its data by running the following command: -```shell -$ kubectl get secret -n demo memcd-quickstart-auth -o go-template='{{ index .data "authData.prev" }}' | base64 -d -user:ikbkjbodeewenrgj +```bash +kubectl get secret -n demo memcd-quickstart-auth -o go-template='{{ index .data "authData.prev" }}' | base64 -d ``` +user:ikbkjbodeewenrgj The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using User Created Credentials @@ -368,20 +371,21 @@ Here, Let's create the `MemcachedOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/memcached/rotate-auth/rotate-auth-user.yaml -Memcachedopsrequest.ops.kubedb.com/mcops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/memcached/rotate-auth/rotate-auth-user.yaml ``` +Memcachedopsrequest.ops.kubedb.com/mcops-rotate-auth-user created Let’s wait for `MemcachedOpsRequest` to be Successful. Run the following command to watch `MemcachedOpsRequest` CRO: -```shell -$ kubectl get Memcachedopsrequest -n demo +```bash +kubectl get Memcachedopsrequest -n demo +``` NAME TYPE STATUS AGE mcops-rotate-auth-user RotateAuth Successful 7m44s -``` 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. -```shell -$ kubectl describe Memcachedopsrequest -n demo mcops-rotate-auth-user +```bash +kubectl describe Memcachedopsrequest -n demo mcops-rotate-auth-user +``` Name: mcops-rotate-auth-user Namespace: demo Labels: @@ -463,28 +467,28 @@ Events: Normal ResumeDatabase 13m KubeDB Ops-manager Operator Resuming Memcached demo/memcd-quickstart Normal ResumeDatabase 13m KubeDB Ops-manager Operator Successfully resumed Memcached demo/memcd-quickstart Normal Successful 13m KubeDB Ops-manager Operator Successfully Rotated Memcached Auth secretfor demo/memcd-quickstart - -``` **Verify auth is rotate** -```shell -$ kubectl get mc -n demo memcd-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get mc -n demo memcd-quickstart -ojson | jq .spec.authSecret.name +``` "mc-new-auth" -$ kubectl get secret -n demo mc-new-auth -o=jsonpath='{.data.authData}' | base64 -d -user:pass + +```bash + kubectl get secret -n demo mc-new-auth -o=jsonpath='{.data.authData}' | base64 -d ``` +user:pass **Let's verify whether the credential is working or not:** We will connect to `memcd-quickstart-0` pod from local-machine using port-frowarding and it must be running in separate terminal. ```bash -$ kubectl port-forward -n demo memcd-quickstart-0 11211 +kubectl port-forward -n demo memcd-quickstart-0 11211 +``` Forwarding from 127.0.0.1:11211 -> 11211 Forwarding from [::1]:11211 -> 11211 - -``` Now, you can connect to this database using `telnet`.Connect to Memcached from local-machine through telnet. -```shell - -$ telnet 127.0.0.1 11211 +```bash +telnet 127.0.0.1 11211 +``` #Output Trying 127.0.0.1... Connected to 127.0.0.1. @@ -506,15 +510,13 @@ VERSION 1.6.40 #output quit Connection closed by foreign host. -``` Your credentials have been rotated successfully, so everything’s working. Also, there will be a new key in the secretthat stores the previous credentials. The key is `authData.prev`. You can find the secretand its data by running the following command: -```shell -$ kubectl get secret -n demo mc-new-auth -o go-template='{{ index .data "authData.prev" }}' | base64 -d -user:yjf3Oc;ZlSs.iMVO - +```bash +kubectl get secret -n demo mc-new-auth -o go-template='{{ index .data "authData.prev" }}' | base64 -d ``` +user:yjf3Oc;ZlSs.iMVO The above output shows that the password has been updated successfully. The previous username & password is stored in the secretfor rollback purpose. @@ -523,17 +525,26 @@ The above output shows that the password has been updated successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete memcachedopsrequest -n demo mcops-rotate-auth-generated mcops-rotate-auth-user +```bash +kubectl delete memcachedopsrequest -n demo mcops-rotate-auth-generated mcops-rotate-auth-user +``` memcachedopsrequest.ops.kubedb.com "mcops-rotate-auth-generated" deleted memcachedopsrequest.ops.kubedb.com "mcops-rotate-auth-user" deleted -$ kubectl delete secret -n demo mc-new-auth + +```bash +kubectl delete secret -n demo mc-new-auth +``` secret "mc-new-auth" deleted -$ kubectl delete secret -n demo memcd-quickstart-auth + +```bash +kubectl delete secret -n demo memcd-quickstart-auth +``` secret "memcd-quickstart-auth" deleted -$ kubectl delete memcached -n demo memcd-quickstart -memcached.kubedb.com "memcd-quickstart" deleted + +```bash +kubectl delete memcached -n demo memcd-quickstart ``` +memcached.kubedb.com "memcd-quickstart" deleted ## Next Steps diff --git a/docs/guides/memcached/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/memcached/scaling/horizontal-scaling/horizontal-scaling.md index d4e8d51ae7..a6f72367ab 100644 --- a/docs/guides/memcached/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/memcached/scaling/horizontal-scaling/horizontal-scaling.md @@ -31,9 +31,9 @@ This guide will give an overview on how KubeDB Ops-manager operator scales up or To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached](/docs/examples/memcached) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -75,24 +75,24 @@ spec: 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/scaling/memcached-horizontal.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/scaling/memcached-horizontal.yaml ``` +memcached.kubedb.com/memcd-quickstart created Now, wait until `memcd-quickstart` has status `Ready`. i.e. , ```bash -$ kubectl get memcached -n demo +kubectl get memcached -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 5m -``` Let's check the number of replicas this database has from the Memcached object ```bash -$ kubectl get memcached -n demo memcd-quickstart -o json | jq '.spec.replicas' -3 +kubectl get memcached -n demo memcd-quickstart -o json | jq '.spec.replicas' ``` +3 We are now ready to apply the `MemcachedOpsRequest` CR to update the resources of this database. @@ -127,9 +127,9 @@ 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/scaling/horizontal-scaling.yaml -memcachedopsrequest.ops.kubedb.com/memcd-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/scaling/horizontal-scaling.yaml ``` +memcachedopsrequest.ops.kubedb.com/memcd-horizontal-up created #### Verify Memcached resources updated successfully @@ -138,17 +138,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CR, ```bash -$ watch kubectl get memcachedopsrequest -n demo memcd-horizontal-up +watch kubectl get memcachedopsrequest -n demo memcd-horizontal-up +``` NAME TYPE STATUS AGE memcd-horizontal-up HorizontalScaling Successful 3m -``` Now, we are going to verify if the number of replicas the memcached database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get memcached -n demo memcd-quickstart -o json | jq '.spec.replicas' -5 +kubectl get memcached -n demo memcd-quickstart -o json | jq '.spec.replicas' ``` +5 The above output verifies that we have successfully scaled up the replicas of the Memcached database. @@ -157,13 +157,16 @@ The above output verifies that we have successfully scaled up the replicas of th To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/memcd-quickstart patched -$ kubectl delete -n demo memcached memcd-quickstart +```bash +kubectl delete -n demo memcached memcd-quickstart +``` memcached.kubedb.com "memcd-quickstart" deleted -$ kubectl delete -n demo memcachedopsrequest memcd-horizontal-up -memcachedopsrequest.ops.kubedb.com "memcd-horizontal-up" deleted -``` \ No newline at end of file +```bash +kubectl delete -n demo memcachedopsrequest memcd-horizontal-up +``` +memcachedopsrequest.ops.kubedb.com "memcd-horizontal-up" deleted \ No newline at end of file diff --git a/docs/guides/memcached/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/memcached/scaling/vertical-scaling/vertical-scaling.md index 8cb1e9a81c..c47c7a90ec 100644 --- a/docs/guides/memcached/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/memcached/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached](/docs/examples/memcached) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -74,22 +74,23 @@ spec: 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/scaling/memcached-vertical.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/scaling/memcached-vertical.yaml ``` +memcached.kubedb.com/memcd-quickstart created Now, wait until `memcd-quickstart` has status `Ready`. i.e. , ```bash -$ kubectl get memcached -n demo +kubectl get memcached -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.40 Ready 5m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "100m", @@ -100,7 +101,6 @@ $ kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].re "memory": "128Mi" } } -``` We can see from the above output that there are some default resources set by the operator. And the scheduler will choose the best suitable node to place the container of the Pod. @@ -144,9 +144,9 @@ 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/scaling/vertical-scaling.yaml -memcachedopsrequest.ops.kubedb.com/memcached-mc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/scaling/vertical-scaling.yaml ``` +memcachedopsrequest.ops.kubedb.com/memcached-mc created #### Verify Memcached Database resources updated successfully @@ -155,16 +155,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CR, ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` NAME TYPE STATUS AGE memcached-mc VerticalScaling Successful 5m -``` We can see from the above output that the `MemcachedOpsRequest` has succeeded. Now, we are going to verify from the Pod yaml whether the resources of the Memcached database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -175,7 +176,6 @@ $ kubectl get pod -n demo memcd-quickstart-0 -o json | jq '.spec.containers[].re "memory": "400Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the Memcached database. @@ -184,13 +184,16 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this turorial, run: ```bash - -$ kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/memcd-quickstart patched -$ kubectl delete -n demo memcached memcd-quickstart +```bash +kubectl delete -n demo memcached memcd-quickstart +``` memcached.kubedb.com "memcd-quickstart" deleted -$ kubectl delete memcachedopsrequest -n demo memcached-mc -memcachedopsrequest.ops.kubedb.com "memcached-mc" deleted -``` \ No newline at end of file +```bash +kubectl delete memcachedopsrequest -n demo memcached-mc +``` +memcachedopsrequest.ops.kubedb.com "memcached-mc" deleted \ No newline at end of file diff --git a/docs/guides/memcached/tls/tls.md b/docs/guides/memcached/tls/tls.md index ff4c1ad648..640578e782 100644 --- a/docs/guides/memcached/tls/tls.md +++ b/docs/guides/memcached/tls/tls.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for `Memcached`. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + 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). @@ -61,13 +61,13 @@ We are going to create an example `Issuer` that will be used throughout the dura - 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" +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 \ +kubectl create secret tls memcached-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo @@ -89,9 +89,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/tls/memcached-ca-issuer.yaml -issuer.cert-manager.io/memcached-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/tls/memcached-ca-issuer.yaml ``` +issuer.cert-manager.io/memcached-ca-issuer created ## TLS/SSL encryption in Memcached Standalone @@ -122,25 +122,26 @@ spec: ### 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 +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 memcached -n demo +watch kubectl get memcached -n demo +``` Every 2.0s: kubectl get memcached -n demo NAME VERSION STATUS AGE memcd-quickstart 1.6.40 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 +kubectl describe secret -n demo memcd-quickstart-client-cert +``` Name: memcd-quickstart-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -165,26 +166,26 @@ 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 +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 \ +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 ``` +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 +telnet 127.0.0.1 12345 +``` Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. @@ -216,21 +217,24 @@ 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" +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 +```bash +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 +```bash +kubectl delete issuer -n demo memcached-ca-issuer ``` +issuer.cert-manager.io "memcached-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/memcached/update-version/update-version.md b/docs/guides/memcached/update-version/update-version.md index 91a4b7cef8..e0e01fd2aa 100644 --- a/docs/guides/memcached/update-version/update-version.md +++ b/docs/guides/memcached/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/memcached](/docs/examples/memcached) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -71,17 +71,17 @@ spec: 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/update-version/memcached.yaml -memcached.kubedb.com/memcd-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/update-version/memcached.yaml ``` +memcached.kubedb.com/memcd-quickstart created Now, wait until `memcd-quickstart` created has status `Ready`. i.e, ```bash -$ kubectl get mc -n demo +kubectl get mc -n demo +``` NAME VERSION STATUS AGE memcd-quickstart 1.6.33 Ready 3m -``` We are now ready to apply the `MemcachedOpsRequest` CR to update this database. @@ -116,9 +116,9 @@ 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/update-version/opsrequest-version-update.yaml -memcachedopsrequest.ops.kubedb.com/update-memcd created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/memcached/update-version/opsrequest-version-update.yaml ``` +memcachedopsrequest.ops.kubedb.com/update-memcd created #### Verify Memcached version updated successfully : @@ -127,26 +127,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `MemcachedOpsRequest` to be `Successful`. Run the following command to watch `MemcachedOpsRequest` CR, ```bash -$ watch kubectl get memcachedopsrequest -n demo +watch kubectl get memcachedopsrequest -n demo +``` Every 2.0s: kubectl get memcachedopsrequest -n demo NAME TYPE STATUS AGE update-memcd UpdateVersion Successful 7m -``` We can see from the above output that the `MemcachedOpsRequest` has succeeded. Now, we are going to verify whether the `Memcached` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get memcached -n demo memcd-quickstart -o=jsonpath='{.spec.version}{"\n"}' +kubectl get memcached -n demo memcd-quickstart -o=jsonpath='{.spec.version}{"\n"}' +``` 1.6.40 -$ kubectl get petset -n demo memcd-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo memcd-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/memcached:1.6.40-alpine -$ kubectl get pods -n demo memcd-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/memcached:1.6.40-alpine +```bash +kubectl get pods -n demo memcd-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/memcached:1.6.40-alpine You can see from above, our `Memcached` database has been updated with the new version. So, the UpdateVersion process is successfully completed. @@ -155,12 +159,16 @@ You can see from above, our `Memcached` database has been updated with the new v To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mc/memcd-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` memcached.kubedb.com/memcd-quickstart patched -$ kubectl delete -n demo Memcached memcd-quickstart +```bash +kubectl delete -n demo Memcached memcd-quickstart +``` memcached.kubedb.com "memcd-quickstart" deleted -$ kubectl delete -n demo memcachedopsrequest update-memcd -memcachedopsrequest.ops.kubedb.com "update-memcd" deleted +```bash +kubectl delete -n demo memcachedopsrequest update-memcd ``` +memcachedopsrequest.ops.kubedb.com "update-memcd" deleted diff --git a/docs/guides/milvus/autoscaler/compute/guide.md b/docs/guides/milvus/autoscaler/compute/guide.md index e3f33e3d40..86683f4a27 100644 --- a/docs/guides/milvus/autoscaler/compute/guide.md +++ b/docs/guides/milvus/autoscaler/compute/guide.md @@ -26,10 +26,10 @@ This guide will show you how to use the `KubeDB` Autoscaler operator to autoscal - Install the **KubeDB Autoscaler** operator and a **metrics server** in your cluster — the VPA recommender needs metrics to produce recommendations. ```bash - $ kubectl get deploy metrics-server -n kube-system + kubectl get deploy metrics-server -n kube-system + ``` NAME READY UP-TO-DATE AVAILABLE AGE metrics-server 1/1 1 1 5m - ``` - An object-storage secret named `my-release-minio` must exist in the `demo` namespace. @@ -68,22 +68,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/autoscaler/compute/yamls/compute-standalone.yaml -milvusautoscaler.autoscaling.kubedb.com/milvus-standalone-compute-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/autoscaler/compute/yamls/compute-standalone.yaml ``` +milvusautoscaler.autoscaling.kubedb.com/milvus-standalone-compute-autoscaler created The autoscaler creates a `VerticalPodAutoscaler` (VPA) object. Once the VPA recommender produces a recommendation that differs from the current resources by more than `resourceDiffPercentage`, the autoscaler creates a `VerticalScaling` `MilvusOpsRequest`. ```bash -$ kubectl get milvusautoscaler -n demo +kubectl get milvusautoscaler -n demo +``` NAME AGE milvus-standalone-compute-autoscaler 59s -``` The autoscaler runs a VPA recommender (fed by the metrics server) and records the recommendation in its status. Once enough samples are collected, the `RecommendationProvided` condition becomes `True` and a target resource set is published: ```bash -$ kubectl get milvusautoscaler milvus-standalone-compute-autoscaler -n demo -o jsonpath='{.status}' | jq . +kubectl get milvusautoscaler milvus-standalone-compute-autoscaler -n demo -o jsonpath='{.status}' | jq . +``` { "vpas": [ { @@ -104,19 +105,20 @@ $ kubectl get milvusautoscaler milvus-standalone-compute-autoscaler -n demo -o j } ] } -``` Here the recommended `target` is `cpu: 143m` / `memory: 256Mi` (the standalone idles well below its `500m` request). Because the recommendation differs from the current request by more than `resourceDiffPercentage` (10%) and stays within `minAllowed`/`maxAllowed`, the autoscaler creates a `VerticalScaling` `MilvusOpsRequest`. This is recorded in the autoscaler status as a `CreateOpsRequest` condition: ```bash -$ kubectl get milvusautoscaler milvus-standalone-compute-autoscaler -n demo \ +kubectl get milvusautoscaler milvus-standalone-compute-autoscaler -n demo \ -o jsonpath='{.status.conditions[?(@.type=="CreateOpsRequest")].message}' +``` Successfully created MilvusOpsRequest demo/mvops-milvus-standalone-xqwkhv -$ kubectl get milvusopsrequest -n demo +```bash +kubectl get milvusopsrequest -n demo +``` NAME TYPE STATUS AGE mvops-milvus-standalone-xqwkhv VerticalScaling Progressing 2s -``` The Ops-manager then applies the vertical scaling exactly as in the [vertical scaling guide](/docs/guides/milvus/scaling/vertical-scaling/guide.md), right-sizing the pod to the recommended resources. @@ -163,9 +165,15 @@ The behavior is identical to standalone, except a VPA object and resource recomm ## Cleaning up ```bash -$ kubectl delete milvusautoscaler -n demo --all -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusautoscaler -n demo --all +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/autoscaler/storage/guide.md b/docs/guides/milvus/autoscaler/storage/guide.md index be5ef5b163..960ebfb270 100644 --- a/docs/guides/milvus/autoscaler/storage/guide.md +++ b/docs/guides/milvus/autoscaler/storage/guide.md @@ -60,26 +60,26 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/autoscaler/storage/yamls/storage-standalone.yaml -milvusautoscaler.autoscaling.kubedb.com/milvus-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/autoscaler/storage/yamls/storage-standalone.yaml ``` +milvusautoscaler.autoscaling.kubedb.com/milvus-storage-autoscaler created When the volume usage crosses `usageThreshold` (30%), the autoscaler creates a `VolumeExpansion` `MilvusOpsRequest` sized per `scalingRules`. ```bash -$ kubectl get milvusautoscaler -n demo +kubectl get milvusautoscaler -n demo +``` NAME AGE milvus-standalone-compute-autoscaler 94s milvus-storage-autoscaler 93s -``` The storage autoscaler watches the `streamingnode`/`node` PVC usage (read from Prometheus). When usage crosses `usageThreshold`, it creates a `VolumeExpansion` `MilvusOpsRequest`. In this walkthrough the volume stayed well below the threshold (a freshly-created, near-empty `1Gi` volume), so no expansion was triggered: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +``` NAME SIZE data-milvus-standalone-0 1Gi -``` > To see the expansion fire, write enough data to push PVC usage past `usageThreshold` (30% here). When it does, the autoscaler creates a `VolumeExpansion` `MilvusOpsRequest` (with `expansionMode` as configured), which the Ops-manager applies — see the [volume expansion guide](/docs/guides/milvus/volume-expansion/guide.md) for the resulting flow and output. @@ -116,9 +116,15 @@ Because only `streamingnode` carries a persistent volume among the distributed r ## Cleaning up ```bash -$ kubectl delete milvusautoscaler -n demo --all -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusautoscaler -n demo --all +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/monitoring/using-prometheus-operator.md b/docs/guides/milvus/monitoring/using-prometheus-operator.md index 2a940b6abc..775290d552 100644 --- a/docs/guides/milvus/monitoring/using-prometheus-operator.md +++ b/docs/guides/milvus/monitoring/using-prometheus-operator.md @@ -54,24 +54,25 @@ Deploy the database and wait until it is `Ready`. When monitoring is enabled, KubeDB creates a dedicated **stats service** named `-stats` exposing the metrics port `9091`: ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE milvus-standalone ClusterIP 10.43.144.154 19530/TCP 91s milvus-standalone-stats ClusterIP 10.43.12.191 9091/TCP 91s -``` ## ServiceMonitor KubeDB also creates a `ServiceMonitor` named `-stats` that selects the stats service: ```bash -$ kubectl get servicemonitor -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get servicemonitor -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME AGE milvus-standalone-stats 90s -``` ```bash -$ kubectl get servicemonitor milvus-standalone-stats -n demo -o yaml +kubectl get servicemonitor milvus-standalone-stats -n demo -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -105,7 +106,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: milvuses.kubedb.com kubedb.com/role: stats -``` Key points: @@ -121,7 +121,8 @@ Once the Prometheus Operator reconciles this `ServiceMonitor`, Milvus metrics be Monitoring works identically for a distributed Milvus. A single stats service and `ServiceMonitor` named `milvus-cluster-stats` are created, and metrics are scraped from the distributed components (each role's pods expose port `9091`). ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE milvus-cluster ClusterIP 10.43.221.1 19530/TCP 3m milvus-cluster-datanode ClusterIP None 9091/TCP 3m @@ -130,7 +131,9 @@ milvus-cluster-querynode ClusterIP None 9091/TCP milvus-cluster-stats ClusterIP 10.43.95.57 9091/TCP 3m milvus-cluster-streamingnode ClusterIP None 9091/TCP 3m -$ kubectl get servicemonitor milvus-cluster-stats -n demo -o yaml +```bash +kubectl get servicemonitor milvus-cluster-stats -n demo -o yaml +``` ... spec: endpoints: @@ -148,13 +151,15 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: milvuses.kubedb.com kubedb.com/role: stats -``` ## Cleaning up ```bash -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/quickstart/distributed.md b/docs/guides/milvus/quickstart/distributed.md index 1fe5a64f40..38c554ab1f 100644 --- a/docs/guides/milvus/quickstart/distributed.md +++ b/docs/guides/milvus/quickstart/distributed.md @@ -27,9 +27,9 @@ This tutorial will show you how to use KubeDB to provision a **Distributed** [Mi - Create the `demo` namespace: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/milvus/quickstart/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -95,53 +95,54 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls/distributed.yaml -milvus.kubedb.com/milvus-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls/distributed.yaml ``` +milvus.kubedb.com/milvus-cluster created ## Wait for the Cluster to be Ready Distributed Milvus takes longer than standalone — allow time for all components and the internal etcd to settle. ```bash -$ kubectl get milvuses.kubedb.com -n demo milvus-cluster -w +kubectl get milvuses.kubedb.com -n demo milvus-cluster -w +``` NAME VERSION STATUS AGE milvus-cluster 2.6.11 Provisioning 20s milvus-cluster 2.6.11 Ready 3m -``` ## Verify the Created Resources ### PetSets — one per role ```bash -$ kubectl get petset -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get petset -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME AGE milvus-cluster-datanode 2m57s milvus-cluster-mixcoord 2m58s milvus-cluster-proxy 2m54s milvus-cluster-querynode 2m56s milvus-cluster-streamingnode 2m55s -``` The four roles other than `streamingnode` were created even though only `streamingnode` was specified — they are the defaulted distributed components. ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME READY STATUS RESTARTS AGE milvus-cluster-datanode-0 1/1 Running 0 2m58s milvus-cluster-mixcoord-0 1/1 Running 0 2m59s milvus-cluster-proxy-0 1/1 Running 0 2m55s milvus-cluster-querynode-0 1/1 Running 0 2m57s milvus-cluster-streamingnode-0 1/1 Running 0 2m55s -``` ### Services A primary client service (`milvus-cluster`, gRPC `19530`, backed by the proxy), a metrics stats service (`milvus-cluster-stats`), and a headless governing service per role (`9091`) are created: ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE milvus-cluster ClusterIP 10.43.221.1 19530/TCP 3m milvus-cluster-datanode ClusterIP None 9091/TCP 3m @@ -149,41 +150,48 @@ milvus-cluster-mixcoord ClusterIP None 9091/TCP milvus-cluster-querynode ClusterIP None 9091/TCP 3m milvus-cluster-stats ClusterIP 10.43.95.57 9091/TCP 3m milvus-cluster-streamingnode ClusterIP None 9091/TCP 3m -``` ### Storage — only on streamingnode There is exactly one Milvus PVC, for the `streamingnode`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-milvus-cluster-streamingnode-0 Bound pvc-... 1Gi RWO local-path 2m55s -``` ### Auth, TLS, and AppBinding As with standalone, KubeDB auto-generates the auth secret (`milvus-cluster-auth`, user `root`), the TLS certificate secrets, the rendered configuration secret, and an `AppBinding`. Because TLS is enabled, the AppBinding scheme is `https`: ```bash -$ kubectl get secret -n demo | grep milvus-cluster +kubectl get secret -n demo | grep milvus-cluster +``` milvus-cluster-auth kubernetes.io/basic-auth 2 3m milvus-cluster-client-cert kubernetes.io/tls 4 3m milvus-cluster-d7497a Opaque 2 3m milvus-cluster-server-cert kubernetes.io/tls 3 3m -$ kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service}' -{"name":"milvus-cluster","path":"/","port":19530,"scheme":"https"} +```bash +kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service}' ``` +{"name":"milvus-cluster","path":"/","port":19530,"scheme":"https"} > These base manifests already include **Prometheus Operator monitoring** and **TLS** — see the [monitoring](/docs/guides/milvus/monitoring/using-prometheus-operator.md) and [TLS](/docs/guides/milvus/tls/configure/index.md) guides. ## Cleaning up ```bash -$ kubectl patch -n demo milvus.kubedb.com milvus-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete milvus.kubedb.com milvus-cluster -n demo -$ kubectl delete ns demo +kubectl patch -n demo milvus.kubedb.com milvus-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete milvus.kubedb.com milvus-cluster -n demo +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/quickstart/standalone.md b/docs/guides/milvus/quickstart/standalone.md index b4a1801e39..b9bbf28427 100644 --- a/docs/guides/milvus/quickstart/standalone.md +++ b/docs/guides/milvus/quickstart/standalone.md @@ -29,9 +29,9 @@ This tutorial will show you how to use KubeDB to provision a **Standalone** [Mil - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/milvus/quickstart/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,22 +40,22 @@ This tutorial will show you how to use KubeDB to provision a **Standalone** [Mil When you install the KubeDB operator, it registers a CRD named `MilvusVersion`. The installation comes with a set of built-in `MilvusVersion` objects. Let's check the available `MilvusVersion`s by: ```bash -$ kubectl get milvusversions +kubectl get milvusversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2.6.11 2.6.11 ghcr.io/appscode-images/milvus:2.6.11 11h 2.6.7 2.6.7 ghcr.io/appscode-images/milvus:2.6.7 11h 2.6.9 2.6.9 ghcr.io/appscode-images/milvus:2.6.9 11h -``` ## Prepare Object Storage Secret Milvus stores its segments/logs in object storage, so an object-storage connection secret **must** exist before you create a `Milvus` object. The secret is referenced through `spec.objectStorage.configSecret`. A typical MinIO-backed secret holds three keys — `address`, `accesskey`, and `secretkey`: ```bash -$ kubectl get secret my-release-minio -n demo +kubectl get secret my-release-minio -n demo +``` NAME TYPE DATA AGE my-release-minio Opaque 3 11h -``` > If you do not have a MinIO deployment yet, you can adapt the sample secret shipped with the Milvus operator. The exact contents depend on your storage endpoint and credentials. @@ -115,9 +115,9 @@ Here, Create the database: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls/standalone.yaml -milvus.kubedb.com/milvus-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/quickstart/yamls/standalone.yaml ``` +milvus.kubedb.com/milvus-standalone created ## Wait for the Database to be Ready @@ -126,11 +126,11 @@ KubeDB will create the necessary resources to provision the Milvus database. Wat > **Note:** Because both `milvuses.kubedb.com` and `milvuses.gitops.kubedb.com` are registered, the short name `milvus` is ambiguous. Use the fully-qualified `milvuses.kubedb.com` (or `kubectl get milvus.kubedb.com`) to query the database. ```bash -$ kubectl get milvuses.kubedb.com -n demo -w +kubectl get milvuses.kubedb.com -n demo -w +``` NAME VERSION STATUS AGE milvus-standalone 2.6.11 Provisioning 24s milvus-standalone 2.6.11 Ready 39s -``` Standalone Milvus typically becomes ready within a few minutes. @@ -139,35 +139,37 @@ Standalone Milvus typically becomes ready within a few minutes. Once Milvus is `Ready`, KubeDB has created the following resources. For a standalone deployment there is exactly **one PetSet** named after the database (``): ```bash -$ kubectl get petset -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get petset -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME AGE milvus-standalone 88s -$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-standalone -o wide +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-standalone -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES milvus-standalone-0 1/1 Running 0 88s 10.42.0.86 urmi -``` ### Services KubeDB creates a primary client service named after the database (gRPC port `19530`) and, because monitoring is enabled, a `-stats` service exposing the metrics port `9091`: ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get svc -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE milvus-standalone ClusterIP 10.43.144.154 19530/TCP 91s milvus-standalone-stats ClusterIP 10.43.12.191 9091/TCP 91s -``` ### Storage The standalone workload mounts a single persistent volume created from `spec.storage`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-milvus-standalone-0 Bound pvc-a6333ee2-f0ab-4ec2-8437-599d270b9ed0 1Gi RWO local-path 90s -``` > The internal etcd metadata store provisions its own PVCs (`etcd-data-demo-etcd-*`), and MinIO has its own storage. Those are separate from the Milvus data volume. @@ -176,15 +178,17 @@ data-milvus-standalone-0 Bound pvc-a6333ee2-f0ab-4ec2-8437-599d270b9ed0 1 Milvus authentication is enabled by default (`spec.disableSecurity` defaults to `false`). Because `spec.authSecret` was not provided, KubeDB auto-generated a basic-auth secret named `-auth` with a `root` user and a random password: ```bash -$ kubectl get secret -n demo | grep milvus-standalone +kubectl get secret -n demo | grep milvus-standalone +``` milvus-standalone-42559a Opaque 2 92s milvus-standalone-auth kubernetes.io/basic-auth 2 92s milvus-standalone-client-cert kubernetes.io/tls 4 91s milvus-standalone-server-cert kubernetes.io/tls 3 91s -$ kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d -root +```bash +kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d ``` +root The other secrets are the rendered configuration secret (`milvus-standalone-42559a`, holding `milvus.yaml` and `glog.conf`) and the TLS certificate secrets (`-server-cert`, `-client-cert`). @@ -193,7 +197,8 @@ The other secrets are the rendered configuration secret (`milvus-standalone-4255 KubeDB also creates an `AppBinding` — a connection descriptor pointing at the primary service, the auth secret, and the connection scheme (note `scheme: https`, because TLS is enabled): ```bash -$ kubectl get appbinding milvus-standalone -n demo -o yaml +kubectl get appbinding milvus-standalone -n demo -o yaml +``` ... spec: appRef: @@ -212,14 +217,14 @@ spec: name: milvus-standalone-auth type: kubedb.com/milvus version: 2.6.11 -``` ## Rendered Configuration KubeDB renders the effective `milvus.yaml` into the configuration secret. Notice that authentication and internal TLS are wired up automatically: ```bash -$ kubectl get secret milvus-standalone-42559a -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d +kubectl get secret milvus-standalone-42559a -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d +``` common: msgChannelType: rocksmq security: @@ -243,16 +248,21 @@ internaltls: sni: milvus-standalone localStorage: path: /var/lib/milvus/data/ -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo milvus.kubedb.com milvus-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete milvus.kubedb.com milvus-standalone -n demo -$ kubectl delete ns demo +kubectl patch -n demo milvus.kubedb.com milvus-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete milvus.kubedb.com milvus-standalone -n demo +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/recommendation/guide.md b/docs/guides/milvus/recommendation/guide.md index 65fb65a1c5..0ef7858829 100644 --- a/docs/guides/milvus/recommendation/guide.md +++ b/docs/guides/milvus/recommendation/guide.md @@ -29,10 +29,10 @@ The KubeDB Recommendation Engine watches your databases and proactively generate - The **Recommendation Engine** and **Supervisor** CRDs must be installed (they ship with the KubeDB Supervisor component): ```bash - $ kubectl get crd recommendations.supervisor.appscode.com + kubectl get crd recommendations.supervisor.appscode.com + ``` NAME CREATED AT recommendations.supervisor.appscode.com 2026-06-30T05:18:01Z - ``` - An object-storage secret named `my-release-minio` must exist in the `demo` namespace. @@ -90,9 +90,9 @@ The distributed sample (`distributed.yaml`) is equivalent, targeting `milvus-clu - `spec.version: "2.6.9"` — an older catalog version, so an update to `2.6.11` is recommended. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/recommendation/yamls/standalone.yaml -milvus.kubedb.com/milvus-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/recommendation/yamls/standalone.yaml ``` +milvus.kubedb.com/milvus-standalone created Wait for the database to become `Ready`. @@ -101,15 +101,16 @@ Wait for the database to become `Ready`. After the database is ready (and `rotateAfter` / certificate-renewal thresholds are reached), `Recommendation` objects appear in the namespace: ```bash -$ kubectl get recommendation -n demo +kubectl get recommendation -n demo +``` NAME STATUS OUTDATED AGE milvus-standalone-x-milvus-x-update-version-3rq4py Pending false 2m -``` Each `Recommendation` is a `supervisor.appscode.com` object that describes one operation and embeds the exact `MilvusOpsRequest` that resolves it. Here is the `UpdateVersion` recommendation generated because the running database is on `2.6.9` while `2.6.11` is available: ```bash -$ kubectl get recommendation milvus-standalone-x-milvus-x-update-version-3rq4py -n demo -o yaml +kubectl get recommendation milvus-standalone-x-milvus-x-update-version-3rq4py -n demo -o yaml +``` apiVersion: supervisor.appscode.com/v1alpha1 kind: Recommendation metadata: @@ -145,7 +146,6 @@ spec: status: approvalStatus: Pending phase: Pending -``` Key fields: @@ -162,15 +162,21 @@ Similarly, once the auth credential exceeds `spec.authSecret.rotateAfter` (15m), Each `Recommendation` embeds the exact `MilvusOpsRequest` that resolves it (`spec.operation`). The Supervisor can apply it automatically within a maintenance window, or you can extract and apply it manually: ```bash -$ kubectl get recommendation -n demo -o jsonpath='{.spec.operation}' | kubectl apply -f - +kubectl get recommendation -n demo -o jsonpath='{.spec.operation}' | kubectl apply -f - ``` ## Cleaning up ```bash -$ kubectl delete recommendation -n demo --all -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete recommendation -n demo --all +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/reconfigure-tls/guide.md b/docs/guides/milvus/reconfigure-tls/guide.md index 871e514505..fa54a584a2 100644 --- a/docs/guides/milvus/reconfigure-tls/guide.md +++ b/docs/guides/milvus/reconfigure-tls/guide.md @@ -33,11 +33,17 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to add, ro All TLS operations need an `Issuer` (or `ClusterIssuer`). First create a CA secret, then an `Issuer` backed by it: -```bash # generate a self-signed CA -$ openssl genrsa -out ca.key 2048 -$ openssl req -x509 -new -nodes -key ca.key -subj "/CN=milvus-ca/O=kubedb" -days 3650 -out ca.crt -$ kubectl create secret tls milvus-ca --cert=ca.crt --key=ca.key -n demo +```bash +openssl genrsa -out ca.key 2048 +``` + +```bash +openssl req -x509 -new -nodes -key ca.key -subj "/CN=milvus-ca/O=kubedb" -days 3650 -out ca.crt +``` + +```bash +kubectl create secret tls milvus-ca --cert=ca.crt --key=ca.key -n demo ``` `issuer.yaml` @@ -54,9 +60,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/issuer.yaml -issuer.cert-manager.io/milvus-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/issuer.yaml ``` +issuer.cert-manager.io/milvus-issuer created ## Reconfigure TLS — Standalone Milvus @@ -93,40 +99,46 @@ spec: - `spec.tls.internal.mode` controls inter-component traffic (`Disabled`/`TLS`). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-add-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-add-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/mvops-add-tls created -$ kubectl get milvusopsrequest mvops-add-tls -n demo +```bash +kubectl get milvusopsrequest mvops-add-tls -n demo +``` NAME TYPE STATUS AGE mvops-add-tls ReconfigureTLS Successful 82s -``` ```bash -$ kubectl describe milvusopsrequest mvops-add-tls -n demo +kubectl describe milvusopsrequest mvops-add-tls -n demo +``` ... Normal CertificateSynced Successfully synced all certificates Normal UpdatePetSets successfully reconciled the Milvus with tls configuration Normal RestartNodes Successfully restarted all nodes Normal Successful Successfully resumed Milvus database: demo/milvus-standalone for MilvusOpsRequest: mvops-add-tls -``` After adding TLS, the certificate secrets exist, the AppBinding scheme becomes `https`, and the certificates are mounted in the pod: ```bash -$ kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' +kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' +``` milvus-standalone-client-cert kubernetes.io/tls 4 91s milvus-standalone-server-cert kubernetes.io/tls 3 91s -$ kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +```bash +kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +``` https -$ kubectl exec -n demo milvus-standalone-0 -c milvus -- ls /milvus/tls +```bash +kubectl exec -n demo milvus-standalone-0 -c milvus -- ls /milvus/tls +``` ca.pem client.key client.pem server.key server.pem -``` ### 2. Rotate Certificates @@ -149,13 +161,15 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-rotate-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-rotate-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/mvops-rotate created -$ kubectl get milvusopsrequest mvops-rotate -n demo +```bash +kubectl get milvusopsrequest mvops-rotate -n demo +``` NAME TYPE STATUS AGE mvops-rotate ReconfigureTLS Successful 52s -``` The server certificate serial number changes, confirming the certificate was re-issued: @@ -190,23 +204,25 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-add-new-issuer-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-add-new-issuer-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/mv-change-issuer created -$ kubectl get milvusopsrequest mv-change-issuer -n demo +```bash +kubectl get milvusopsrequest mv-change-issuer -n demo +``` NAME TYPE STATUS AGE mv-change-issuer ReconfigureTLS Successful 62s -``` The database's issuer reference is updated and the new certificate chains to the new CA: ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.tls.issuerRef}' +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.tls.issuerRef}' +``` {"apiGroup":"cert-manager.io","kind":"Issuer","name":"mv-new-issuer"} # certificate issuer before: issuer=CN=milvus-ca, O=kubedb # certificate issuer after: issuer=CN=mvnew-ca, O=kubedb -``` ### 4. Remove TLS @@ -229,26 +245,32 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-remove-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure-tls/yamls/reconfigureTls-remove-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/mvops-remove created -$ kubectl get milvusopsrequest mvops-remove -n demo +```bash +kubectl get milvusopsrequest mvops-remove -n demo +``` NAME TYPE STATUS AGE mvops-remove ReconfigureTLS Successful 82s -``` After removal, the `tls` block is gone, the certificate secrets are removed, and the AppBinding scheme reverts to `http`: ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.tls}' +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.tls}' +``` # (empty) -$ kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +```bash +kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +``` http -$ kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' -# (no cert secrets) +```bash +kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' ``` +# (no cert secrets) ## Reconfigure TLS — Distributed Milvus @@ -286,31 +308,40 @@ On the distributed database the operator drives each flow exactly as for standal **Remove TLS** (distributed): ```bash -$ kubectl get milvusopsrequest mvops-remove -n demo +kubectl get milvusopsrequest mvops-remove -n demo +``` NAME TYPE STATUS AGE mvops-remove ReconfigureTLS Successful 11m # after removal: certificate secrets are deleted and the AppBinding scheme reverts to http -$ kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +```bash +kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' +``` http -$ kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' -# (no cert secrets) + +```bash +kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' ``` +# (no cert secrets) **Add TLS** (distributed) — the `server`/`client` certificate secrets are recreated and mounted into every role's pods: ```bash -$ kubectl get milvusopsrequest mvops-add-tls -n demo +kubectl get milvusopsrequest mvops-add-tls -n demo +``` NAME TYPE STATUS AGE mvops-add-tls ReconfigureTLS Successful 9m -$ kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' +```bash +kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' +``` milvus-cluster-client-cert kubernetes.io/tls 4 2m milvus-cluster-server-cert kubernetes.io/tls 3 2m -$ kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' -https +```bash +kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' ``` +https **Rotate certificates** and **Change issuer** behave identically to the standalone flows shown above — applying `reconfigureTls-rotate-distributed.yaml` re-issues the `server`/`client` certificates (the serial numbers change), and `reconfigureTls-add-new-issuer-distributed.yaml` repoints `spec.tls.issuerRef` to `mv-new-issuer` so new certificates chain to the new CA. @@ -319,9 +350,15 @@ https ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo mvops-add-tls mvops-rotate mv-change-issuer mvops-remove -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo mvops-add-tls mvops-rotate mv-change-issuer mvops-remove +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/reconfigure/guide.md b/docs/guides/milvus/reconfigure/guide.md index 2e14300cc6..a25e0e8a65 100644 --- a/docs/guides/milvus/reconfigure/guide.md +++ b/docs/guides/milvus/reconfigure/guide.md @@ -28,9 +28,9 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to reconfi - To keep things isolated, this tutorial uses a separate namespace called `demo`: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Milvus configuration is always supplied through a file named **`milvus.yaml`**. Use that exact key in config secrets and in `applyConfig`. @@ -43,10 +43,10 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to reconfi Deploy a standalone Milvus and wait for it to become `Ready` (see the [standalone quickstart](/docs/guides/milvus/quickstart/standalone.md)): ```bash -$ kubectl get milvuses.kubedb.com -n demo milvus-standalone +kubectl get milvuses.kubedb.com -n demo milvus-standalone +``` NAME VERSION STATUS AGE milvus-standalone 2.6.11 Ready 2m -``` ### Apply the Reconfigure OpsRequest @@ -109,21 +109,22 @@ Here, - `spec.configuration.restart: "false"` requests the configuration be applied without forcing a restart. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure/yamls/reconfigure-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure/yamls/reconfigure-standalone.yaml +``` secret/mv-configuration created milvusopsrequest.ops.kubedb.com/reconfigure-1 created -``` ### Watch Progress ```bash -$ kubectl get milvusopsrequest -n demo +kubectl get milvusopsrequest -n demo +``` NAME TYPE STATUS AGE reconfigure-1 Reconfigure Successful 28s -``` ```bash -$ kubectl describe milvusopsrequest reconfigure-1 -n demo +kubectl describe milvusopsrequest reconfigure-1 -n demo +``` ... Status: Conditions: @@ -145,15 +146,18 @@ Events: Normal UpdatePetSets successfully reconciled the milvus with new configuration Normal Starting Resuming Milvus database: demo/milvus-standalone Normal Successful Successfully resumed Milvus database: demo/milvus-standalone for MilvusOpsRequest: reconfigure-1 -``` ### Verify the New Configuration The applied values are rendered into the configuration secret's `milvus.yaml`: ```bash -$ CFG=$(kubectl get secret -n demo -o name | grep -oE 'milvus-standalone-[a-f0-9]{6}' | head -1) -$ kubectl get secret $CFG -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A3 -E '^log:|^queryNode:' +CFG=$(kubectl get secret -n demo -o name | grep -oE 'milvus-standalone-[a-f0-9]{6}' | head -1) +``` + +```bash +kubectl get secret $CFG -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A3 -E '^log:|^queryNode:' +``` log: file: maxAge: 30 @@ -164,7 +168,6 @@ log: queryNode: gracefulTime: 500 port: 19536 -``` The `log.level` is now `info`, `log.file.maxAge` is `30`, and `queryNode.gracefulTime` is `500` — exactly the values supplied through `applyConfig`. @@ -221,20 +224,26 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure/yamls/reconfigure-distributed.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/reconfigure/yamls/reconfigure-distributed.yaml +``` secret/mv-configuration created milvusopsrequest.ops.kubedb.com/reconfigure-1 created -$ kubectl get milvusopsrequest reconfigure-1 -n demo +```bash +kubectl get milvusopsrequest reconfigure-1 -n demo +``` NAME TYPE STATUS AGE reconfigure-1 Reconfigure Successful 21s -``` The applied configuration is rendered into the cluster's configuration secret and propagated to all roles: ```bash -$ CFG=$(kubectl get secret -n demo -o name | grep -oE 'milvus-cluster-[a-f0-9]{6}' | head -1) -$ kubectl get secret $CFG -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A2 -E '^log:|^queryNode:|level:' +CFG=$(kubectl get secret -n demo -o name | grep -oE 'milvus-cluster-[a-f0-9]{6}' | head -1) +``` + +```bash +kubectl get secret $CFG -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A2 -E '^log:|^queryNode:|level:' +``` log: file: maxAge: 30 @@ -245,17 +254,25 @@ queryNode: enableDisk: true gracefulTime: 500 port: 21123 -``` As with standalone, `log.level` is now `info`, `log.file.maxAge` is `30`, and `queryNode.gracefulTime` is `500`. ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo reconfigure-1 -$ kubectl delete secret -n demo mv-configuration -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo reconfigure-1 +``` + +```bash +kubectl delete secret -n demo mv-configuration +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/restart/guide.md b/docs/guides/milvus/restart/guide.md index d000843d0f..d69b981814 100644 --- a/docs/guides/milvus/restart/guide.md +++ b/docs/guides/milvus/restart/guide.md @@ -55,20 +55,21 @@ Here, - `spec.apply: Always` applies the restart regardless of the database's current readiness. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/restart/yamls/restart-standalone.yaml -milvusopsrequest.ops.kubedb.com/restart created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/restart/yamls/restart-standalone.yaml ``` +milvusopsrequest.ops.kubedb.com/restart created ### Watch Progress ```bash -$ kubectl get milvusopsrequest restart -n demo +kubectl get milvusopsrequest restart -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 57s -``` ```bash -$ kubectl describe milvusopsrequest restart -n demo +kubectl describe milvusopsrequest restart -n demo +``` ... Status: Conditions: @@ -94,15 +95,14 @@ Events: Warning check pod running; ConditionStatus:True; PodName:milvus-standalone-0 Normal RestartNodes Successfully Restarted Milvus nodes Normal Successful Successfully resumed Milvus database: demo/milvus-standalone for MilvusOpsRequest: restart -``` The pod has been evicted and recreated: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME READY STATUS RESTARTS AGE milvus-standalone-0 1/1 Running 0 14s -``` ## Restart Distributed Milvus @@ -125,18 +125,21 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/restart/yamls/restart-distributed.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/restart/yamls/restart-distributed.yaml +``` milvusopsrequest.ops.kubedb.com/restart created -$ kubectl get milvusopsrequest restart -n demo +```bash +kubectl get milvusopsrequest restart -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 2m8s -``` The describe output shows each role's pod being evicted and checked in turn: ```bash -$ kubectl describe milvusopsrequest restart -n demo +kubectl describe milvusopsrequest restart -n demo +``` ... Status: Conditions: @@ -151,26 +154,31 @@ Status: Type: EvictPod--milvus-cluster-datanode-0 ... (querynode, streamingnode, proxy follow) Phase: Successful -``` All role pods have been recreated: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster +kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster +``` NAME READY STATUS RESTARTS AGE milvus-cluster-datanode-0 1/1 Running 0 105s milvus-cluster-mixcoord-0 1/1 Running 0 114s milvus-cluster-proxy-0 1/1 Running 0 13s milvus-cluster-querynode-0 1/1 Running 0 65s milvus-cluster-streamingnode-0 1/1 Running 0 25s -``` ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo restart -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo restart +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/rotate-auth/guide.md b/docs/guides/milvus/rotate-auth/guide.md index 930e122e06..425ebef959 100644 --- a/docs/guides/milvus/rotate-auth/guide.md +++ b/docs/guides/milvus/rotate-auth/guide.md @@ -32,13 +32,15 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to rotate Milvus authentication is enabled by default. When `spec.authSecret` is omitted, KubeDB creates a `kubernetes.io/basic-auth` secret named `-auth` with a `root` user and a random password: ```bash -$ kubectl get secret milvus-standalone-auth -n demo +kubectl get secret milvus-standalone-auth -n demo +``` NAME TYPE DATA AGE milvus-standalone-auth kubernetes.io/basic-auth 2 92s -$ kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d -root +```bash +kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.data.username}' | base64 -d ``` +root There are two ways to rotate this credential. @@ -78,21 +80,22 @@ spec: Here, `spec.authentication.secretRef.name` points at the user-created secret. To let the operator generate a random password instead, simply omit `spec.authentication`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/rotate-auth/yamls/rotate-auth-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/rotate-auth/yamls/rotate-auth-standalone.yaml +``` secret/milvus-new-auth1 created milvusopsrequest.ops.kubedb.com/milvus-rotate-auth-user-secret created -``` ### Watch Progress ```bash -$ kubectl get milvusopsrequest milvus-rotate-auth-user-secret -n demo +kubectl get milvusopsrequest milvus-rotate-auth-user-secret -n demo +``` NAME TYPE STATUS AGE milvus-rotate-auth-user-secret RotateAuth Successful 83s -``` ```bash -$ kubectl describe milvusopsrequest milvus-rotate-auth-user-secret -n demo +kubectl describe milvusopsrequest milvus-rotate-auth-user-secret -n demo +``` ... Status: Conditions: @@ -112,19 +115,20 @@ Status: Reason: RestartNodes ... Phase: Successful -``` ### Verify the Rotation The database now references the new secret: ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.authSecret.name}' +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.authSecret.name}' +``` milvus-new-auth1 -$ kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.metadata.annotations.kubedb\.com/auth-active-from}' -2026-06-30T17:19:33Z +```bash +kubectl get secret milvus-standalone-auth -n demo -o jsonpath='{.metadata.annotations.kubedb\.com/auth-active-from}' ``` +2026-06-30T17:19:33Z ## Rotate Distributed Milvus @@ -160,19 +164,22 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/rotate-auth/yamls/rotate-auth-distributed.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/rotate-auth/yamls/rotate-auth-distributed.yaml +``` secret/milvus-new-auth1 created milvusopsrequest.ops.kubedb.com/milvus-rotate-auth-user-secret created -$ kubectl get milvusopsrequest milvus-rotate-auth-user-secret -n demo +```bash +kubectl get milvusopsrequest milvus-rotate-auth-user-secret -n demo +``` NAME TYPE STATUS AGE milvus-rotate-auth-user-secret RotateAuth Successful 3m56s -``` The credential is updated dynamically and then every role is reconciled and restarted: ```bash -$ kubectl describe milvusopsrequest milvus-rotate-auth-user-secret -n demo +kubectl describe milvusopsrequest milvus-rotate-auth-user-secret -n demo +``` ... Status: Conditions: @@ -187,9 +194,10 @@ Status: Type: UpdatePetSets Phase: Successful -$ kubectl get milvuses.kubedb.com milvus-cluster -n demo -o jsonpath='{.spec.authSecret.name}' -milvus-new-auth1 +```bash +kubectl get milvuses.kubedb.com milvus-cluster -n demo -o jsonpath='{.spec.authSecret.name}' ``` +milvus-new-auth1 ## Automatic Rotation Recommendations @@ -203,10 +211,19 @@ See the [Recommendation Engine guide](/docs/guides/milvus/recommendation/guide.m ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo milvus-rotate-auth-user-secret -$ kubectl delete secret -n demo milvus-new-auth1 -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo milvus-rotate-auth-user-secret +``` + +```bash +kubectl delete secret -n demo milvus-new-auth1 +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/scaling/horizontal-scaling/guide.md b/docs/guides/milvus/scaling/horizontal-scaling/guide.md index 7b930f35e2..7e9b4ade63 100644 --- a/docs/guides/milvus/scaling/horizontal-scaling/guide.md +++ b/docs/guides/milvus/scaling/horizontal-scaling/guide.md @@ -34,11 +34,11 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to horizon Deploy the distributed database (`milvus-cluster`) and wait until it is `Ready` (see the [distributed quickstart](/docs/guides/milvus/quickstart/distributed.md)). By default each role runs a single replica. ```bash -$ kubectl get petset milvus-cluster-proxy milvus-cluster-streamingnode -n demo -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas +kubectl get petset milvus-cluster-proxy milvus-cluster-streamingnode -n demo -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas +``` NAME REPLICAS milvus-cluster-proxy 1 milvus-cluster-streamingnode 1 -``` ## Apply the HorizontalScaling OpsRequest @@ -65,20 +65,21 @@ spec: Here, `spec.horizontalScaling.topology` carries the desired replica count per role. The API also accepts `mixcoord`, `querynode` and `dataNode`; this sample only scales `proxy` and `streamingnode`, but the other roles are scaled the same way. ```bash -$ kubectl apply -f horizontal-scaling-distributed.yaml -milvusopsrequest.ops.kubedb.com/milvus-hscale-up created +kubectl apply -f horizontal-scaling-distributed.yaml ``` +milvusopsrequest.ops.kubedb.com/milvus-hscale-up created ## Watch Progress and Verify ```bash -$ kubectl get milvusopsrequest milvus-hscale-up -n demo +kubectl get milvusopsrequest milvus-hscale-up -n demo +``` NAME TYPE STATUS AGE milvus-hscale-up HorizontalScaling Successful 57s -``` ```bash -$ kubectl describe milvusopsrequest milvus-hscale-up -n demo +kubectl describe milvusopsrequest milvus-hscale-up -n demo +``` ... Status: Conditions: @@ -94,31 +95,38 @@ Status: Reason: ScaleUpStreamingNode Type: ScaleUpStreamingNode Phase: Successful -``` Both roles now run two replicas: ```bash -$ kubectl get petset milvus-cluster-proxy milvus-cluster-streamingnode -n demo -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas +kubectl get petset milvus-cluster-proxy milvus-cluster-streamingnode -n demo -o custom-columns=NAME:.metadata.name,REPLICAS:.spec.replicas +``` NAME REPLICAS milvus-cluster-proxy 2 milvus-cluster-streamingnode 2 -$ kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster | grep -E 'proxy|streamingnode' +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=milvus-cluster | grep -E 'proxy|streamingnode' +``` milvus-cluster-proxy-0 1/1 Running 0 70s milvus-cluster-proxy-1 1/1 Running 0 39s milvus-cluster-streamingnode-0 1/1 Running 0 119s milvus-cluster-streamingnode-1 1/1 Running 0 18s -``` > Scaling **down** works the same way — set lower replica counts in `spec.horizontalScaling.topology`. ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo milvus-hscale-up -$ kubectl delete milvus.kubedb.com -n demo milvus-cluster -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo milvus-hscale-up +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/scaling/vertical-scaling/guide.md b/docs/guides/milvus/scaling/vertical-scaling/guide.md index e6ac33dce4..fd262d31e3 100644 --- a/docs/guides/milvus/scaling/vertical-scaling/guide.md +++ b/docs/guides/milvus/scaling/vertical-scaling/guide.md @@ -32,9 +32,9 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to update Deploy a standalone Milvus and wait until it is `Ready`. By default the standalone workload requests `cpu: 500m` / `memory: 1Gi`: ```bash -$ kubectl get petset milvus-standalone -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' -{"limits":{"memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} +kubectl get petset milvus-standalone -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' ``` +{"limits":{"memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} ### Apply the VerticalScaling OpsRequest @@ -66,20 +66,21 @@ spec: Here, `spec.verticalScaling.node` carries the new resources for the **standalone** workload (use the `node` key for standalone). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/scaling/vertical-scaling/yamls/vertical-scaling-standalone.yaml -milvusopsrequest.ops.kubedb.com/vertical-scaling-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/scaling/vertical-scaling/yamls/vertical-scaling-standalone.yaml ``` +milvusopsrequest.ops.kubedb.com/vertical-scaling-standalone created ### Watch Progress ```bash -$ kubectl get milvusopsrequest vertical-scaling-standalone -n demo +kubectl get milvusopsrequest vertical-scaling-standalone -n demo +``` NAME TYPE STATUS AGE vertical-scaling-standalone VerticalScaling Successful 56s -``` ```bash -$ kubectl describe milvusopsrequest vertical-scaling-standalone -n demo +kubectl describe milvusopsrequest vertical-scaling-standalone -n demo +``` ... Status: Conditions: @@ -98,19 +99,20 @@ Status: Reason: Successful Type: Successful Phase: Successful -``` ### Verify the New Resources Both the `Milvus` spec and the PetSet pod template now carry the new resources: ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.podTemplate.spec.containers[0].resources}' +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.podTemplate.spec.containers[0].resources}' +``` {"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} -$ kubectl get petset milvus-standalone -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' -{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} +```bash +kubectl get petset milvus-standalone -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' ``` +{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} ## Vertical Scaling Distributed Milvus @@ -152,30 +154,40 @@ spec: The same approach applies to `datanode`, `querynode` and `streamingnode`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/scaling/vertical-scaling/yamls/vertical-scaling-distributed.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/scaling/vertical-scaling/yamls/vertical-scaling-distributed.yaml +``` milvusopsrequest.ops.kubedb.com/vertical-scaling created -$ kubectl get milvusopsrequest vertical-scaling -n demo +```bash +kubectl get milvusopsrequest vertical-scaling -n demo +``` NAME TYPE STATUS AGE vertical-scaling VerticalScaling Successful 36s -``` Both the `mixcoord` and `proxy` PetSets now carry the new resources (other roles are unchanged): ```bash -$ kubectl get petset milvus-cluster-mixcoord -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' +kubectl get petset milvus-cluster-mixcoord -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' +``` {"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} -$ kubectl get petset milvus-cluster-proxy -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' -{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} +```bash +kubectl get petset milvus-cluster-proxy -n demo -o jsonpath='{.spec.template.spec.containers[0].resources}' ``` +{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo vertical-scaling-standalone -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo vertical-scaling-standalone +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/storage-migration/guide.md b/docs/guides/milvus/storage-migration/guide.md index bd90222a9b..cf56635dbe 100644 --- a/docs/guides/milvus/storage-migration/guide.md +++ b/docs/guides/milvus/storage-migration/guide.md @@ -27,11 +27,11 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to migrate - You need **at least two** `StorageClass`es — the current one and the target one. This guide migrates from `local-path` to `longhorn-custom`: ```bash - $ kubectl get sc + kubectl get sc + ``` NAME PROVISIONER ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path false 11h longhorn-custom driver.longhorn.io true 11h - ``` > Note: The yaml files used in this tutorial are stored in [docs/guides/milvus/storage-migration/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/milvus/storage-migration/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,10 +40,10 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to migrate Deploy a standalone Milvus on `local-path` and wait until it is `Ready`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-milvus-standalone-0 Bound pvc-... 1Gi RWO local-path 14m -``` ### Apply the StorageMigration OpsRequest @@ -71,20 +71,21 @@ Here, - `spec.migration.oldPVReclaimPolicy` controls what happens to the old PersistentVolume (`Delete` or `Retain`). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/storage-migration/yamls/storage-migration-standalone.yaml -milvusopsrequest.ops.kubedb.com/storage-migration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/storage-migration/yamls/storage-migration-standalone.yaml ``` +milvusopsrequest.ops.kubedb.com/storage-migration created ### Watch Progress ```bash -$ kubectl get milvusopsrequest storage-migration -n demo +kubectl get milvusopsrequest storage-migration -n demo +``` NAME TYPE STATUS AGE storage-migration StorageMigration Successful 87s -``` ```bash -$ kubectl describe milvusopsrequest storage-migration -n demo +kubectl describe milvusopsrequest storage-migration -n demo +``` ... Status: Conditions: @@ -97,7 +98,6 @@ Status: Type: GetStorageClass ... Phase: Successful -``` During migration, the operator runs a migrator job to copy the data, recreates the PVC on the new `StorageClass`, and recreates the pod. @@ -106,13 +106,15 @@ During migration, the operator runs a migrator job to copy the data, recreates t The PVC is now backed by `longhorn-custom`, and the database spec reflects the new class: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-milvus-standalone-0 Bound pvc-... 1Gi RWO longhorn-custom 33s -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.storage.storageClassName}' -longhorn-custom +```bash +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.storage.storageClassName}' ``` +longhorn-custom ## Storage Migration — Distributed Milvus @@ -139,36 +141,46 @@ spec: The operator migrates the PVC of every `streamingnode` replica. Starting from `local-path`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +``` NAME SIZE SC data-milvus-cluster-streamingnode-0 1Gi local-path data-milvus-cluster-streamingnode-1 1Gi local-path -``` After the migration completes: ```bash -$ kubectl get milvusopsrequest storage-migration -n demo +kubectl get milvusopsrequest storage-migration -n demo +``` NAME TYPE STATUS AGE storage-migration StorageMigration Successful 3m40s -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +```bash +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +``` NAME SIZE SC data-milvus-cluster-streamingnode-0 1Gi longhorn-custom data-milvus-cluster-streamingnode-1 1Gi longhorn-custom -$ kubectl get milvuses.kubedb.com milvus-cluster -n demo -o jsonpath='{.spec.topology.distributed.streamingnode.storage.storageClassName}' -longhorn-custom +```bash +kubectl get milvuses.kubedb.com milvus-cluster -n demo -o jsonpath='{.spec.topology.distributed.streamingnode.storage.storageClassName}' ``` +longhorn-custom (This example was run with `streamingnode` scaled to two replicas; both PVCs are migrated.) ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo storage-migration -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo storage-migration +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/tls/configure/index.md b/docs/guides/milvus/tls/configure/index.md index b6419959f9..bfd9b1e271 100644 --- a/docs/guides/milvus/tls/configure/index.md +++ b/docs/guides/milvus/tls/configure/index.md @@ -33,11 +33,17 @@ This guide will show you how to deploy a Milvus database with TLS/SSL enabled fr KubeDB uses cert-manager to issue the Milvus certificates. First create a self-signed CA secret, then an `Issuer` (or `ClusterIssuer`) backed by it. ```bash -$ openssl genrsa -out ca.key 2048 -$ openssl req -x509 -new -nodes -key ca.key -subj "/CN=milvus-ca/O=kubedb" -days 3650 -out ca.crt -$ kubectl create secret tls milvus-ca --cert=ca.crt --key=ca.key -n demo -secret/milvus-ca created +openssl genrsa -out ca.key 2048 +``` + +```bash +openssl req -x509 -new -nodes -key ca.key -subj "/CN=milvus-ca/O=kubedb" -days 3650 -out ca.crt +``` + +```bash +kubectl create secret tls milvus-ca --cert=ca.crt --key=ca.key -n demo ``` +secret/milvus-ca created `issuer.yaml` @@ -53,13 +59,15 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/tls/configure/yamls/issuer.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/tls/configure/yamls/issuer.yaml +``` issuer.cert-manager.io/milvus-issuer created -$ kubectl get issuer -n demo +```bash +kubectl get issuer -n demo +``` NAME READY AGE milvus-issuer True 5s -``` > A `ClusterIssuer` works the same way; a sample `cluster-issuer.yaml` (backed by secret `milvus-cluster-ca`) is included in the `yamls` folder. With a `ClusterIssuer`, set `spec.tls.issuerRef.kind: ClusterIssuer`. @@ -103,9 +111,9 @@ spec: - `spec.tls.internal.mode: TLS` encrypts inter-component traffic. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/tls/configure/yamls/standalone.yaml -milvus.kubedb.com/milvus-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/tls/configure/yamls/standalone.yaml ``` +milvus.kubedb.com/milvus-standalone created Wait until it is `Ready`. @@ -116,45 +124,45 @@ Wait until it is `Ready`. KubeDB requests the `server` and `client` certificates and stores them in secrets: ```bash -$ kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' +kubectl get secret -n demo | grep -E 'milvus-standalone-(server|client)-cert' +``` milvus-standalone-client-cert kubernetes.io/tls 4 91s milvus-standalone-server-cert kubernetes.io/tls 3 91s -``` ### TLS Files Mounted in the Pod The certificates and CA are mounted at `/milvus/tls`: ```bash -$ kubectl exec -n demo milvus-standalone-0 -c milvus -- ls -l /milvus/tls +kubectl exec -n demo milvus-standalone-0 -c milvus -- ls -l /milvus/tls +``` ca.pem client.key client.pem server.key server.pem -``` ### Rendered Configuration The rendered `milvus.yaml` wires the certificates into Milvus: ```bash -$ kubectl get secret -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A4 internaltls +kubectl get secret -n demo -o jsonpath='{.data.milvus\.yaml}' | base64 -d | grep -A4 internaltls +``` internaltls: caPemPath: /milvus/tls/ca.pem serverKeyPath: /milvus/tls/server.key serverPemPath: /milvus/tls/server.pem sni: milvus-standalone -``` ### AppBinding Scheme Because TLS is enabled, the AppBinding connection scheme is `https`: ```bash -$ kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' -https +kubectl get appbinding milvus-standalone -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' ``` +https ## TLS-Secured Distributed Milvus @@ -197,28 +205,41 @@ spec: After it becomes `Ready`, the certificate secrets exist, the certificates are mounted into every role's pods, and the AppBinding scheme is `https`: ```bash -$ kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' +kubectl get secret -n demo | grep -E 'milvus-cluster-(server|client)-cert' +``` milvus-cluster-client-cert kubernetes.io/tls 4 4m milvus-cluster-server-cert kubernetes.io/tls 3 4m -$ kubectl exec -n demo milvus-cluster-mixcoord-0 -c milvus -- ls /milvus/tls +```bash +kubectl exec -n demo milvus-cluster-mixcoord-0 -c milvus -- ls /milvus/tls +``` ca.pem client.key client.pem server.key server.pem -$ kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' -https +```bash +kubectl get appbinding milvus-cluster -n demo -o jsonpath='{.spec.clientConfig.service.scheme}' ``` +https ## Cleaning up ```bash -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete issuer -n demo milvus-issuer -$ kubectl delete secret -n demo milvus-ca -$ kubectl delete ns demo +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete issuer -n demo milvus-issuer +``` + +```bash +kubectl delete secret -n demo milvus-ca +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/update-version/guide.md b/docs/guides/milvus/update-version/guide.md index 4fccd8676b..ce48d814ef 100644 --- a/docs/guides/milvus/update-version/guide.md +++ b/docs/guides/milvus/update-version/guide.md @@ -30,22 +30,22 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to update ## Available Versions ```bash -$ kubectl get milvusversions +kubectl get milvusversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2.6.11 2.6.11 ghcr.io/appscode-images/milvus:2.6.11 11h 2.6.7 2.6.7 ghcr.io/appscode-images/milvus:2.6.7 11h 2.6.9 2.6.9 ghcr.io/appscode-images/milvus:2.6.9 11h -``` ## Update Version of Standalone Milvus Deploy a standalone Milvus at version `2.6.9` and wait until it is `Ready`: ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo +kubectl get milvuses.kubedb.com milvus-standalone -n demo +``` NAME VERSION STATUS AGE milvus-standalone 2.6.9 Ready 46s -``` ### Apply the UpdateVersion OpsRequest @@ -70,20 +70,21 @@ spec: Here, `spec.updateVersion.targetVersion` is the name of the target `MilvusVersion` (`2.6.11`). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/update-version/yamls/update-version-standalone.yaml -milvusopsrequest.ops.kubedb.com/milvus-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/update-version/yamls/update-version-standalone.yaml ``` +milvusopsrequest.ops.kubedb.com/milvus-update-version created ### Watch Progress ```bash -$ kubectl get milvusopsrequest milvus-update-version -n demo +kubectl get milvusopsrequest milvus-update-version -n demo +``` NAME TYPE STATUS AGE milvus-update-version UpdateVersion Successful 77s -``` ```bash -$ kubectl describe milvusopsrequest milvus-update-version -n demo +kubectl describe milvusopsrequest milvus-update-version -n demo +``` ... Status: Conditions: @@ -102,15 +103,14 @@ Status: Reason: Successful Type: Successful Phase: Successful -``` ### Verify the New Version ```bash -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo +kubectl get milvuses.kubedb.com milvus-standalone -n demo +``` NAME VERSION STATUS AGE milvus-standalone 2.6.11 Ready 2m3s -``` ## Update Version of Distributed Milvus @@ -137,9 +137,9 @@ spec: Apply it the same way, pointing at the distributed database: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/update-version/yamls/update-version-distributed.yaml -milvusopsrequest.ops.kubedb.com/milvus-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/update-version/yamls/update-version-distributed.yaml ``` +milvusopsrequest.ops.kubedb.com/milvus-update-version created The distributed flow is mechanically identical to the standalone flow shown above: the operator validates the target `MilvusVersion`, pauses the database, updates the container image of **each** distributed role (`mixcoord`, `datanode`, `querynode`, `streamingnode`, `proxy`), restarts them one workload at a time, and resumes the database. Because `apply: IfReady` is set, the ops request runs only once the database is `Ready`, after which it reports `Successful`. @@ -148,9 +148,15 @@ The distributed flow is mechanically identical to the standalone flow shown abov ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo milvus-update-version -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo milvus-update-version +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/milvus/volume-expansion/guide.md b/docs/guides/milvus/volume-expansion/guide.md index 77de9c73d6..8b986da9f6 100644 --- a/docs/guides/milvus/volume-expansion/guide.md +++ b/docs/guides/milvus/volume-expansion/guide.md @@ -28,9 +28,9 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to expand - The PVC's `StorageClass` **must** support volume expansion (`allowVolumeExpansion: true`). The base examples use `local-path`, which does **not** support expansion, so this guide uses `longhorn-custom`: ```bash - $ kubectl get sc longhorn-custom -o jsonpath='{.allowVolumeExpansion}' - true + kubectl get sc longhorn-custom -o jsonpath='{.allowVolumeExpansion}' ``` + true > Note: The yaml files used in this tutorial are stored in [docs/guides/milvus/volume-expansion/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/milvus/volume-expansion/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -39,10 +39,10 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to expand Deploy a standalone Milvus on an expansion-capable `StorageClass` (here `longhorn-custom`) with a `1Gi` volume: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +``` NAME SIZE SC data-milvus-standalone-0 1Gi longhorn-custom -``` ### Offline Volume Expansion @@ -66,21 +66,23 @@ spec: Here, `spec.volumeExpansion.node` is the standalone target size, and `mode: Offline` takes the pod down while the volume is resized. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/volume-expansion/yamls/volume-expansion-offline-standalone.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/milvus/volume-expansion/yamls/volume-expansion-offline-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/volume-expansion-offline created -$ kubectl get milvusopsrequest volume-expansion-offline -n demo +```bash +kubectl get milvusopsrequest volume-expansion-offline -n demo +``` NAME TYPE STATUS AGE volume-expansion-offline VolumeExpansion Successful 2m -``` The volume is now `4Gi`: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +``` NAME SIZE SC data-milvus-standalone-0 4Gi longhorn-custom -``` ### Online Volume Expansion @@ -104,24 +106,28 @@ spec: ``` ```bash -$ kubectl apply -f volume-expansion-online-standalone.yaml +kubectl apply -f volume-expansion-online-standalone.yaml +``` milvusopsrequest.ops.kubedb.com/volume-expansion-online created -$ kubectl get milvusopsrequest volume-expansion-online -n demo +```bash +kubectl get milvusopsrequest volume-expansion-online -n demo +``` NAME TYPE STATUS AGE volume-expansion-online VolumeExpansion Successful 2m4s -``` The volume has grown to `6Gi`, and the database spec reflects the new size: ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-standalone -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage,SC:.spec.storageClassName +``` NAME SIZE SC data-milvus-standalone-0 6Gi longhorn-custom -$ kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.storage.resources.requests.storage}' -6Gi +```bash +kubectl get milvuses.kubedb.com milvus-standalone -n demo -o jsonpath='{.spec.storage.resources.requests.storage}' ``` +6Gi ## Volume Expansion — Distributed Milvus @@ -148,18 +154,20 @@ spec: The operator expands the PVC of every `streamingnode` replica. Starting from `1Gi` on `longhorn-custom`, an **offline** expansion to `3Gi` followed by an **online** expansion to `4Gi`: -```bash # offline: streamingnode 1Gi -> 3Gi -$ kubectl get milvusopsrequest volume-expansion-offline -n demo +```bash +kubectl get milvusopsrequest volume-expansion-offline -n demo +``` NAME TYPE STATUS AGE volume-expansion-offline VolumeExpansion Successful ... # online: streamingnode 3Gi -> 4Gi -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +```bash +kubectl get pvc -n demo -l app.kubernetes.io/instance=milvus-cluster -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +``` NAME SIZE data-milvus-cluster-streamingnode-0 4Gi data-milvus-cluster-streamingnode-1 4Gi -``` Both `streamingnode` replicas are expanded. The stateless roles (`mixcoord`, `datanode`, `querynode`, `proxy`) have no persistent volume and are unaffected. @@ -168,9 +176,15 @@ Both `streamingnode` replicas are expanded. The stateless roles (`mixcoord`, `da ## Cleaning up ```bash -$ kubectl delete milvusopsrequest -n demo volume-expansion-offline volume-expansion-online -$ kubectl delete milvus.kubedb.com -n demo milvus-standalone -$ kubectl delete ns demo +kubectl delete milvusopsrequest -n demo volume-expansion-offline volume-expansion-online +``` + +```bash +kubectl delete milvus.kubedb.com -n demo milvus-standalone +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mongodb/arbiter/replicaset.md b/docs/guides/mongodb/arbiter/replicaset.md index 64271c5138..ac3f09d4ca 100644 --- a/docs/guides/mongodb/arbiter/replicaset.md +++ b/docs/guides/mongodb/arbiter/replicaset.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,9 +67,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/arbiter/replicaset.yaml -mongodb.kubedb.com/mongo-arb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/arbiter/replicaset.yaml ``` +mongodb.kubedb.com/mongo-arb created Here, @@ -83,7 +83,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create two new PetSets (one for replicas & one for arbiter) and a Service with the matching MongoDB object name. This service will always point to the primary of the replicaset. KubeDB operator will also create a governing service for the pods of those two PetSets with the name `-pods`. ```bash -$ kubectl dba describe mg -n demo mongo-arb +kubectl dba describe mg -n demo mongo-arb +``` Name: mongo-arb Namespace: demo CreationTimestamp: Thu, 21 Apr 2022 14:39:32 +0600 @@ -204,33 +205,35 @@ Events: Normal Successful 1m Postgres operator Successfully created Primary Service Normal Successful 1m Postgres operator Successfully created appbinding - - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mongo-arb 2/2 2m37s mongo-arb-arbiter 1/1 108s - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mongo-arb-0 Bound pvc-93a2681f-096d-4af1-b1fb-93cd7b7b6020 500Mi RWO standard 2m57s datadir-mongo-arb-1 Bound pvc-fb06ea3b-a9dd-4479-87b2-de73ca272718 500Mi RWO standard 2m35s datadir-mongo-arb-arbiter-0 Bound pvc-169fd172-0e41-48e3-81a5-3abae4a85056 500Mi RWO standard 2m8s - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-169fd172-0e41-48e3-81a5-3abae4a85056 500Mi RWO Delete Bound demo/datadir-mongo-arb-arbiter-0 standard 2m23s pvc-93a2681f-096d-4af1-b1fb-93cd7b7b6020 500Mi RWO Delete Bound demo/datadir-mongo-arb-0 standard 3m11s pvc-fb06ea3b-a9dd-4479-87b2-de73ca272718 500Mi RWO Delete Bound demo/datadir-mongo-arb-1 standard 2m50s - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mongo-arb ClusterIP 10.96.148.184 27017/TCP 3m32s mongo-arb-pods ClusterIP None 27017/TCP 3m32s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: @@ -342,14 +345,18 @@ Now, you can connect to this database through [mongo-arb](https://docs.mongodb.c At first, insert data inside primary member `rs0:PRIMARY`. ```bash -$ kubectl get secrets -n demo mongo-arb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mongo-arb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mongo-arb-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mongo-arb-auth -o jsonpath='{.data.password}' | base64 -d +``` OX4yb!IFm;~yAHkD -$ kubectl exec -it mongo-arb-0 -n demo bash - +```bash +kubectl exec -it mongo-arb-0 -n demo bash +``` mongodb@mongo-arb-0:/$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -488,7 +495,6 @@ rs0:PRIMARY> rs.status() }, "operationTime" : Timestamp(1650530787, 1) } -``` Here you can see the arbiter pod in the members list of `rs.status()` output. @@ -539,7 +545,8 @@ Now, check the redundancy and data availability in secondary members. We will exec in `mongo-arb-1`(which is secondary member right now) to check the data availability. ```bash -$ kubectl exec -it mongo-arb-1 -n demo bash +kubectl exec -it mongo-arb-1 -n demo bash +``` mongodb@mongo-arb-1:/$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -584,33 +591,36 @@ rs0:SECONDARY> db.songs.find().pretty() rs0:SECONDARY> exit bye -``` - ## Automatic Failover To test automatic failover, we will force the primary member to restart. As the primary member (`pod`) becomes unavailable, the rest of the members will elect a primary member by election. ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mongo-arb-0 2/2 Running 0 15m mongo-arb-1 2/2 Running 0 14m mongo-arb-arbiter-0 1/1 Running 0 14m -$ kubectl delete pod -n demo mongo-arb-0 +```bash +kubectl delete pod -n demo mongo-arb-0 +``` pod "mongo-arb-0" deleted -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mongo-arb-0 2/2 Terminating 0 16m mongo-arb-1 2/2 Running 0 15m mongo-arb-arbiter-0 1/1 Running 0 15m -``` Now verify the automatic failover, Let's exec in `mongo-arb-0` pod, ```bash -$ kubectl exec -it mongo-arb-0 -n demo bash +kubectl exec -it mongo-arb-0 -n demo bash +``` mongodb@mongo-arb-0:/$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -638,8 +648,6 @@ rs0:SECONDARY> db.songs.find().pretty() "pink floyd" : "shine on you crazy diamond" } -``` - ## Halt Database When [DeletionPolicy](/docs/guides/mongodb/concepts/mongodb.md#specdeletionpolicy) is set to halt, and you delete the mongodb object, the KubeDB operator will delete the PetSet and its pods but leaves the PVCs, secrets and database backup (snapshots) intact. Learn details of all `DeletionPolicy` [here](/docs/guides/mongodb/concepts/mongodb.md#specdeletionpolicy). @@ -649,23 +657,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mongo-arb -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mongo-arb patched +kubectl patch -n demo mg/mongo-arb -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mongo-arb patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-arb -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mongo-arb patched +kubectl patch -n demo mg/mongo-arb -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mongo-arb patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-arb 4.4.26 Halted 21m @@ -678,7 +687,6 @@ NAME STATUS VOLUME persistentvolumeclaim/datadir-mongo-arb-0 Bound pvc-93a2681f-096d-4af1-b1fb-93cd7b7b6020 500Mi RWO standard 21m persistentvolumeclaim/datadir-mongo-arb-1 Bound pvc-fb06ea3b-a9dd-4479-87b2-de73ca272718 500Mi RWO standard 21m persistentvolumeclaim/datadir-mongo-arb-arbiter-0 Bound pvc-169fd172-0e41-48e3-81a5-3abae4a85056 500Mi RWO standard 21m -``` ## Resume Halted Database @@ -686,23 +694,23 @@ persistentvolumeclaim/datadir-mongo-arb-arbiter-0 Bound pvc-169fd172-0e41-4 Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-arb -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mongo-arb patched +kubectl patch -n demo mg/mongo-arb -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mongo-arb patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-arb 4.4.26 Ready 23m -``` Now, If you again exec into the primary `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it mongo-arb-1 -n demo bash - +kubectl exec -it mongo-arb-1 -n demo bash +``` mongodb@mongo-arb-1:/$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' rs0:PRIMARY> use mydb @@ -712,7 +720,6 @@ rs0:PRIMARY> db.songs.find().pretty() "_id" : ObjectId("62611ae33583279dfca0a5e4"), "pink floyd" : "shine on you crazy diamond" } -``` ## Cleaning up diff --git a/docs/guides/mongodb/arbiter/sharding.md b/docs/guides/mongodb/arbiter/sharding.md index fbf660a7a2..83c0a1842e 100644 --- a/docs/guides/mongodb/arbiter/sharding.md +++ b/docs/guides/mongodb/arbiter/sharding.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -86,9 +86,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/arbiter/sharding.yaml -mongodb.kubedb.com/mongo-sh-arb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/arbiter/sharding.yaml ``` +mongodb.kubedb.com/mongo-sh-arb created Here, @@ -119,15 +119,16 @@ KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `Mong MongoDB `mongo-sh-arb` state, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-sh-arb 4.4.26 Ready 97s -``` All the types of nodes `Shard`, `ConfigServer` & `Mongos` are deployed as petset. ```bash -$ kubectl get petset -n demo +kubectl get petset -n demo +``` NAME READY AGE petset.apps/mongo-sh-arb-configsvr 3/3 97s petset.apps/mongo-sh-arb-mongos 2/2 29s @@ -135,12 +136,12 @@ petset.apps/mongo-sh-arb-shard0 2/2 97s petset.apps/mongo-sh-arb-shard0-arbiter 1/1 53s petset.apps/mongo-sh-arb-shard1 2/2 97s petset.apps/mongo-sh-arb-shard1-arbiter 1/1 52s -``` All PVCs and PVs for MongoDB `mongo-sh-arb`, ```bash -$ kubectl get pvc -n demo +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/datadir-mongo-sh-arb-configsvr-0 Bound pvc-a9589ccb-24c2-4d17-8174-1e552d63d943 500Mi RWO standard 97s persistentvolumeclaim/datadir-mongo-sh-arb-configsvr-1 Bound pvc-697aa035-6ff2-45c4-8e00-0787b520159b 500Mi RWO standard 75s @@ -152,7 +153,9 @@ persistentvolumeclaim/datadir-mongo-sh-arb-shard1-0 Bound pvc-33cde persistentvolumeclaim/datadir-mongo-sh-arb-shard1-1 Bound pvc-569cedf8-b16e-4616-ae1d-74168aacc227 500Mi RWO standard 74s persistentvolumeclaim/datadir-mongo-sh-arb-shard1-arbiter-0 Bound pvc-c65c7054-a9de-40c4-9797-4d0a730e9c5b 500Mi RWO standard 52s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-2548ee7e-5416-4ddc-960b-33d17bd53b43 500Mi RWO Delete Bound demo/datadir-mongo-sh-arb-configsvr-2 standard 50s persistentvolume/pvc-33cde211-4ed5-49a9-b7a8-48e94690e12d 500Mi RWO Delete Bound demo/datadir-mongo-sh-arb-shard1-0 standard 93s @@ -163,19 +166,18 @@ persistentvolume/pvc-a5cdb597-ad01-4362-b56e-c5d6226a38bb 500Mi RWO persistentvolume/pvc-a9589ccb-24c2-4d17-8174-1e552d63d943 500Mi RWO Delete Bound demo/datadir-mongo-sh-arb-configsvr-0 standard 94s persistentvolume/pvc-ae9e594a-7370-4339-9f51-6ec07588c8e0 500Mi RWO Delete Bound demo/datadir-mongo-sh-arb-shard0-1 standard 73s persistentvolume/pvc-c65c7054-a9de-40c4-9797-4d0a730e9c5b 500Mi RWO Delete Bound demo/datadir-mongo-sh-arb-shard1-arbiter-0 standard 49s -``` Services created for MongoDB `mongo-sh-arb` ```bash -$ kubectl get svc -n demo +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mongo-sh-arb ClusterIP 10.96.34.129 27017/TCP 97s service/mongo-sh-arb-configsvr-pods ClusterIP None 27017/TCP 97s service/mongo-sh-arb-mongos-pods ClusterIP None 27017/TCP 97s service/mongo-sh-arb-shard0-pods ClusterIP None 27017/TCP 97s service/mongo-sh-arb-shard1-pods ClusterIP None 27017/TCP 97s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. It has also defaulted some field of crd object. Run the following command to see the modified MongoDB object: @@ -319,16 +321,16 @@ If you want to use custom or existing secret please specify that when creating t - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo mongo-sh-arb-auth -o jsonpath='{.data.username}' | base64 -d - root + kubectl get secrets -n demo mongo-sh-arb-auth -o jsonpath='{.data.username}' | base64 -d ``` + root - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo mongo-sh-arb-auth -o jsonpath='{.data.password}' | base64 -d - 6&UiN5;qq)Tnai=7 + kubectl get secrets -n demo mongo-sh-arb-auth -o jsonpath='{.data.password}' | base64 -d ``` + 6&UiN5;qq)Tnai=7 Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/). @@ -337,13 +339,15 @@ Now, you can connect to this database through [mongo-shell](https://docs.mongodb In this tutorial, we will insert sharded and unsharded document, and we will see if the data actually sharded across cluster or not. ```bash -$ kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-arb-mongos +kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-arb-mongos +``` NAME READY STATUS RESTARTS AGE mongo-sh-arb-mongos-0 1/1 Running 0 6m34s mongo-sh-arb-mongos-1 1/1 Running 0 6m20s -$ kubectl exec -it mongo-sh-arb-mongos-0 -n demo bash - +```bash +kubectl exec -it mongo-sh-arb-mongos-0 -n demo bash +``` mongodb@mongo-sh-mongos-0:/$ mongosh admin -u root -p '6&UiN5;qq)Tnai=7' MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb @@ -360,7 +364,6 @@ The server generated these startup warnings when booting: 2022-04-21T09:30:28.259+00:00: You are running this process as the root user, which is not recommended --- mongos> -``` To detect if the MongoDB instance that your client is connected to is mongos, use the isMaster command. When a client connects to a mongos, isMaster returns a document with a `msg` field that holds the string `isdbgrid`. @@ -708,23 +711,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mongo-sh-arb patched +kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh-arb patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mongo-sh-arb patched +kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh-arb patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-sh-arb 4.4.26 Halted 26m @@ -743,7 +747,6 @@ persistentvolumeclaim/datadir-mongo-sh-arb-shard0-arbiter-0 Bound pvc-8296c persistentvolumeclaim/datadir-mongo-sh-arb-shard1-0 Bound pvc-33cde211-4ed5-49a9-b7a8-48e94690e12d 500Mi RWO standard 26m persistentvolumeclaim/datadir-mongo-sh-arb-shard1-1 Bound pvc-569cedf8-b16e-4616-ae1d-74168aacc227 500Mi RWO standard 26m persistentvolumeclaim/datadir-mongo-sh-arb-shard1-arbiter-0 Bound pvc-c65c7054-a9de-40c4-9797-4d0a730e9c5b 500Mi RWO standard 25m -``` From the above output, you can see that MongoDB object, PVCs, Secret are still there. @@ -752,29 +755,30 @@ From the above output, you can see that MongoDB object, PVCs, Secret are still t Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mongo-sh-arb patched +kubectl patch -n demo mg/mongo-sh-arb -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh-arb patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-sh-arb 4.4.26 Ready 28m -``` Now, If you again exec into `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-arb-mongos +kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-arb-mongos +``` NAME READY STATUS RESTARTS AGE mongo-sh-arb-mongos-0 1/1 Running 0 89s mongo-sh-arb-mongos-1 1/1 Running 0 29s - -$ kubectl exec -it mongo-sh-arb-mongos-0 -n demo bash - +```bash +kubectl exec -it mongo-sh-arb-mongos-0 -n demo bash +``` mongodb@mongo-sh-mongos-0:/$ mongosh admin -u root -p '6&UiN5;qq)Tnai=7' mongos> use songs @@ -834,7 +838,6 @@ mongos> sh.status() chunks: shard1 1 { "myfield" : { "$minKey" : 1 } } -->> { "myfield" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0) -``` ## Cleaning up diff --git a/docs/guides/mongodb/autoscaler/compute/replicaset.md b/docs/guides/mongodb/autoscaler/compute/replicaset.md index 3a61eaeecc..6a236ab414 100644 --- a/docs/guides/mongodb/autoscaler/compute/replicaset.md +++ b/docs/guides/mongodb/autoscaler/compute/replicaset.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -81,22 +81,23 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-rs.yaml -mongodb.kubedb.com/mg-rs created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-rs.yaml ``` +mongodb.kubedb.com/mg-rs created Now, wait until `mg-rs` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-rs 4.4.26 Ready 2m53s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -107,11 +108,11 @@ $ kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' "memory": "300Mi" } } -``` Let's check the MongoDB resources, ```bash -$ kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +``` { "limits": { "cpu": "200m", @@ -122,7 +123,6 @@ $ kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.contain "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mongodb. @@ -197,20 +197,23 @@ It has two fields inside it. Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-rs.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as-rs created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-rs.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as-rs created #### Verify Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as-rs 102s -$ kubectl describe mongodbautoscaler mg-as-rs -n demo +```bash +kubectl describe mongodbautoscaler mg-as-rs -n demo +``` Name: mg-as-rs Namespace: demo Labels: @@ -355,7 +358,6 @@ Status: Memory: 1Gi Vpa Name: mg-rs Events: -``` So, the `mongodbautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `mongodbopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -363,25 +365,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-rs-cxhsy1 VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-rs-cxhsy1 VerticalScaling Successful 68s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-mg-rs-cxhsy1 +kubectl describe mongodbopsrequest -n demo mops-mg-rs-cxhsy1 +``` Name: mops-mg-rs-cxhsy1 Namespace: demo Labels: @@ -492,12 +495,11 @@ Events: Normal Successful 2m43s KubeDB Ops-manager Operator Successfully Vertically Scaled Database Normal UpdateReplicaSetResources 2m43s KubeDB Ops-manager Operator Successfully Vertically Scaled Replicaset Resources -``` - Now, we are going to verify from the Pod, and the MongoDB yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -509,7 +511,9 @@ $ kubectl get pod -n demo mg-rs-0 -o json | jq '.spec.containers[].resources' } } -$ kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +```bash +kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +``` { "limits": { "cpu": "400m", @@ -520,7 +524,6 @@ $ kubectl get mongodb -n demo mg-rs -o json | jq '.spec.podTemplate.spec.contain "memory": "400Mi" } } -``` The above output verifies that we have successfully auto scaled the resources of the MongoDB replicaset database. diff --git a/docs/guides/mongodb/autoscaler/compute/sharding.md b/docs/guides/mongodb/autoscaler/compute/sharding.md index ba7896ce3a..7cd0d93680 100644 --- a/docs/guides/mongodb/autoscaler/compute/sharding.md +++ b/docs/guides/mongodb/autoscaler/compute/sharding.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -102,22 +102,23 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-sh.yaml -mongodb.kubedb.com/mg-sh created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-sh.yaml ``` +mongodb.kubedb.com/mg-sh created Now, wait until `mg-sh` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sh 4.4.26 Ready 3m57s -``` Let's check a shard Pod containers resources, ```bash -$ kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -128,11 +129,11 @@ $ kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resour "memory": "300Mi" } } -``` Let's check the MongoDB resources, ```bash -$ kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podTemplate.spec.resources' +kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podTemplate.spec.resources' +``` { "limits": { "cpu": "200m", @@ -143,7 +144,6 @@ $ kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podT "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mongodb. @@ -220,20 +220,23 @@ It has two fields inside it. Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-sh.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as-sh created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-sh.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as-sh created #### Verify Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as-sh 102s -$ kubectl describe mongodbautoscaler mg-as-sh -n demo +```bash +kubectl describe mongodbautoscaler mg-as-sh -n demo +``` Name: mg-as-sh Namespace: demo Labels: @@ -398,8 +401,6 @@ Status: Memory: 1Gi Vpa Name: mg-sh-shard1 Events: - -``` So, the `mongodbautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `mongodbopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -407,25 +408,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-vpa-mg-sh-shard-ml75qi VerticalScaling Progressing 19s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-vpa-mg-sh-shard-ml75qi VerticalScaling Successful 5m8s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-vpa-mg-sh-shard-ml75qi +kubectl describe mongodbopsrequest -n demo mops-vpa-mg-sh-shard-ml75qi +``` Name: mops-vpa-mg-sh-shard-ml75qi Namespace: demo Labels: @@ -534,12 +536,12 @@ Events: Normal ResumeDatabase 46s KubeDB Ops-manager Operator Resuming MongoDB demo/mg-sh Normal ResumeDatabase 46s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-sh Normal Successful 46s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` Now, we are going to verify from the Pod, and the MongoDB yaml whether the resources of the shard pod of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "400Mi" @@ -550,8 +552,9 @@ $ kubectl get pod -n demo mg-sh-shard0-0 -o json | jq '.spec.containers[].resour } } - -$ kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podTemplate.spec.resources' +```bash +kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podTemplate.spec.resources' +``` { "limits": { "memory": "400Mi" @@ -562,8 +565,6 @@ $ kubectl get mongodb -n demo mg-sh -o json | jq '.spec.shardTopology.shard.podT } } -``` - The above output verifies that we have successfully auto scaled the resources of the MongoDB sharded database. diff --git a/docs/guides/mongodb/autoscaler/compute/standalone.md b/docs/guides/mongodb/autoscaler/compute/standalone.md index c5a617fd04..020ab848c3 100644 --- a/docs/guides/mongodb/autoscaler/compute/standalone.md +++ b/docs/guides/mongodb/autoscaler/compute/standalone.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -77,22 +77,23 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-standalone.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-standalone.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 4.4.26 Ready 2m53s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -103,11 +104,11 @@ $ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resou "memory": "300Mi" } } -``` Let's check the MongoDB resources, ```bash -$ kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +``` { "limits": { "cpu": "200m", @@ -118,7 +119,6 @@ $ kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mongodb. @@ -194,20 +194,23 @@ It has two fields inside it. Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-standalone.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/compute/mg-as-standalone.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as created #### Verify Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as 102s -$ kubectl describe mongodbautoscaler mg-as -n demo +```bash +kubectl describe mongodbautoscaler mg-as -n demo +``` Name: mg-as Namespace: demo Labels: @@ -334,8 +337,6 @@ Status: Memory: 1Gi Vpa Name: mg-standalone Events: - -``` So, the `mongodbautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `mongodbopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -343,25 +344,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-standalone-57huq2 VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-standalone-57huq2 VerticalScaling Successful 68s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-mg-standalone-57huq2 +kubectl describe mongodbopsrequest -n demo mops-mg-standalone-57huq2 +``` Name: mops-mg-standalone-57huq2 Namespace: demo Labels: @@ -470,12 +472,12 @@ Events: Normal ResumeDatabase 2m15s KubeDB Ops-manager Operator Resuming MongoDB demo/mg-standalone Normal ResumeDatabase 2m15s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-standalone Normal Successful 2m15s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` Now, we are going to verify from the Pod, and the MongoDB yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -487,7 +489,9 @@ $ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resou } } -$ kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +```bash +kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mongodb") | .resources' +``` { "limits": { "cpu": "400m", @@ -498,7 +502,6 @@ $ kubectl get mongodb -n demo mg-standalone -o json | jq '.spec.podTemplate.spec "memory": "400Mi" } } -``` The above output verifies that we have successfully auto scaled the resources of the MongoDB standalone database. diff --git a/docs/guides/mongodb/autoscaler/storage/replicaset.md b/docs/guides/mongodb/autoscaler/storage/replicaset.md index 6af3b90cfc..11b3a06201 100644 --- a/docs/guides/mongodb/autoscaler/storage/replicaset.md +++ b/docs/guides/mongodb/autoscaler/storage/replicaset.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Mongo To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -85,30 +85,32 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-rs.yaml -mongodb.kubedb.com/mg-rs created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-rs.yaml ``` +mongodb.kubedb.com/mg-rs created Now, wait until `mg-rs` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-rs 4.4.26 Ready 2m53s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mg-rs -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-rs -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-b16daa50-83fc-4d25-b553-4a25f13166d5 1Gi RWO Delete Bound demo/datadir-mg-rs-0 topolvm-provisioner 2m12s pvc-d4616bef-359d-4b73-ab9f-38c24aaaec8c 1Gi RWO Delete Bound demo/datadir-mg-rs-1 topolvm-provisioner 61s pvc-ead21204-3dc7-453c-8121-d2fe48b1c3e2 1Gi RWO Delete Bound demo/datadir-mg-rs-2 topolvm-provisioner 18s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -150,20 +152,23 @@ Here, Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-rs.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as-rs created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-rs.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as-rs created #### Storage Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as-rs 20s -$ kubectl describe mongodbautoscaler mg-as-rs -n demo +```bash +kubectl describe mongodbautoscaler mg-as-rs -n demo +``` Name: mg-as-rs Namespace: demo Labels: @@ -208,7 +213,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `mongodbautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -216,7 +220,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo mg-rs-0 -- bash +kubectl exec -it -n demo mg-rs-0 -- bash +``` root@mg-rs-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/760cb655-91fe-4497-ab4a-a771aa53ece4 1014M 335M 680M 33% /data/db @@ -227,32 +232,32 @@ root@mg-rs-0:/# dd if=/dev/zero of=/data/db/file.img bs=500M count=1 root@mg-rs-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/760cb655-91fe-4497-ab4a-a771aa53ece4 1014M 835M 180M 83% /data/db -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 60%. Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-rs-mft11m VolumeExpansion Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-rs-mft11m VolumeExpansion Successful 97s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-mg-rs-mft11m +kubectl describe mongodbopsrequest -n demo mops-mg-rs-mft11m +``` Name: mops-mg-rs-mft11m Namespace: demo Labels: app.kubernetes.io/component=database @@ -361,19 +366,21 @@ Events: Normal ResumeDatabase 81s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-rs Normal ReadyPetSets 76s KubeDB Ops-manager operator PetSet is recreated Normal Successful 76s KubeDB Ops-manager operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-rs -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-rs -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-b16daa50-83fc-4d25-b553-4a25f13166d5 2Gi RWO Delete Bound demo/datadir-mg-rs-0 topolvm-provisioner 11m pvc-d4616bef-359d-4b73-ab9f-38c24aaaec8c 2Gi RWO Delete Bound demo/datadir-mg-rs-1 topolvm-provisioner 10m pvc-ead21204-3dc7-453c-8121-d2fe48b1c3e2 2Gi RWO Delete Bound demo/datadir-mg-rs-2 topolvm-provisioner 9m52s -``` The above output verifies that we have successfully autoscaled the volume of the MongoDB replicaset database. diff --git a/docs/guides/mongodb/autoscaler/storage/sharding.md b/docs/guides/mongodb/autoscaler/storage/sharding.md index c761646387..89c50037f8 100644 --- a/docs/guides/mongodb/autoscaler/storage/sharding.md +++ b/docs/guides/mongodb/autoscaler/storage/sharding.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Mongo To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -95,25 +95,28 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-sh.yaml -mongodb.kubedb.com/mg-sh created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-sh.yaml ``` +mongodb.kubedb.com/mg-sh created Now, wait until `mg-sh` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sh 4.4.26 Ready 3m51s -``` Let's check volume size from one of the shard petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mg-sh-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-sh-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-031836c6-95ae-4015-938c-da183c205828 1Gi RWO Delete Bound demo/datadir-mg-sh-configsvr-0 topolvm-provisioner 5m1s pvc-2515233f-0f7d-4d0d-8b45-97a3cb9d4488 1Gi RWO Delete Bound demo/datadir-mg-sh-shard0-2 topolvm-provisioner 3m44s @@ -124,7 +127,6 @@ pvc-80dc91d3-f56f-4037-b6e1-f69e13fb434c 1Gi RWO Delete pvc-c1965a32-7471-4885-ac52-f9eab056d48e 1Gi RWO Delete Bound demo/datadir-mg-sh-shard1-2 topolvm-provisioner 3m57s pvc-c838a27d-c75d-4caa-9c1d-456af3bfaba0 1Gi RWO Delete Bound demo/datadir-mg-sh-shard1-0 topolvm-provisioner 4m59s pvc-d47f19be-f206-41c5-a0b1-5022776fea2f 1Gi RWO Delete Bound demo/datadir-mg-sh-shard0-1 topolvm-provisioner 4m25s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -169,20 +171,23 @@ Here, Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-sh.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as-sh created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-sh.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as-sh created #### Storage Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as-sh 20s -$ kubectl describe mongodbautoscaler mg-as-sh -n demo +```bash +kubectl describe mongodbautoscaler mg-as-sh -n demo +``` Name: mg-as-sh Namespace: demo Labels: @@ -227,7 +232,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `mongodbautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up one of the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -235,7 +239,8 @@ Now, for this demo, we are going to manually fill up one of the persistent volum Let's exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo mg-sh-shard0-0 -- bash +kubectl exec -it -n demo mg-sh-shard0-0 -- bash +``` root@mg-sh-shard0-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/ad11042f-f4cc-4dfc-9680-2afbbb199d48 1014M 335M 680M 34% /data/db @@ -246,32 +251,32 @@ root@mg-sh-shard0-0:/# dd if=/dev/zero of=/data/db/file.img bs=500M count=1 root@mg-sh-shard0-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/ad11042f-f4cc-4dfc-9680-2afbbb199d48 1014M 837M 178M 83% /data/db -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 60%. Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-sh-ba5ikn VolumeExpansion Progressing 41s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-sh-ba5ikn VolumeExpansion Successful 2m54s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-mg-sh-ba5ikn +kubectl describe mongodbopsrequest -n demo mops-mg-sh-ba5ikn +``` Name: mops-mg-sh-ba5ikn Namespace: demo Labels: app.kubernetes.io/component=database @@ -380,14 +385,17 @@ Events: Normal ResumeDatabase 36s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-sh Normal ReadyPetSets 31s KubeDB Ops-manager operator PetSet is recreated Normal Successful 31s KubeDB Ops-manager operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the shard nodes of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-sh-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-sh-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-031836c6-95ae-4015-938c-da183c205828 1Gi RWO Delete Bound demo/datadir-mg-sh-configsvr-0 topolvm-provisioner 13m pvc-2515233f-0f7d-4d0d-8b45-97a3cb9d4488 2Gi RWO Delete Bound demo/datadir-mg-sh-shard0-2 topolvm-provisioner 11m @@ -398,7 +406,6 @@ pvc-80dc91d3-f56f-4037-b6e1-f69e13fb434c 2Gi RWO Delete pvc-c1965a32-7471-4885-ac52-f9eab056d48e 2Gi RWO Delete Bound demo/datadir-mg-sh-shard1-2 topolvm-provisioner 11m pvc-c838a27d-c75d-4caa-9c1d-456af3bfaba0 2Gi RWO Delete Bound demo/datadir-mg-sh-shard1-0 topolvm-provisioner 12m pvc-d47f19be-f206-41c5-a0b1-5022776fea2f 2Gi RWO Delete Bound demo/datadir-mg-sh-shard0-1 topolvm-provisioner 12m -``` The above output verifies that we have successfully autoscaled the volume of the shard nodes of this MongoDB database. diff --git a/docs/guides/mongodb/autoscaler/storage/standalone.md b/docs/guides/mongodb/autoscaler/storage/standalone.md index b1111c16e0..1cc12c0238 100644 --- a/docs/guides/mongodb/autoscaler/storage/standalone.md +++ b/docs/guides/mongodb/autoscaler/storage/standalone.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Mongo To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -82,28 +82,30 @@ spec: Let's create the `MongoDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-standalone.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-standalone.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 4.4.26 Ready 2m53s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-cf469ed8-a89a-49ca-bf7c-8c76b7889428 1Gi RWO Delete Bound demo/datadir-mg-standalone-0 topolvm-provisioner 7m41s -``` You can see the petset has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -145,20 +147,23 @@ Here, Let's create the `MongoDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-standalone.yaml -mongodbautoscaler.autoscaling.kubedb.com/mg-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/autoscaling/storage/mg-as-standalone.yaml ``` +mongodbautoscaler.autoscaling.kubedb.com/mg-as created #### Storage Autoscaling is set up successfully Let's check that the `mongodbautoscaler` resource is created successfully, ```bash -$ kubectl get mongodbautoscaler -n demo +kubectl get mongodbautoscaler -n demo +``` NAME AGE mg-as 102s -$ kubectl describe mongodbautoscaler mg-as -n demo +```bash +kubectl describe mongodbautoscaler mg-as -n demo +``` Name: mg-as Namespace: demo Labels: @@ -203,7 +208,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `mongodbautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -211,7 +215,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo mg-standalone-0 -- bash +kubectl exec -it -n demo mg-standalone-0 -- bash +``` root@mg-standalone-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/1df4ee9e-b900-4c0f-9d2c-8493fb30bdc0 1014M 334M 681M 33% /data/db @@ -222,32 +227,32 @@ root@mg-standalone-0:/# dd if=/dev/zero of=/data/db/file.img bs=500M count=1 root@mg-standalone-0:/# df -h /data/db Filesystem Size Used Avail Use% Mounted on /dev/topolvm/1df4ee9e-b900-4c0f-9d2c-8493fb30bdc0 1014M 835M 180M 83% /data/db -``` So, from the above output we can see that the storage usage is 84%, which exceeded the `usageThreshold` 60%. Let's watch the `mongodbopsrequest` in the demo namespace to see if any `mongodbopsrequest` object is created. After some time you'll see that a `mongodbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-standalone-p27c11 VolumeExpansion Progressing 26s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-mg-standalone-p27c11 VolumeExpansion Successful 73s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-mg-standalone-p27c11 +kubectl describe mongodbopsrequest -n demo mops-mg-standalone-p27c11 +``` Name: mops-mg-standalone-p27c11 Namespace: demo Labels: app.kubernetes.io/component=database @@ -356,17 +361,19 @@ Events: Normal ResumeDatabase 50s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-standalone Normal ReadyPetSets 45s KubeDB Ops-manager operator PetSet is recreated Normal Successful 45s KubeDB Ops-manager operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-cf469ed8-a89a-49ca-bf7c-8c76b7889428 2Gi RWO Delete Bound demo/datadir-mg-standalone-0 topolvm-provisioner 26m -``` The above output verifies that we have successfully autoscaled the volume of the MongoDB standalone database. diff --git a/docs/guides/mongodb/backup/kubestash/application-level/index.md b/docs/guides/mongodb/backup/kubestash/application-level/index.md index 0156328a80..1b4b0c8606 100644 --- a/docs/guides/mongodb/backup/kubestash/application-level/index.md +++ b/docs/guides/mongodb/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mongodb/backup/kubestash/application-level/examples](https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -81,32 +81,34 @@ spec: Create the above `MongoDB` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/sample-mongodb.yaml -mongodb.kubedb.com/sample-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/sample-mongodb.yaml ``` +mongodb.kubedb.com/sample-mongodb created KubeDB will deploy a `MongoDB` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mongodb +kubectl get mg -n demo sample-mongodb +``` NAME VERSION STATUS AGE sample-mongodb 4.4.26 Ready 3m53s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-mongodb-auth kubernetes.io/basic-auth 2 5m20s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mongodb ClusterIP 10.128.34.128 27017/TCP 4m47s sample-mongodb-pods ClusterIP None 27017/TCP 4m47s -``` Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -116,15 +118,15 @@ Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` t Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-mongodb mongodb 4.4.26 24h -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mongodb -o yaml +kubectl get appbindings -n demo sample-mongodb -o yaml ``` ```yaml @@ -194,22 +196,26 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +``` NAME READY STATUS RESTARTS AGE sample-mongodb-0 2/2 Running 0 16m sample-mongodb-1 2/2 Running 0 13m sample-mongodb-2 2/2 Running 0 13m -``` Now, let’s exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` replicaset:PRIMARY> show dbs admin 0.000GB config 0.000GB @@ -227,7 +233,6 @@ replicaset:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` Now, we are ready to backup the database. @@ -240,13 +245,19 @@ We are going to store our backed up data into a `S3` bucket. At first, we need t Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -276,9 +287,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -291,10 +302,10 @@ We have to create a `BackupConfiguration` targeting respective MongoDB crd of ou EncryptionSecret refers to the Secret containing the encryption key which will be used to encode/decode the backed up data. Let's create a secret called `encry-secret` ```bash -$ kubectl create secret generic encry-secret -n demo \ +kubectl create secret generic encry-secret -n demo \ --from-literal=RESTIC_PASSWORD='123' -n demo -secret/encry-secret created ``` +secret/encry-secret created **Create Retention Policy:** @@ -318,9 +329,9 @@ spec: Let's create the RetentionPolicy we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/backup-rp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/backup-rp created **Create BackupConfiguration:** @@ -373,27 +384,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mongodb-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mongodb-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mongodb-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-mongodb-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the S3 bucket, we will see the `Repository` YAML stored in the `demo-application-level/mongodb` directory. @@ -404,20 +415,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mongodb-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mongodb-backup-frequent-backup-1725449400 BackupConfiguration sample-mongodb-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -426,18 +437,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `s3-mongodb-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-mongodb-repo +kubectl get repository -n demo s3-mongodb-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-mongodb-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-mongodb-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-mongodb-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-mongodb-repo-sample-mongodb-backup-frequent-backup-1725449400 s3-mongodb-repo frequent-backup 2024-09-17T06:53:42Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -450,7 +461,7 @@ s3-mongodb-repo-sample-mongodb-backup-frequent-backup-1725449400 s3-mongodb If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-mongodb-repo-sample-mongodb-backup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo s3-mongodb-repo-sample-mongodb-backup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -555,9 +566,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -599,18 +610,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-mongodb created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE restore-sample-mongodb s3-mongodb-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -620,10 +631,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `MongoDB` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get mongodb -n dev +kubectl get mongodb -n dev +``` NAME VERSION STATUS AGE sample-mongodb 4.4.26 Ready 9m46s -``` The output confirms that the `MongoDB` database has been successfully created with the same configuration as it had at the time of backup. @@ -635,31 +646,35 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get mongodb -n dev sample-mongodb +kubectl get mongodb -n dev sample-mongodb +``` NAME VERSION STATUS AGE sample-mongodb 4.4.26 Ready 9m46s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mongodb" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mongodb" +``` NAME READY STATUS RESTARTS AGE sample-mongodb-0 2/2 Running 0 12m sample-mongodb-1 2/2 Running 0 12m sample-mongodb-2 2/2 Running 0 12m -``` Now, lets exec one of the Pod and verify restored data. ```bash -$ export USER=$(kubectl get secrets -n dev sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n dev sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n dev sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n dev sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n dev sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n dev sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` --- replicaset:PRIMARY> show dbs admin 0.000GB @@ -680,8 +695,6 @@ replicaset:PRIMARY> db.movie.find() replicaset:PRIMARY> exit bye -``` - So, from the above output, we can see that in `dev` namespace the original database `sample-mongodb` has been restored successfully. ## Cleanup diff --git a/docs/guides/mongodb/backup/kubestash/auto-backup/index.md b/docs/guides/mongodb/backup/kubestash/auto-backup/index.md index 7c6ff3f4c7..87712fd5fe 100644 --- a/docs/guides/mongodb/backup/kubestash/auto-backup/index.md +++ b/docs/guides/mongodb/backup/kubestash/auto-backup/index.md @@ -37,9 +37,9 @@ You should be familiar with the following `KubeStash` concepts: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Backup Blueprint @@ -54,13 +54,19 @@ We are going to store our backed up data into a S3 bucket. At first, we need to Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created ### Create BackupStorage: @@ -90,9 +96,9 @@ spec: Let's create the `BackupStorage` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created We also need to create an secret for encrypt data and retention policy for `BackupBlueprint` to create `BackupConfiguration` ### Create Encryption Secret: @@ -100,10 +106,10 @@ We also need to create an secret for encrypt data and retention policy for `Back EncryptionSecret refers to the Secret containing the encryption key which will be used to encode/decode the backed up data. Let's create a secret called `encry-secret` ```bash -$ kubectl create secret generic encry-secret -n demo \ +kubectl create secret generic encry-secret -n demo \ --from-literal=RESTIC_PASSWORD='123' -n demo -secret/encry-secret created ``` +secret/encry-secret created ### Create Retention Policy: @@ -127,9 +133,9 @@ spec: Let's create the RetentionPolicy we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/backup-rp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/backup-rp created Now we can create `BackupBlueprint`. Below is the YAML of `BackupBlueprint` object that we are going to use in this tutorial, diff --git a/docs/guides/mongodb/backup/kubestash/logical/replicaset/index.md b/docs/guides/mongodb/backup/kubestash/logical/replicaset/index.md index 0278754b85..ba3a86b1ea 100644 --- a/docs/guides/mongodb/backup/kubestash/logical/replicaset/index.md +++ b/docs/guides/mongodb/backup/kubestash/logical/replicaset/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MongoDB @@ -74,33 +74,35 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/mongodb-replicaset.yaml -mongodb.kubedb.com/sample-mg-rs created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/mongodb-replicaset.yaml ``` +mongodb.kubedb.com/sample-mg-rs created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mongodb -n demo sample-mg-rs +kubectl get mongodb -n demo sample-mg-rs +``` NAME VERSION STATUS AGE sample-mg-rs 4.4.26 Ready 2m27s -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mg-rs +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mg-rs +``` NAME TYPE DATA AGE sample-mg-rs-auth kubernetes.io/basic-auth 2 3m53s sample-mg-rs-key Opaque 1 3m53s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mg-rs +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mg-rs +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mg-rs ClusterIP 10.96.211.27 27017/TCP 4m38s sample-mg-rs-pods ClusterIP None 27017/TCP 4m38s -``` Here, we have to use service `sample-mg-rs` and secret `sample-mg-rs-auth` to connect with the database. @@ -111,22 +113,26 @@ Here, we have to use service `sample-mg-rs` and secret `sample-mg-rs-auth` to co For simplicity, we are going to exec into the database pod and create some sample data. At first, find out the database pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mg-rs" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mg-rs" +``` NAME READY STATUS RESTARTS AGE sample-mg-rs-0 2/2 Running 0 6m15s sample-mg-rs-1 2/2 Running 0 5m36s sample-mg-rs-2 2/2 Running 0 5m14s -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mg-rs-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mg-rs-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mg-rs-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mg-rs-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mg-rs-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mg-rs-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> show dbs admin 0.000GB config 0.000GB @@ -163,8 +169,6 @@ rs0:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` - Now, we are ready to backup this sample database. ### Prepare Backend @@ -176,13 +180,19 @@ We are going to store our backed up data into a S3 bucket. At first, we need to Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -212,9 +222,9 @@ spec: Let's create the `BackupStorage` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/backupstorage-replicaset.yaml -backupstorage.storage.kubestash.com/s3-storage-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/backupstorage-replicaset.yaml ``` +backupstorage.storage.kubestash.com/s3-storage-replicaset created Now, we are ready to backup our database to our desired backend. @@ -227,10 +237,10 @@ We have to create a `BackupConfiguration` targeting respective MongoDB crd of ou EncryptionSecret refers to the Secret containing the encryption key which will be used to encode/decode the backed up data. Let's create a secret called `encry-secret` ```bash -$ kubectl create secret generic encry-secret -n demo \ +kubectl create secret generic encry-secret -n demo \ --from-literal=RESTIC_PASSWORD='123' -n demo -secret/encry-secret created ``` +secret/encry-secret created **Create Retention Policy:** @@ -254,9 +264,9 @@ spec: Let's create the RetentionPolicy we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/backup-rp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/backup-rp created **Create BackupConfiguration:** @@ -314,19 +324,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/backupconfiguration-replicaset.yaml -backupconfiguration.core.kubestash.com/mg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/backupconfiguration-replicaset.yaml ``` +backupconfiguration.core.kubestash.com/mg created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE mg Ready 85s -``` **Verify CronJob:** @@ -335,10 +345,10 @@ KubeStash will create a CronJob with the schedule specified in `spec.sessions.sc Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-mg-frequent */3 * * * * False 0 101s -``` **Wait for BackupSession:** @@ -347,11 +357,11 @@ The `trigger-mg-frequent` CronJob will trigger a backup on each schedule by crea Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mg-frequent-1701940862 BackupConfiguration mg Succeeded 3m16s mg-frequent-1701941042 BackupConfiguration mg Running 16s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -360,19 +370,19 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, KubeStash will update the respective `Snapshot` crd to reflect the backup. It will be created when a backup is triggered. Check that the `Snapshot` Phase to verify backup. ```bash -$ kubectl get snapshot -n demo +kubectl get snapshot -n demo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE VERIFICATION-STATUS AGE s3-repo-mg-frequent-1701940862 s3-repo frequent 2023-12-07T09:21:07Z Delete Succeeded 3m53s s3-repo-mg-frequent-1701941042 s3-repo frequent 2023-12-07T09:24:08Z Delete Succeeded 53s -``` KubeStash will also update the respective `Repository` crd to reflect the backup. Check that the repository `s3-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-repo +kubectl get repository -n demo s3-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-repo true 2 2.883 KiB Ready 55s 8m5s -``` Now, if we navigate to the S3 bucket, we are going to see backed up data has been stored in `demo/replicaset/` directory as specified by `spec.sessions.repositories.directory` field of `BackupConfiguration` crd. @@ -387,17 +397,17 @@ It's important to stop taking any further backup of the old database so that no Let's pause the `mg` BackupConfiguration by patching, ```bash -$ kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.core.kubestash.com/mg patched +kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.core.kubestash.com/mg patched Now, wait for a moment. KubeStash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo mg +kubectl get backupconfiguration -n demo mg +``` NAME PHASE PAUSED AGE mg Ready true 11m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -431,27 +441,31 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/mongodb-replicaset-restore.yaml -mongodb.kubedb.com/sample-mg-rs-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/mongodb-replicaset-restore.yaml ``` +mongodb.kubedb.com/sample-mg-rs-restore created Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mg-rs-restore +kubectl get mg -n demo sample-mg-rs-restore +``` NAME VERSION STATUS AGE sample-mg-rs-restore 4.4.26 Ready 2m45s -``` Let's verify all the databases of this `sample-mg-rs-restore` by exec into its pod ```bash -$ export USER=$(kubectl get secrets -n demo sample-mg-rs-restore-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mg-rs-restore-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mg-rs-restore-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mg-rs-restore-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mg-rs-restore-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mg-rs-restore-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> show dbs admin 0.000GB config 0.000GB @@ -478,7 +492,6 @@ rs0:PRIMARY> show users rs0:PRIMARY> exit bye -``` As we can see no database named `newdb` exist in this new `sample-mg-rs-restore` database. @@ -520,19 +533,19 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/restoresession-replicaset.yaml -restoresession.core.kubestash.com/mg-rs-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/replicaset/examples/restoresession-replicaset.yaml ``` +restoresession.core.kubestash.com/mg-rs-restore created Once, you have created the `RestoreSession` crd, KubeStash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo mg-rs-restore -w +kubectl get restoresession -n demo mg-rs-restore -w +``` NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE mg-rs-restore s3-repo Succeeded 9s 34s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -543,8 +556,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database pod and list available tables, ```bash -$ kubectl exec -it -n demo sample-mg-rs-restore-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mg-rs-restore-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> show dbs admin 0.000GB config 0.000GB @@ -578,7 +591,6 @@ rs0:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored into another new `MongoDB` database. diff --git a/docs/guides/mongodb/backup/kubestash/logical/sharding/index.md b/docs/guides/mongodb/backup/kubestash/logical/sharding/index.md index 87ebabe51c..5d288c1f0a 100644 --- a/docs/guides/mongodb/backup/kubestash/logical/sharding/index.md +++ b/docs/guides/mongodb/backup/kubestash/logical/sharding/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MongoDB @@ -83,29 +83,32 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/mongodb-sharding.yaml -mongodb.kubedb.com/sample-mg-sh created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/mongodb-sharding.yaml ``` +mongodb.kubedb.com/sample-mg-sh created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mongodb -n demo sample-mg-sh +kubectl get mongodb -n demo sample-mg-sh +``` NAME VERSION STATUS AGE sample-mg-sh 4.4.26 Ready 5m39s -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mg-sh +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mg-sh +``` NAME TYPE DATA AGE sample-mg-sh-auth kubernetes.io/basic-auth 2 21m sample-mg-sh-key Opaque 1 21m -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mg-sh +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mg-sh +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mg-sh ClusterIP 10.96.80.43 27017/TCP 21m sample-mg-sh-configsvr-pods ClusterIP None 27017/TCP 21m @@ -113,7 +116,6 @@ sample-mg-sh-mongos-pods ClusterIP None 27017/TCP sample-mg-sh-shard0-pods ClusterIP None 27017/TCP 21m sample-mg-sh-shard1-pods ClusterIP None 27017/TCP 21m sample-mg-sh-shard2-pods ClusterIP None 27017/TCP 21m -``` Here, we have to use service `sample-mg-sh` and secret `sample-mg-sh-auth` to connect with the database. @@ -124,21 +126,25 @@ Here, we have to use service `sample-mg-sh` and secret `sample-mg-sh-auth` to co For simplicity, we are going to exec into the database pod and create some sample data. At first, find out the database mongos pod using the following command, ```bash -$ kubectl get pods -n demo --selector="mongodb.kubedb.com/node.mongos=sample-mg-sh-mongos" +kubectl get pods -n demo --selector="mongodb.kubedb.com/node.mongos=sample-mg-sh-mongos" +``` NAME READY STATUS RESTARTS AGE sample-mg-sh-mongos-0 1/1 Running 0 21m sample-mg-sh-mongos-1 1/1 Running 0 21m -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mg-sh-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mg-sh-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mg-sh-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mg-sh-mongos-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mg-sh-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mg-sh-mongos-0 -- mongosh admin -u $USER -p $PASSWORD +``` mongos> show dbs admin 0.000GB config 0.002GB @@ -171,8 +177,6 @@ WriteResult({ "nInserted" : 1 }) mongos> exit bye -``` - Now, we are ready to backup this sample database. ### Prepare Backend @@ -184,13 +188,19 @@ We are going to store our backed up data into a S3 bucket. At first, we need to Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -220,9 +230,9 @@ spec: Let's create the `BackupStorage` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/backupstorage-sharding.yaml -backupstorage.storage.kubestash.com/s3-storage-sharding created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/backupstorage-sharding.yaml ``` +backupstorage.storage.kubestash.com/s3-storage-sharding created Now, we are ready to backup our database to our desired backend. @@ -235,10 +245,10 @@ We have to create a `BackupConfiguration` targeting respective MongoDB crd of ou EncryptionSecret refers to the Secret containing the encryption key which will be used to encode/decode the backed up data. Let's create a secret called `encry-secret` ```bash -$ kubectl create secret generic encry-secret -n demo \ +kubectl create secret generic encry-secret -n demo \ --from-literal=RESTIC_PASSWORD='123' -n demo -secret/encry-secret created ``` +secret/encry-secret created **Create Retention Policy:** @@ -262,9 +272,9 @@ spec: Let's create the RetentionPolicy we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/backup-rp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/backup-rp created **Create BackupConfiguration:** @@ -322,19 +332,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/backupconfiguration-sharding.yaml -backupconfiguration.core.kubestash.com/mg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/backupconfiguration-sharding.yaml ``` +backupconfiguration.core.kubestash.com/mg created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE mg Ready 85s -``` **Verify CronJob:** @@ -343,10 +353,10 @@ KubeStash will create a CronJob with the schedule specified in `spec.sessions.sc Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-mg-frequent */3 * * * * False 0 101s -``` **Wait for BackupSession:** @@ -355,11 +365,11 @@ The `trigger-mg-frequent` CronJob will trigger a backup on each schedule by crea Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mg-frequent-1701950402 BackupConfiguration mg Succeeded 3m5s mg-frequent-1701950582 BackupConfiguration mg Running 5s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -368,19 +378,19 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, KubeStash will update the respective `Snapshot` crd to reflect the backup. It will be created when a backup is triggered. Check that the `Snapshot` Phase to verify backup. ```bash -$ kubectl get snapshot -n demo +kubectl get snapshot -n demo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE VERIFICATION-STATUS AGE s3-repo-mg-frequent-1701950402 s3-repo frequent 2023-12-07T12:00:11Z Delete Succeeded 3m37s s3-repo-mg-frequent-1701950582 s3-repo frequent 2023-12-07T12:03:08Z Delete Succeeded 37s -``` KubeStash will also update the respective `Repository` crd to reflect the backup. Check that the repository `s3-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-repo +kubectl get repository -n demo s3-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-repo true 2 95.660 KiB Ready 41s 4m3s -``` Now, if we navigate to the S3 bucket, we are going to see backed up data has been stored in `demo/sharding/` directory as specified by `spec.sessions.repositories.directory` field of `BackupConfiguration` crd. @@ -395,17 +405,17 @@ It's important to stop taking any further backup of the old database so that no Let's pause the `mg` BackupConfiguration by patching, ```bash -$ kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.core.kubestash.com/mg patched +kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.core.kubestash.com/mg patched Now, wait for a moment. KubeStash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo mg +kubectl get backupconfiguration -n demo mg +``` NAME PHASE PAUSED AGE mg Ready true 11m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -447,27 +457,31 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/mongodb-sharding-restore.yaml -mongodb.kubedb.com/sample-mg-sh-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/mongodb-sharding-restore.yaml ``` +mongodb.kubedb.com/sample-mg-sh-restore created Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mg-sh-restore +kubectl get mg -n demo sample-mg-sh-restore +``` NAME VERSION STATUS AGE sample-mg-sh-restore 4.4.26 Ready 7m47s -``` Let's verify all the databases of this `sample-mg-sh-restore` by exec into its mongos pod ```bash -$ export USER=$(kubectl get secrets -n demo sample-mg-sh-restore-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mg-sh-restore-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mg-sh-restore-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mg-sh-restore-mongos-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mg-sh-restore-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mg-sh-restore-mongos-0 -- mongosh admin -u $USER -p $PASSWORD +``` mongos> show dbs admin 0.000GB config 0.002GB @@ -493,7 +507,6 @@ mongos> show users mongos> exit bye -``` As we can see no database named `newdb` exist in this new `sample-mg-sh-restore` database. @@ -535,19 +548,19 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/restoresession-sharding.yaml -restoresession.core.kubestash.com/mg-sh-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/sharding/examples/restoresession-sharding.yaml ``` +restoresession.core.kubestash.com/mg-sh-restore created Once, you have created the `RestoreSession` crd, KubeStash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo mg-sh-restore -w +kubectl get restoresession -n demo mg-sh-restore -w +``` NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE mg-sh-restore s3-repo Succeeded 15s 48s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -558,8 +571,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database's mongos pod and list available tables, ```bash -$ kubectl exec -it -n demo sample-mg-sh-restore-mongos-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mg-sh-restore-mongos-0 -- mongosh admin -u $USER -p $PASSWORD +``` mongos> show dbs admin 0.000GB config 0.002GB @@ -592,7 +605,6 @@ mongos> db.movie.find().pretty() mongos> exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored into another new `MongoDB` database. diff --git a/docs/guides/mongodb/backup/kubestash/logical/standalone/index.md b/docs/guides/mongodb/backup/kubestash/logical/standalone/index.md index 81e69708f9..bd131bd586 100644 --- a/docs/guides/mongodb/backup/kubestash/logical/standalone/index.md +++ b/docs/guides/mongodb/backup/kubestash/logical/standalone/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MongoDB @@ -72,32 +72,34 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/mongodb.yaml -mongodb.kubedb.com/sample-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/mongodb.yaml ``` +mongodb.kubedb.com/sample-mongodb created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mongodb +kubectl get mg -n demo sample-mongodb +``` NAME VERSION STATUS AGE sample-mongodb 4.4.26 Ready 2m9s -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mongodb +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mongodb +``` NAME TYPE DATA AGE sample-mongodb-auth Opaque 2 2m28s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mongodb ClusterIP 10.107.58.222 27017/TCP 2m48s sample-mongodb-gvr ClusterIP None 27017/TCP 2m48s -``` Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` to connect with the database. @@ -108,20 +110,24 @@ Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` t For simplicity, we are going to exec into the database pod and create some sample data. At first, find out the database pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +``` NAME READY STATUS RESTARTS AGE sample-mongodb-0 1/1 Running 0 12m -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -157,7 +163,6 @@ WriteResult({ "nInserted" : 1 }) > exit bye -``` Now, we are ready to backup this sample database. @@ -170,13 +175,19 @@ We are going to store our backed up data into a S3 bucket. At first, we need to Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -206,9 +217,9 @@ spec: Let's create the `BackupStorage` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/backupstorage.yaml -storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/backupstorage.yaml ``` +storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -221,10 +232,10 @@ We have to create a `BackupConfiguration` targeting respective MongoDB crd of ou EncryptionSecret refers to the Secret containing the encryption key which will be used to encode/decode the backed up data. Let's create a secret called `encry-secret` ```bash -$ kubectl create secret generic encry-secret -n demo \ +kubectl create secret generic encry-secret -n demo \ --from-literal=RESTIC_PASSWORD='123' -n demo -secret/encry-secret created ``` +secret/encry-secret created **Create Retention Policy:** @@ -248,9 +259,9 @@ spec: Let's create the RetentionPolicy we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/backup-rp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/backup-rp created **Create BackupConfiguration:** @@ -308,19 +319,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/mg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/mg created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE mg Ready 85s -``` **Verify CronJob:** @@ -329,10 +340,10 @@ KubeStash will create a CronJob with the schedule specified in `spec.sessions.sc Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-mg-frequent */3 * * * * False 0 101s -``` **Wait for BackupSession:** @@ -341,11 +352,11 @@ The `trigger-mg-frequent` CronJob will trigger a backup on each schedule by crea Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mg-frequent-1701923402 BackupConfiguration mg Succeeded 3m4s mg-frequent-1701923582 BackupConfiguration mg Running 4s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -354,20 +365,20 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, KubeStash will update the respective `Snapshot` crd to reflect the backup. It will be created when a backup is triggered. Check that the `Snapshot` Phase to verify backup. ```bash -$ kubectl get snapshot -n demo +kubectl get snapshot -n demo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE VERIFICATION-STATUS AGE s3-repo-mg-frequent-1701923402 s3-repo frequent 2023-12-07T04:30:10Z Delete Succeeded 3m25s s3-repo-mg-frequent-1701923582 s3-repo frequent 2023-12-07T04:33:06Z Delete Succeeded 25s -``` KubeStash will also update the respective `Repository` crd to reflect the backup. Check that the repository `s3-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-repo +kubectl get repository -n demo s3-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-repo true 2 2.613 KiB Ready 2m42s 8m38s -``` Now, if we navigate to the S3 bucket, we are going to see backed up data has been stored in `demo/mongodb/` directory as specified by `spec.sessions.repositories.directory` field of `BackupConfiguration` crd. @@ -382,17 +393,17 @@ It's important to stop taking any further backup of the old database so that no Let's pause the `mg` BackupConfiguration by patching, ```bash -$ kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.core.kubestash.com/mg patched +kubectl patch backupconfiguration -n demo mg --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.core.kubestash.com/mg patched Now, wait for a moment. KubeStash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo mg +kubectl get backupconfiguration -n demo mg +``` NAME PHASE PAUSED AGE mg Ready true 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -424,27 +435,31 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/mongodb-restore.yaml -mongodb.kubedb.com/restore-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/mongodb-restore.yaml ``` +mongodb.kubedb.com/restore-mongodb created Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo restore-mongodb +kubectl get mg -n demo restore-mongodb +``` NAME VERSION STATUS AGE restore-mongodb 4.4.26 Ready 3m30s -``` Let's verify all the databases of this `restore-mongodb` by exec into its pod ```bash -$ export USER=$(kubectl get secrets -n demo restore-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo restore-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo restore-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo restore-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo restore-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo restore-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -471,7 +486,6 @@ local 0.000GB > exit bye -``` As we can see no database named `newdb` exist in this new `restore-mongodb` database. @@ -513,19 +527,19 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/restoresession.yaml -restoresession.core.kubestash.com/mg-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/kubestash/logical/standalone/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/mg-restore created Once, you have created the `RestoreSession` crd, KubeStash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo sample-mongodb-restore -w +kubectl get restoresession -n demo sample-mongodb-restore -w +``` NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE mg-restore s3-repo Succeeded 8s 49s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -536,8 +550,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database pod and list available tables, ```bash -$ kubectl exec -it -n demo restore-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo restore-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -571,7 +585,6 @@ switched to db newdb > exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored into another new `MongoDB` database. diff --git a/docs/guides/mongodb/backup/stash/logical/replicaset/index.md b/docs/guides/mongodb/backup/stash/logical/replicaset/index.md index 3c87dce52e..a0366122a0 100644 --- a/docs/guides/mongodb/backup/stash/logical/replicaset/index.md +++ b/docs/guides/mongodb/backup/stash/logical/replicaset/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MongoDB ReplicaSet using Stash @@ -74,33 +74,35 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/mongodb-replicaset.yaml -mongodb.kubedb.com/sample-mgo-rs created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/mongodb-replicaset.yaml ``` +mongodb.kubedb.com/sample-mgo-rs created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mgo-rs +kubectl get mg -n demo sample-mgo-rs +``` NAME VERSION STATUS AGE sample-mgo-rs 4.4.26 Ready 1m -``` The database is `Running`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mgo-rs +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mgo-rs +``` NAME TYPE DATA AGE sample-mgo-rs-auth Opaque 2 117s sample-mgo-rs-cert Opaque 4 116s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mgo-rs +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mgo-rs +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mgo-rs ClusterIP 10.107.13.16 27017/TCP 2m14s sample-mgo-rs-gvr ClusterIP None 27017/TCP 2m14s -``` KubeDB creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) crd that holds the necessary information to connect with the database. @@ -109,15 +111,15 @@ KubeDB creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) crd Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mgo-rs 58s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mgo-rs -o yaml +kubectl get appbindings -n demo sample-mgo-rs -o yaml ``` ```yaml @@ -188,22 +190,26 @@ Stash uses the `AppBinding` crd to connect with the target database. It requires Now, we are going to exec into the database pod and create some sample data. At first, find out the database pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mgo-rs" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mgo-rs" +``` NAME READY STATUS RESTARTS AGE sample-mgo-rs-0 1/1 Running 0 16m sample-mgo-rs-1 1/1 Running 0 15m sample-mgo-rs-2 1/1 Running 0 15m -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mgo-rs-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mgo-rs-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mgo-rs-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mgo-rs-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> rs.isMaster().primary sample-mgo-rs-0.sample-mgo-rs-gvr.demo.svc.cluster.local:27017 @@ -237,7 +243,6 @@ rs0:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` Now, we are ready to backup this sample database. @@ -250,15 +255,24 @@ We are going to store our backed up data into a GCS bucket. At first, we need to Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -281,9 +295,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/repository-replicaset.yaml -repository.stash.appscode.com/gcs-repo-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/repository-replicaset.yaml ``` +repository.stash.appscode.com/gcs-repo-replicaset created Now, we are ready to backup our database to our desired backend. @@ -324,19 +338,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/backupconfiguration-replicaset.yaml -backupconfiguration.stash.appscode.com/sample-mgo-rs-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/backupconfiguration-replicaset.yaml ``` +backupconfiguration.stash.appscode.com/sample-mgo-rs-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mgo-rs-backup mongodb-backup-4.4.6 */5 * * * * Ready 11s -``` **Verify CronJob:** @@ -345,10 +359,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE sample-mgo-rs-backup */5 * * * * False 0 62s -``` **Wait for BackupSession:** @@ -357,11 +371,11 @@ The `sample-mgo-rs-backup` CronJob will trigger a backup on each schedule by cre Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mgo-rs-backup-1563540308 BackupConfiguration sample-mgo-rs-backup Running 5m19s sample-mgo-rs-backup-1563540308 BackupConfiguration sample-mgo-rs-backup Succeeded 5m45s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -370,10 +384,10 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, Stash will update the respective `Repository` crd to reflect the backup. Check that the repository `gcs-repo-replicaset` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo-replicaset +kubectl get repository -n demo gcs-repo-replicaset +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo-replicaset true 3.844 KiB 2 14s 10m -``` Now, if we navigate to the GCS bucket, we are going to see backed up data has been stored in `demo/mongodb/sample-mgo-rs` directory as specified by `spec.backend.gcs.prefix` field of Repository crd. @@ -388,22 +402,22 @@ At first, let's stop taking any further backup of the old database so that no ba Let's pause the `sample-mgo-rs-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mgo-rs-backup --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mgo-rs-backup patched +kubectl patch backupconfiguration -n demo sample-mgo-rs-backup --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mgo-rs-backup patched Or you can use the Stash `kubectl` plugin to pause the `BackupConfiguration`, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mgo-rs-backup -BackupConfiguration demo/sample-mgo-rs-backup has been paused successfu +kubectl stash pause backup -n demo --backupconfig=sample-mgo-rs-backup ``` +BackupConfiguration demo/sample-mgo-rs-backup has been paused successfu Now, wait for a moment. Stash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo sample-mgo-rs-backup +kubectl get backupconfiguration -n demo sample-mgo-rs-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mgo-rs-backup mongodb-backup-4.4.6 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -411,8 +425,8 @@ Notice the `PAUSED` column. Value `true` for this field means that the BackupCon Now, let’s simulate an accidental deletion scenario. Here, we are going to exec into the database pod and delete the `newdb` database we had created earlier. ```bash -$ kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> rs.isMaster().primary sample-mgo-rs-0.sample-mgo-rs-gvr.demo.svc.cluster.local:27017 @@ -429,7 +443,6 @@ local 0.000GB rs0:PRIMARY> exit bye -``` #### Create RestoreSession: Now, we need to create a `RestoreSession` crd pointing to the AppBinding of `sample-mgo-rs` database. @@ -461,20 +474,20 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/estoresession-replicaset.yaml -restoresession.stash.appscode.com/sample-mgo-rs-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/estoresession-replicaset.yaml ``` +restoresession.stash.appscode.com/sample-mgo-rs-restore created Once, you have created the `RestoreSession` crd, Stash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo sample-mgo-rs-restore -w +kubectl get restoresession -n demo sample-mgo-rs-restore -w +``` NAME REPOSITORY-NAME PHASE AGE sample-mgo-rs-restore gcs-repo-replicaset Running 5s sample-mgo-rs-restore gcs-repo-replicaset Succeeded 43s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -487,8 +500,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database pod and list available tables, ```bash -$ kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mgo-rs-0 -- mongosh admin -u $USER -p $PASSWORD +``` rs0:PRIMARY> rs.isMaster().primary restored-mgo-rs-0.restored-mgo-rs-gvr.demo.svc.cluster.local:27017 @@ -520,7 +533,6 @@ rs0:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored. @@ -587,21 +599,23 @@ spec: This time, we have to provide the Stash Addon information in `spec.task` section of `BackupConfiguration` object as it does not present in the `AppBinding` object that we are creating manually. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/standalone-backup.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/examples/standalone-backup.yaml +``` appbinding.appcatalog.appscode.com/sample-mgo-rs-custom created repository.stash.appscode.com/gcs-repo-custom created backupconfiguration.stash.appscode.com/sample-mgo-rs-backup2 created - -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME BACKUPCONFIGURATION PHASE AGE sample-mgo-rs-backup2-1563541509 sample-mgo-rs-backup Succeeded 35s - -$ kubectl get repository -n demo gcs-repo-custom +```bash +kubectl get repository -n demo gcs-repo-custom +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo-custom true 1.640 KiB 1 1m 5m -``` ### Restore to a standalone database @@ -653,30 +667,40 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/rexamples/estored-standalone.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/rexamples/estored-standalone.yaml +``` mongodb.kubedb.com/restored-mongodb created -$ kubectl get mg -n demo restored-mongodb +```bash +kubectl get mg -n demo restored-mongodb +``` NAME VERSION STATUS AGE restored-mongodb 4.4.26 Provisioning 56s -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/rexamples/estoresession-standalone.yaml +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/replicaset/rexamples/estoresession-standalone.yaml +``` restoresession.stash.appscode.com/sample-mongodb-restore created -$ kubectl get mg -n demo restored-mongodb +```bash +kubectl get mg -n demo restored-mongodb +``` NAME VERSION STATUS AGE restored-mongodb 4.4.26 Ready 2m -``` Now, exec into the database pod and list available tables, ```bash -$ export USER=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo restored-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo restored-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -705,7 +729,6 @@ switched to db newdb > exit bye -``` So, from the above output, we can see the database `newdb` that we had created in the original database `sample-mgo-rs` is restored in the restored database `restored-mongodb`. diff --git a/docs/guides/mongodb/backup/stash/logical/sharding/index.md b/docs/guides/mongodb/backup/stash/logical/sharding/index.md index 55c49aaf3b..66a17233ee 100644 --- a/docs/guides/mongodb/backup/stash/logical/sharding/index.md +++ b/docs/guides/mongodb/backup/stash/logical/sharding/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup Sharded MongoDB Cluster @@ -82,36 +82,38 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/mongodb-sharding.yaml -mongodb.kubedb.com/sample-mgo-sh created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/mongodb-sharding.yaml ``` +mongodb.kubedb.com/sample-mgo-sh created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mgo-sh +kubectl get mg -n demo sample-mgo-sh +``` NAME VERSION STATUS AGE sample-mgo-sh 4.4.26 Ready 35m -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mgo-sh +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mgo-sh +``` NAME TYPE DATA AGE sample-mgo-sh-auth Opaque 2 36m sample-mgo-sh-cert Opaque 4 36m -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mgo-sh +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mgo-sh +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mgo-sh ClusterIP 10.107.11.117 27017/TCP 36m sample-mgo-sh-configsvr-gvr ClusterIP None 27017/TCP 36m sample-mgo-sh-shard0-gvr ClusterIP None 27017/TCP 36m sample-mgo-sh-shard1-gvr ClusterIP None 27017/TCP 36m sample-mgo-sh-shard2-gvr ClusterIP None 27017/TCP 36m -``` KubeDB creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) crd that holds the necessary information to connect with the database. @@ -120,15 +122,15 @@ KubeDB creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) crd Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mgo-sh 30m -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mgo-sh -o yaml +kubectl get appbindings -n demo sample-mgo-sh -o yaml ``` ```yaml @@ -203,21 +205,25 @@ Stash uses the `AppBinding` crd to connect with the target database. It requires Now, we are going to exec into the database pod and create some sample data. At first, find out the database pod using the following command, ```bash -$ kubectl get pods -n demo --selector="mongodb.kubedb.com/node.mongos=sample-mgo-sh-mongos" +kubectl get pods -n demo --selector="mongodb.kubedb.com/node.mongos=sample-mgo-sh-mongos" +``` NAME READY STATUS RESTARTS AGE sample-mgo-sh-mongos-9459cfc44-4jthd 1/1 Running 0 60m sample-mgo-sh-mongos-9459cfc44-6d2st 1/1 Running 0 60m -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mgo-sh-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mgo-sh-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mgo-sh-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mgo-sh-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD +``` mongos> show dbs admin 0.000GB config 0.001GB @@ -248,7 +254,6 @@ mongos> db.movie.find().pretty() mongos> exit bye -``` Now, we are ready to backup this sample database. @@ -261,15 +266,24 @@ We are going to store our backed up data into a GCS bucket. At first, we need to Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -292,9 +306,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/repository-sharding.yaml -repository.stash.appscode.com/gcs-repo-sharding created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/repository-sharding.yaml ``` +repository.stash.appscode.com/gcs-repo-sharding created Now, we are ready to backup our database to our desired backend. @@ -335,19 +349,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/backupconfiguration-sharding.yaml -backupconfiguration.stash.appscode.com/sample-mgo-sh-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/backupconfiguration-sharding.yaml ``` +backupconfiguration.stash.appscode.com/sample-mgo-sh-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mgo-sh-backup mongodb-backup-4.4.6 */5 * * * * Ready 11s -``` **Verify CronJob:** @@ -356,10 +370,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE sample-mgo-sh-backup */5 * * * * False 0 13s -``` **Wait for BackupSession:** @@ -368,11 +382,11 @@ The `sample-mgo-sh-backup` CronJob will trigger a backup on each schedule by cre Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mgo-sh-backup-1563512707 BackupConfiguration sample-mgo-sh-backup Running 5m19s sample-mgo-sh-backup-1563512707 BackupConfiguration sample-mgo-sh-backup Succeeded 5m45s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -381,10 +395,10 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, Stash will update the respective `Repository` crd to reflect the backup. Check that the repository `gcs-repo-sharding` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo-sharding +kubectl get repository -n demo gcs-repo-sharding +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo-sharding true 66.453 KiB 12 1m 20m -``` Now, if we navigate to the GCS bucket, we are going to see backed up data has been stored in `demo/mongodb/sample-mgo-sh` directory as specified by `spec.backend.gcs.prefix` field of Repository crd. @@ -400,23 +414,23 @@ At first, let's stop taking any further backup of the old database so that no ba Let's pause the `sample-mgo-sh-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mgo-sh-backup --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mgo-sh-backup patched +kubectl patch backupconfiguration -n demo sample-mgo-sh-backup --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mgo-sh-backup patched Or you can use the Stash `kubectl` plugin to pause the `BackupConfiguration`, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mgo-sh-backup -BackupConfiguration demo/sample-mgo-sh-backup has been paused successfully. +kubectl stash pause backup -n demo --backupconfig=sample-mgo-sh-backup ``` +BackupConfiguration demo/sample-mgo-sh-backup has been paused successfully. Now, wait for a moment. Stash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo sample-mgo-sh-backup +kubectl get backupconfiguration -n demo sample-mgo-sh-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mgo-sh-backup mongodb-restore-4.4.6 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -424,8 +438,8 @@ Notice the `PAUSED` column. Value `true` for this field means that the BackupCon Now, let’s simulate an accidental deletion scenario. Here, we are going to exec into the database pod and delete the `newdb` database we had created earlier. ```bash -$ kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD +``` mongos> use newdb switched to db newdb @@ -439,7 +453,6 @@ local 0.000GB mongos> exit bye -``` #### Create RestoreSession: @@ -474,20 +487,20 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restoresession-sharding.yaml -restoresession.stash.appscode.com/sample-mgo-sh-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restoresession-sharding.yaml ``` +restoresession.stash.appscode.com/sample-mgo-sh-restore created Once, you have created the `RestoreSession` crd, Stash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo sample-mgo-sh-restore -w +kubectl get restoresession -n demo sample-mgo-sh-restore -w +``` NAME REPOSITORY-NAME PHASE AGE sample-mgo-sh-restore gcs-repo-sharding Running 5s sample-mgo-sh-restore gcs-repo-sharding Succeeded 43s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -498,9 +511,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database pod and list available tables, ```bash - -$ kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mgo-sh-mongos-9459cfc44-4jthd -- mongosh admin -u $USER -p $PASSWORD +``` mongos> show dbs admin 0.000GB config 0.001GB @@ -529,7 +541,6 @@ mongos> db.movie.find().pretty() mongos> exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored. @@ -596,21 +607,23 @@ spec: This time, we have to provide Stash addon info in `spec.task` section of `BackupConfiguration` object as the `AppBinding` we are creating manually does not have those info. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/standalone-backup.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/standalone-backup.yaml +``` appbinding.appcatalog.appscode.com/sample-mgo-sh-custom created repository.stash.appscode.com/gcs-repo-custom created backupconfiguration.stash.appscode.com/sample-mgo-sh-backup2 created - -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME BACKUPCONFIGURATION PHASE AGE sample-mgo-sh-backup-1563528902 sample-mgo-sh-backup Succeeded 35s - -$ kubectl get repository -n demo gcs-repo-custom +```bash +kubectl get repository -n demo gcs-repo-custom +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo-custom true 22.160 KiB 4 1m 2m -``` ### Restore to a standalone database @@ -662,30 +675,40 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restored-standalone.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restored-standalone.yaml +``` mongodb.kubedb.com/restored-mongodb created -$ kubectl get mg -n demo restored-mongodb +```bash +kubectl get mg -n demo restored-mongodb +``` NAME VERSION STATUS AGE restored-mongodb 4.4.26 Provisioning 56s -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restoresession-standalone.yaml +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/sharding/examples/restoresession-standalone.yaml +``` restoresession.stash.appscode.com/sample-mongodb-restore created -$ kubectl get mg -n demo restored-mongodb +```bash +kubectl get mg -n demo restored-mongodb +``` NAME VERSION STATUS AGE restored-mongodb 4.4.26 Ready 56s -``` Now, exec into the database pod and list available tables, ```bash -$ export USER=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo restored-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo restored-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo restored-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -714,7 +737,6 @@ switched to db newdb > exit bye -``` So, from the above output, we can see the database `newdb` that we had created in the original database `sample-mgo-sh` is restored in the restored database `restored-mongodb`. diff --git a/docs/guides/mongodb/backup/stash/logical/standalone/index.md b/docs/guides/mongodb/backup/stash/logical/standalone/index.md index aaf4723328..9980062a65 100644 --- a/docs/guides/mongodb/backup/stash/logical/standalone/index.md +++ b/docs/guides/mongodb/backup/stash/logical/standalone/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MongoDB @@ -72,32 +72,34 @@ spec: Create the above `MongoDB` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/mongodb.yaml -mongodb.kubedb.com/sample-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/mongodb.yaml ``` +mongodb.kubedb.com/sample-mongodb created KubeDB will deploy a MongoDB database according to the above specification. It will also create the necessary secrets and services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mg -n demo sample-mongodb +kubectl get mg -n demo sample-mongodb +``` NAME VERSION STATUS AGE sample-mongodb 4.4.26 Ready 2m9s -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mongodb +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mongodb +``` NAME TYPE DATA AGE sample-mongodb-auth Opaque 2 2m28s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mongodb +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mongodb ClusterIP 10.107.58.222 27017/TCP 2m48s sample-mongodb-gvr ClusterIP None 27017/TCP 2m48s -``` Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` to connect with the database. KubeDB creates an [AppBinding](/docs/guides/mongodb/concepts/appbinding.md) crd that holds the necessary information to connect with the database. @@ -106,15 +108,15 @@ Here, we have to use service `sample-mongodb` and secret `sample-mongodb-auth` t Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mongodb 20m -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mongodb -o yaml +kubectl get appbindings -n demo sample-mongodb -o yaml ``` ```yaml @@ -182,20 +184,24 @@ Stash uses the `AppBinding` crd to connect with the target database. It requires Now, we are going to exec into the database pod and create some sample data. At first, find out the database pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mongodb" +``` NAME READY STATUS RESTARTS AGE sample-mongodb-0 1/1 Running 0 12m -``` Now, let's exec into the pod and create a table, ```bash -$ export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) - -$ export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +export USER=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.username}' | base64 -d) +``` -$ kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +```bash +export PASSWORD=$(kubectl get secrets -n demo sample-mongodb-auth -o jsonpath='{.data.password}' | base64 -d) +``` +```bash +kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB local 0.000GB @@ -225,7 +231,6 @@ WriteResult({ "nInserted" : 1 }) > exit bye -``` Now, we are ready to backup this sample database. @@ -238,15 +243,24 @@ We are going to store our backed up data into a GCS bucket. At first, we need to Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -269,9 +283,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database to our desired backend. @@ -312,19 +326,19 @@ Here, Let's create the `BackupConfiguration` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-mongodb-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-mongodb-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mongodb-backup mongodb-backup-4.4.6 */5 * * * * Ready 11s -``` **Verify CronJob:** @@ -333,10 +347,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE sample-mongodb-backup */5 * * * * False 0 61s -``` **Wait for BackupSession:** @@ -345,11 +359,11 @@ The `sample-mongodb-backup` CronJob will trigger a backup on each schedule by cr Wait for the next schedule. Run the following command to watch `BackupSession` crd, ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mongodb-backup-1561974001 BackupConfiguration sample-mongodb-backup Running 5m19s sample-mongodb-backup-1561974001 BackupConfiguration sample-mongodb-backup Succeeded 5m45s -``` We can see above that the backup session has succeeded. Now, we are going to verify that the backed up data has been stored in the backend. @@ -358,10 +372,10 @@ We can see above that the backup session has succeeded. Now, we are going to ver Once a backup is complete, Stash will update the respective `Repository` crd to reflect the backup. Check that the repository `gcs-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo +kubectl get repository -n demo gcs-repo +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo true 1.611 KiB 1 33s 33m -``` Now, if we navigate to the GCS bucket, we are going to see backed up data has been stored in `demo/mongodb/sample-mongodb` directory as specified by `spec.backend.gcs.prefix` field of Repository crd. @@ -376,23 +390,23 @@ At first, let's stop taking any further backup of the old database so that no ba Let's pause the `sample-mongodb-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mongodb-backup --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mongodb-backup patched +kubectl patch backupconfiguration -n demo sample-mongodb-backup --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mongodb-backup patched Or you can use the Stash `kubectl` plugin to pause the `BackupConfiguration`, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mongodb-backup -BackupConfiguration demo/sample-mongodb-backup has been paused successfully. +kubectl stash pause backup -n demo --backupconfig=sample-mongodb-backup ``` +BackupConfiguration demo/sample-mongodb-backup has been paused successfully. Now, wait for a moment. Stash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, ```bash -$ kubectl get backupconfiguration -n demo sample-mongodb-backup +kubectl get backupconfiguration -n demo sample-mongodb-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mongodb-backup mongodb-backup-4.4.6 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -400,7 +414,8 @@ Notice the `PAUSED` column. Value `true` for this field means that the BackupCon Now, let’s simulate an accidental deletion scenario. Here, we are going to exec into the database pod and delete the `newdb` database we had created earlier. ```bash -$ kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > use newdb switched to db newdb @@ -414,7 +429,6 @@ local 0.000GB > exit bye -``` #### Create RestoreSession: Now, we need to create a `RestoreSession` crd pointing to the AppBinding of `sample-mongodb` database. @@ -447,20 +461,20 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-mongodb-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mongodb/backup/logical/standalone/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-mongodb-restore created Once, you have created the `RestoreSession` crd, Stash will create a job to restore. We can watch the `RestoreSession` phase to check if the restore process is succeeded or not. Run the following command to watch `RestoreSession` phase, ```bash -$ kubectl get restoresession -n demo sample-mongodb-restore -w +kubectl get restoresession -n demo sample-mongodb-restore -w +``` NAME REPOSITORY-NAME PHASE AGE sample-mongodb-restore gcs-repo Running 5s sample-mongodb-restore gcs-repo Succeeded 43s -``` So, we can see from the output of the above command that the restore process succeeded. @@ -471,8 +485,8 @@ In this section, we are going to verify that the desired data has been restored Lets, exec into the database pod and list available tables, ```bash -$ kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD - +kubectl exec -it -n demo sample-mongodb-0 -- mongosh admin -u $USER -p $PASSWORD +``` > show dbs admin 0.000GB config 0.000GB @@ -500,7 +514,6 @@ switched to db newdb > exit bye -``` So, from the above output, we can see the database `newdb` that we had created earlier is restored. diff --git a/docs/guides/mongodb/cli/cli.md b/docs/guides/mongodb/cli/cli.md index 93c6cc94fc..b58e95e02e 100644 --- a/docs/guides/mongodb/cli/cli.md +++ b/docs/guides/mongodb/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a MongoDB object as specified in `mongodb.yaml`. ```bash -$ kubectl create -f mongodb-demo.yaml -mongodb.kubedb.com/mongodb-demo created +kubectl create -f mongodb-demo.yaml ``` +mongodb.kubedb.com/mongodb-demo created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f mongodb-demo.yaml --namespace=kube-system -mongodb.kubedb.com/mongodb-demo +kubectl create -f mongodb-demo.yaml --namespace=kube-system ``` +mongodb.kubedb.com/mongodb-demo `kubectl create` command also considers `stdin` as input. @@ -45,13 +45,13 @@ cat mongodb-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all MongoDB objects in `default` namespace, run the following command: ```bash -$ kubectl get mongodb +kubectl get mongodb +``` NAME VERSION STATUS AGE mongodb-demo 3.4-v3 Ready 13m mongodb-dev 3.4-v3 Ready 11m mongodb-prod 3.4-v3 Ready 11m mongodb-qa 3.4-v3 Ready 10m -``` To get YAML of an object, use `--output=yaml` flag. @@ -123,7 +123,8 @@ kubectl get mongodb mongodb-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get kubedb -o wide +kubectl get kubedb -o wide +``` NAME VERSION STATUS AGE mg/mongodb-demo 3.4 Ready 3h mg/mongodb-dev 3.4 Ready 3h @@ -133,7 +134,6 @@ mg/mongodb-qa 3.4 Ready 3h NAME DATABASE BUCKET STATUS AGE snap/mongodb-demo-20170605-073557 mg/mongodb-demo gs:bucket-name Succeeded 9m snap/snapshot-20171212-114700 mg/mongodb-demo gs:bucket-name Succeeded 1h -``` Flag `--output=wide` is used to print additional information. @@ -146,39 +146,40 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Snapshots with their corresponding labels. ```bash -$ kubectl get snap --show-labels +kubectl get snap --show-labels +``` NAME DATABASE STATUS AGE LABELS mongodb-demo-20170605-073557 mg/mongodb-demo Succeeded 11m app.kubernetes.io/name=mongodbs.kubedb.com,app.kubernetes.io/instance=mongodb-demo snapshot-20171212-114700 mg/mongodb-demo Succeeded 1h app.kubernetes.io/name=mongodbs.kubedb.com,app.kubernetes.io/instance=mongodb-demo -``` You can also filter list using `--selector` flag. ```bash -$ kubectl get snap --selector='app.kubernetes.io/name=mongodbs.kubedb.com' --show-labels +kubectl get snap --selector='app.kubernetes.io/name=mongodbs.kubedb.com' --show-labels +``` NAME DATABASE STATUS AGE LABELS mongodb-demo-20171212-073557 mg/mongodb-demo Succeeded 14m app.kubernetes.io/name=mongodbs.kubedb.com,app.kubernetes.io/instance=mongodb-demo snapshot-20171212-114700 mg/mongodb-demo Succeeded 2h app.kubernetes.io/name=mongodbs.kubedb.com,app.kubernetes.io/instance=mongodb-demo -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` mongodb/mongodb-demo mongodb/mongodb-dev mongodb/mongodb-prod mongodb/mongodb-qa snapshot/mongodb-demo-20170605-073557 snapshot/snapshot-20170505-114700 -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe MongoDB database `mongodb-demo` with relevant information. ```bash -$ kubectl dba describe mg mongodb-demo +kubectl dba describe mg mongodb-demo +``` Name: mongodb-demo Namespace: default CreationTimestamp: Wed, 06 Feb 2019 16:31:04 +0600 @@ -247,7 +248,6 @@ Events: Normal Successful 2m KubeDB operator Successfully created appbinding Normal Successful 2m KubeDB operator Successfully patched PetSet Normal Successful 2m KubeDB operator Successfully patched MongoDB -``` `kubectl dba describe` command provides following basic information about a MongoDB database. @@ -311,16 +311,16 @@ For DormantDatabase, `spec.origin` can't be edited using `kubectl edit` `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a MongoDB `mongodb-dev` in default namespace ```bash -$ kubectl delete mongodb mongodb-dev -mongodb.kubedb.com "mongodb-dev" deleted +kubectl delete mongodb mongodb-dev ``` +mongodb.kubedb.com "mongodb-dev" deleted You can also use YAML files to delete objects. The following command will delete a mongodb using the type and name specified in `mongodb.yaml`. ```bash -$ kubectl delete -f mongodb-demo.yaml -mongodb.kubedb.com "mongodb-dev" deleted +kubectl delete -f mongodb-demo.yaml ``` +mongodb.kubedb.com "mongodb-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -338,16 +338,23 @@ kubectl delete mongodb -l mongodb.app.kubernetes.io/instance=mongodb-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # Create objects -$ kubectl create -f +```bash +kubectl create -f +``` # List objects -$ kubectl get mongodb -$ kubectl get mongodb.kubedb.com +```bash +kubectl get mongodb +``` + +```bash +kubectl get mongodb.kubedb.com +``` # Delete objects -$ kubectl delete mongodb +```bash +kubectl delete mongodb ``` ## Next Steps diff --git a/docs/guides/mongodb/clustering/replicaset.md b/docs/guides/mongodb/clustering/replicaset.md index 6172900a06..dac2fed22b 100644 --- a/docs/guides/mongodb/clustering/replicaset.md +++ b/docs/guides/mongodb/clustering/replicaset.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,9 +62,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/replicaset.yaml -mongodb.kubedb.com/mgo-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/replicaset.yaml ``` +mongodb.kubedb.com/mgo-replicaset created Here, @@ -77,7 +77,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MongoDB object name. This service will always point to the primary of the replicaset. KubeDB operator will also create a governing service for PetSets with the name `-pods`. ```bash -$ kubectl dba describe mg -n demo mgo-replicaset +kubectl dba describe mg -n demo mgo-replicaset +``` Name: mgo-replicaset Namespace: demo CreationTimestamp: Wed, 10 Feb 2021 11:05:06 +0600 @@ -195,28 +196,34 @@ Events: Normal Successful 10m MongoDB operator Successfully patched PetSet demo/mgo-replicaset Normal Successful 10m MongoDB operator Successfully patched MongoDB - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mgo-replicaset 3/3 105s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mgo-replicaset-0 Bound pvc-597784c9-c093-11e8-b4a9-0800272618ed 1Gi RWO standard 1h datadir-mgo-replicaset-1 Bound pvc-8ca7a9d9-c093-11e8-b4a9-0800272618ed 1Gi RWO standard 1h datadir-mgo-replicaset-2 Bound pvc-b7d8a624-c093-11e8-b4a9-0800272618ed 1Gi RWO standard 1h -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-597784c9-c093-11e8-b4a9-0800272618ed 1Gi RWO Delete Bound demo/datadir-mgo-replicaset-0 standard 1h pvc-8ca7a9d9-c093-11e8-b4a9-0800272618ed 1Gi RWO Delete Bound demo/datadir-mgo-replicaset-1 standard 1h pvc-b7d8a624-c093-11e8-b4a9-0800272618ed 1Gi RWO Delete Bound demo/datadir-mgo-replicaset-2 standard 1h -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mgo-replicaset ClusterIP 10.97.174.220 27017/TCP 119s mgo-replicaset-pods ClusterIP None 27017/TCP 119s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: @@ -361,14 +368,18 @@ Now, you can connect to this database through [mgo-replicaset](https://docs.mong At first, insert data inside primary member `rs0:PRIMARY`. ```bash -$ kubectl get secrets -n demo mgo-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mgo-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mgo-replicaset-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mgo-replicaset-auth -o jsonpath='{.data.password}' | base64 -d +``` 5O4R2ze2bWXcWsdP -$ kubectl exec -it mgo-replicaset-0 -n demo bash - +```bash +kubectl exec -it mgo-replicaset-0 -n demo bash +``` mongodb@mgo-replicaset-0:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -413,13 +424,13 @@ rs0:PRIMARY> db.movie.find().pretty() rs0:PRIMARY> exit bye -``` Now, check the redundancy and data availability in secondary members. We will exec in `mgo-replicaset-1`(which is secondary member right now) to check the data availability. ```bash -$ kubectl exec -it mgo-replicaset-1 -n demo bash +kubectl exec -it mgo-replicaset-1 -n demo bash +``` mongodb@mgo-replicaset-1:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -460,34 +471,36 @@ rs0:SECONDARY> db.movie.find().pretty() rs0:SECONDARY> exit bye -``` - ## Automatic Failover To test automatic failover, we will force the primary member to restart. As the primary member (`pod`) becomes unavailable, the rest of the members will elect a primary member by election. ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mgo-replicaset-0 1/1 Running 0 1h mgo-replicaset-1 1/1 Running 0 1h mgo-replicaset-2 1/1 Running 0 1h -$ kubectl delete pod -n demo mgo-replicaset-0 +```bash +kubectl delete pod -n demo mgo-replicaset-0 +``` pod "mgo-replicaset-0" deleted -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mgo-replicaset-0 1/1 Terminating 0 1h mgo-replicaset-1 1/1 Running 0 1h mgo-replicaset-2 1/1 Running 0 1h -``` - Now verify the automatic failover, Let's exec in `mgo-replicaset-1` pod, ```bash -$ kubectl exec -it mgo-replicaset-1 -n demo bash +kubectl exec -it mgo-replicaset-1 -n demo bash +``` mongodb@mgo-replicaset-1:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -528,7 +541,6 @@ switched to db newdb rs0:SECONDARY> db.movie.find().pretty() { "_id" : ObjectId("5b5efeea9d097ca0600694a3"), "name" : "batman" } -``` ## Halt Database @@ -539,23 +551,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mgo-replicaset patched +kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mgo-replicaset patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mgo-replicaset patched +kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mgo-replicaset patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mgo-replicaset 4.4.26 Halted 9m43s @@ -568,7 +581,6 @@ NAME STATUS VOLUME persistentvolumeclaim/datadir-mgo-replicaset-0 Bound pvc-816daa52-ee40-496f-a148-c75344a1b433 1Gi RWO standard 9m43s persistentvolumeclaim/datadir-mgo-replicaset-1 Bound pvc-e818bc86-ab3c-4ec5-901f-630aab6b814b 1Gi RWO standard 9m5s persistentvolumeclaim/datadir-mgo-replicaset-2 Bound pvc-5a50bce3-f85f-4157-be22-64dfc26e7517 1Gi RWO standard 8m25s -``` ## Resume Halted Database @@ -576,23 +588,23 @@ persistentvolumeclaim/datadir-mgo-replicaset-2 Bound pvc-5a50bce3-f85f-4157 Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mgo-replicaset patched +kubectl patch -n demo mg/mgo-replicaset -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mgo-replicaset patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mgo-replicaset 4.4.26 Ready 6m27s -``` Now, If you again exec into the primary `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it mgo-replicaset-1 -n demo bash - +kubectl exec -it mgo-replicaset-1 -n demo bash +``` mongodb@mgo-replicaset-1:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP rs0:PRIMARY> use newdb @@ -600,7 +612,6 @@ switched to db newdb rs0:PRIMARY> db.movie.find() { "_id" : ObjectId("6024b3e47c614cd582c9bb44"), "name" : "batman" } -``` ## Cleaning up diff --git a/docs/guides/mongodb/clustering/sharding.md b/docs/guides/mongodb/clustering/sharding.md index fff71a4d89..914fe9d2ed 100644 --- a/docs/guides/mongodb/clustering/sharding.md +++ b/docs/guides/mongodb/clustering/sharding.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,9 +70,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/mongo-sharding.yaml -mongodb.kubedb.com/mongo-sh created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/mongo-sharding.yaml ``` +mongodb.kubedb.com/mongo-sh created Here, @@ -102,26 +102,27 @@ KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `Mong MongoDB `mongo-sh` state, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mongo-sh 4.4.26 Ready 9m41s -``` All the types of nodes `Shard`, `ConfigServer` & `Mongos` are deployed as petset. ```bash -$ kubectl get petset -n demo +kubectl get petset -n demo +``` NAME READY AGE mongo-sh-configsvr 3/3 11m mongo-sh-mongos 3/3 8m41s mongo-sh-shard0 3/3 10m mongo-sh-shard1 3/3 8m59s -``` All PVCs and PVs for MongoDB `mongo-sh`, ```bash -$ kubectl get pvc -n demo +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mongo-sh-configsvr-0 Bound pvc-1db4185e-6a5f-11e9-a871-080027a851ba 1Gi RWO standard 16m datadir-mongo-sh-configsvr-1 Bound pvc-330cc6ee-6a5f-11e9-a871-080027a851ba 1Gi RWO standard 16m @@ -133,8 +134,9 @@ datadir-mongo-sh-shard1-0 Bound pvc-75feb227-6a5f-11e9-a871-080027a851ba datadir-mongo-sh-shard1-1 Bound pvc-89bb7bb3-6a5f-11e9-a871-080027a851ba 1Gi RWO standard 13m datadir-mongo-sh-shard1-2 Bound pvc-98c96ae4-6a5f-11e9-a871-080027a851ba 1Gi RWO standard 13m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-1db4185e-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete Bound demo/datadir-mongo-sh-configsvr-0 standard 17m pvc-330cc6ee-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete Bound demo/datadir-mongo-sh-configsvr-1 standard 16m @@ -145,19 +147,18 @@ pvc-6ba3263e-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete pvc-75feb227-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete Bound demo/datadir-mongo-sh-shard1-0 standard 14m pvc-89bb7bb3-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete Bound demo/datadir-mongo-sh-shard1-1 standard 14m pvc-98c96ae4-6a5f-11e9-a871-080027a851ba 1Gi RWO Delete Bound demo/datadir-mongo-sh-shard1-2 standard 13m -``` Services created for MongoDB `mongo-sh` ```bash -$ kubectl get svc -n demo +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mongo-sh ClusterIP 10.108.188.201 27017/TCP 18m mongo-sh-configsvr-pods ClusterIP None 27017/TCP 18m mongo-sh-mongos-pods ClusterIP None 27017/TCP 18m mongo-sh-shard0-pods ClusterIP None 27017/TCP 18m mongo-sh-shard1-pods ClusterIP None 27017/TCP 18m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. It has also defaulted some field of crd object. Run the following command to see the modified MongoDB object: @@ -351,16 +352,16 @@ If you want to use custom or existing secret please specify that when creating t - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo mongo-sh-auth -o jsonpath='{.data.username}' | base64 -d - root + kubectl get secrets -n demo mongo-sh-auth -o jsonpath='{.data.username}' | base64 -d ``` + root - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo mongo-sh-auth -o jsonpath='{.data.password}' | base64 -d - 7QiqLcuSCmZ8PU5a + kubectl get secrets -n demo mongo-sh-auth -o jsonpath='{.data.password}' | base64 -d ``` + 7QiqLcuSCmZ8PU5a Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/). @@ -369,13 +370,15 @@ Now, you can connect to this database through [mongo-shell](https://docs.mongodb In this tutorial, we will insert sharded and unsharded document, and we will see if the data actually sharded across cluster or not. ```bash -$ kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-mongos +kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-mongos +``` NAME READY STATUS RESTARTS AGE mongo-sh-mongos-0 1/1 Running 0 49m mongo-sh-mongos-1 1/1 Running 0 49m -$ kubectl exec -it mongo-sh-mongos-0 -n demo bash - +```bash +kubectl exec -it mongo-sh-mongos-0 -n demo bash +``` mongodb@mongo-sh-mongos-0:/$ mongosh admin -u root -p 7QiqLcuSCmZ8PU5a MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin?gssapiServiceName=mongodb @@ -388,7 +391,6 @@ For more comprehensive documentation, see Questions? Try the support group http://groups.google.com/group/mongodb-user mongos> -``` To detect if the MongoDB instance that your client is connected to is mongos, use the isMaster command. When a client connects to a mongos, isMaster returns a document with a `msg` field that holds the string `isdbgrid`. @@ -616,23 +618,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mongo-sh -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mongo-sh patched +kubectl patch -n demo mg/mongo-sh -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-sh -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mongo-sh patched +kubectl patch -n demo mg/mongo-sh -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-sh 4.4.26 Halted 74m @@ -651,7 +654,6 @@ persistentvolumeclaim/datadir-mongo-sh-shard0-2 Bound pvc-82f83359-6e31- persistentvolumeclaim/datadir-mongo-sh-shard1-0 Bound pvc-07ef7cd3-99b2-47de-b1bb-ef6c5606d92e 1Gi RWO standard 74m persistentvolumeclaim/datadir-mongo-sh-shard1-1 Bound pvc-ffa4b9a7-2492-4f18-be90-7950004e9efd 1Gi RWO standard 74m persistentvolumeclaim/datadir-mongo-sh-shard1-2 Bound pvc-4e75b90e-dac5-4431-a50e-2bc8dfcf481b 1Gi RWO standard 73m -``` From the above output, you can see that MongoDB object, PVCs, Secret are still there. @@ -660,29 +662,30 @@ From the above output, you can see that MongoDB object, PVCs, Secret are still t Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mongo-sh -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mongo-sh patched +kubectl patch -n demo mg/mongo-sh -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mongo-sh patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mongo-sh 4.4.26 Ready 6m27s -``` Now, If you again exec into `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-mongos +kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-mongos +``` NAME READY STATUS RESTARTS AGE mongo-sh-mongos-0 1/1 Running 0 3m52s mongo-sh-mongos-1 1/1 Running 0 3m52s - -$ kubectl exec -it mongo-sh-mongos-0 -n demo bash - +```bash +kubectl exec -it mongo-sh-mongos-0 -n demo bash +``` mongodb@mongo-sh-mongos-0:/$ mongosh admin -u root -p 7QiqLcuSCmZ8PU5a mongos> use test; @@ -733,7 +736,6 @@ mongos> sh.status() chunks: shard1 1 { "myfield" : { "$minKey" : 1 } } -->> { "myfield" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0) -``` ## Cleaning up diff --git a/docs/guides/mongodb/clustering/standalone.md b/docs/guides/mongodb/clustering/standalone.md index 9fc0f380fb..c34eeb15a8 100644 --- a/docs/guides/mongodb/clustering/standalone.md +++ b/docs/guides/mongodb/clustering/standalone.md @@ -27,9 +27,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,9 +64,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/standalone.yaml -mongodb.kubedb.com/mg-alone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/clustering/standalone.yaml ``` +mongodb.kubedb.com/mg-alone created Here, @@ -77,7 +77,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MongoDB object name. KubeDB operator will also create a governing service for PetSets with the name `-pods`. ```bash -$ kubectl dba describe mg -n demo mg-alone +kubectl dba describe mg -n demo mg-alone +``` Name: mg-alone Namespace: demo CreationTimestamp: Fri, 04 Nov 2022 10:30:07 +0600 @@ -192,9 +193,9 @@ Events: Normal Successful 4s MongoDB operator Successfully patched PetSet demo/mg-alone Normal Successful 4s MongoDB operator Successfully patched MongoDB - - -$ kubectl get petset,svc,pvc,pv -n demo +```bash +kubectl get petset,svc,pvc,pv -n demo +``` NAME READY AGE petset.apps/mg-alone 1/1 65s @@ -208,8 +209,6 @@ persistentvolumeclaim/datadir-mg-alone-0 Bound pvc-78328965-1210-4f7a-a508- NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pvc-78328965-1210-4f7a-a508-2749b328a5ac 500Mi RWO Delete Bound demo/datadir-mg-alone-0 standard 62s -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: ```yaml @@ -335,14 +334,18 @@ Now, you can connect to this database through [mg-alone](https://docs.mongodb.co At first, insert data inside primary member `rs0:PRIMARY`. ```bash -$ kubectl get secrets -n demo mg-alone-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-alone-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-alone-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mg-alone-auth -o jsonpath='{.data.password}' | base64 -d +``` 5O4R2ze2bWXcWsdP -$ kubectl exec -it mg-alone-0 -n demo bash - +```bash +kubectl exec -it mg-alone-0 -n demo bash +``` mongodb@mg-alone-0:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin @@ -402,7 +405,6 @@ WriteResult({ "nInserted" : 1 }) > exit bye -``` ## Data availability As this is a standalone database which doesn't have multiple replicas, It offers no redundancy & high availability of data. All the data are stored in one place, & deleting that will occur in data lost. @@ -416,23 +418,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mg-alone -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mg-alone patched +kubectl patch -n demo mg/mg-alone -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mg-alone patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mg-alone -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mg-alone patched +kubectl patch -n demo mg/mg-alone -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mg-alone patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-alone 4.4.26 Halted 2m4s @@ -443,31 +446,29 @@ secret/mongo-ca kubernetes.io/tls 2 15d NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/datadir-mg-alone-0 Bound pvc-a1a873a6-4f6d-42eb-a38f-83d36fc44e1a 500Mi RWO standard 2m4s -``` - ## Resume Halted Database Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mg-alone -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mg-alone patched +kubectl patch -n demo mg/mg-alone -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mg-alone patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-alone 4.4.26 Ready 6m27s -``` Now, If you again exec into the primary `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it mg-alone-1 -n demo bash - +kubectl exec -it mg-alone-1 -n demo bash +``` mongodb@mg-alone-1:/$ mongosh admin -u root -p 5O4R2ze2bWXcWsdP > use newdb @@ -477,8 +478,6 @@ movie > db.movie.find() { "_id" : ObjectId("6364af93b1ae8e7a8467058a"), "name" : "batman" } -``` - ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/mongodb/concepts/mongodb.md b/docs/guides/mongodb/concepts/mongodb.md index 8680f7c53d..115e850dab 100644 --- a/docs/guides/mongodb/concepts/mongodb.md +++ b/docs/guides/mongodb/concepts/mongodb.md @@ -236,11 +236,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic mgo1-auth -n demo \ +kubectl create secret generic mgo1-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "mgo1-auth" created ``` +secret "mgo1-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/mongodb/configuration/using-config-file.md b/docs/guides/mongodb/configuration/using-config-file.md index 89dbea0f52..f212b9dc4f 100644 --- a/docs/guides/mongodb/configuration/using-config-file.md +++ b/docs/guides/mongodb/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for MongoDB. This tutorial will s - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,9 +60,9 @@ Here, `maxIncomingConnections` is set to `10000`, whereas the default value is 6 Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo mg-configuration --from-file=./mongod.conf -secret/mg-configuration created +kubectl create secret generic -n demo mg-configuration --from-file=./mongod.conf ``` +secret/mg-configuration created Verify the secret has the configuration file. @@ -108,33 +108,37 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/configuration/demo-1.yaml -mongodb.kubedb.com/mgo-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/configuration/demo-1.yaml ``` +mongodb.kubedb.com/mgo-custom-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `mgo-custom-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo mgo-custom-config-0 +kubectl get pod -n demo mgo-custom-config-0 +``` NAME READY STATUS RESTARTS AGE mgo-custom-config-0 1/1 Running 0 1m -``` Now, we will check if the database has started with the custom configuration we have provided. Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/). In this tutorial, we are connecting to the MongoDB server from inside the pod. ```bash -$ kubectl get secrets -n demo mgo-custom-config-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mgo-custom-config-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mgo-custom-config-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mgo-custom-config-auth -o jsonpath='{.data.password}' | base64 -d +``` ErialNojWParBFoP -$ kubectl exec -it mgo-custom-config-0 -n demo sh - +```bash +kubectl exec -it mgo-custom-config-0 -n demo sh +``` > mongosh admin > db.auth("root","ErialNojWParBFoP") @@ -175,7 +179,6 @@ $ kubectl exec -it mgo-custom-config-0 -n demo sh > exit bye -``` As we can see from the configuration of running mongodb, the value of `maxIncomingConnections` has been set to 10000 successfully. diff --git a/docs/guides/mongodb/configuration/using-podtemplate.md b/docs/guides/mongodb/configuration/using-podtemplate.md index 6558afc87f..d975f203aa 100644 --- a/docs/guides/mongodb/configuration/using-podtemplate.md +++ b/docs/guides/mongodb/configuration/using-podtemplate.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for MongoDB via [PodTemplate](/do - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -95,33 +95,37 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/configuration/mgo-misc-config.yaml -mongodb.kubedb.com/mgo-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/configuration/mgo-misc-config.yaml ``` +mongodb.kubedb.com/mgo-misc-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `mgo-misc-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mgo-misc-config-0 1/1 Running 0 14m -``` Now, check if the database has started with the custom configuration we have provided. Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v3.4/mongo/). In this tutorial, we are connecting to the MongoDB server from inside the pod. ```bash -$ kubectl get secrets -n demo mgo-misc-config-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mgo-misc-config-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mgo-misc-config-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mgo-misc-config-auth -o jsonpath='{.data.password}' | base64 -d +``` zyp5hDfRlVOWOyk9 -$ kubectl exec -it mgo-misc-config-0 -n demo sh - +```bash +kubectl exec -it mgo-misc-config-0 -n demo sh +``` > mongosh admin > db.auth("root","zyp5hDfRlVOWOyk9") @@ -162,7 +166,6 @@ $ kubectl exec -it mgo-misc-config-0 -n demo sh > exit bye -``` You can see the maximum connection is set to `100` in `parsed.net.maxIncomingConnections`. diff --git a/docs/guides/mongodb/custom-rbac/using-custom-rbac.md b/docs/guides/mongodb/custom-rbac/using-custom-rbac.md index 37b701f622..fa2d430d56 100644 --- a/docs/guides/mongodb/custom-rbac/using-custom-rbac.md +++ b/docs/guides/mongodb/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the MongoDB instance named `quick-mongodb`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -98,10 +98,9 @@ This permission is required for MongoDB pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -129,9 +128,9 @@ subjects: Now, create a MongoDB crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-db.yaml -mongodb.kubedb.com/quick-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-db.yaml ``` +mongodb.kubedb.com/quick-mongodb created Below is the YAML for the MongoDB crd we just created. @@ -162,15 +161,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, deployme Check that the petset's pod is running ```bash -$ kubectl get pod -n demo quick-mongodb-0 +kubectl get pod -n demo quick-mongodb-0 +``` NAME READY STATUS RESTARTS AGE quick-mongodb-0 1/1 Running 0 28s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo quick-mongodb-0 +kubectl logs -f -n demo quick-mongodb-0 +``` about to fork child process, waiting until server is ready for connections. forked process: 17 2019-06-10T08:56:45.259+0000 I CONTROL [main] ***** SERVER RESTARTED ***** @@ -182,7 +182,6 @@ MongoDB init process complete; ready for start up. .. 2019-06-10T08:56:49.287+0000 I NETWORK [thread1] waiting for connections on port 27017 2019-06-10T08:56:57.179+0000 I NETWORK [thread1] connection accepted from 127.0.0.1:39214 #1 (1 connection now open) -``` Once we see `connection accepted` in the log, the database is ready. @@ -193,9 +192,9 @@ An existing service account can be reused in another MongoDB instance. No new ac Now, create MongoDB crd `minute-mongodb` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-db-two.yaml -mongodb.kubedb.com/quick-mongodb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/custom-rbac/mg-custom-db-two.yaml ``` +mongodb.kubedb.com/quick-mongodb created Below is the YAML for the MongoDB crd we just created. @@ -226,15 +225,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo minute-mongodb-0 +kubectl get pod -n demo minute-mongodb-0 +``` NAME READY STATUS RESTARTS AGE minute-mongodb-0 1/1 Running 0 50s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo minute-mongodb-0 +kubectl logs -f -n demo minute-mongodb-0 +``` about to fork child process, waiting until server is ready for connections. forked process: 17 2019-06-10T08:56:45.259+0000 I CONTROL [main] ***** SERVER RESTARTED ***** @@ -246,7 +246,6 @@ MongoDB init process complete; ready for start up. .. 2019-06-10T08:56:49.287+0000 I NETWORK [thread1] waiting for connections on port 27017 2019-06-10T08:56:57.179+0000 I NETWORK [thread1] connection accepted from 127.0.0.1:39214 #1 (1 connection now open) -``` `connection accepted` in the log signifies that the database is running successfully. diff --git a/docs/guides/mongodb/external-connection/horizon.md b/docs/guides/mongodb/external-connection/horizon.md index 8b7deff41b..c455e5c6b2 100644 --- a/docs/guides/mongodb/external-connection/horizon.md +++ b/docs/guides/mongodb/external-connection/horizon.md @@ -27,9 +27,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Prerequisites @@ -104,9 +104,9 @@ spec: > If you want to use `NodePort` service. Update `.spec.provider.kubernetes.envoyService.type` to `NodePort` in the above YAML. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/envoyproxy.yaml -envoyproxy.gateway.envoyproxy.io/ace created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/envoyproxy.yaml ``` +envoyproxy.gateway.envoyproxy.io/ace created > Before creating `GatewayClass`, create a certificate secret named `ace-gw-cert` in ace namespace. @@ -142,16 +142,16 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/gatewayclass.yaml -gatewayclass.gateway.networking.k8s.io/ace created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/gatewayclass.yaml ``` +gatewayclass.gateway.networking.k8s.io/ace created Check the `GatewayClass` status `True`. ```bash -$ kubectl get gatewayclass +kubectl get gatewayclass +``` NAME CONTROLLER ACCEPTED AGE ace gateway.envoyproxy.io/gatewayclass-controller True 16s -``` ### Install `FluxCD` in your cluster Install `FluxCD` in your cluster using the following command: @@ -167,16 +167,20 @@ helm upgrade -i flux2 \ Install `Keda` in your cluster using the following command: ```bash -$ kubectl create ns kubeops +kubectl create ns kubeops +``` namespace/kubeops created -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/helmrepo.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/helmrepo.yaml +``` helmrepository.source.toolkit.fluxcd.io/appscode-charts-oci created -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/keda.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/keda.yaml +``` helmrelease.helm.toolkit.fluxcd.io/keda created helmrelease.helm.toolkit.fluxcd.io/keda-add-ons-http created -``` ### Install `Catalog Manager` @@ -238,9 +242,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml -issuer.cert-manager.io/mongo-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml ``` +issuer.cert-manager.io/mongo-ca-issuer created ## MongoDB Replicaset with Horizons @@ -308,18 +312,18 @@ Here, ### Deploy MongoDB Replicaset Horizons ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/mongodb.yaml -mongodb.kubedb.com/mongodb-horizons created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/mongodb.yaml ``` +mongodb.kubedb.com/mongodb-horizons created Now, wait until `mongodb-horizons` has status `Ready`. i.e, ```bash -$ watch kubectl get mg -n demo +watch kubectl get mg -n demo +``` Every 2.0s: kubectl get mg -n demo NAME VERSION STATUS AGE mongodb-horizons 7.0.16 Ready 4m10s -``` Now, create `MongoDBBinding` object to configure the whole process. ```yaml @@ -335,20 +339,20 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/binding.yaml -mongodbbinding.catalog.appscode.com/mongodb-bind created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/horizons/binding.yaml ``` +mongodbbinding.catalog.appscode.com/mongodb-bind created Now, check the status of `mongodbbinding` objects and ops requests. ```bash -$ kubectl get mongodbbinding,mongodbopsrequest -n demo +kubectl get mongodbbinding,mongodbopsrequest -n demo +``` NAME SRC_NS SRC_NAME STATUS AGE mongodbbinding.catalog.appscode.com/mongodb-bind demo mongodb-horizons Current 3m28s NAME TYPE STATUS AGE mongodbopsrequest.ops.kubedb.com/mongodb-horizons-jddiql Horizons Successful 2m58s -``` ### Connect to MongoDB as Replicaset @@ -356,16 +360,18 @@ To connect to the MongoDB replica set, you can use the following command: Collect the replicas from the `mongodb-horizons` object: ```bash -$ kubectl get mongodb -n demo mongodb-horizons -ojson | jq .spec.replicaSet.horizons.pods +kubectl get mongodb -n demo mongodb-horizons -ojson | jq .spec.replicaSet.horizons.pods +``` [ "mongo-0.kubedb.cloud:10000", "mongo-1.kubedb.cloud:10001", "mongo-2.kubedb.cloud:10002" ] -$ mongosh "mongodb://root:@mongo-0.kubedb.cloud:10000,mongo-1.kubedb.cloud:10001,mongo-2.kubedb.cloud:10002/admin?authSource=admin&tls=true&tlsCAFile=" -rs0 [primary] admin> +```bash +mongosh "mongodb://root:@mongo-0.kubedb.cloud:10000,mongo-1.kubedb.cloud:10001,mongo-2.kubedb.cloud:10002/admin?authSource=admin&tls=true&tlsCAFile=" ``` +rs0 [primary] admin> ## Connect Using MongoDB `SRV` To connect to the MongoDB replica set using `mongodb+srv`, you need to create `srv` records with the `A/CNAME` records you created earlier like, @@ -384,9 +390,9 @@ You can keep it empty. Now, you can connect to the MongoDB replica set using the following command: ```bash -$ mongosh "mongodb+srv://root:@kubedb.cloud/admin?tls=true&tlsCAFile=" -rs0 [primary] admin> +mongosh "mongodb+srv://root:@kubedb.cloud/admin?tls=true&tlsCAFile=" ``` +rs0 [primary] admin> > You can use `ca.crt` from default path. ```bash @@ -397,9 +403,9 @@ sudo update-ca-certificates Now, you can connect without specifying `tlsCAFile` in the connection string. ```bash -$ mongosh "mongodb+srv://root:@kubedb.cloud/admin" -rs0 [primary] admin> +mongosh "mongodb+srv://root:@kubedb.cloud/admin" ``` +rs0 [primary] admin> ## Cleaning up diff --git a/docs/guides/mongodb/failure-and-disaster-recovery/overview.md b/docs/guides/mongodb/failure-and-disaster-recovery/overview.md index 5c0b2ee727..13a4e6e5ff 100644 --- a/docs/guides/mongodb/failure-and-disaster-recovery/overview.md +++ b/docs/guides/mongodb/failure-and-disaster-recovery/overview.md @@ -97,8 +97,9 @@ watch kubectl get mg,petset,pods -n demo ``` See the database is ready. -```shell -$ kubectl get mg,petset,pods -n demo +```bash +kubectl get mg,petset,pods -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-ha-demo 4.4.26 Ready 3m58s @@ -109,34 +110,42 @@ NAME READY STATUS RESTARTS AGE pod/mg-ha-demo-0 2/2 Running 0 3m52s pod/mg-ha-demo-1 2/2 Running 0 3m27s pod/mg-ha-demo-2 2/2 Running 0 3m3s -``` Inspect who is primary and who is standby. -```shell # you can inspect who is primary # and who is secondary like below - -$ kubectl get pods -n demo --show-labels | grep role +```bash +kubectl get pods -n demo --show-labels | grep role +``` mg-ha-demo-0 2/2 Running 0 5m6s app.kubernetes.io/component=database,app.kubernetes.io/instance=mg-ha-demo,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mongodbs.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=mg-ha-demo-6b559c9645,kubedb.com/role=primary,statefulset.kubernetes.io/pod-name=mg-ha-demo-0 mg-ha-demo-1 2/2 Running 0 4m41s app.kubernetes.io/component=database,app.kubernetes.io/instance=mg-ha-demo,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mongodbs.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=mg-ha-demo-6b559c9645,kubedb.com/role=standby,statefulset.kubernetes.io/pod-name=mg-ha-demo-1 mg-ha-demo-2 2/2 Running 0 4m17s app.kubernetes.io/component=database,app.kubernetes.io/instance=mg-ha-demo,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mongodbs.kubedb.com,apps.kubernetes.io/pod-index=2,controller-revision-hash=mg-ha-demo-6b559c9645,kubedb.com/role=standby,statefulset.kubernetes.io/pod-name=mg-ha-demo-2 -``` The pod having `kubedb.com/role=primary` is the primary and `kubedb.com/role=standby` are the standby's. Lets create a table in the primary. -```shell -$ kubectl get secrets -n demo mg-ha-demo-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secrets -n demo mg-ha-demo-auth -o jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secrets -n demo mg-ha-demo-auth -o jsonpath='{.data.password}' | base64 -d + +```bash +kubectl get secrets -n demo mg-ha-demo-auth -o jsonpath='{.data.password}' | base64 -d +``` JUIevJ)ISh!Srg4y⏎ + # find the primary pod -$ kubectl exec -it -n demo mg-ha-demo-0 -- bash +```bash +kubectl exec -it -n demo mg-ha-demo-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) + # exec into the primary pod -$ mongodb@mg-ha-demo-0:/$ mongosh admin +```bash +mongodb@mg-ha-demo-0:/$ mongosh admin +``` MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/admin?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("57604543-ec8b-478a-bca3-bdbcf4dda0b6") } @@ -186,8 +195,6 @@ config 0.000GB kubedb-system 0.000GB local 0.000GB -``` - Now, connect to a secondary node to inspect how the data reflects changes from the primary, and observe any visible differences between their states. @@ -308,10 +315,10 @@ mg-ha-demo-2 standby Lets delete the current primary and see how the role change happens almost immediately. -```shell -$ kubectl delete pods -n demo mg-ha-demo-0 -pod "mg-ha-demo-0" deleted +```bash +kubectl delete pods -n demo mg-ha-demo-0 ``` +pod "mg-ha-demo-0" deleted You can see after some time the deleted pod came back as `standby` and one of the previous standby pods becomes the new `primary`. ```shell mg-ha-demo-0 standby @@ -321,8 +328,9 @@ mg-ha-demo-2 standby Now we know how failover is done, let's check if the new primary is working. -```shell -$ `kubectl exec -it -n demo mg-ha-demo-1 -- bash +```bash +`kubectl exec -it -n demo mg-ha-demo-1 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-ha-demo-1:/$ mongosh admin MongoDB shell version v4.4.26 @@ -369,13 +377,12 @@ config 0.000GB kubedb-system 0.000GB local 0.000GB -``` - You will see the deleted pod `mg-ha-demo-0` is brought back by the kubedb operator and it is now assigned to standby role. Lets check if the standby `mg-ha-demo-0` got the updated data from new primary `mg-ha-demo-1`. -```shell -$ kubectl exec -it -n demo mg-ha-demo-0 -- bash +```bash +kubectl exec -it -n demo mg-ha-demo-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-ha-demo-0:/$ mongosh admin MongoDB shell version v4.4.26 @@ -395,15 +402,13 @@ kubedb-system 0.000GB local 0.000GB rs1:SECONDARY> -``` - #### Case 2: Delete the current primary and One replica -```shell -$ kubectl delete pods -n demo mg-ha-demo-1 mg-ha-demo-2 +```bash +kubectl delete pods -n demo mg-ha-demo-1 mg-ha-demo-2 +``` pod "mg-ha-demo-1" deleted pod "mg-ha-demo-2" deleted -``` Again we can see the failover happened pretty quickly. ```shell mg-ha-demo-0 @@ -417,8 +422,9 @@ mg-ha-demo-1 standby mg-ha-demo-2 standby ``` You can validate the replica set status from the new primary `mg-ha-demo-0` by checking the role, state, and health of each member. -```shell -$ kubectl exec -it -n demo mg-ha-demo-0 -- bash +```bash +kubectl exec -it -n demo mg-ha-demo-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-ha-demo-0:/$ mongosh admin MongoDB shell version v4.4.26 @@ -595,8 +601,6 @@ mg-ha-demo-0.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE PRIMARY mg-ha-demo-1.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY mg-ha-demo-2.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY -``` - #### Case3: Delete any of the replica's Let's delete both of the standby's. @@ -620,8 +624,9 @@ mg-ha-demo-2 standby ``` Lets verify cluster state. -```shell -$ kubectl exec -it -n demo mg-ha-demo-0 -- bash +```bash +kubectl exec -it -n demo mg-ha-demo-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-ha-demo-0:/$ mongosh admin MongoDB shell version v4.4.26 @@ -648,20 +653,17 @@ mg-ha-demo-0.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE PRIMARY mg-ha-demo-1.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY mg-ha-demo-2.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY -``` - #### Case 4: Delete both primary and all replicas Let's delete all the pods. -```shell -$ kubectl delete pods -n demo mg-ha-demo-0 mg-ha-demo-1 mg-ha-demo-2 +```bash +kubectl delete pods -n demo mg-ha-demo-0 mg-ha-demo-1 mg-ha-demo-2 +``` pod "mg-ha-demo-0" deleted pod "mg-ha-demo-1" deleted pod "mg-ha-demo-2" deleted -``` - ```shell mg-ha-demo-0 mg-ha-demo-1 @@ -679,8 +681,9 @@ mg-ha-demo-2 standby Lets verify the cluster state now. -```shell -$ kubectl exec -it -n demo mg-ha-demo-1 -- bash +```bash +kubectl exec -it -n demo mg-ha-demo-1 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-ha-demo-1:/$ mongosh admin MongoDB shell version v4.4.26 @@ -705,7 +708,6 @@ rs1:PRIMARY> rs.status().members.forEach(function(member) { mg-ha-demo-0.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY mg-ha-demo-1.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE PRIMARY mg-ha-demo-2.mg-ha-demo-pods.demo.svc.cluster.local 27017 ONLINE SECONDARY -``` #### Retryable Writes Retryable writes allow MongoDB drivers to safely retry certain write operations (like insert, update, delete) once automatically if a network error or primary failover occurs. diff --git a/docs/guides/mongodb/gitops/gitops.md b/docs/guides/mongodb/gitops/gitops.md index 634ce98817..711f7a386e 100644 --- a/docs/guides/mongodb/gitops/gitops.md +++ b/docs/guides/mongodb/gitops/gitops.md @@ -28,13 +28,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create MongoDB d - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/MongoDB](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -94,11 +95,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── MongoDB.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `MongoDB` CR is created in your cluster. @@ -106,19 +107,19 @@ Our `gitops` operator will create an actual `MongoDB` database CR in the cluster ```bash -$ kubectl get MongoDB.gitops.kubedb.com,MongoDB.kubedb.com -n demo + kubectl get MongoDB.gitops.kubedb.com,MongoDB.kubedb.com -n demo +``` NAME AGE mongodb.gitops.kubedb.com/mg-gitops 33m NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 33m -``` - List the resources created by `kubedb` operator created for `kubedb.com/v1` MongoDB. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mg-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mg-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/mg-gitops 34m @@ -137,8 +138,6 @@ service/mg-gitops-pods ClusterIP None 27017/TCP 3 NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/mg-gitops kubedb.com/mongodb 8.0.10 34m -``` - ## Update MongoDB Database using GitOps ### Scale MongoDB Database Resources @@ -194,7 +193,8 @@ Resource Requests and Limits are updated from `800m` to `1000m` CPU and `2Gi` Me Now, `gitops` operator will detect the resource changes and create a `MongoDBOpsRequest` to update the `MongoDB` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 13m @@ -203,11 +203,11 @@ mongodb.gitops.kubedb.com/mg-gitops 13m NAME TYPE STATUS AGE mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 4m35s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo mg-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mg-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "2Gi" @@ -218,8 +218,6 @@ $ kubectl get pod -n demo mg-gitops-0 -o json | jq '.spec.containers[0].resource } } -``` - ### Scale MongoDB Replicas Update the `MongoDB.yaml` with the following, ```yaml @@ -257,7 +255,8 @@ Update the `replicas` to `3`. Commit the changes and push to your Git repository Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` MongoDBOpsRequest to update the `MongoDB` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 18m @@ -267,16 +266,15 @@ mongodb.gitops.kubedb.com/mg-gitops 18m NAME TYPE STATUS AGE mongodbopsrequest.ops.kubedb.com/mg-gitops-horizontalscaling-n8xx64 HorizontalScaling Successful 4m2s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 9m5s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=mg-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=mg-gitops' +``` NAME READY STATUS RESTARTS AGE mg-gitops-0 2/2 Running 0 8m37s mg-gitops-1 2/2 Running 0 9m22s mg-gitops-2 2/2 Running 0 4m34s -``` We can also scale down the replicas by updating the `replicas` fields. @@ -319,7 +317,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` MongoDBOpsRequest to update the `MongoDB` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 21m @@ -330,16 +329,15 @@ NAME TYPE mongodbopsrequest.ops.kubedb.com/mg-gitops-horizontalscaling-n8xx64 HorizontalScaling Successful 7m24s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 12m mongodbopsrequest.ops.kubedb.com/mg-gitops-volumeexpansion-8441ym VolumeExpansion Successful 2m10s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mg-gitops' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mg-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE datadir-mg-gitops-0 Bound pvc-cea7fe6a-dd75-4e81-99d3-9ab2867c6650 2Gi RWO longhorn 22m datadir-mg-gitops-1 Bound pvc-bcd63bd2-b3b8-4fb8-8c35-5f6e40031f61 2Gi RWO longhorn 21m datadir-mg-gitops-2 Bound pvc-2535f213-28fb-41ef-bdfd-7fbe91859c81 2Gi RWO longhorn 7m56s -``` ## Reconfigure MongoDB @@ -400,7 +398,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` MongoDBOpsRequest to update the `MongoDB` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo + kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 32m @@ -412,7 +411,6 @@ mongodbopsrequest.ops.kubedb.com/mg-gitops-horizontalscaling-n8xx64 Horizontal mongodbopsrequest.ops.kubedb.com/mg-gitops-reconfigure-djow20 Reconfigure Successful 6m7s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 22m mongodbopsrequest.ops.kubedb.com/mg-gitops-volumeexpansion-8441ym VolumeExpansion Successful 12m -``` We can also reconfigure the parameters creating another secret and reference the secret in the `configuration.secretName` field. Also you can remove the `configuration` field to use the default parameters. @@ -436,13 +434,13 @@ stringData: Let's add that to our `kubedb/mg-auth.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── mg-configuration.yaml │ ├── mg-auth.yaml │ └── mongodb.yaml 1 directories, 3 files -``` @@ -488,7 +486,8 @@ Add the secret name in `authSecret` field. Commit the changes and push to your G Now, `gitops` operator will detect the auth changes and create a `RotateAuth` MongoDBOpsRequest to update the `MongoDB` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.10 Ready 41m @@ -501,7 +500,6 @@ mongodbopsrequest.ops.kubedb.com/mg-gitops-reconfigure-djow20 Reconfigur mongodbopsrequest.ops.kubedb.com/mg-gitops-rotate-auth-u75ihg RotateAuth Successful 3m10s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 32m mongodbopsrequest.ops.kubedb.com/mg-gitops-volumeexpansion-8441ym VolumeExpansion Successful 22m -``` ### Update Version @@ -546,7 +544,8 @@ Update the `version` field to `8.0.17`. Commit the changes and push to your Git Now, `gitops` operator will detect the version changes and create a `VersionUpdate` MongoDBOpsRequest to update the `MongoDB` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.17 Ready 46m @@ -560,19 +559,24 @@ mongodbopsrequest.ops.kubedb.com/mg-gitops-rotate-auth-u75ihg RotateAuth mongodbopsrequest.ops.kubedb.com/mg-gitops-versionupdate-kkc2gc UpdateVersion Successful 2m38s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 36m mongodbopsrequest.ops.kubedb.com/mg-gitops-volumeexpansion-8441ym VolumeExpansion Successful 26m -``` Now, we are going to verify whether the `MongoDB`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get MongoDB -n demo mg-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get MongoDB -n demo mg-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` 8.0.17 -$ kubectl get petset -n demo mg-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/mongo:8.0.17@sha256:b3e1ae71bd7df56b3497527f2b08549bfccb532d9e26df6d4a1331a71cd085db -$ kubectl get pod -n demo mg-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get petset -n demo mg-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/mongo:8.0.17@sha256:b3e1ae71bd7df56b3497527f2b08549bfccb532d9e26df6d4a1331a71cd085db + +```bash +kubectl get pod -n demo mg-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/mongo:8.0.17@sha256:b3e1ae71bd7df56b3497527f2b08549bfccb532d9e26df6d4a1331a71cd085db ### Enable Monitoring @@ -626,7 +630,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` MongoDBOpsRequest to add the `MongoDB` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.17 Ready 52m @@ -641,7 +646,6 @@ mongodbopsrequest.ops.kubedb.com/mg-gitops-rotate-auth-u75ihg RotateAuth mongodbopsrequest.ops.kubedb.com/mg-gitops-versionupdate-kkc2gc UpdateVersion Successful 9m15s mongodbopsrequest.ops.kubedb.com/mg-gitops-verticalscaling-ojwxpm VerticalScaling Successful 43m mongodbopsrequest.ops.kubedb.com/mg-gitops-volumeexpansion-8441ym VolumeExpansion Successful 32m -``` Verify the monitoring is enabled by checking the prometheus targets. @@ -660,7 +664,7 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - Now create a ca-secret using the certificate files you have just generated. ```bash -$ kubectl create secret tls mongo-ca \ +kubectl create secret tls mongo-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo @@ -682,13 +686,14 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml -issuer.cert-manager.io/mongo-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml ``` +issuer.cert-manager.io/mongo-ca-issuer created Let's add that to our `kubedb/mg-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── mg-configuration.yaml │ ├── mg-auth.yaml @@ -696,7 +701,6 @@ $ tree . │ ├── mg-secret.yaml │ └── mongodb.yaml 1 directories, 5 files -``` Update the `mongodb.yaml` with the following, @@ -759,7 +763,8 @@ Add `sslMode` and `tls` fields in the spec. Commit the changes and push to your Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` ElasticsearchOpsRequest to update the `MongoDB` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mg,mongodb,mgops -n demo +kubectl get mg,mongodb,mgops -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-gitops 8.0.17 Ready 20m @@ -768,7 +773,6 @@ mongodb.gitops.kubedb.com/mg-gitops 20m NAME TYPE STATUS AGE mongodbopsrequest.ops.kubedb.com/mg-gitops-reconfiguretls-2pzvw4 ReconfigureTLS Successful 10m -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for MongoDB. diff --git a/docs/guides/mongodb/hidden-node/replicaset.md b/docs/guides/mongodb/hidden-node/replicaset.md index 1ff22272bf..3788bc7f7b 100644 --- a/docs/guides/mongodb/hidden-node/replicaset.md +++ b/docs/guides/mongodb/hidden-node/replicaset.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: > Note: inMemory databases are only allowed for Percona variations of mongodb ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/hidden-node/replicaset.yaml -mongodb.kubedb.com/mongo-rs-hid created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/hidden-node/replicaset.yaml ``` +mongodb.kubedb.com/mongo-rs-hid created Here, @@ -107,7 +107,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create two new PetSets (one for replicas & one for hidden-nodes) and a Service with the matching MongoDB object name. This service will always point to the primary of the replicaset. KubeDB operator will also create a governing service for the pods of those two PetSets with the name `-pods`. ```bash -$ kubectl dba describe mg -n demo mongo-rs-hid +kubectl dba describe mg -n demo mongo-rs-hid +``` Name: mongo-rs-hid Namespace: demo CreationTimestamp: Mon, 31 Oct 2022 11:03:50 +0600 @@ -250,31 +251,33 @@ Events: Normal Successful 7m MongoDB operator Successfully patched PetSet demo/mongo-rs-hid-hidden Normal Successful 7m MongoDB operator Successfully patched MongoDB - - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mongo-rs-hid 3/3 13m mongo-rs-hid-hidden 2/2 12m - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mongo-rs-hid-hidden-0 Bound pvc-e8c2a3b3-0c47-453f-8a5a-40d7dcb5b4d7 2Gi RWO standard 13m datadir-mongo-rs-hid-hidden-1 Bound pvc-7b752799-b6b9-43cf-9aa7-d39a2577216c 2Gi RWO standard 13m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-7b752799-b6b9-43cf-9aa7-d39a2577216c 2Gi RWO Delete Bound demo/datadir-mongo-rs-hid-hidden-1 standard 13m pvc-e8c2a3b3-0c47-453f-8a5a-40d7dcb5b4d7 2Gi RWO Delete Bound demo/datadir-mongo-rs-hid-hidden-0 standard 13m - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mongo-rs-hid ClusterIP 10.96.197.33 27017/TCP 14m mongo-rs-hid-pods ClusterIP None 27017/TCP 14m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: @@ -393,14 +396,18 @@ Now, you can connect to this database through [mongo-rs-hid](https://docs.mongod At first, insert data inside primary member `rs0:PRIMARY`. ```bash -$ kubectl get secrets -n demo mongo-rs-hid-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mongo-rs-hid-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mongo-rs-hid-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mongo-rs-hid-auth -o jsonpath='{.data.password}' | base64 -d +``` OX4yb!IFm;~yAHkD -$ kubectl exec -it mongo-rs-hid-0 -n demo bash - +```bash +kubectl exec -it mongo-rs-hid-0 -n demo bash +``` bash-4.4$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' Percona Server for MongoDB shell version v7.0.4-11 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb @@ -610,7 +617,6 @@ replicaset:PRIMARY> rs.status() }, "operationTime" : Timestamp(1667193912, 1) } -``` Here, Hidden-node's `statestr` is showing SECONDARY. If you want to see if they have been really added as hidden or not, you need to run `rs.conf()` command, look at the `hidden: true` specifications. @@ -756,7 +762,8 @@ Now, check the redundancy and data availability in secondary members. We will exec in `mongo-rs-hid-hidden-0`(which is a hidden node right now) to check the data availability. ```bash -$ kubectl exec -it mongo-rs-hid-hidden-0 -n demo bash +kubectl exec -it mongo-rs-hid-hidden-0 -n demo bash +``` bash-4.4$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' Percona Server for MongoDB server version: v7.0.4-11 connecting to: mongodb://127.0.0.1:27017/admin @@ -805,14 +812,13 @@ replicaset:SECONDARY> db.songs.find().pretty() rs0:SECONDARY> exit bye -``` - ## Automatic Failover To test automatic failover, we will force the primary member to restart. As the primary member (`pod`) becomes unavailable, the rest of the members will elect a primary member by election. ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mongo-rs-hid-0 2/2 Running 0 34m mongo-rs-hid-1 2/2 Running 0 33m @@ -820,22 +826,26 @@ mongo-rs-hid-2 2/2 Running 0 33m mongo-rs-hid-hidden-0 1/1 Running 0 33m mongo-rs-hid-hidden-1 1/1 Running 0 32m -$ kubectl delete pod -n demo mongo-rs-hid-0 +```bash +kubectl delete pod -n demo mongo-rs-hid-0 +``` pod "mongo-rs-hid-0" deleted -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mongo-rs-hid-0 2/2 Terminating 0 34m mongo-rs-hid-1 2/2 Running 0 33m mongo-rs-hid-2 2/2 Running 0 33m mongo-rs-hid-hidden-0 1/1 Running 0 33m mongo-rs-hid-hidden-1 1/1 Running 0 32m -``` Now verify the automatic failover, Let's exec in `mongo-rs-hid-0` pod, ```bash -$ kubectl exec -it mongo-rs-hid-0 -n demo bash +kubectl exec -it mongo-rs-hid-0 -n demo bash +``` bash-4.4:/$ mongosh admin -u root -p 'OX4yb!IFm;~yAHkD' Percona Server for MongoDB server version: v7.0.4-11 connecting to: mongodb://127.0.0.1:27017/admin @@ -862,7 +872,6 @@ replicaset:SECONDARY> db.songs.find().pretty() "_id" : ObjectId("635f5df01804db954f81276e"), "pink floyd" : "shine on you crazy diamond" } -``` We could terminate the hidden-nodes also in a similar fashion, & check the automatic failover. ## Cleaning up diff --git a/docs/guides/mongodb/hidden-node/sharding.md b/docs/guides/mongodb/hidden-node/sharding.md index 58af76400b..4407f9a881 100644 --- a/docs/guides/mongodb/hidden-node/sharding.md +++ b/docs/guides/mongodb/hidden-node/sharding.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -80,9 +80,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/hidden-node/sharding.yaml -mongodb.kubedb.com/mongo-sh-hid created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/hidden-node/sharding.yaml ``` +mongodb.kubedb.com/mongo-sh-hid created Here, @@ -120,7 +120,8 @@ MongoDB `mongo-sh-hid` state, All the types of nodes `Shard`, `ConfigServer` & `Mongos` are deployed as petset. ```bash -$ kubectl get mg,petset,svc,pvc,pv -n demo +kubectl get mg,petset,svc,pvc,pv -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mongo-sh-hid percona-7.0.18 Ready 4m46s @@ -151,8 +152,6 @@ persistentvolume/pvc-61712454-2038-4692-a6ea-88685d7f34e1 2Gi RWO persistentvolume/pvc-9a4fd907-8225-4ed2-90e3-8ca43c0521d2 2Gi RWO Delete Bound demo/datadir-mongo-sh-hid-shard0-hidden-0 standard 3m42s persistentvolume/pvc-b77cd5d1-d5c1-433b-90dd-3784c5207cd6 2Gi RWO Delete Bound demo/datadir-mongo-sh-hid-shard0-hidden-1 standard 3m20s -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. It has also defaulted some field of crd object. Run the following command to see the modified MongoDB object: @@ -301,16 +300,16 @@ If you want to use custom or existing secret please specify that when creating t - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo mongo-sh-hid-auth -o jsonpath='{.data.username}' | base64 -d - root + kubectl get secrets -n demo mongo-sh-hid-auth -o jsonpath='{.data.username}' | base64 -d ``` + root - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo mongo-sh-hid-auth -o jsonpath='{.data.password}' | base64 -d - 6&UiN5;qq)Tnai=7 + kubectl get secrets -n demo mongo-sh-hid-auth -o jsonpath='{.data.password}' | base64 -d ``` + 6&UiN5;qq)Tnai=7 Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/). @@ -319,13 +318,15 @@ Now, you can connect to this database through [mongo-shell](https://docs.mongodb In this tutorial, we will insert sharded and unsharded document, and we will see if the data actually sharded across cluster or not. ```bash -$ kubectl get pod -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-hid-mongos +kubectl get pod -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-hid-mongos +``` NAME READY STATUS RESTARTS AGE mongo-sh-hid-mongos-0 1/1 Running 0 6m38s mongo-sh-hid-mongos-1 1/1 Running 0 6m20s -$ kubectl exec -it mongo-sh-hid-mongos-0 -n demo bash - +```bash +kubectl exec -it mongo-sh-hid-mongos-0 -n demo bash +``` mongodb@mongo-sh-mongos-0:/$ mongosh admin -u root -p '6&UiN5;qq)Tnai=7' Percona Server for MongoDB shell version v7.0.4-11 connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb @@ -338,7 +339,6 @@ For more comprehensive documentation, see Questions? Try the support group https://www.percona.com/forums/questions-discussions/percona-server-for-mongodb mongos> -``` To detect if the MongoDB instance that your client is connected to is mongos, use the isMaster command. When a client connects to a mongos, isMaster returns a document with a `msg` field that holds the string `isdbgrid`. diff --git a/docs/guides/mongodb/initialization/gitsync.md b/docs/guides/mongodb/initialization/gitsync.md index 6f030a41e1..4cce677044 100644 --- a/docs/guides/mongodb/initialization/gitsync.md +++ b/docs/guides/mongodb/initialization/gitsync.md @@ -25,9 +25,9 @@ In this example, we will initialize MongoDB using a `.js` script from the GitHub To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## From Public Git Repository @@ -82,16 +82,16 @@ The `git-sync` container has two required flags: Now, wait until `mg-git` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-git 8.0.4 Ready 49m -``` - Next, we will connect to the MongoDB database and verify the data inserted from the `*.js` script stored in the Git repository. ```bash -$ kubectl exec -it -n demo mg-git-0 -- bash + kubectl exec -it -n demo mg-git-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, copy-config (init), git-sync (init) mongodb@mg-git-0:/$ mongosh -u root -p $ Current Mongosh Log ID: 6900695d231f7a9e99ce5f46 @@ -127,7 +127,6 @@ kubedb> db.people.find() } ] kubedb> exit -``` ## From Private Git Repository ### 1. Using SSH Key @@ -137,7 +136,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -152,7 +151,7 @@ This secret will be used by git-sync to authenticate with the Git repository. >Here, we are using the default SSH key file located at `$HOME/.ssh/id_rsa`. If your SSH key is stored in a different location, please update the command accordingly. Also, you can use any name instead of `git-creds` to create the secret. ```bash -$ kubectl create secret generic -n demo git-creds \ +kubectl create secret generic -n demo git-creds \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -214,7 +213,8 @@ Once the database reaches the `Ready` state, you can verify the data using the m Next, we will connect to the MongoDB database and verify the data inserted from the `*.js` script stored in the Git repository. ```bash -$ kubectl exec -it -n demo mg-git-ssh-0 -- bash + kubectl exec -it -n demo mg-git-ssh-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, copy-config (init), git-sync (init) mongodb@mg-git-ssh-0:/$ mongosh -u root -p 'tQ;c(ykM_T_EbLKS' Current Mongosh Log ID: 6900695d231f7a9e99ce5f46 @@ -250,7 +250,6 @@ kubedb> db.people.find() } ] kubedb> exit -``` ### 2. Using Username and Personal Access Token(PAT) First, create a `Personal Access Token (PAT)` on your Git host server with the required permissions to access the repository. @@ -259,7 +258,7 @@ Then create a Kubernetes secret using the `Personal Access Token (PAT)`: > Here, you can use any key name instead of `git-pat` to store the token in the secret. ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -331,7 +330,13 @@ mg-git-pat 8.0.4 Ready 38m To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete MongoDB -n demo mg-git mg-git-ssh mg-git-pat -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete MongoDB -n demo mg-git mg-git-ssh mg-git-pat +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/mongodb/initialization/using-script.md b/docs/guides/mongodb/initialization/using-script.md index 3fd51e3d24..76a8929e8c 100644 --- a/docs/guides/mongodb/initialization/using-script.md +++ b/docs/guides/mongodb/initialization/using-script.md @@ -25,9 +25,9 @@ This tutorial will show you how to use KubeDB to initialize a MongoDB database w - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created In this tutorial we will use .js script stored in GitHub repository [kubedb/mongodb-init-scripts](https://github.com/kubedb/mongodb-init-scripts). @@ -44,10 +44,10 @@ At first, we will create a ConfigMap from `init.js` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo mg-init-script \ +kubectl create configmap -n demo mg-init-script \ --from-literal=init.js="$(curl -fsSL https://github.com/kubedb/mongodb-init-scripts/raw/master/init.js)" -configmap/mg-init-script created ``` +configmap/mg-init-script created ## Create a MongoDB database with Init-Script @@ -75,9 +75,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/initialization/demo-1.yaml -mongodb.kubedb.com/mgo-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/initialization/demo-1.yaml ``` +mongodb.kubedb.com/mgo-init-script created Here, @@ -86,7 +86,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MongoDB object name. KubeDB operator will also create a governing service for PetSets with the name `-gvr`, if one is not already present. No MongoDB specific RBAC roles are required for [RBAC enabled clusters](/docs/setup/README.md#using-yaml). ```bash -$ kubectl dba describe mg -n demo mgo-init-script +kubectl dba describe mg -n demo mgo-init-script +``` Name: mgo-init-script Namespace: demo CreationTimestamp: Thu, 11 Feb 2021 10:58:22 +0600 @@ -194,23 +195,30 @@ Events: Normal Successful 27s MongoDB operator Successfully patched PetSet demo/mgo-init-script Normal Successful 27s MongoDB operator Successfully patched MongoDB -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mgo-init-script 1/1 30s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mgo-init-script-0 Bound pvc-a10d636b-c08c-11e8-b4a9-0800272618ed 1Gi RWO standard 11m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-a10d636b-c08c-11e8-b4a9-0800272618ed 1Gi RWO Delete Bound demo/datadir-mgo-init-script-0 standard 12m -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mgo-init-script ClusterIP 10.107.34.91 27017/TCP 52s mgo-init-script-pods ClusterIP None 27017/TCP 52s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: @@ -350,7 +358,8 @@ Please note that KubeDB operator has created a new Secret called `mgo-init-scrip If you want to use an existing secret please specify that when creating the MongoDB object using `spec.authSecret.name`. While creating this secret manually, make sure the secret contains these two keys containing data `username` and `password`. ```bash -$ kubectl get secrets -n demo mgo-init-script-auth -o yaml +kubectl get secrets -n demo mgo-init-script-auth -o yaml +``` apiVersion: v1 data: password: eGtBaTRmRVpmSVFrNmczVw== @@ -367,19 +376,22 @@ metadata: selfLink: /api/v1/namespaces/demo/secrets/mgo-init-script-auth uid: b7cf2369-29f3-11e9-aebf-080027875192 type: Opaque -``` Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v3.4/mongo/). In this tutorial, we are connecting to the MongoDB server from inside the pod. ```bash -$ kubectl get secrets -n demo mgo-init-script-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mgo-init-script-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mgo-init-script-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mgo-init-script-auth -o jsonpath='{.data.password}' | base64 -d +``` oEwk7IGxCPM5OWo5 -$ kubectl exec -it mgo-init-script-0 -n demo sh - +```bash +kubectl exec -it mgo-init-script-0 -n demo sh +``` > mongosh admin MongoDB shell version v3.4.10 connecting to: mongodb://127.0.0.1:27017/admin @@ -408,7 +420,6 @@ switched to db kubedb > exit bye -``` As you can see here, the initial script has successfully created a database named `kubedb` and inserted data into that database successfully. diff --git a/docs/guides/mongodb/migration/databaseMigration.md b/docs/guides/mongodb/migration/databaseMigration.md index e20b72677d..fae00608e4 100644 --- a/docs/guides/mongodb/migration/databaseMigration.md +++ b/docs/guides/mongodb/migration/databaseMigration.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` Migration to migrate an existing `M To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Source Database @@ -76,7 +76,7 @@ See the official [MongoDB Replica Set](https://www.mongodb.com/docs/manual/repli Connect to the source instance and verify that the oplog is available: ```bash -$ mongosh "mongodb+srv://.mongo.ondigitalocean.com" -u admin -p +mongosh "mongodb+srv://.mongo.ondigitalocean.com" -u admin -p ``` ```bash @@ -172,7 +172,7 @@ db.orders.find().pretty() First, create an authentication secret using the `migrator` user credentials: ```bash -$ kubectl create secret generic source-mongodb-auth -n demo \ +kubectl create secret generic source-mongodb-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=migrator \ --from-literal=password= @@ -250,9 +250,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/migration/mgo-destination.yaml -mongodb.kubedb.com/mgo-destination created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/migration/mgo-destination.yaml ``` +mongodb.kubedb.com/mgo-destination created > Note: Adjust the `resources.requests.storage` based on the source database size. @@ -288,9 +288,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/migration/mongodb-migrate.yaml -migration.courier.kubedb.com/mongodb-migrate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/migration/mongodb-migrate.yaml ``` +migration.courier.kubedb.com/mongodb-migrate created Here, @@ -331,7 +331,7 @@ mongodb-migrate Running mongodb incr 0 17h You can also see collection-wise progress, detailed checkpoints, and sync metrics by checking the migration pod logs: ```bash -$ kubectl logs -n demo migration- +kubectl logs -n demo migration- ``` Example output during the full sync stage — showing per-collection progress, total/finished/processing/waiting collections: @@ -351,7 +351,7 @@ Example output during incremental sync — showing LAG, checkpoint timestamps, a Once the migration reaches the `incr` stage (continuous oplog tailing), exec into the KubeDB target pod and confirm all seed documents were copied over: ```bash -$ kubectl exec -it -n demo mgo-destination-0 -- mongosh -u root -p +kubectl exec -it -n demo mgo-destination-0 -- mongosh -u root -p ``` ```bash @@ -390,7 +390,7 @@ db.orders.find().pretty() With the migration still running, connect to the **source DigitalOcean** instance and run some DML: ```bash -$ mongosh "mongodb+srv://.mongo.ondigitalocean.com" -u migrator -p +mongosh "mongodb+srv://.mongo.ondigitalocean.com" -u migrator -p ``` ```bash @@ -453,8 +453,8 @@ Once the `LAG` drops to near zero, stop all writes to the source database. Wait Now delete the `Migration` CR to stop the migration process: ```bash -$ kubectl delete migration -n demo mongodb-migrate -migration.courier.kubedb.com "mongodb-migrate" deleted +kubectl delete migration -n demo mongodb-migrate ``` +migration.courier.kubedb.com "mongodb-migrate" deleted Finally, update your application's connection string to point to the target KubeDB-managed `MongoDB` database. The migration is complete. diff --git a/docs/guides/mongodb/monitoring/using-builtin-prometheus.md b/docs/guides/mongodb/monitoring/using-builtin-prometheus.md index 2a1062ec52..49f523a7a7 100644 --- a/docs/guides/mongodb/monitoring/using-builtin-prometheus.md +++ b/docs/guides/mongodb/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor MongoDB database using builtin [Prome - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the MongoDB crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/monitoring/builtin-prom-mgo.yaml -mongodb.kubedb.com/builtin-prom-mgo created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/monitoring/builtin-prom-mgo.yaml ``` +mongodb.kubedb.com/builtin-prom-mgo created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get mg -n demo builtin-prom-mgo +kubectl get mg -n demo builtin-prom-mgo +``` NAME VERSION STATUS AGE builtin-prom-mgo 4.4.26 Ready 2m34s -``` KubeDB will create a separate stats service with name `{MongoDB crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-mgo" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-mgo" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-mgo ClusterIP 10.99.28.40 27017/TCP 55s builtin-prom-mgo-pods ClusterIP None 27017/TCP 55s builtin-prom-mgo-stats ClusterIP 10.98.202.26 56790/TCP 36s -``` Here, `builtin-prom-mgo-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-mgo-stats +kubectl describe svc -n demo builtin-prom-mgo-stats +``` Name: builtin-prom-mgo-stats Namespace: demo Labels: app.kubernetes.io/name=mongodbs.kubedb.com @@ -111,7 +114,6 @@ TargetPort: prom-http/TCP Endpoints: 172.17.0.7:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -275,20 +277,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -299,9 +301,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -310,18 +312,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-7bd56c6865-8dlpv 1/1 Running 0 28s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-mgo-stats` service as one of the targets. diff --git a/docs/guides/mongodb/monitoring/using-prometheus-operator.md b/docs/guides/mongodb/monitoring/using-prometheus-operator.md index c3beba4eab..c6e645a4cb 100644 --- a/docs/guides/mongodb/monitoring/using-prometheus-operator.md +++ b/docs/guides/mongodb/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE monitoring prometheus-kube-prometheus-prometheus v2.39.0 1 13d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -165,27 +167,27 @@ Here, Let's create the MongoDB object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/monitoring/coreos-prom-mgo.yaml -mongodb.kubedb.com/coreos-prom-mgo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/monitoring/coreos-prom-mgo.yaml ``` +mongodb.kubedb.com/coreos-prom-mgo created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get mg -n demo coreos-prom-mgo +kubectl get mg -n demo coreos-prom-mgo +``` NAME VERSION STATUS AGE coreos-prom-mgo 4.4.26 Ready 34s -``` KubeDB will create a separate stats service with name `{MongoDB crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-mgo" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-mgo" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-mgo ClusterIP 10.96.150.171 27017/TCP 84s coreos-prom-mgo-pods ClusterIP None 27017/TCP 84s coreos-prom-mgo-stats ClusterIP 10.96.218.41 56790/TCP 64s -``` Here, `coreos-prom-mgo-stats` service has been created for monitoring purpose. @@ -220,10 +222,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this informatio KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-mgo-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-mgo-stats 2m40s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of MongoDB crd. @@ -280,20 +282,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 13d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `coreos-prom-mgo-stats` service as one of the targets. diff --git a/docs/guides/mongodb/pitr/pitr.md b/docs/guides/mongodb/pitr/pitr.md index bb81cf8b2f..14aa97bd47 100644 --- a/docs/guides/mongodb/pitr/pitr.md +++ b/docs/guides/mongodb/pitr/pitr.md @@ -29,9 +29,9 @@ Now, To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [mg-archiver-demo](https://github.com/kubedb/mg-archiver-demo) ## Continuous archiving Continuous archiving involves making regular copies (or "archives") of the MongoDB transaction log files. To ensure continuous archiving to a remote location we need to prepare `BackupStorage`,`RetentionPolicy`,`MongoDBArchiver` for the KubeDB Managed MongoDB Databases. @@ -70,10 +70,10 @@ s3: secret: linode-secret ``` -```bash - $ kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/backupstorage.yaml + ```bash + kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/backupstorage.yaml + ``` backupstorage.storage.kubestash.com/gcs-storage created -``` ### Secret for BackupStorage @@ -93,10 +93,10 @@ kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_SECRET_ACCESS_KEY ``` -```bash - $ kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/storage-secret.yaml + ```bash + kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/storage-secret.yaml + ``` secret/gcs-secret created -``` ### Retention policy RetentionPolicy is a CR provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -114,9 +114,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/retention-policy.yaml -retentionpolicy.storage.kubestash.com/mongodb-retention-policy created +kubectl apply -https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/retention-policy.yaml ``` +retentionpolicy.storage.kubestash.com/mongodb-retention-policy created ## Ensure volumeSnapshotClass @@ -130,11 +130,11 @@ longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h If not any, try using `longhorn` or any other [volumeSnapshotClass](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/). ```bash -$ helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +``` ... ... kubectl get pod -n longhorn-system -```` ```yaml @@ -161,9 +161,9 @@ deletionPolicy: Delete ```bash -$ kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/volume-snapshot-class.yaml - volumesnapshotclass.snapshot.storage.k8s.io/gke-vsc unchanged +kubectl apply -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/gke/volume-snapshot-class.yaml ``` + volumesnapshotclass.snapshot.storage.k8s.io/gke-vsc unchanged ### MongoDBArchiver @@ -224,10 +224,13 @@ stringData: RESTIC_PASSWORD: "changeit" ``` -```bash - $ kubectl create -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/encrypt-secret.yaml - $ kubectl create -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/archiver.yaml -``` + ```bash + kubectl create -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/encrypt-secret.yaml + ``` + + ```bash + kubectl create -f https://raw.githubusercontent.com/kubedb/mg-archiver-demo/master/common/archiver.yaml + ``` # Deploy MongoDB @@ -269,7 +272,8 @@ The `archiver: "true"` label is important here. Because that's how we are specif ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mg-rs-0 2/2 Running 0 8m30s mg-rs-1 2/2 Running 0 7m32s @@ -279,8 +283,6 @@ mg-rs-backup-manifest-backup-1702457110-fjpw5 0/1 Completed 0 mg-rs-backup-manifest-backup-1702457253-f4chq 0/1 Completed 0 65s mg-rs-sidekick 1/1 Running 0 5m29s trigger-mg-rs-backup-manifest-backup-28374285-rdcfq 0/1 Completed 0 3m38s - -``` `mg-rs-sidekick` is responsible for uploading oplog-files `mg-rs-full-backup-*****` are the volumes levels backups for MongoDB. `mg-rs-manifest-backup-*****` are the backups of the manifest relate to MongoDB object @@ -288,8 +290,8 @@ trigger-mg-rs-backup-manifest-backup-28374285-rdcfq 0/1 Completed 0 ### Validate BackupConfiguration and VolumeSnapshot ```bash -$ kubectl get backupstorage,backupconfigurations,backupsession,volumesnapshots -A - +kubectl get backupstorage,backupconfigurations,backupsession,volumesnapshots -A +``` NAMESPACE NAME PROVIDER DEFAULT DELETION-POLICY TOTAL-SIZE PHASE AGE demo backupstorage.storage.kubestash.com/gcs-storage gcs WipeOut 3.292 KiB Ready 11m @@ -304,12 +306,11 @@ demo backupsession.core.kubestash.com/mg-rs-backup-manifest-backup-170245 NAMESPACE NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE demo volumesnapshot.snapshot.storage.k8s.io/mg-rs-1702457262 true datadir-mg-rs-1 1Gi gke-vsc snapcontent-87f1013f-cd7e-4153-b245-da9552d2e44f 2m7s 2m11s -``` - ## data insert and switch oplog After each and every oplog switch the oplog files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo mg-rs-0 bash +kubectl exec -it -n demo mg-rs-0 bash +``` kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mg-rs-0:/$ @@ -342,7 +343,6 @@ songs rs:PRIMARY> db.songs.find() { "_id" : ObjectId("657970c1f965be0513c7f4d7"), "name" : "shine on you crazy diamond" } rs:PRIMARY> -``` > At this point We have a document in our newly created collection `songs` on database `pink_floyd` ## Point-in-time Recovery Point-In-Time Recovery allows you to restore a MongoDB database to a specific point in time using the archived transaction logs. This is particularly useful in scenarios where you need to recover to a state just before a specific error or data corruption occurred. diff --git a/docs/guides/mongodb/private-registry/using-private-registry.md b/docs/guides/mongodb/private-registry/using-private-registry.md index 06d0822ecc..d81948a2c2 100644 --- a/docs/guides/mongodb/private-registry/using-private-registry.md +++ b/docs/guides/mongodb/private-registry/using-private-registry.md @@ -27,7 +27,8 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images into your private registry. For mongodb, push `DB_IMAGE`, `TOOLS_IMAGE`, `EXPORTER_IMAGE` of following MongoDBVersions, where `deprecated` is not true, to your private registry. ```bash - $ kubectl get mongodbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,INITCONTAINER_IMAGE:.spec.initContainer.image,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image + kubectl get mongodbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,INITCONTAINER_IMAGE:.spec.initContainer.image,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image + ``` NAME VERSION INITCONTAINER_IMAGE DB_IMAGE EXPORTER_IMAGE 3.4.17-v1 3.4.17 kubedb/mongodb-init:4.1-v7 mongo:3.4.17 kubedb/mongodb_exporter:v0.20.4 3.4.22-v1 3.4.22 kubedb/mongodb-init:4.1-v7 mongo:3.4.22 kubedb/mongodb_exporter:v0.32.0 @@ -47,7 +48,6 @@ KubeDB operator supports using private Docker registry. This tutorial will show percona-4.0.10 4.0.10 kubedb/mongodb-init:4.1-v7 percona/percona-server-mongodb:4.0.10 kubedb/mongodb_exporter:v0.32.0 percona-4.2.7 4.2.7 kubedb/mongodb-init:4.2-v7 percona/percona-server-mongodb:4.2.7-7 kubedb/mongodb_exporter:v0.32.0 percona-4.4.10 4.4.10 kubedb/mongodb-init:4.2-v7 percona/percona-server-mongodb:4.4.10 kubedb/mongodb_exporter:v0.32.0 - ``` Docker hub repositories: @@ -95,13 +95,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created DOCKER_REGISTRY_SERVER value will be `docker.io` for docker hub. @@ -114,9 +114,9 @@ NB: If you are using `kubectl` 1.9.0, update to 1.9.1 or later to avoid this [is To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Deploy MongoDB @@ -147,22 +147,23 @@ spec: Now run the command to deploy this `MongoDB` object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/private-registry/replicaset.yaml -mongodb.kubedb.com/mgo-pvt-reg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/private-registry/replicaset.yaml ``` +mongodb.kubedb.com/mgo-pvt-reg created To check if the images pulled successfully from the repository, see if the `MongoDB` is in running state: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mgo-pvt-reg-0 1/1 Running 0 5m - -$ kubectl get mg -n demo +```bash +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mgo-pvt-reg 4.4.26 Ready 38s -``` ## Cleaning up diff --git a/docs/guides/mongodb/quickstart/quickstart.md b/docs/guides/mongodb/quickstart/quickstart.md index b0aaad3143..d01d67c76b 100644 --- a/docs/guides/mongodb/quickstart/quickstart.md +++ b/docs/guides/mongodb/quickstart/quickstart.md @@ -29,18 +29,17 @@ This tutorial will show you how to use KubeDB to run a MongoDB database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 2m5s - ``` - - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -49,7 +48,8 @@ This tutorial will show you how to use KubeDB to run a MongoDB database. When you have installed KubeDB, it has created `MongoDBVersion` crd for all supported MongoDB versions. Check it out. ```bash -$ kubectl get mongodbversions +kubectl get mongodbversions +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 4.4.26 4.4.26 Official ghcr.io/appscode-images/mongo:4.4.26 13d 5.0.31 5.0.31 Official ghcr.io/appscode-images/mongo:5.0.31 13d @@ -66,8 +66,6 @@ percona-7.0.28 7.0.28 Percona docker.io/percona/percona-server-mongo percona-8.0.17 8.0.17 Percona docker.io/percona/percona-server-mongodb:8.0.17 13d percona-8.0.8 8.0.8 Percona docker.io/percona/percona-server-mongodb:8.0.8 13d -``` - ## Create a MongoDB database KubeDB implements a `MongoDB` CRD to define the specification of a MongoDB database. Below is the `MongoDB` object created in this tutorial. @@ -97,9 +95,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/quickstart/replicaset-v1.yaml -mongodb.kubedb.com/mgo-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/quickstart/replicaset-v1.yaml ``` +mongodb.kubedb.com/mgo-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -124,9 +122,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/quickstart/replicaset-v1alpha2.yaml -mongodb.kubedb.com/mgo-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/quickstart/replicaset-v1alpha2.yaml ``` +mongodb.kubedb.com/mgo-quickstart created Here, @@ -142,7 +140,8 @@ Here, KubeDB operator watches for `MongoDB` objects using Kubernetes api. When a `MongoDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching MongoDB object name. KubeDB operator will also create a governing service for PetSets with the name `-pods`. ```bash -$ kubectl dba describe mg -n demo mgo-quickstart +kubectl dba describe mg -n demo mgo-quickstart +``` Name: mgo-quickstart Namespace: demo CreationTimestamp: Mon, 13 Jun 2022 18:01:55 +0600 @@ -249,32 +248,36 @@ Events: Normal Successful 3m KubeDB Operator Successfully created governing service Normal Successful 3m KubeDB Operator Successfully created Primary Service Normal Successful 3m KubeDB Operator Successfully created appbinding -``` ```bash -$ kubectl get petset -n demo +kubectl get petset -n demo +``` NAME READY AGE mgo-quickstart 3/3 3m36s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE datadir-mgo-quickstart-0 Bound pvc-18c3c456-c9a9-40b2-bec8-4302cc0aeccc 1Gi RWO standard 3m56s datadir-mgo-quickstart-1 Bound pvc-7ac4c470-8fa7-47a9-b118-2ac20f01186d 1Gi RWO standard 104s datadir-mgo-quickstart-2 Bound pvc-2e6dfb71-056b-4186-927d-855db35d0014 1Gi RWO standard 77s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-18c3c456-c9a9-40b2-bec8-4302cc0aeccc 1Gi RWO Delete Bound demo/datadir-mgo-quickstart-0 standard 4m8s pvc-2e6dfb71-056b-4186-927d-855db35d0014 1Gi RWO Delete Bound demo/datadir-mgo-quickstart-2 standard 90s pvc-7ac4c470-8fa7-47a9-b118-2ac20f01186d 1Gi RWO Delete Bound demo/datadir-mgo-quickstart-1 standard 117s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mgo-quickstart ClusterIP 10.96.20.114 27017/TCP 4m25s mgo-quickstart-pods ClusterIP None 27017/TCP 4m25s -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified MongoDB object: ```yaml @@ -370,14 +373,18 @@ If you want to use custom or existing secret please specify that when creating t Now, you can connect to this database through [mongo-shell](https://docs.mongodb.com/v3.4/mongo/). In this tutorial, we are connecting to the MongoDB server from inside the pod. ```bash -$ kubectl get secrets -n demo mgo-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mgo-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mgo-quickstart-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mgo-quickstart-auth -o jsonpath='{.data.password}' | base64 -d +``` CaM8v9LmmSGB~&hj -$ kubectl exec -it mgo-quickstart-0 -n demo sh - +```bash +kubectl exec -it mgo-quickstart-0 -n demo sh +``` > mongosh admin rs1:PRIMARY> db.auth("root","CaM8v9LmmSGB~&hj") @@ -423,7 +430,6 @@ rs1:PRIMARY> db.movies.find() > exit bye -``` # Database DeletionPolicy This field is used to regulate the deletion process of the related resources when mongodb object is deleted. User can set the value of this field according to their needs. The available options and their use case scenario is described below: @@ -433,9 +439,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete mg mgo-quickstart -n demo -Error from server (BadRequest): admission webhook "mongodbwebhook.validators.kubedb.com" denied the request: mongodb "demo/mgo-quickstart" can't be terminated. To delete, change spec.deletionPolicy +kubectl delete mg mgo-quickstart -n demo ``` +Error from server (BadRequest): admission webhook "mongodbwebhook.validators.kubedb.com" denied the request: mongodb "demo/mgo-quickstart" can't be terminated. To delete, change spec.deletionPolicy ## Halt Database @@ -446,23 +452,24 @@ You can also keep the mongodb object and halt the database to resume it again la To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -mongodb.kubedb.com/mgo-quickstart patched +kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +mongodb.kubedb.com/mgo-quickstart patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"halted":true}}' --type="merge" -mongodb.kubedb.com/mgo-quickstart patched +kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"halted":true}}' --type="merge" ``` +mongodb.kubedb.com/mgo-quickstart patched After that, kubedb will delete the petsets and services and you can see the database Phase as `Halted`. Now, you can run the following command to get all mongodb resources in demo namespaces, ```bash -$ kubectl get mg,petset,svc,secret,pvc -n demo +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mgo-quickstart 4.4.26 Halted 12m @@ -475,7 +482,6 @@ NAME STATUS VOLUME persistentvolumeclaim/datadir-mgo-quickstart-0 Bound pvc-18c3c456-c9a9-40b2-bec8-4302cc0aeccc 1Gi RWO standard 12m persistentvolumeclaim/datadir-mgo-quickstart-1 Bound pvc-7ac4c470-8fa7-47a9-b118-2ac20f01186d 1Gi RWO standard 9m57s persistentvolumeclaim/datadir-mgo-quickstart-2 Bound pvc-2e6dfb71-056b-4186-927d-855db35d0014 1Gi RWO standard 9m30s -``` ## Resume Halted Database @@ -483,23 +489,23 @@ persistentvolumeclaim/datadir-mgo-quickstart-2 Bound pvc-2e6dfb71-056b-4186 Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"halted":false}}' --type="merge" -mongodb.kubedb.com/mgo-quickstart patched +kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"halted":false}}' --type="merge" ``` +mongodb.kubedb.com/mgo-quickstart patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mgo-quickstart 4.4.26 Ready 13m -``` Now, If you again exec into the `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it mgo-quickstart-0 -n demo bash - +kubectl exec -it mgo-quickstart-0 -n demo bash +``` mongodb@mgo-quickstart-0:/$ mongosh admin -u root -p 'CaM8v9LmmSGB~&hj' rs1:SECONDARY> use mydb switched to db mydb @@ -510,8 +516,6 @@ WARNING: slaveOk() is deprecated and may be removed in the next major release. P rs1:SECONDARY> db.movies.find() { "_id" : ObjectId("62a72949198bad2c983d6611"), "top gun" : "maverick" } -``` - ## Cleaning up @@ -523,29 +527,40 @@ If you want to delete the existing database along with the volumes used, but wan When the DeletionPolicy is set to Delete and the mongodb object is deleted, the KubeDB operator will delete the PetSet and its pods along with PVCs but leaves the secret and database backup data(snapshots) intact. ```bash -$ kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +``` kubectl delete -n demo mg/mgo-quickstart -$ kubectl get mg,petset,svc,secret,pvc -n demo +```bash +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/default-token-swg6h kubernetes.io/service-account-token 3 27m secret/mgo-quickstart-auth Opaque 2 27m secret/mgo-quickstart-key Opaque 1 27m -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ### WipeOut But if you want to cleanup each of the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo mg/mgo-quickstart +kubectl patch -n demo mg/mgo-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo mg/mgo-quickstart +``` -$ kubectl get mg,petset,svc,secret,pvc -n demo +```bash +kubectl get mg,petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ## Tips for Testing diff --git a/docs/guides/mongodb/reconfigure-tls/reconfigure-tls.md b/docs/guides/mongodb/reconfigure-tls/reconfigure-tls.md index 49589b6e3b..ff3cc69162 100644 --- a/docs/guides/mongodb/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/mongodb/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,18 +64,21 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mg-replicaset.yaml -mongodb.kubedb.com/mg-rs created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mg-replicaset.yaml ``` +mongodb.kubedb.com/mg-rs created Now, wait until `mg-replicaset` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-rs 4.4.26 Ready 10m -$ kubectl dba describe mongodb mg-rs -n demo +```bash +kubectl dba describe mongodb mg-rs -n demo +``` Name: mg-rs Namespace: demo CreationTimestamp: Thu, 11 Mar 2021 13:25:05 +0600 @@ -190,19 +193,23 @@ Events: Normal Successful 13m MongoDB operator Successfully stats service Normal Successful 12m MongoDB operator Successfully stats service Normal Successful 12m MongoDB operator Successfully patched PetSet demo/mg-rs -``` Now, we can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/) and verify that the TLS is disabled. ```bash -$ kubectl get secrets -n demo mg-rs-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-rs-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-rs-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mg-rs-auth -o jsonpath='{.data.password}' | base64 -d +``` U6(h_pYrekLZ2OOd -$ kubectl exec -it mg-rs-0 -n demo -- mongosh admin -u root -p 'U6(h_pYrekLZ2OOd' +```bash +kubectl exec -it mg-rs-0 -n demo -- mongosh admin -u root -p 'U6(h_pYrekLZ2OOd' +``` rs0:PRIMARY> db.adminCommand({ getParameter:1, sslMode:1 }) { "sslMode" : "disabled", @@ -216,7 +223,6 @@ rs0:PRIMARY> db.adminCommand({ getParameter:1, sslMode:1 }) }, "operationTime" : Timestamp(1615468344, 1) } -``` We can verify from the above output that TLS is disabled for this database. @@ -227,23 +233,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 mongo-ca \ +kubectl create secret tls mongo-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/mongo-ca created ``` +secret/mongo-ca created Now, Let's create an `Issuer` using the `mongo-ca` secret that we have just created. The `YAML` file looks like this: @@ -261,9 +267,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/mg-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/mg-issuer created ### Create MongoDBOpsRequest @@ -308,25 +314,26 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-add-tls.yaml -mongodbopsrequest.ops.kubedb.com/mops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-add-tls.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CRO, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-add-tls ReconfigureTLS Successful 91s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-add-tls +kubectl describe mongodbopsrequest -n demo mops-add-tls +``` Name: mops-add-tls Namespace: demo Labels: @@ -429,17 +436,16 @@ Events: Normal ResumeDatabase 10s KubeDB Ops-manager operator Resuming MongoDB demo/mg-rs Normal ResumeDatabase 10s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-rs Normal Successful 10s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, Let's exec into a database primary node and find out the username to connect in a mongo shell, ```bash -$ kubectl exec -it mg-rs-2 -n demo bash +kubectl exec -it mg-rs-2 -n demo bash +``` root@mgo-rs-tls-2:/$ ls /var/run/mongodb/tls ca.crt client.pem mongo.pem root@mgo-rs-tls-2:/$ openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -subject -nameopt RFC2253 -noout subject=CN=root,OU=client,O=mongo -``` Now, we can connect using `CN=root,OU=client,O=mongo` as root to connect to the mongo shell of the master pod, @@ -473,10 +479,10 @@ We can see from the above output that, `sslMode` is set to `requireSSL`. So, dat Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it mg-rs-2 -n demo bash +kubectl exec -it mg-rs-2 -n demo bash +``` root@mg-rs-2:/# openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 13:32:20 2021 GMT -``` So, the certificate will expire on this time `Jun 9 13:32:20 2021 GMT`. @@ -507,25 +513,26 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-rotate.yaml -mongodbopsrequest.ops.kubedb.com/mops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-rotate.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CRO, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-rotate ReconfigureTLS Successful 112s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-rotate +kubectl describe mongodbopsrequest -n demo mops-rotate +``` Name: mops-rotate Namespace: demo Labels: @@ -615,15 +622,14 @@ Events: Normal CertificateIssuingSuccessful 2m10s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 25s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 25s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it mg-rs-2 -n demo bash +kubectl exec -it mg-rs-2 -n demo bash +``` root@mg-rs-2:/# openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 16:17:55 2021 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -634,23 +640,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 mongo-new-ca \ +kubectl create secret tls mongo-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/mongo-new-ca created ``` +secret/mongo-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -668,9 +674,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/mg-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/mg-new-issuer created ### Create MongoDBOpsRequest @@ -702,25 +708,26 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-change-issuer.yaml -mongodbopsrequest.ops.kubedb.com/mops-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-change-issuer.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-change-issuer created #### Verify Issuer is changed successfully Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CRO, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-change-issuer ReconfigureTLS Successful 105s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-change-issuer +kubectl describe mongodbopsrequest -n demo mops-change-issuer +``` Name: mops-change-issuer Namespace: demo Labels: @@ -811,15 +818,14 @@ Events: Normal CertificateIssuingSuccessful 2m27s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 42s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 42s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it mg-rs-2 -n demo bash +kubectl exec -it mg-rs-2 -n demo bash +``` root@mgo-rs-tls-2:/$ openssl x509 -in /var/run/mongodb/tls/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -854,25 +860,26 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-remove.yaml -mongodbopsrequest.ops.kubedb.com/mops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure-tls/mops-remove.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-remove created #### Verify TLS Removed Successfully Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CRO, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-remove +kubectl describe mongodbopsrequest -n demo mops-remove +``` Name: mops-remove Namespace: demo Labels: @@ -960,12 +967,12 @@ Events: Normal ResumeDatabase 35s KubeDB Ops-manager operator Resuming MongoDB demo/mg-rs Normal ResumeDatabase 35s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-rs Normal Successful 35s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, Let's exec into the database primary node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo mg-rs-1 -- mongosh admin -u root -p 'U6(h_pYrekLZ2OOd' +kubectl exec -it -n demo mg-rs-1 -- mongosh admin -u root -p 'U6(h_pYrekLZ2OOd' +``` rs0:PRIMARY> db.adminCommand({ getParameter:1, sslMode:1 }) { "sslMode" : "disabled", @@ -979,7 +986,6 @@ rs0:PRIMARY> db.adminCommand({ getParameter:1, sslMode:1 }) }, "operationTime" : Timestamp(1615480817, 1) } -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/mongodb/reconfigure/replicaset.md b/docs/guides/mongodb/reconfigure/replicaset.md index 2fa8a51004..e2f13966ea 100644 --- a/docs/guides/mongodb/reconfigure/replicaset.md +++ b/docs/guides/mongodb/reconfigure/replicaset.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -57,9 +57,9 @@ Here, `maxIncomingConnections` is set to `10000`, whereas the default value is ` Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf -secret/mg-custom-config created +kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf ``` +secret/mg-custom-config created In this section, we are going to create a MongoDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MongoDB` CR that we are going to create, @@ -89,33 +89,36 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-replicaset-config.yaml -mongodb.kubedb.com/mg-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-replicaset-config.yaml ``` +mongodb.kubedb.com/mg-replicaset created Now, wait until `mg-replicaset` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-replicaset 4.4.26 Ready 19m -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mongodb instance, ```bash -$ kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now let's connect to a mongodb instance and run a mongodb internal command to check the configuration we have provided. ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -163,7 +166,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS }, "operationTime" : Timestamp(1614668500, 1) } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been set to `10000`. @@ -182,9 +184,9 @@ net: Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf ``` +secret/new-custom-config created #### Create MongoDBOpsRequest @@ -222,9 +224,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-replicaset created #### Verify the new configuration is working @@ -233,16 +235,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-replicaset Reconfigure Successful 113s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-replicaset +kubectl describe mongodbopsrequest -n demo mops-reconfigure-replicaset +``` Name: mops-reconfigure-replicaset Namespace: demo Labels: @@ -350,12 +353,12 @@ Events: Normal ResumeDatabase 65s KubeDB Ops-manager operator Resuming MongoDB demo/mg-replicaset Normal ResumeDatabase 65s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 65s KubeDB Ops-manager operator Successfully Reconfigured Database -``` Now let's connect to a mongodb instance and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -403,7 +406,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS }, "operationTime" : Timestamp(1614668887, 1) } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been changed from `10000` to `20000`. So the reconfiguration of the database is successful. @@ -450,9 +452,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-replicaset created #### Verify the new configuration is working @@ -461,16 +463,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-apply-replicaset Reconfigure Successful 109s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-replicaset +kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-replicaset +``` Name: mops-reconfigure-apply-replicaset Namespace: demo Labels: @@ -577,12 +580,12 @@ Events: Normal ResumeDatabase 7m45s KubeDB Ops-manager operator Resuming MongoDB demo/mg-replicaset Normal ResumeDatabase 7m45s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 7m45s KubeDB Ops-manager operator Successfully Reconfigured Database -``` Now let's connect to a mongodb instance and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -630,7 +633,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS }, "operationTime" : Timestamp(1614669580, 1) } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been changed from `20000` to `30000`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/mongodb/reconfigure/sharding.md b/docs/guides/mongodb/reconfigure/sharding.md index cc81d3d992..15f3203950 100644 --- a/docs/guides/mongodb/reconfigure/sharding.md +++ b/docs/guides/mongodb/reconfigure/sharding.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -57,9 +57,9 @@ Here, `maxIncomingConnections` is set to `10000`, whereas the default value is ` Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf -secret/mg-custom-config created +kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf ``` +secret/mg-custom-config created In this section, we are going to create a MongoDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MongoDB` CR that we are going to create, @@ -100,33 +100,36 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-shard-config.yaml -mongodb.kubedb.com/mg-sharding created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-shard-config.yaml ``` +mongodb.kubedb.com/mg-sharding created Now, wait until `mg-sharding` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sharding 4.4.26 Ready 3m23s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mongodb instance, ```bash -$ kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.password}' | base64 -d -Dv8F55zVNiEkhHM6 +```bash +kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.password}' | base64 -d ``` +Dv8F55zVNiEkhHM6 Now let's connect to a mongodb instance from each type of nodes and run a mongodb internal command to check the configuration we have provided. ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -137,7 +140,9 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55 } } -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -148,7 +153,9 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8 } } -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -158,7 +165,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55 "mode" : "disabled" } } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been set to `10000` in all nodes. @@ -177,9 +183,9 @@ net: Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf ``` +secret/new-custom-config created #### Create MongoDBOpsRequest @@ -227,9 +233,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-shard created #### Verify the new configuration is working @@ -238,23 +244,23 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-shard Reconfigure Successful 3m8s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-shard - +kubectl describe mongodbopsrequest -n demo mops-reconfigure-shard ``` Now let's connect to a mongodb instance from each type of nodes and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "0.0.0.0", "maxIncomingConnections" : 20000, @@ -264,7 +270,9 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55 } } -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "0.0.0.0", "maxIncomingConnections" : 20000, @@ -274,7 +282,9 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8 } } -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "0.0.0.0", "maxIncomingConnections" : 20000, @@ -283,7 +293,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55 "mode" : "disabled" } } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been changed from `10000` to `20000` in all type of nodes. So the reconfiguration of the database is successful. @@ -343,9 +352,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-shard created #### Verify the new configuration is working @@ -354,16 +363,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-apply-shard Reconfigure Successful 3m24s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-shard +kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-shard +``` Name: mops-reconfigure-apply-shard Namespace: demo Labels: @@ -520,12 +530,12 @@ Events: Normal ResumeDatabase 8m12s KubeDB Ops-manager operator Resuming MongoDB demo/mg-sharding Normal ResumeDatabase 8m12s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-sharding Normal Successful 8m12s KubeDB Ops-manager operator Successfully Reconfigured Database -``` Now let's connect to a mongodb instance from each type of nodes and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -536,7 +546,9 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p Dv8F55 } } -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -547,7 +559,9 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p Dv8 } } -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +```bash +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55zVNiEkhHM6 --eval "db._adminCommand( {getCmdLineOpts: 1}).parsed.net" --quiet +``` { "bindIp" : "*", "ipv6" : true, @@ -557,7 +571,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p Dv8F55 "mode" : "disabled" } } -``` As we can see from the configuration of ready mongodb, the value of `maxIncomingConnections` has been changed from `20000` to `30000` in all nodes. So the reconfiguration of the database using the data field is successful. diff --git a/docs/guides/mongodb/reconfigure/standalone.md b/docs/guides/mongodb/reconfigure/standalone.md index 43586849e2..2ed09f8e46 100644 --- a/docs/guides/mongodb/reconfigure/standalone.md +++ b/docs/guides/mongodb/reconfigure/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -56,9 +56,9 @@ Here, `maxIncomingConnections` is set to `10000`, whereas the default value is ` Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf -secret/mg-custom-config created +kubectl create secret generic -n demo mg-custom-config --from-file=./mongod.conf ``` +secret/mg-custom-config created In this section, we are going to create a MongoDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MongoDB` CR that we are going to create, @@ -85,33 +85,36 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-standalone-config.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mg-standalone-config.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 4.4.26 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mongodb instance, ```bash -$ kubectl get secrets -n demo mg-standalone-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-standalone-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-standalone-auth -o jsonpath='{.data.password}' | base64 -d -m6lXjZugrC4VEpB8 +```bash +kubectl get secrets -n demo mg-standalone-auth -o jsonpath='{.data.password}' | base64 -d ``` +m6lXjZugrC4VEpB8 Now let's connect to a mongodb instance and run a mongodb internal command to check the configuration we have provided. ```bash -$ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -143,7 +146,6 @@ $ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4 }, "ok" : 1 } -``` As we can see from the configuration of running mongodb, the value of `maxIncomingConnections` has been set to `10000`. @@ -162,9 +164,9 @@ net: Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./mongod.conf ``` +secret/new-custom-config created #### Create MongoDBOpsRequest @@ -201,9 +203,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-standalone.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-standalone.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-standalone created #### Verify the new configuration is working @@ -212,16 +214,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-standalone Reconfigure Successful 10m -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-standalone +kubectl describe mongodbopsrequest -n demo mops-reconfigure-standalone +``` Name: mops-reconfigure-standalone Namespace: demo Labels: @@ -329,12 +332,12 @@ Events: Normal ResumeDatabase 35s KubeDB Ops-manager operator Resuming MongoDB demo/mg-standalone Normal ResumeDatabase 35s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-standalone Normal Successful 35s KubeDB Ops-manager operator Successfully Reconfigured Database -``` Now let's connect to a mongodb instance and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -366,7 +369,6 @@ $ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4 }, "ok" : 1 } -``` As we can see from the configuration of running mongodb, the value of `maxIncomingConnections` has been changed from `10000` to `20000`. So the reconfiguration of the database is successful. @@ -411,9 +413,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-standalone.yaml -mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reconfigure/mops-reconfigure-apply-standalone.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-reconfigure-apply-standalone created #### Verify the new configuration is working @@ -422,16 +424,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-reconfigure-apply-standalone Reconfigure Successful 38s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-standalone +kubectl describe mongodbopsrequest -n demo mops-reconfigure-apply-standalone +``` Name: mops-reconfigure-apply-standalone Namespace: demo Labels: @@ -538,12 +541,12 @@ Events: Normal ResumeDatabase 93s KubeDB Ops-manager operator Resuming MongoDB demo/mg-standalone Normal ResumeDatabase 93s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-standalone Normal Successful 93s KubeDB Ops-manager operator Successfully Reconfigured Database -``` Now let's connect to a mongodb instance and run a mongodb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4VEpB8 --eval "db._adminCommand( {getCmdLineOpts: 1})" --quiet +``` { "argv" : [ "mongod", @@ -575,7 +578,6 @@ $ kubectl exec -n demo mg-standalone-0 -- mongosh admin -u root -p m6lXjZugrC4 }, "ok" : 1 } -``` As we can see from the configuration of running mongodb, the value of `maxIncomingConnections` has been changed from `20000` to `30000`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/mongodb/reprovision/reprovision.md b/docs/guides/mongodb/reprovision/reprovision.md index c3c9a538e1..7bcfaba9c6 100644 --- a/docs/guides/mongodb/reprovision/reprovision.md +++ b/docs/guides/mongodb/reprovision/reprovision.md @@ -24,10 +24,10 @@ KubeDB supports reprovisioning the MongoDB database via a MongoDBOpsRequest. Rep - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo + ```bash + kubectl create ns demo + ``` namespace/demo created -``` > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -86,9 +86,9 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reprovision/mongo.yaml -mongodb.kubedb.com/mongo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reprovision/mongo.yaml ``` +mongodb.kubedb.com/mongo created ## Apply Reprovision opsRequest @@ -114,9 +114,9 @@ spec: Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reprovision/ops.yaml -mongodbopsrequest.ops.kubedb.com/repro created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/reprovision/ops.yaml ``` +mongodbopsrequest.ops.kubedb.com/repro created Now the Ops-manager operator will 1) Pause the DB @@ -125,13 +125,15 @@ Now the Ops-manager operator will 4) Reconcile the db for start 5) Wait for DB to be Ready. -```shell -$ kubectl get mgops -n demo +```bash +kubectl get mgops -n demo +``` NAME TYPE STATUS AGE repro Reprovision Successful 2m - -$ kubectl get mgops -n demo -oyaml repro +```bash +kubectl get mgops -n demo -oyaml repro +``` apiVersion: ops.kubedb.com/v1alpha1 kind: MongoDBOpsRequest metadata: @@ -177,7 +179,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/mongodb/restart/restart.md b/docs/guides/mongodb/restart/restart.md index bf74bf49bc..46c79a48c7 100644 --- a/docs/guides/mongodb/restart/restart.md +++ b/docs/guides/mongodb/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the MongoDB database via a MongoDBOpsRequest. Restart - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -86,9 +86,9 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/restart/mongo.yaml -mongodb.kubedb.com/mongo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/restart/mongo.yaml ``` +mongodb.kubedb.com/mongo created ## Apply Restart opsRequest @@ -118,18 +118,21 @@ spec: Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/restart/ops.yaml -mongodbopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/restart/ops.yaml ``` +mongodbopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the general secondary pods, then serially the arbiters, the hidden nodes, & lastly will restart the Primary of the database. -```shell -$ kubectl get mgops -n demo +```bash +kubectl get mgops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 10m -$ kubectl get mgops -n demo -oyaml restart +```bash +kubectl get mgops -n demo -oyaml restart +``` apiVersion: ops.kubedb.com/v1alpha1 kind: MongoDBOpsRequest metadata: @@ -173,7 +176,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/mongodb/rotate-auth/rotateauth.md b/docs/guides/mongodb/rotate-auth/rotateauth.md index 3ef9316df5..00325a3dc7 100644 --- a/docs/guides/mongodb/rotate-auth/rotateauth.md +++ b/docs/guides/mongodb/rotate-auth/rotateauth.md @@ -31,9 +31,9 @@ existing secret with the new credential The KubeDB operator automatically genera - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Create a MongoDB database KubeDB implements a MongoDB CRD to define the specification of a MongoDB database. @@ -64,25 +64,25 @@ spec: Command: -```shell -$ kubectl apply -f mongodb.yaml -mongodb.kubedb.com/mgo-quickstart created +```bash +kubectl apply -f mongodb.yaml ``` +mongodb.kubedb.com/mgo-quickstart created Or, you can deploy by using command: -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/quickstart/replicaset-v1alpha2.yaml -mongodb.kubedb.com/mgo-quickstart created +```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/quickstart/replicaset-v1alpha2.yaml ``` +mongodb.kubedb.com/mgo-quickstart created Now, wait until mgo-quickstart has status Ready. i.e, -```shell -$ kubectl get mg -n demo -w +```bash +kubectl get mg -n demo -w +``` NAME VERSION STATUS AGE mgo-quickstart 4.4.26 Ready 8m1s -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the secret. @@ -95,8 +95,9 @@ $ kubectl get secret -n demo mgo-quickstart-auth -o=jsonpath='{.data.password}' eR*W_mz6bjyZxeiG⏎ ```` Now, you can exec into the pod `mgo-quickstart` and connect to database using `username` and `password` -```shell -$ kubectl exec -it -n demo mgo-quickstart-0 -- bash +```bash +kubectl exec -it -n demo mgo-quickstart-0 -- bash +``` Defaulted container "mongodb" out of: mongodb, replication-mode-detector, copy-config (init) mongodb@mgo-quickstart-0:/$ mongosh -u root -p $MONGO_INITDB_ROOT_PASSWORD MongoDB shell version v4.4.26 @@ -115,8 +116,6 @@ The server generated these startup warnings when booting: --- rs1:SECONDARY> use Mohiniyattam switched to db Mohiniyattam - -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth MongoDBOpsRequest @@ -142,19 +141,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on MongoDB. Let's create the `MongoDBOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/rotate-auth/rotate-auth-generated.yaml + ``` mongodbopsrequest.ops.kubedb.com/mgops-rotate-auth-generated created -``` Let's wait for `MongoDBOpsrequest` to be `Successful`. Run the following command to watch `MongoDBOpsrequest` CRO -```shell - $kubectl get mongodbopsrequest -n demo + ```bash + kubectl get mongodbopsrequest -n demo + ``` NAME TYPE STATUS AGE mgops-rotate-auth-generated RotateAuth Successful 45m -``` If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe mongodbopsrequest -n demo mgops-rotate-auth-generated +```bash +kubectl describe mongodbopsrequest -n demo mgops-rotate-auth-generated +``` Name: mgops-rotate-auth-generated Namespace: demo Labels: @@ -291,37 +291,44 @@ Events: Normal ResumeDatabase 43m KubeDB Ops-manager Operator Resuming MongoDB demo/mgo-quickstart Normal ResumeDatabase 43m KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mgo-quickstart Normal Successful 43m KubeDB Ops-manager Operator Successfully Rotate Auth - -``` **Verify Auth is rotated** -```shell -$ kubectl get mg -n demo mgo-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get mg -n demo mgo-quickstart -ojson | jq .spec.authSecret.name +``` "mgo-quickstart-auth" -$ kubectl get secret -n demo mgo-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo mgo-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mgo-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d -09wZM.)t8kpwKF5z⏎ + +```bash +kubectl get secret -n demo mgo-quickstart-auth -o=jsonpath='{.data.password}' | base64 -d ``` +09wZM.)t8kpwKF5z⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo mgo-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo mgo-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mgo-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -eR*W_mz6bjyZxeiG⏎ + +```bash +kubectl get secret -n demo mgo-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +eR*W_mz6bjyZxeiG⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > Note: `Username` must be `root` -```shell -$ kubectl create secret generic quick-mg-user-auth -n demo \ +```bash + kubectl create secret generic quick-mg-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=root \ --from-literal=password=mongodb-secret -secret/quick-mg-user-auth created ``` +secret/quick-mg-user-auth created Now create a `MongoDBOpsRequest` with `RotateAuth` type. Below is the YAML of the `MongoDBOpsRequest` that we are going to create, ```shell @@ -349,21 +356,22 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/rotate-auth/rotate-auth-user.yaml -mongodbopsrequest.ops.kubedb.com/mgops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mongodb/rotate-auth/rotate-auth-user.yaml ``` +mongodbopsrequest.ops.kubedb.com/mgops-rotate-auth-user created Let’s wait for `MongoDBOpsRequest` to be Successful. Run the following command to watch `MongoDBOpsRequest` CRO: -```shell -$ kubectl get mongodbopsrequest -n demo +```bash +kubectl get mongodbopsrequest -n demo +``` NAME TYPE STATUS AGE mgops-rotate-auth-generated RotateAuth Successful 153m mgops-rotate-auth-user RotateAuth Successful 59m -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe mgops -n demo mgops-rotate-auth-user +```bash +kubectl describe mgops -n demo mgops-rotate-auth-user +``` Name: mgops-rotate-auth-user Namespace: demo Labels: @@ -501,24 +509,31 @@ Events: Normal ResumeDatabase 5m21s KubeDB Ops-manager Operator Resuming MongoDB demo/mgo-quickstart Normal ResumeDatabase 5m21s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mgo-quickstart Normal Successful 5m21s KubeDB Ops-manager Operator Successfully Rotate Auth - -``` **Verify auth is rotate** -```shell -$ kubectl get mg -n demo mgo-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get mg -n demo mgo-quickstart -ojson | jq .spec.authSecret.name +``` "quick-mg-user-auth" -$ kubectl get secret -n demo quick-mg-user-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo quick-mg-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo quick-mg-user-auth -o=jsonpath='{.data.password}' | base64 -d -mongodb-secret⏎ + +```bash +kubectl get secret -n demo quick-mg-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +mongodb-secret⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo quick-mg-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo quick-mg-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo quick-mg-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -09wZM.)t8kpwKF5z⏎ + +```bash +kubectl get secret -n demo quick-mg-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +09wZM.)t8kpwKF5z⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -527,14 +542,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete mongodbopsrequest mgops-rotate-auth-generated mgops-rotate-auth-user -n demo +```bash +kubectl delete mongodbopsrequest mgops-rotate-auth-generated mgops-rotate-auth-user -n demo +``` mongodbopsrequest.ops.kubedb.com "mgops-rotate-auth-generated" "mgops-rotate-auth-user" deleted -$ kubectl delete secret -n demo quick-mg-user-auth + +```bash +kubectl delete secret -n demo quick-mg-user-auth +``` secret "quick-mg-user-auth" deleted -$ kubectl delete secret -n demo mgo-quickstart-auth -secret "mgo-quickstart-auth" deleted + +```bash +kubectl delete secret -n demo mgo-quickstart-auth ``` +secret "mgo-quickstart-auth" deleted ## Next Steps diff --git a/docs/guides/mongodb/scaling/horizontal-scaling/replicaset.md b/docs/guides/mongodb/scaling/horizontal-scaling/replicaset.md index 333254e1a7..5aa67d44e3 100644 --- a/docs/guides/mongodb/scaling/horizontal-scaling/replicaset.md +++ b/docs/guides/mongodb/scaling/horizontal-scaling/replicaset.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,27 +73,29 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-replicaset.yaml -mongodb.kubedb.com/mg-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-replicaset.yaml ``` +mongodb.kubedb.com/mg-replicaset created Now, wait until `mg-replicaset` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-replicaset 4.4.26 Ready 2m36s -``` Let's check the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' ``` +3 We can see from both command that the database has 3 replicas in the replicaset. @@ -101,17 +103,20 @@ Also, we can verify the replicas of the replicaset from an internal mongodb comm First we need to get the username and password to connect to a mongodb instance, ```bash -$ kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo mg-replicaset-auth -o jsonpath='{.data.password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -190,7 +195,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS "configVersion" : 3 } ] -``` We can see from the above output that the replicaset has 3 nodes. @@ -227,9 +231,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-up-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-hscale-up-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-up-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-hscale-up-replicaset created #### Verify Replicaset replicas scaled up successfully @@ -238,16 +242,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-hscale-up-replicaset HorizontalScaling Successful 106s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-hscale-up-replicaset +kubectl describe mongodbopsrequest -n demo mops-hscale-up-replicaset +``` Name: mops-hscale-up-replicaset Namespace: demo Labels: @@ -328,21 +333,23 @@ Events: Normal ResumeDatabase 45s KubeDB Ops-manager operator Resuming MongoDB demo/mg-replicaset Normal ResumeDatabase 45s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 45s KubeDB Ops-manager operator Successfully Horizontally Scaled Database -``` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +``` 4 -$ kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' -4 +```bash +kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' ``` +4 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -448,7 +455,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS "configVersion" : 4 } ] -``` From all the above outputs we can see that the replicas of the replicaset is `4`. That means we have successfully scaled up the replicas of the MongoDB replicaset. @@ -484,9 +490,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-down-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-hscale-down-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-down-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-hscale-down-replicaset created #### Verify Replicaset replicas scaled down successfully @@ -495,16 +501,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-hscale-down-replicaset HorizontalScaling Successful 2m32s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-hscale-down-replicaset +kubectl describe mongodbopsrequest -n demo mops-hscale-down-replicaset +``` Name: mops-hscale-down-replicaset Namespace: demo Labels: @@ -585,21 +592,23 @@ Events: Normal ResumeDatabase 30s KubeDB Ops-manager operator Resuming MongoDB demo/mg-replicaset Normal ResumeDatabase 30s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 30s KubeDB Ops-manager operator Successfully Horizontally Scaled Database -``` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +kubectl get mongodb -n demo mg-replicaset -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-replicaset -o json | jq '.spec.replicas' ``` +3 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDSMrgwy --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -678,7 +687,6 @@ $ kubectl exec -n demo mg-replicaset-0 -- mongosh admin -u root -p nrKuxni0wDS "configVersion" : 5 } ] -``` From all the above outputs we can see that the replicas of the replicaset is `3`. That means we have successfully scaled down the replicas of the MongoDB replicaset. diff --git a/docs/guides/mongodb/scaling/horizontal-scaling/sharding.md b/docs/guides/mongodb/scaling/horizontal-scaling/sharding.md index 2db5b9b0b6..a3e9458af5 100644 --- a/docs/guides/mongodb/scaling/horizontal-scaling/sharding.md +++ b/docs/guides/mongodb/scaling/horizontal-scaling/sharding.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the s To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,45 +80,49 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-shard.yaml -mongodb.kubedb.com/mg-sharding created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-shard.yaml ``` +mongodb.kubedb.com/mg-sharding created Now, wait until `mg-sharding` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sharding 4.4.26 Ready 10m -``` ##### Verify Number of Shard and Shard Replicas Let's check the number of shards this database from the MongoDB object and the number of petsets it has, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +``` 2 -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mg-sharding-configsvr 3/3 23m mg-sharding-mongos 2/2 22m mg-sharding-shard0 3/3 23m mg-sharding-shard1 3/3 23m -``` So, We can see from the both output that the database has 2 shards. Now, Let's check the number of replicas each shard has from the MongoDB object and the number of pod the petsets have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +``` 3 -$ kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' ``` +3 We can see from both output that the database has 3 replicas in each shards. @@ -126,17 +130,20 @@ Also, we can verify the number of shard from an internal mongodb command by exec First we need to get the username and password to connect to a mongos instance, ```bash -$ kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.password}' | base64 -d -xBC-EwMFivFCgUlK +```bash +kubectl get secrets -n demo mg-sharding-auth -o jsonpath='{.data.password}' | base64 -d ``` +xBC-EwMFivFCgUlK Now let's connect to a mongos instance and run a mongodb internal command to check the number of shards, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -159,7 +166,6 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew No recent migrations databases: { "_id" : "config", "primary" : "config", "partitioned" : true } -``` We can see from the above output that the number of shard is 2. @@ -168,7 +174,8 @@ Also, we can verify the number of replicas each shard has from an internal mongo Now let's connect to a shard instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -247,7 +254,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-Ew "configVersion" : 3 } ] -``` We can see from the above output that the number of replica is 3. @@ -256,19 +262,22 @@ We can see from the above output that the number of replica is 3. Let's check the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +``` 3 -$ kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' ``` +3 We can see from both command that the database has `3` replicas in the configServer. Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -347,7 +356,6 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC "configVersion" : 3 } ] -``` We can see from the above output that the configServer has 3 nodes. @@ -355,19 +363,22 @@ We can see from the above output that the configServer has 3 nodes. Let's check the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +``` 2 -$ kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' ``` +2 We can see from both command that the database has `2` replicas in the mongos. Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -390,7 +401,6 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew No recent migrations databases: { "_id" : "config", "primary" : "config", "partitioned" : true } -``` We can see from the above output that the mongos has 2 active nodes. @@ -438,9 +448,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-up-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-hscale-up-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-up-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-hscale-up-shard created #### Verify scaling up is successful @@ -449,16 +459,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the shard and Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-hscale-up-shard HorizontalScaling Successful 9m57s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-hscale-up-shard +kubectl describe mongodbopsrequest -n demo mops-hscale-up-shard +``` Name: mops-hscale-up-shard Namespace: demo Labels: @@ -583,28 +594,30 @@ Events: Normal ResumeDatabase 36s KubeDB Ops-manager operator Resuming MongoDB demo/mg-sharding Normal ResumeDatabase 36s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-sharding Normal Successful 36s KubeDB Ops-manager operator Successfully Horizontally Scaled Database -``` #### Verify Number of Shard and Shard Replicas Now, we are going to verify the number of shards this database has from the MongoDB object, number of petsets it has, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +``` 3 -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mg-sharding-configsvr 4/4 66m mg-sharding-mongos 3/3 64m mg-sharding-shard0 4/4 66m mg-sharding-shard1 4/4 66m mg-sharding-shard2 4/4 12m -``` Now let's connect to a mongos instance and run a mongodb internal command to check the number of shards, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -637,23 +650,25 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew chunks: shard0 1 { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0 Timestamp(1, 0) -``` From all the above outputs we can see that the number of shards are `3`. Now, we are going to verify the number of replicas each shard has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +``` 4 -$ kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' -4 +```bash +kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' ``` +4 Now let's connect to a shard instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -759,7 +774,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-Ew "configVersion" : 4 } ] -``` From all the above outputs we can see that the replicas of each shard has is `4`. @@ -767,16 +781,19 @@ From all the above outputs we can see that the replicas of each shard has is `4` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +``` 4 -$ kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' -4 +```bash +kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' ``` +4 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -882,7 +899,6 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC "configVersion" : 4 } ] -``` From all the above outputs we can see that the replicas of the configServer is `3`. That means we have successfully scaled up the replicas of the MongoDB configServer replicas. @@ -890,16 +906,19 @@ From all the above outputs we can see that the replicas of the configServer is ` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +``` 3 -$ kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' ``` +3 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -932,7 +951,6 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew chunks: shard0 1 { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0 Timestamp(1, 0) -``` From all the above outputs we can see that the replicas of the mongos is `3`. That means we have successfully scaled up the replicas of the MongoDB mongos replicas. @@ -981,9 +999,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-down-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-hscale-down-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/horizontal-scaling/mops-hscale-down-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-hscale-down-shard created #### Verify scaling down is successful @@ -992,16 +1010,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the shards an Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ watch kubectl get mongodbopsrequest -n demo +watch kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-hscale-down-shard HorizontalScaling Successful 81s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale down the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-hscale-down-shard +kubectl describe mongodbopsrequest -n demo mops-hscale-down-shard +``` Name: mops-hscale-down-shard Namespace: demo Labels: @@ -1126,27 +1145,29 @@ Events: Normal ResumeDatabase 4m6s KubeDB Ops-manager operator Resuming MongoDB demo/mg-sharding Normal ResumeDatabase 4m6s KubeDB Ops-manager operator Successfully resumed MongoDB demo/mg-sharding Normal Successful 4m6s KubeDB Ops-manager operator Successfully Horizontally Scaled Database -``` ##### Verify Number of Shard and Shard Replicas Now, we are going to verify the number of shards this database has from the MongoDB object, number of petsets it has, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.shards' +``` 2 -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mg-sharding-configsvr 3/3 77m mg-sharding-mongos 2/2 75m mg-sharding-shard0 3/3 77m mg-sharding-shard1 3/3 77m -``` Now let's connect to a mongos instance and run a mongodb internal command to check the number of shards, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -1178,23 +1199,25 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew chunks: shard0 1 { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0 Timestamp(1, 0) -``` From all the above outputs we can see that the number of shards are `2`. Now, we are going to verify the number of replicas each shard has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.shard.replicas' +``` 3 -$ kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.replicas' ``` +3 Now let's connect to a shard instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -1273,7 +1296,6 @@ $ kubectl exec -n demo mg-sharding-shard0-0 -- mongosh admin -u root -p xBC-Ew "configVersion" : 5 } ] -``` From all the above outputs we can see that the replicas of each shard has is `3`. @@ -1282,16 +1304,19 @@ From all the above outputs we can see that the replicas of each shard has is `3` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.configServer.replicas' +``` 3 -$ kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.replicas' ``` +3 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "db.adminCommand( { replSetGetStatus : 1 } ).members" --quiet +``` [ { "_id" : 0, @@ -1370,7 +1395,6 @@ $ kubectl exec -n demo mg-sharding-configsvr-0 -- mongosh admin -u root -p xBC "configVersion" : 5 } ] -``` From all the above outputs we can see that the replicas of the configServer is `3`. That means we have successfully scaled down the replicas of the MongoDB configServer replicas. @@ -1379,16 +1403,19 @@ From all the above outputs we can see that the replicas of the configServer is ` Now, we are going to verify the number of replicas this database has from the MongoDB object, number of pods the petset have, ```bash -$ kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +kubectl get mongodb -n demo mg-sharding -o json | jq '.spec.shardTopology.mongos.replicas' +``` 2 -$ kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo mg-sharding-mongos -o json | jq '.spec.replicas' ``` +2 Now let's connect to a mongodb instance and run a mongodb internal command to check the number of replicas, ```bash -$ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-EwMFivFCgUlK --eval "sh.status()" --quiet +``` --- Sharding Status --- sharding version: { "_id" : 1, @@ -1420,7 +1447,6 @@ $ kubectl exec -n demo mg-sharding-mongos-0 -- mongosh admin -u root -p xBC-Ew chunks: shard0 1 { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard0 Timestamp(1, 0) -``` From all the above outputs we can see that the replicas of the mongos is `2`. That means we have successfully scaled down the replicas of the MongoDB mongos replicas. diff --git a/docs/guides/mongodb/scaling/vertical-scaling/replicaset.md b/docs/guides/mongodb/scaling/vertical-scaling/replicaset.md index ec0988c5b5..ca315de0bf 100644 --- a/docs/guides/mongodb/scaling/vertical-scaling/replicaset.md +++ b/docs/guides/mongodb/scaling/vertical-scaling/replicaset.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,22 +73,23 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-replicaset.yaml -mongodb.kubedb.com/mg-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-replicaset.yaml ``` +mongodb.kubedb.com/mg-replicaset created Now, wait until `mg-replicaset` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-replicaset 4.4.26 Ready 3m46s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -99,7 +100,6 @@ $ kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resou "memory": "1Gi" } } -``` You can see the Pod has the default resources which is assigned by KubeDB operator. @@ -150,9 +150,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-vscale-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-vscale-replicaset created #### Verify MongoDB Replicaset resources updated successfully @@ -161,16 +161,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-vscale-replicaset VerticalScaling Successful 3m56s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-vscale-replicaset +kubectl describe mongodbopsrequest -n demo mops-vscale-replicaset +``` Name: mops-vscale-replicaset Namespace: demo Labels: @@ -280,12 +281,11 @@ Events: Normal ResumeDatabase 10s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 10s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` - Now, we are going to verify from one of the Pod yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -296,7 +296,6 @@ $ kubectl get pod -n demo mg-replicaset-0 -o json | jq '.spec.containers[].resou "memory": "1288490188800m" } } -``` The above output verifies that we have successfully scaled up the resources of the MongoDB replicaset database. diff --git a/docs/guides/mongodb/scaling/vertical-scaling/sharding.md b/docs/guides/mongodb/scaling/vertical-scaling/sharding.md index 42034af839..098ae42e6e 100644 --- a/docs/guides/mongodb/scaling/vertical-scaling/sharding.md +++ b/docs/guides/mongodb/scaling/vertical-scaling/sharding.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,22 +80,23 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-shard.yaml -mongodb.kubedb.com/mg-sharding created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-shard.yaml ``` +mongodb.kubedb.com/mg-sharding created Now, wait until `mg-sharding` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sharding 4.4.26 Ready 8m51s -``` Let's check the Pod containers resources of various components (mongos, shard, configserver etc.) of the database, ```bash -$ kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -107,7 +108,9 @@ $ kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[]. } } -$ kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -119,7 +122,9 @@ $ kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers } } -$ kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -130,7 +135,6 @@ $ kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[]. "memory": "1Gi" } } -``` You can see all the Pod of mongos, configserver and shard has default resources which is assigned by KubeDB operator. @@ -201,9 +205,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-vscale-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-vscale-shard created #### Verify MongoDB Shard resources updated successfully @@ -212,16 +216,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-vscale-shard VerticalScaling Successful 8m21s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-vscale-shard +kubectl describe mongodbopsrequest -n demo mops-vscale-shard +``` Name: mops-vscale-shard Namespace: demo Labels: @@ -384,12 +389,12 @@ Events: Normal ResumeDatabase 29s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-sharding Normal Successful 29s KubeDB Ops-manager Operator Successfully Vertically Scaled Database Normal UpdateShardResources 28s KubeDB Ops-manager Operator Successfully Vertically Scaled Shard Resources -``` Now, we are going to verify from one of the Pod yaml whether the resources of the shard nodes has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "550m", @@ -401,7 +406,9 @@ $ kubectl get pod -n demo mg-sharding-shard0-0 -o json | jq '.spec.containers[]. } } -$ kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "550m", @@ -413,7 +420,9 @@ $ kubectl get pod -n demo mg-sharding-configsvr-0 -o json | jq '.spec.containers } } -$ kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "550m", @@ -424,7 +433,6 @@ $ kubectl get pod -n demo mg-sharding-mongos-0 -o json | jq '.spec.containers[]. "memory": "1100Mi" } } -``` The above output verifies that we have successfully scaled the resources of all components of the MongoDB sharded database. diff --git a/docs/guides/mongodb/scaling/vertical-scaling/standalone.md b/docs/guides/mongodb/scaling/vertical-scaling/standalone.md index 487d7376de..d6d896da7a 100644 --- a/docs/guides/mongodb/scaling/vertical-scaling/standalone.md +++ b/docs/guides/mongodb/scaling/vertical-scaling/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -69,22 +69,23 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-standalone.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/mg-standalone.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 4.4.26 Ready 5m56s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -95,7 +96,6 @@ $ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resou "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -145,9 +145,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-standalone.yaml -mongodbopsrequest.ops.kubedb.com/mops-vscale-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/scaling/vertical-scaling/mops-vscale-standalone.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-vscale-standalone created #### Verify MongoDB Standalone resources updated successfully @@ -156,16 +156,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-vscale-standalone VerticalScaling Successful 108s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-vscale-standalone +kubectl describe mongodbopsrequest -n demo mops-vscale-standalone +``` Name: mops-vscale-standalone Namespace: demo Labels: @@ -276,12 +277,11 @@ Events: Normal ResumeDatabase 3s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-standalone Normal Successful 3s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` - Now, we are going to verify from the Pod yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -292,7 +292,6 @@ $ kubectl get pod -n demo mg-standalone-0 -o json | jq '.spec.containers[].resou "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the MongoDB standalone database. diff --git a/docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/index.md b/docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/index.md index 1543c99344..64b7b66b42 100644 --- a/docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/index.md +++ b/docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/index.md @@ -33,9 +33,9 @@ This guide will show you how to create database with MongoDB Schema Manager usin To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mongodb/schema-manager/deploy-mongodbdatabase/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -98,9 +98,9 @@ Here, Let’s save this yaml configuration into `mongodb.yaml` Then create the above `MongoDB` CR ```bash -$ kubectl apply -f mongodb.yaml -mongodb.kubedb.com/mongodb created +kubectl apply -f mongodb.yaml ``` +mongodb.kubedb.com/mongodb created ### Deploy Vault Server @@ -154,9 +154,9 @@ Here, Let’s save this yaml configuration into `vault.yaml` Then create the above `VaultServer` CR ```bash -$ kubectl apply -f vault.yaml -vaultserver.kubevault.com/vault created +kubectl apply -f vault.yaml ``` +vaultserver.kubevault.com/vault created ### Create Separate Namespace For Schema Manager @@ -174,9 +174,9 @@ metadata: Let’s save this yaml configuration into `namespace.yaml`. Then create the above `Namespace`, ```bash -$ kubectl apply -f namespace.yaml -namespace/dev created +kubectl apply -f namespace.yaml ``` +namespace/dev created ### Deploy Schema Manager @@ -221,18 +221,17 @@ Here, Let’s save this yaml configuration into `mongodb-schema.yaml` and apply it, ```bash -$ kubectl apply -f mongodb-schema.yaml -mongodbdatabase.schema.kubedb.com/mongodb-schema created +kubectl apply -f mongodb-schema.yaml ``` +mongodbdatabase.schema.kubedb.com/mongodb-schema created Let's check the `STATUS` of `Schema Manager`, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE dev mongodb-schema mongodb emptydb Current 54s - -``` Here, > In `STATUS` section, `Current` means that the current `Secret` of `Schema Manager` is vaild, and it will automatically `Expired` after it reaches the limit of `defaultTTL` that we've defined in the above yaml. @@ -240,20 +239,23 @@ Here, Now, let's get the secret name from `schema-manager`, and get the login credentials for connecting to the database, ```bash -$ kubectl get mongodbdatabase mongodb-schema -n dev -o=jsonpath='{.status.authSecret.name}' +kubectl get mongodbdatabase mongodb-schema -n dev -o=jsonpath='{.status.authSecret.name}' +``` mongodb-schema-mongo-req-fybh8z -$ kubectl view-secret -n dev mongodb-schema-mongo-req-fybh8z -a +```bash +kubectl view-secret -n dev mongodb-schema-mongo-req-fybh8z -a +``` password=u-kDmBcMITz9dLrZ7cAL username=v-kubernetes-demo-k8s-f7695915-1e-0NV83LXHuGMiittiObYE-1662635657 -``` ### Insert Sample Data Here, we are going to connect to the database with the login credentials and insert some sample data into it. ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=emptydb --username='v-kubernetes-demo-k8s-f7695915-1e-0NV83LXHuGMiittiObYE-1662635657' --password='u-kDmBcMITz9dLrZ7cAL' emptydb MongoDB shell version v4.4.26 ... @@ -270,21 +272,20 @@ replicaset:PRIMARY> db.product.find().pretty() replicaset:PRIMARY> exit bye -``` - Now, Let's check the `STATUS` of `Schema Manager` again, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE dev mongodb-schema mongodb emptydb Expired 6m -``` Here, we can see that the `STATUS` of the `schema-manager` is `Expired` because it's exceeded `defaultTTL: "5m"`, which means the current `Secret` of `Schema Manager` isn't vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from `schema-manager`, it won't work. ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=emptydb --username='v-kubernetes-demo-k8s-f7695915-1e-0NV83LXHuGMiittiObYE-1662635657' --password='u-kDmBcMITz9dLrZ7cAL' emptydb MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/emptydb?authSource=emptydb&compressors=disabled&gssapiServiceName=mongodb @@ -295,7 +296,6 @@ exception: connect failed exiting with code 1 root@mongodb-0:/# exit exit -``` > Note: We can't connect to the database with the login credentials, which is `Expired`. We will not be able to access the database even though we're in the middle of a connected session. And when the `Schema Manager` is deleted, the associated database and user will also be deleted. @@ -304,8 +304,11 @@ exit To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete ns dev -$ kubectl delete ns demo +kubectl delete ns dev +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mongodb/schema-manager/initializing-with-script/index.md b/docs/guides/mongodb/schema-manager/initializing-with-script/index.md index ad7e521600..bba4a7980e 100644 --- a/docs/guides/mongodb/schema-manager/initializing-with-script/index.md +++ b/docs/guides/mongodb/schema-manager/initializing-with-script/index.md @@ -33,9 +33,9 @@ This guide will show you how to to create database and initialize script with Mo To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mongodb/schema-manager/initializing-with-script/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mongodb/schema-manager/initializing-with-script/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -98,9 +98,9 @@ Here, Let’s save this yaml configuration into `mongodb.yaml` Then create the above `MongoDB` CR ```bash -$ kubectl apply -f mongodb.yaml -mongodb.kubedb.com/mongodb created +kubectl apply -f mongodb.yaml ``` +mongodb.kubedb.com/mongodb created ### Deploy Vault Server @@ -154,9 +154,9 @@ Here, Let’s save this yaml configuration into `vault.yaml` Then create the above `VaultServer` CR ```bash -$ kubectl apply -f vault.yaml -vaultserver.kubevault.com/vault created +kubectl apply -f vault.yaml ``` +vaultserver.kubevault.com/vault created ### Create Separate Namespace For Schema Manager @@ -174,9 +174,9 @@ metadata: Let’s save this yaml configuration into `namespace.yaml`. Then create the above `Namespace`, ```bash -$ kubectl apply -f namespace.yaml -namespace/dev created +kubectl apply -f namespace.yaml ``` +namespace/dev created ### Script with ConfigMap @@ -194,9 +194,9 @@ data: ``` ```bash -$ kubectl apply -f test-script.yaml -configmap/test-script created +kubectl apply -f test-script.yaml ``` +configmap/test-script created ### Deploy Schema Manager Initialize with Script @@ -264,17 +264,17 @@ Here, Let’s save this yaml configuration into `sample-script.yaml` and apply it, ```bash -$ kubectl apply -f sample-script.yaml -mongodbdatabase.schema.kubedb.com/sample-script created +kubectl apply -f sample-script.yaml ``` +mongodbdatabase.schema.kubedb.com/sample-script created Let's check the `STATUS` of `Schema Manager`, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE dev sample-script mongodb initdb Current 56s -``` Here, > In `STATUS` section, `Current` means that the current `Secret` of `Schema Manager` is vaild, and it will automatically `Expired` after it reaches the limit of `defaultTTL` that we've defined in the above yaml. @@ -282,20 +282,23 @@ Here, Now, let's get the secret name from `schema-manager`, and get the login credentials for connecting to the database, ```bash -$ kubectl get mongodbdatabase sample-script -n dev -o=jsonpath='{.status.authSecret.name}' +kubectl get mongodbdatabase sample-script -n dev -o=jsonpath='{.status.authSecret.name}' +``` sample-script-mongo-req-98k0ch -$ kubectl view-secret -n dev sample-script-mongo-req-98k0ch -a +```bash +kubectl view-secret -n dev sample-script-mongo-req-98k0ch -a +``` password=-e4v396GFjjjMgPPuU7q username=v-kubernetes-demo-k8s-f7695915-1e-6sXNTvVpPDtueRQWvoyH-1662641233 -``` ### Verify Initialization Here, we are going to connect to the database with the login credentials and verify the database initialization, ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=initdb --username='v-kubernetes-demo-k8s-f7695915-1e-6sXNTvVpPDtueRQWvoyH-1662641233' --password='-e4v396GFjjjMgPPuU7q' initdb MongoDB shell version v4.4.26 ... @@ -311,20 +314,20 @@ replicaset:PRIMARY> db.product.find() replicaset:PRIMARY> exit bye -``` Now, Let's check the `STATUS` of `Schema Manager` again, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE dev sample-script mongodb initdb Expired 6m -``` Here, we can see that the `STATUS` of the `schema-manager` is `Expired` because it's exceeded `defaultTTL: "5m"`, which means the current `Secret` of `Schema Manager` isn't vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from `schema-manager`, it won't work. ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=initdb --username='v-kubernetes-demo-k8s-f7695915-1e-6sXNTvVpPDtueRQWvoyH-1662641233' --password='-e4v396GFjjjMgPPuU7q' initdb MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/initdb?authSource=initdb&compressors=disabled&gssapiServiceName=mongodb @@ -335,7 +338,6 @@ exception: connect failed exiting with code 1 root@mongodb-0:/# exit exit -``` > We can't connect to the database with the login credentials, which is `Expired`. We will not be able to access the database even though we're in the middle of a connected session. @@ -345,8 +347,11 @@ exit To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete ns dev -$ kubectl delete ns demo +kubectl delete ns dev +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mongodb/schema-manager/initializing-with-snapshot/index.md b/docs/guides/mongodb/schema-manager/initializing-with-snapshot/index.md index 6ce753b325..88ecfd2a59 100644 --- a/docs/guides/mongodb/schema-manager/initializing-with-snapshot/index.md +++ b/docs/guides/mongodb/schema-manager/initializing-with-snapshot/index.md @@ -55,10 +55,10 @@ metadata: Let’s save this yaml configuration into `namespace.yaml` Then create those above namespaces. ```bash -$ kubectl apply -f namespace.yaml +kubectl apply -f namespace.yaml +``` namespace/db created namespace/demo created -``` ## Deploy MongoDB Server and Vault Server @@ -112,9 +112,9 @@ Here, Let’s save this yaml configuration into `mongodb.yaml` Then create the above `MongoDB` CR ```bash -$ kubectl apply -f mongodb.yaml -mongodb.kubedb.com/mongodb created +kubectl apply -f mongodb.yaml ``` +mongodb.kubedb.com/mongodb created ### Deploy Vault Server @@ -167,9 +167,9 @@ Here, Let’s save this yaml configuration into `vault.yaml` Then create the above `VaultServer` CR ```bash -$ kubectl apply -f vault.yaml -vaultserver.kubevault.com/vault created +kubectl apply -f vault.yaml ``` +vaultserver.kubevault.com/vault created ### Create Repository Secret @@ -179,17 +179,20 @@ Here, we are using local backend for storing data snapshots. It can be a cloud s Let's, create a Secret for our Repository, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo repo-secret --from-file=./RESTIC_PASSWORD -secret/repo-secret created +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo repo-secret --from-file=./RESTIC_PASSWORD ``` +secret/repo-secret created Let’s save this yaml configuration into `repo-secret.yaml` Then create the secret, ```bash -$ kubectl apply -f repo-secret.yaml -secret/repo-secret created +kubectl apply -f repo-secret.yaml ``` +secret/repo-secret created ### Create Repository @@ -218,9 +221,9 @@ This repository CRO specifies the `repo-secret` that we've created before and sp Let’s save this yaml configuration into `repo.yaml` Lets create the repository, ```bash -$ kubectl apply -f repo.yaml -repository.stash.appscode.com/repo created +kubectl apply -f repo.yaml ``` +repository.stash.appscode.com/repo created After creating the repository we've backed up one of our MongoDB database with some sample data via Stash. So, now our repository contains some sample data inside it. @@ -277,18 +280,17 @@ Here, Let’s save this yaml configuration into `schema-restore.yaml` and apply it, ```bash -$ kubectl apply -f schema-restore.yaml -mongodbdatabase.schema.kubedb.com/schema-restore created - +kubectl apply -f schema-restore.yaml ``` +mongodbdatabase.schema.kubedb.com/schema-restore created Let's check the `STATUS` of `Schema Manager`, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demo schema-restore mongodb products Current 56s -``` Here, > In `STATUS` section, `Current` means that the current `Secret` of `Schema Manager` is vaild, and it will automatically `Expired` after it reaches the limit of `defaultTTL` that we've defined in the above yaml. @@ -296,29 +298,32 @@ Here, Also, check the `STATUS` of `restoresession` ```bash -$ kubectl get restoresession -n demo +kubectl get restoresession -n demo +``` NAME REPOSITORY PHASE DURATION AGE schema-restore-mongo-rs repo Succeeded 5s 21s -``` Now, let's get the secret name from `schema-manager`, and the login credentials for connecting to the database, ```bash -$ kubectl get mongodbdatabase schema-restore -n demo -o=jsonpath='{.status.authSecret.name}' +kubectl get mongodbdatabase schema-restore -n demo -o=jsonpath='{.status.authSecret.name}' +``` schema-restore-mongo-req-98k0ch -$ kubectl view-secret -n demo schema-restore-mongo-req-98k0ch -a +```bash +kubectl view-secret -n demo schema-restore-mongo-req-98k0ch -a +``` password=6ykdBljJ7D8agXeoSp-f username=v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843 -``` ### Verify Initialization Here, we are going to connect to the database with the login credentials and verify the database initialization, ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=products --username='v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843' --password='6ykdBljJ7D8agXeoSp-f' products MongoDB shell version v4.4.26 ... @@ -335,21 +340,20 @@ replicaset:PRIMARY> db.products.find() replicaset:PRIMARY> exit bye -``` - Now, Let's check the `STATUS` of `Schema Manager` again, ```bash -$ kubectl get mongodbdatabase -A +kubectl get mongodbdatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demo schema-restore mongodb products Expired 7m -``` Here, we can see that the `STATUS` of the `schema-manager` is `Expired` because it's exceeded `defaultTTL: "5m"`, which means the current `Secret` of `Schema Manager` isn't vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from `schema-manager`, it won't work. ```bash -$ kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +kubectl exec -it -n demo mongodb-0 -c mongodb -- bash +``` root@mongodb-0:/# mongosh --authenticationDatabase=products --username='v-kubernetes-demo-k8s-f7695915-1e-2zXmduPS89LfvW6tr5Bw-1662639843' --password='6ykdBljJ7D8agXeoSp-f' products MongoDB shell version v4.4.26 connecting to: mongodb://127.0.0.1:27017/products?authSource=products&compressors=disabled&gssapiServiceName=mongodb @@ -360,7 +364,6 @@ exception: connect failed exiting with code 1 root@mongodb-0:/# exit exit -``` > We can't connect to the database with the login credentials, which is `Expired`. We will not be able to access the database even though we're in the middle of a connected session. @@ -370,8 +373,11 @@ exit To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete ns db -$ kubectl delete ns demo +kubectl delete ns db +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mongodb/tls/replicaset.md b/docs/guides/mongodb/tls/replicaset.md index 10507aafcb..58a537debf 100644 --- a/docs/guides/mongodb/tls/replicaset.md +++ b/docs/guides/mongodb/tls/replicaset.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `clusterAuthMod - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -87,9 +87,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml -issuer.cert-manager.io/mongo-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml ``` +issuer.cert-manager.io/mongo-ca-issuer created ## TLS/SSL encryption in MongoDB Replicaset @@ -125,25 +125,26 @@ spec: ### Deploy MongoDB Replicaset ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-replicaset-ssl.yaml -mongodb.kubedb.com/mgo-rs-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-replicaset-ssl.yaml ``` +mongodb.kubedb.com/mgo-rs-tls created Now, wait until `mgo-rs-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get mg -n demo +watch kubectl get mg -n demo +``` Every 2.0s: kubectl get mongodb -n demo NAME VERSION STATUS AGE mgo-rs-tls 4.4.26 Ready 4m10s -``` ### Verify TLS/SSL in MongoDB Replicaset Now, connect to this database through [mongo-shell](https://docs.mongodb.com/v4.0/mongo/) and verify if `SSLMode` and `ClusterAuthMode` has been set up as intended. ```bash -$ kubectl describe secret -n demo mgo-rs-tls-client-cert +kubectl describe secret -n demo mgo-rs-tls-client-cert +``` Name: mgo-rs-tls-client-cert Namespace: demo Labels: @@ -163,17 +164,16 @@ Data ca.crt: 1147 bytes tls.crt: 1172 bytes tls.key: 1679 bytes -``` Now, Let's exec into a mongodb container and find out the username to connect in a mongo shell, ```bash -$ kubectl exec -it mgo-rs-tls-0 -n demo bash +kubectl exec -it mgo-rs-tls-0 -n demo bash +``` root@mgo-rs-tls-0:/$ ls /var/run/mongodb/tls ca.crt client.pem mongo.pem root@mgo-rs-tls-0:/$ openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -subject -nameopt RFC2253 -noout subject=CN=root,O=kubedb -``` Now, we can connect using `CN=root,O=kubedb` as root to connect to the mongo shell, @@ -237,9 +237,9 @@ User can update `sslMode` & `ClusterAuthMode` if needed. Some changes may be inv The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the MongoDB object.** i.e., ```bash -$ kubectl patch -n demo mg/mgo-rs-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" -Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 +kubectl patch -n demo mg/mgo-rs-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" ``` +Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 To **update from Keyfile Authentication to x.509 Authentication**, change the `sslMode` and `clusterAuthMode` in recommended sequence as suggested in [official documentation](https://docs.mongodb.com/manual/tutorial/update-keyfile-to-x509/). Each time after changing the specs, follow the procedure that is described above to verify the changes of `sslMode` and `clusterAuthMode` inside the database. diff --git a/docs/guides/mongodb/tls/sharding.md b/docs/guides/mongodb/tls/sharding.md index 4348c54a02..d110f391cd 100644 --- a/docs/guides/mongodb/tls/sharding.md +++ b/docs/guides/mongodb/tls/sharding.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `clusterAuthMod - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -87,9 +87,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml -issuer.cert-manager.io/mongo-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml ``` +issuer.cert-manager.io/mongo-ca-issuer created ## TLS/SSL encryption in MongoDB Sharding @@ -135,25 +135,26 @@ spec: ### Deploy MongoDB Sharding ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-shard-ssl.yaml -mongodb.kubedb.com/mongo-sh-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-shard-ssl.yaml ``` +mongodb.kubedb.com/mongo-sh-tls created Now, wait until `mongo-sh-tls created` has status `Ready`. ie, ```bash -$ watch kubectl get mg -n demo +watch kubectl get mg -n demo +``` Every 2.0s: kubectl get mongodb -n demo NAME VERSION STATUS AGE mongo-sh-tls 4.4.26 Ready 4m24s -``` ### Verify TLS/SSL in MongoDB Sharding Now, connect to `mongos` component of this database through [mongo-shell](https://docs.mongodb.com/v4.0/mongo/) and verify if `SSLMode` and `ClusterAuthMode` has been set up as intended. ```bash -$ kubectl describe secret -n demo mongo-sh-tls-client-cert +kubectl describe secret -n demo mongo-sh-tls-client-cert +``` Name: mongo-sh-tls-client-cert Namespace: demo Labels: @@ -173,17 +174,16 @@ Data ca.crt: 1147 bytes tls.crt: 1172 bytes tls.key: 1679 bytes -``` Now, Let's exec into a mongodb container and find out the username to connect in a mongo shell, ```bash -$ kubectl exec -it mongo-sh-tls-mongos-0 -n demo bash +kubectl exec -it mongo-sh-tls-mongos-0 -n demo bash +``` root@mongo-sh-tls-mongos-0:/$ ls /var/run/mongodb/tls ca.crt client.pem mongo.pem mongodb@mgo-sh-tls-mongos-0:/$ openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -subject -nameopt RFC2253 -noout subject=CN=root,O=kubedb -``` Now, we can connect using `CN=root,O=kubedb` as root to connect to the mongo shell, @@ -245,9 +245,9 @@ User can update `sslMode` & `ClusterAuthMode` if needed. Some changes may be inv The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the MongoDB object.** i.e., ```bash -$ kubectl patch -n demo mg/mgo-sh-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" -Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 +kubectl patch -n demo mg/mgo-sh-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" ``` +Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 To **update from Keyfile Authentication to x.509 Authentication**, change the `sslMode` and `clusterAuthMode` in recommended sequence as suggested in [official documentation](https://docs.mongodb.com/manual/tutorial/update-keyfile-to-x509/). Each time after changing the specs, follow the procedure that is described above to verify the changes of `sslMode` and `clusterAuthMode` inside the database. diff --git a/docs/guides/mongodb/tls/standalone.md b/docs/guides/mongodb/tls/standalone.md index a4d46d5b15..eae5baa6bf 100644 --- a/docs/guides/mongodb/tls/standalone.md +++ b/docs/guides/mongodb/tls/standalone.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `clusterAuthMod - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -87,9 +87,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml -issuer.cert-manager.io/mongo-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/issuer.yaml ``` +issuer.cert-manager.io/mongo-ca-issuer created ## TLS/SSL encryption in MongoDB Standalone @@ -121,25 +121,26 @@ spec: ### Deploy MongoDB Standalone ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-standalone-ssl.yaml -mongodb.kubedb.com/mgo-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/tls/mg-standalone-ssl.yaml ``` +mongodb.kubedb.com/mgo-tls created Now, wait until `mgo-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get mg -n demo +watch kubectl get mg -n demo +``` Every 2.0s: kubectl get mongodb -n demo NAME VERSION STATUS AGE mgo-tls 4.4.26 Ready 14s -``` ### Verify TLS/SSL in MongoDB Standalone Now, connect to this database through [mongo-shell](https://docs.mongodb.com/v4.0/mongo/) and verify if `SSLMode` has been set up as intended (i.e, `requireSSL`). ```bash -$ kubectl describe secret -n demo mgo-tls-client-cert +kubectl describe secret -n demo mgo-tls-client-cert +``` Name: mgo-tls-client-cert Namespace: demo Labels: @@ -159,17 +160,16 @@ Data tls.crt: 1172 bytes tls.key: 1679 bytes ca.crt: 1147 bytes -``` Now, Let's exec into a mongodb container and find out the username to connect in a mongo shell, ```bash -$ kubectl exec -it mgo-tls-0 -n demo bash +kubectl exec -it mgo-tls-0 -n demo bash +``` mongodb@mgo-tls-0:/$ ls /var/run/mongodb/tls ca.crt client.pem mongo.pem mongodb@mgo-tls-0:/$ openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -subject -nameopt RFC2253 -noout subject=CN=root,O=kubedb -``` Now, we can connect using `CN=root,O=kubedb` as root to connect to the mongo shell, @@ -216,9 +216,9 @@ User can update `sslMode` & `ClusterAuthMode` if needed. Some changes may be inv The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the MongoDB object.** i.e., ```bash -$ kubectl patch -n demo mg/mgo-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" -Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 +kubectl patch -n demo mg/mgo-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge" ``` +Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509 To **update from Keyfile Authentication to x.509 Authentication**, change the `sslMode` and `clusterAuthMode` in recommended sequence as suggested in [official documentation](https://docs.mongodb.com/manual/tutorial/update-keyfile-to-x509/). Each time after changing the specs, follow the procedure that is described above to verify the changes of `sslMode` and `clusterAuthMode` inside the database. diff --git a/docs/guides/mongodb/update-version/replicaset.md b/docs/guides/mongodb/update-version/replicaset.md index 251634c874..84c663d258 100644 --- a/docs/guides/mongodb/update-version/replicaset.md +++ b/docs/guides/mongodb/update-version/replicaset.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -69,17 +69,17 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-replicaset.yaml -mongodb.kubedb.com/mg-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-replicaset.yaml ``` +mongodb.kubedb.com/mg-replicaset created Now, wait until `mg-replicaset` created has status `Ready`. i.e, ```bash -$ k get mongodb -n demo +k get mongodb -n demo +``` NAME VERSION STATUS AGE mg-replicaset 7.0.28 Ready 109s -``` We are now ready to apply the `MongoDBOpsRequest` CR to update this database. @@ -120,9 +120,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-replicaset .yaml -mongodbopsrequest.ops.kubedb.com/mops-replicaset-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-replicaset .yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-replicaset-update created #### Verify MongoDB version updated successfully @@ -131,16 +131,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-replicaset-update UpdateVersion Successful 84s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-replicaset-update +kubectl describe mongodbopsrequest -n demo mops-replicaset-update +``` Name: mops-replicaset-update Namespace: demo Labels: @@ -238,20 +239,23 @@ Events: Normal ResumeDatabase 38s KubeDB Ops-manager Operator Resuming MongoDB demo/mg-replicaset Normal ResumeDatabase 38s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-replicaset Normal Successful 38s KubeDB Ops-manager Operator Successfully Updated Database -``` Now, we are going to verify whether the `MongoDB` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get mg -n demo mg-replicaset -o=jsonpath='{.spec.version}{"\n"}' +kubectl get mg -n demo mg-replicaset -o=jsonpath='{.spec.version}{"\n"}' +``` 8.0.17 -$ kubectl get petset -n demo mg-replicaset -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mg-replicaset -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get pods -n demo mg-replicaset-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mongo:8.0.17 +```bash +kubectl get pods -n demo mg-replicaset-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mongo:8.0.17 You can see from above, our `MongoDB` replicaset database has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/mongodb/update-version/sharding.md b/docs/guides/mongodb/update-version/sharding.md index 73c1a10854..6df13f609a 100644 --- a/docs/guides/mongodb/update-version/sharding.md +++ b/docs/guides/mongodb/update-version/sharding.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -76,17 +76,17 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-shard.yaml -mongodb.kubedb.com/mg-sharding created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-shard.yaml ``` +mongodb.kubedb.com/mg-sharding created Now, wait until `mg-sharding` created has status `Ready`. i.e, ```bash -$ k get mongodb -n demo +k get mongodb -n demo +``` NAME VERSION STATUS AGE mg-sharding 7.0.28 Ready 2m9s -``` We are now ready to apply the `MongoDBOpsRequest` CR to update this database. @@ -127,9 +127,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-shard-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-shard-update created #### Verify MongoDB version updated successfully @@ -138,17 +138,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-shard-update UpdateVersion Successful 2m31s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to update the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-shard-update - +kubectl describe mongodbopsrequest -n demo mops-shard-update +``` Name: mops-shard-update Namespace: demo Labels: @@ -278,32 +278,43 @@ Events: Normal ResumeDatabase 109s KubeDB Ops-manager Operator Resuming MongoDB demo/mg-sharding Normal ResumeDatabase 109s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-sharding Normal Successful 109s KubeDB Ops-manager Operator Successfully Updated Database -``` Now, we are going to verify whether the `MongoDB` and the related `PetSets` of `Mongos`, `Shard` and `ConfigeServer` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get mg -n demo mg-sharding -o=jsonpath='{.spec.version}{"\n"}' +kubectl get mg -n demo mg-sharding -o=jsonpath='{.spec.version}{"\n"}' +``` 8.0.17 -$ kubectl get petset -n demo mg-sharding-configsvr -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mg-sharding-configsvr -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get petset -n demo mg-sharding-shard0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mg-sharding-shard0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get petset -n demo mg-sharding-mongos -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mg-sharding-mongos -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get pods -n demo mg-sharding-configsvr-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +```bash +kubectl get pods -n demo mg-sharding-configsvr-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get pods -n demo mg-sharding-shard0-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +```bash +kubectl get pods -n demo mg-sharding-shard0-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get pods -n demo mg-sharding-mongos-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mongo:8.0.17 +```bash +kubectl get pods -n demo mg-sharding-mongos-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mongo:8.0.17 You can see from above, our `MongoDB` sharded database has been updated with the new version. So, the update process is successfully completed. diff --git a/docs/guides/mongodb/update-version/standalone.md b/docs/guides/mongodb/update-version/standalone.md index 2d4409b5ed..93cee8c62e 100644 --- a/docs/guides/mongodb/update-version/standalone.md +++ b/docs/guides/mongodb/update-version/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mongodb](/docs/examples/mongodb) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -65,17 +65,17 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-standalone.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mg-standalone.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` created has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 7.0.28 Ready 8m58s -``` We are now ready to apply the `MongoDBOpsRequest` CR to update this database. @@ -117,9 +117,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-standalone.yaml -mongodbopsrequest.ops.kubedb.com/mops-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/update-version/mops-update-standalone.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-update created #### Verify MongoDB version updated successfully : @@ -128,16 +128,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE mops-update UpdateVersion Successful 3m45s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to update the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-update +kubectl describe mongodbopsrequest -n demo mops-update +``` Name: mops-update Namespace: demo Labels: @@ -236,20 +237,22 @@ Events: Normal ResumeDatabase 50s KubeDB Ops-manager Operator Successfully resumed MongoDB demo/mg-standalone Normal Successful 50s KubeDB Ops-manager Operator Successfully Updated Database -``` - Now, we are going to verify whether the `MongoDB` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get mg -n demo mg-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get mg -n demo mg-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 8.0.17 -$ kubectl get petset -n demo mg-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mg-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mongo:8.0.17 -$ kubectl get pods -n demo mg-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mongo:8.0.17 +```bash +kubectl get pods -n demo mg-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mongo:8.0.17 You can see from above, our `MongoDB` standalone database has been updated with the new version. So, the update process is successfully completed. diff --git a/docs/guides/mongodb/vault-integration/kmip-encryption/index.md b/docs/guides/mongodb/vault-integration/kmip-encryption/index.md index 02fa8b8f7c..c0c4e77acd 100644 --- a/docs/guides/mongodb/vault-integration/kmip-encryption/index.md +++ b/docs/guides/mongodb/vault-integration/kmip-encryption/index.md @@ -34,9 +34,9 @@ To demonstrate how to configure KubeDB MongoDB with [HashiCorp Vault KMIP secret - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Setup Hashicorp Vault KMIP secret engine @@ -45,42 +45,66 @@ For this demo we will use [Hashicorp Cloud Provider(HCP)](https://portal.cloud.h So First we created a `Vault Plus` cluster in HCP. Then we need to configure Vault KMIP according to [this](https://developer.hashicorp.com/vault/tutorials/adp/kmip-engine?variants=vault-deploy%3Ahcp) documentation step by step. -```bash # setup vault environment -$ export VAULT_ADDR= -$ export VAULT_TOKEN= -$ export VAULT_NAMESPACE=admin +```bash +export VAULT_ADDR= +``` + +```bash +export VAULT_TOKEN= +``` + +```bash +export VAULT_NAMESPACE=admin +``` # configure kmip secret engine -$ vault secrets enable kmip +```bash +vault secrets enable kmip +``` Success! Enabled the kmip secrets engine at: kmip/ -$ vault write kmip/config \ +```bash +vault write kmip/config \ listen_addrs=0.0.0.0:5696 \ server_hostnames=$(echo ${VAULT_ADDR:8} | rev | cut -c6- | rev) +``` Success! Data written to: kmip/config # create scope -$ vault write -f kmip/scope/finance +```bash +vault write -f kmip/scope/finance +``` Success! Data written to: kmip/scope/finance # create role -$ vault write kmip/scope/finance/role/accounting operation_all=true +```bash +vault write kmip/scope/finance/role/accounting operation_all=true +``` Success! Data written to: kmip/scope/finance/role/accounting # store vault-ca.pem -$ vault read kmip/ca -format=json | jq -r '.data | .ca_pem' >> vault-ca.pem +```bash +vault read kmip/ca -format=json | jq -r '.data | .ca_pem' >> vault-ca.pem +``` # generate and store client.pem -$ vault write -format=json \ +```bash +vault write -format=json \ kmip/scope/finance/role/accounting/credential/generate \ format=pem > credential.json +``` -$ jq -r .data.certificate < credential.json > cert.pem +```bash +jq -r .data.certificate < credential.json > cert.pem +``` -$ jq -r .data.private_key < credential.json > key.pem +```bash +jq -r .data.private_key < credential.json > key.pem +``` -$ cat cert.pem key.pem > client.pem +```bash +cat cert.pem key.pem > client.pem ``` We will use this `client.pem` and `vault-ca.pem` files to configure KMIP in MongoDB. @@ -89,7 +113,8 @@ We will use this `client.pem` and `vault-ca.pem` files to configure KMIP in Mong Now we need to make a `mongod.conf` file to use it as configuration folder for our `MongoDB`. ```bash -$ cat mongod.conf +cat mongod.conf +``` security: enableEncryption: true kmip: @@ -97,7 +122,6 @@ security: port: 5696 clientCertificateFile: /etc/certs/client.pem serverCAFile: /etc/certs/ca.pem -``` Here, - `serverName` is the public address of our HCP Vault Plus cluster without port @@ -112,13 +136,14 @@ Here `/etc/certs/client.pem` and `/etc/certs/ca.pem` will be mounted by secret i Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo mg-configuration --from-file=./mongod.conf -secret/mg-configuration created +kubectl create secret generic -n demo mg-configuration --from-file=./mongod.conf ``` +secret/mg-configuration created Verify the secret has the configuration file. ```bash -$ kubectl get secret -n demo mg-configuration -o yaml +kubectl get secret -n demo mg-configuration -o yaml +``` apiVersion: v1 data: mongod.conf: c2VjdXJpdHk6CiAgZW5hYmxlRW5jcnlwdGlvbjogdHJ1ZQogIGttaXA6CiAgICBzZXJ2ZXJOYW1lOiB2YXVsdC1jbHVzdGVyLWRvYy1wdWJsaWMtdmF1bHQtYTMzYmI3NjEuMzcxMzFkZDEuejEuaGFzaGljb3JwLmNsb3VkCiAgICBwb3J0OiA1Njk2CiAgICBjbGllbnRDZXJ0aWZpY2F0ZUZpbGU6IC9ldGMvY2VydHMvY2xpZW50LnBlbQogICAgc2VydmVyQ0FGaWxlOiAvZXRjL2NlcnRzL2NhLnBlbQ== @@ -130,17 +155,16 @@ metadata: resourceVersion: "322831" uid: 005f0cac-6bbb-4fb6-a728-87b0ca55785a type: Opaque -``` ### Create MongoDB Before creating `MongoDB`, we need to create a secret with `client.pem` and `vault-ca.pem` to use as volume for our `MongoDB` ```bash -$ kubectl create secret generic vault-tls-secret -n demo \ +kubectl create secret generic vault-tls-secret -n demo \ --from-file=client.pem=client.pem \ --from-file=ca.pem=vault-ca.pem -secret/vault-tls-secret created ``` +secret/vault-tls-secret created Now lets create KubeDB MongoDB. Currently, we have KMIP encryption support for `percona-4.2.24`,`percona-4.2.26`,`percona-5.0.23`, , `percona-5.0.31` ,`percona-6.0.12` and `percona-7.0.4` version of KubeDB managed MongoDB. @@ -178,19 +202,19 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guids/mongodb/vault-integration/kmip-enryption/examples/mg.yaml -mongodb.kubedb.com/mg-kmip created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guids/mongodb/vault-integration/kmip-enryption/examples/mg.yaml ``` +mongodb.kubedb.com/mg-kmip created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `mg-kmip-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo mg-kmip-0 +kubectl get pod -n demo mg-kmip-0 +``` NAME READY STATUS RESTARTS AGE mg-kmip-0 1/1 Running 0 1m -``` Now, we will check if the database has started with the custom configuration we have provided. @@ -210,14 +234,18 @@ We should see these logs which confirm that this `MongoDB` is setup with KMIP Now, we can connect to this database through [mongo-shell](https://docs.mongodb.com/v4.2/mongo/). In this tutorial, we are connecting to the MongoDB server from inside the pod. ```bash -$ kubectl get secrets -n demo mg-kmip-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mg-kmip-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mg-kmip-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mg-kmip-auth -o jsonpath='{.data.password}' | base64 -d +``` bJI!1H!)V7!2U.wJ -$ kubectl exec -it mg-kmip-0 -n demo -- bash - +```bash +kubectl exec -it mg-kmip-0 -n demo -- bash +``` > mongosh admin > db.auth("root","bJI!1H!)V7!2U.wJ") @@ -264,7 +292,6 @@ $ kubectl exec -it mg-kmip-0 -n demo -- bash } > exit bye -``` We can see that in `parsed.security` field, encryption is enabled. diff --git a/docs/guides/mongodb/volume-expansion/replicaset.md b/docs/guides/mongodb/volume-expansion/replicaset.md index dc2a3ca8b6..e29727c7be 100644 --- a/docs/guides/mongodb/volume-expansion/replicaset.md +++ b/docs/guides/mongodb/volume-expansion/replicaset.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `MongoDB` replicaset using a supported version b At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -85,30 +85,32 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-replicaset.yaml -mongodb.kubedb.com/mg-replicaset created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-replicaset.yaml ``` +mongodb.kubedb.com/mg-replicaset created Now, wait until `mg-replicaset` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-replicaset 4.4.26 Ready 10m -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mg-replicaset -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-replicaset -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-2067c63d-f982-4b66-a008-5e9c3ff6218a 1Gi RWO Delete Bound demo/datadir-mg-replicaset-0 longhorn 10m pvc-9db1aeb0-f1af-4555-93a3-0ca754327751 1Gi RWO Delete Bound demo/datadir-mg-replicaset-2 longhorn 9m45s pvc-d38f42a8-50d4-4fa9-82ba-69fc7a464ff4 1Gi RWO Delete Bound demo/datadir-mg-replicaset-1 longhorn 10m -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -146,9 +148,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-replicaset.yaml -mongodbopsrequest.ops.kubedb.com/mops-volume-exp-replicaset created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-replicaset.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-volume-exp-replicaset created #### Verify MongoDB replicaset volume expanded successfully @@ -157,15 +159,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-volume-exp-replicaset VolumeExpansion Successful 83s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-volume-exp-replicaset +kubectl describe mongodbopsrequest -n demo mops-volume-exp-replicaset +``` Name: mops-volume-exp-replicaset Namespace: demo Labels: @@ -220,20 +223,21 @@ Events: Normal ResumeDatabase 3m11s KubeDB Ops-manager operator Resuming MongoDB Normal ResumeDatabase 3m11s KubeDB Ops-manager operator Successfully Resumed mongodb Normal Successful 3m11s KubeDB Ops-manager operator Successfully Scaled Database -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-replicaset -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-replicaset -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-2067c63d-f982-4b66-a008-5e9c3ff6218a 2Gi RWO Delete Bound demo/datadir-mg-replicaset-0 longhorn 19m pvc-9db1aeb0-f1af-4555-93a3-0ca754327751 2Gi RWO Delete Bound demo/datadir-mg-replicaset-2 longhorn 18m pvc-d38f42a8-50d4-4fa9-82ba-69fc7a464ff4 2Gi RWO Delete Bound demo/datadir-mg-replicaset-1 longhorn 19m -``` The above output verifies that we have successfully expanded the volume of the MongoDB database. diff --git a/docs/guides/mongodb/volume-expansion/sharding.md b/docs/guides/mongodb/volume-expansion/sharding.md index 2b2d571c64..20b2d093ad 100644 --- a/docs/guides/mongodb/volume-expansion/sharding.md +++ b/docs/guides/mongodb/volume-expansion/sharding.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `MongoDB` Sharded Database using a supported vers At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -92,28 +92,33 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-shard.yaml -mongodb.kubedb.com/mg-sharding created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-shard.yaml ``` +mongodb.kubedb.com/mg-sharding created Now, wait until `mg-sharding` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-sharding 4.4.26 Ready 2m45s -``` Let's check volume size from petset, and from the persistent volume of shards and config servers, ```bash -$ kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-194f6e9c-b9a7-4d00-a125-a6c01273468c 1Gi RWO Delete Bound demo/datadir-mg-sharding-shard0-0 longhorn 68s pvc-390b6343-f97e-4761-a516-e3c9607c55d6 1Gi RWO Delete Bound demo/datadir-mg-sharding-shard1-1 longhorn 2m26s @@ -123,7 +128,6 @@ pvc-5be2ab13-e12c-4053-8680-7c5588dff8eb 1Gi RWO Delete pvc-7e11502d-13e0-4a84-9ebe-29bc2b15f026 1Gi RWO Delete Bound demo/datadir-mg-sharding-shard0-1 longhorn 44s pvc-7e20906c-462d-47b7-b4cf-ba0ef69ba26e 1Gi RWO Delete Bound demo/datadir-mg-sharding-shard2-0 longhorn 3m7s pvc-87634059-0f95-4595-ae8a-121944961103 1Gi RWO Delete Bound demo/datadir-mg-sharding-configsvr-0 longhorn 3m7s -``` You can see the petsets have 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -164,9 +168,9 @@ Here, Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-shard.yaml -mongodbopsrequest.ops.kubedb.com/mops-volume-exp-shard created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-shard.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-volume-exp-shard created #### Verify MongoDB shard volumes expanded successfully @@ -175,15 +179,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-volume-exp-shard VolumeExpansion Successful 3m49s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-volume-exp-shard +kubectl describe mongodbopsrequest -n demo mops-volume-exp-shard +``` Name: mops-volume-exp-shard Namespace: demo Labels: @@ -245,18 +250,22 @@ Events: Normal ResumeDatabase 50s KubeDB Ops-manager operator Resuming MongoDB Normal ResumeDatabase 50s KubeDB Ops-manager operator Successfully Resumed mongodb Normal Successful 50s KubeDB Ops-manager operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-sharding-configsvr -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo mg-sharding-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-194f6e9c-b9a7-4d00-a125-a6c01273468c 2Gi RWO Delete Bound demo/datadir-mg-sharding-shard0-0 longhorn 3m38s pvc-390b6343-f97e-4761-a516-e3c9607c55d6 2Gi RWO Delete Bound demo/datadir-mg-sharding-shard1-1 longhorn 4m56s @@ -266,7 +275,6 @@ pvc-5be2ab13-e12c-4053-8680-7c5588dff8eb 2Gi RWO Delete pvc-7e11502d-13e0-4a84-9ebe-29bc2b15f026 2Gi RWO Delete Bound demo/datadir-mg-sharding-shard0-1 longhorn 3m14s pvc-7e20906c-462d-47b7-b4cf-ba0ef69ba26e 2Gi RWO Delete Bound demo/datadir-mg-sharding-shard2-0 longhorn 5m37s pvc-87634059-0f95-4595-ae8a-121944961103 2Gi RWO Delete Bound demo/datadir-mg-sharding-configsvr-0 longhorn 5m37s -``` The above output verifies that we have successfully expanded the volume of the shard nodes and configServer nodes of the MongoDB database. diff --git a/docs/guides/mongodb/volume-expansion/standalone.md b/docs/guides/mongodb/volume-expansion/standalone.md index d3eaee0266..985653fcba 100644 --- a/docs/guides/mongodb/volume-expansion/standalone.md +++ b/docs/guides/mongodb/volume-expansion/standalone.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mongodb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mongodb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,10 +47,10 @@ Here, we are going to deploy a `MongoDB` standalone using a supported version by At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE longhorn (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -81,28 +81,30 @@ spec: Let's create the `MongoDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-standalone.yaml -mongodb.kubedb.com/mg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mg-standalone.yaml ``` +mongodb.kubedb.com/mg-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get mg -n demo +kubectl get mg -n demo +``` NAME VERSION STATUS AGE mg-standalone 4.4.26 Ready 2m53s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 1Gi RWO Delete Bound demo/datadir-mg-standalone-0 longhorn 49s -``` You can see the petset has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -143,9 +145,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `MongoDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-standalone.yaml -mongodbopsrequest.ops.kubedb.com/mops-volume-exp-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mongodb/volume-expansion/mops-volume-exp-standalone.yaml ``` +mongodbopsrequest.ops.kubedb.com/mops-volume-exp-standalone created #### Verify MongoDB Standalone volume expanded successfully @@ -154,15 +156,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MongoDBOpsRequest` to be `Successful`. Run the following command to watch `MongoDBOpsRequest` CR, ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-volume-exp-standalone VolumeExpansion Successful 75s -``` We can see from the above output that the `MongoDBOpsRequest` has succeeded. If we describe the `MongoDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mongodbopsrequest -n demo mops-volume-exp-standalone +kubectl describe mongodbopsrequest -n demo mops-volume-exp-standalone +``` Name: mops-volume-exp-standalone Namespace: demo Labels: @@ -217,18 +220,19 @@ $ kubectl describe mongodbopsrequest -n demo mops-volume-exp-standalone Normal ResumeDatabase 29s KubeDB Ops-manager operator Resuming MongoDB Normal ResumeDatabase 29s KubeDB Ops-manager operator Successfully Resumed mongodb Normal Successful 29s KubeDB Ops-manager operator Successfully Scaled Database -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 2Gi RWO Delete Bound demo/datadir-mg-standalone-0 longhorn 4m29s -``` The above output verifies that we have successfully expanded the volume of the MongoDB standalone database. diff --git a/docs/guides/mssqlserver/autoscaler/compute/cluster.md b/docs/guides/mssqlserver/autoscaler/compute/cluster.md index c0df0d1fef..40b08c01ea 100644 --- a/docs/guides/mssqlserver/autoscaler/compute/cluster.md +++ b/docs/guides/mssqlserver/autoscaler/compute/cluster.md @@ -36,9 +36,9 @@ This guide will show you how to use `KubeDB` to auto-scale compute resources i.e To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of MSSQLServer Availability Group Cluster Here, we are going to deploy a `MSSQLServer` Availability Group Cluster using a supported version by `KubeDB` operator. Then we are going to apply `MSSQLServerAutoscaler` to set up autoscaling. @@ -57,9 +57,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -75,9 +75,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created In this section, we are going to deploy a MSSQLServer Availability Group Cluster with version `2025-cu0`. Then, in the next section we will set up autoscaling for this database using `MSSQLServerAutoscaler` CRD. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -132,21 +132,22 @@ spec: Let's create the `MSSQLServer` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/compute/mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/compute/mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created Now, wait until `mssqlserver-ag-cluster` has status `Ready`. i.e, ```bash -$ kubectl get mssqlserver -n demo +kubectl get mssqlserver -n demo +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 8m27s -``` Let's check the MSSQLServer resources, ```bash -$ kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mssql") | .resources' +kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mssql") | .resources' +``` { "limits": { "cpu": "600m", @@ -157,13 +158,13 @@ $ kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate. "memory": "1536Mi" } } -``` Let's check the Pod containers resources, there are two containers here, first one with index 0 named `mssql` is the main container of mssqlserver. ```bash -$ kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "600m", @@ -174,7 +175,10 @@ $ kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.container "memory": "1536Mi" } } -$ kubectl get pod -n demo mssqlserver-ag-cluster-1 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssqlserver-ag-cluster-1 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "600m", @@ -185,7 +189,10 @@ $ kubectl get pod -n demo mssqlserver-ag-cluster-1 -o json | jq '.spec.container "memory": "1536Mi" } } -$ kubectl get pod -n demo mssqlserver-ag-cluster-2 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssqlserver-ag-cluster-2 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "600m", @@ -196,7 +203,6 @@ $ kubectl get pod -n demo mssqlserver-ag-cluster-2 -o json | jq '.spec.container "memory": "1536Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mssqlserver. @@ -258,20 +264,23 @@ Here, Let's create the `MSSQLServerAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/compute/ms-as-compute.yaml -mssqlserverautoscaler.autoscaling.kubedb.com/ms-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/compute/ms-as-compute.yaml ``` +mssqlserverautoscaler.autoscaling.kubedb.com/ms-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `mssqlserverautoscaler` resource is created successfully, ```bash -$ kubectl get mssqlserverautoscaler -n demo +kubectl get mssqlserverautoscaler -n demo +``` NAME AGE ms-as-compute 16s -$ kubectl describe mssqlserverautoscaler ms-as-compute -n demo +```bash +kubectl describe mssqlserverautoscaler ms-as-compute -n demo +``` Name: ms-as-compute Namespace: demo Labels: @@ -410,7 +419,6 @@ Status: Memory: 9063982612 Vpa Name: mssqlserver-ag-cluster Events: -``` So, the `mssqlserverautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -420,23 +428,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `mssqlserveropsrequest` in the demo namespace to see if any `mssqlserveropsrequest` object is created. After some time you'll see that a `mssqlserveropsrequest` will be created based on the recommendation. ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE msops-mssqlserver-ag-cluster-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE msops-mssqlserver-ag-cluster-8li26q VerticalScaling Successful 11m -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe msops -n demo msops-mssqlserver-ag-cluster-8li26q +kubectl describe msops -n demo msops-mssqlserver-ag-cluster-8li26q +``` Name: msops-mssqlserver-ag-cluster-8li26q Namespace: demo Labels: app.kubernetes.io/component=database @@ -552,12 +561,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, we are going to verify from the Pod, and the MSSQLServer yaml whether the resources of the cluster database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "960m", @@ -569,7 +578,9 @@ $ kubectl get pod -n demo mssqlserver-ag-cluster-0 -o json | jq '.spec.container } } -$ kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mssql") | .resources' +```bash +kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mssql") | .resources' +``` { "limits": { "cpu": "960m", @@ -580,7 +591,6 @@ $ kubectl get ms -n demo mssqlserver-ag-cluster -o json | jq '.spec.podTemplate. "memory": "2Gi" } } -``` The above output verifies that we have successfully autoscaled the resources of the MSSQLServer cluster. diff --git a/docs/guides/mssqlserver/autoscaler/storage/cluster.md b/docs/guides/mssqlserver/autoscaler/storage/cluster.md index 2c9c518b33..649bddd776 100644 --- a/docs/guides/mssqlserver/autoscaler/storage/cluster.md +++ b/docs/guides/mssqlserver/autoscaler/storage/cluster.md @@ -39,21 +39,21 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a MSSQL To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling MSSQLServer Cluster At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 4d21h longhorn (default) driver.longhorn.io Delete Immediate true 2d20h longhorn-static driver.longhorn.io Delete Immediate true 2d20h -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -73,9 +73,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -91,9 +91,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, we are going to deploy a MSSQLServer cluster database with version `2025-cu0`. Then, in the next section we will set up autoscaling for this database using `MSSQLServerAutoscaler` CRD. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -150,30 +150,32 @@ spec: Let's create the `MSSQLServer` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/storage/mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/storage/mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created Now, wait until `mssqlserver-ag-cluster` has status `Ready`. i.e, ```bash -$ kubectl get mssqlserver -n demo +kubectl get mssqlserver -n demo +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 4m -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-1497dd6d-9cbd-467a-8e0c-c3963ce09e1b 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-1 longhorn 8m pvc-37a7bc8d-2c04-4eb4-8e53-e610fd1daaf5 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-0 longhorn 8m pvc-817866af-5277-4d51-8d81-434e8ec1c442 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-2 longhorn 8m -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -216,21 +218,23 @@ Here, Let's create the `MSSQLServerAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/storage/ms-as-storage.yaml -mssqlserverautoscaler.autoscaling.kubedb.com/ms-as-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/autoscaler/storage/ms-as-storage.yaml ``` +mssqlserverautoscaler.autoscaling.kubedb.com/ms-as-storage created #### Storage Autoscaling is set up successfully Let's check that the `mssqlserverautoscaler` resource is created successfully, ```bash -$ kubectl get mssqlserverautoscaler -n demo +kubectl get mssqlserverautoscaler -n demo +``` NAME AGE ms-as-storage 17s - -$ kubectl describe mssqlserverautoscaler ms-as-storage -n demo +```bash +kubectl describe mssqlserverautoscaler ms-as-storage -n demo +``` Name: ms-as-storage Namespace: demo Labels: @@ -258,7 +262,6 @@ Spec: Upper Bound: 100Gi Usage Threshold: 60 Events: -``` So, the `mssqlserverautoscaler` resource is created successfully. @@ -267,7 +270,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Lets exec into the database pod and fill the database volume(`/var/opt/mssql/`) using the following commands: ```bash -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ df -h /var/opt/mssql Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-37a7bc8d-2c04-4eb4-8e53-e610fd1daaf5 974M 274M 685M 29% /var/opt/mssql @@ -279,7 +283,6 @@ mssql@mssqlserver-ag-cluster-0:/$ dd if=/dev/zero of=/var/opt/mssql/file.img bs= mssql@mssqlserver-ag-cluster-0:/$ df -h /var/opt/mssql Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-37a7bc8d-2c04-4eb4-8e53-e610fd1daaf5 974M 874M 85M 92% /var/opt/mssql -``` So, from the above output we can see that the storage usage is 92%, which exceeded the `usageThreshold` 60%. @@ -287,23 +290,24 @@ Let's watch the `mssqlserveropsrequest` in the demo namespace to see if any `mss ```bash -$ watch kubectl get mssqlserveropsrequest -n demo +watch kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE msops-mssqlserver-ag-cluster-8m7l5s VolumeExpansion Progressing 2m20s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE msops-mssqlserver-ag-cluster-8m7l5s VolumeExpansion Successful 17m -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-mssqlserver-ag-cluster-8m7l5s +kubectl describe mssqlserveropsrequest -n demo msops-mssqlserver-ag-cluster-8m7l5s +``` Name: msops-mssqlserver-ag-cluster-8m7l5s Namespace: demo Labels: app.kubernetes.io/component=database @@ -423,19 +427,21 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1531054080" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-2ff83356-1bbc-44ab-99f1-025e3690a471 1462Mi RWO Delete Bound demo/data-mssqlserver-ag-cluster-2 longhorn 15m pvc-a5cc0ae9-2c8d-456c-ace2-fc4fafc6784f 1462Mi RWO Delete Bound demo/data-mssqlserver-ag-cluster-1 longhorn 16m pvc-e8ab47a4-17a6-45fb-9f39-e71a03498ab5 1462Mi RWO Delete Bound demo/data-mssqlserver-ag-cluster-0 longhorn 16m -``` The above output verifies that we have successfully autoscaled the volume of the MSSQLServer cluster database. diff --git a/docs/guides/mssqlserver/backup/application-level/index.md b/docs/guides/mssqlserver/backup/application-level/index.md index 8f001ab007..db5f98530e 100644 --- a/docs/guides/mssqlserver/backup/application-level/index.md +++ b/docs/guides/mssqlserver/backup/application-level/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mssqlserver/backup/application-level/examples](/docs/guides/mssqlserver/backup/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -65,15 +65,15 @@ By following the below steps, we are going to create our desired issuer, - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" ``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, @@ -91,9 +91,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/mssqlserver-ca-issuer-demo.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer-demo.yaml created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/mssqlserver-ca-issuer-demo.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer-demo.yaml created **Create MSSQLServer CR:** @@ -136,35 +136,37 @@ spec: Create the above `MSSQLServer` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/sample-mssqlserver.yaml -mssqlserver.kubedb.com/sample-mssqlserver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/sample-mssqlserver.yaml ``` +mssqlserver.kubedb.com/sample-mssqlserver created KubeDB will deploy a `Microsoft SQL Server` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mssqlserver -n demo sample-mssqlserver +kubectl get mssqlserver -n demo sample-mssqlserver +``` NAME VERSION STATUS AGE sample-mssqlserver 2022-cu12 Ready 3m27 -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE mssqlserver-ca kubernetes.io/tls 2 2d20h sample-mssqlserver-auth kubernetes.io/basic-auth 2 3m44s sample-mssqlserver-client-cert kubernetes.io/tls 3 3m14s sample-mssqlserver-server-cert kubernetes.io/tls 3 3m14s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mssqlserver +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mssqlserver +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mssqlserver ClusterIP 10.96.165.94 1433/TCP 4m32s sample-mssqlserver-pods ClusterIP None 1433/TCP 4m32s -``` Here, we have to use service `sample-mssqlserver` and secret `sample-mssqlserver-auth` to connect with the database. `KubeDB` creates an AppBinding CR that holds the necessary information to connect with the database. @@ -173,15 +175,15 @@ Here, we have to use service `sample-mssqlserver` and secret `sample-mssqlserver Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-mssqlserver kubedb.com/mssqlserver 2022 4m18s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mssqlserver -o yaml +kubectl get appbindings -n demo sample-mssqlserver -o yaml ``` ```yaml @@ -242,25 +244,28 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mssqlserver" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mssqlserver" +``` NAME READY STATUS RESTARTS AGE sample-mssqlserver-0 1/1 Running 0 4m44s -``` And copy the username and password of the `sa` user to access into `mssqlserver` shell. ```bash -$ kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d -kkvAFfl8sIxRO2i3⏎ +```bash +kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d ``` +kkvAFfl8sIxRO2i3⏎ Now, Lets exec into the `Pod` to enter into `mssqlserver` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "kkvAFfl8sIxRO2i3" -No +kubectl exec -it -n demo sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "kkvAFfl8sIxRO2i3" -No +``` # list available databases 1> SELECT name from sys.databases; 2> GO @@ -313,7 +318,6 @@ id type quant color # exit from the pod 1> exit -``` Now, we are ready to backup the database. @@ -326,13 +330,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -361,9 +371,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -394,9 +404,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -452,27 +462,27 @@ spec: > KubeStash utilizes [Wal-G](https://wal-g.readthedocs.io/SQLServer/) to perform logical backups of `Microsoft SQL Server` databases. Since Wal-G operates with `root` user privileges, it’s necessary to configure our backup job to run as a `root` user by specifying `runAsUser: 0` in the `spec.sessions[*].addon.jobTemplate.spec.securityContext` section. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mssqlserver-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mssqlserver-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mssqlserver-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mssqlserver-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mssqlserver` directory. @@ -483,20 +493,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mssqlserver-backup-frequent-backup */5 * * * * False 0 4m52s 15m -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mssqlserver-backup-frequent-backup-1725449400 BackupConfiguration sample-mssqlserver-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -505,18 +515,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `gcs-mssqlserver-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mssqlserver-repo +kubectl get repository -n demo gcs-mssqlserver-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mssqlserver-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 gcs-mssqlserver-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -529,7 +539,7 @@ gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 gcs-mssqlserve If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -611,9 +621,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created **Create Issuer/ClusterIssuer:** @@ -624,15 +634,15 @@ By following the below steps, we are going to create our desired issuer, - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" ``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=dev -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=dev ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` CR using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, @@ -650,9 +660,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/mssqlserver-ca-issuer-dev.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer-dev.yaml created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/mssqlserver-ca-issuer-dev.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer-dev.yaml created #### Create RestoreSession: @@ -708,18 +718,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-mssqlserver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-mssqlserver created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n dev +watch kubectl get restoresession -n dev +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE restore-sample-mssqlserver gcs-mssqlserver-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -730,33 +740,36 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get mssqlserver -n dev sample-mssqlserver +kubectl get mssqlserver -n dev sample-mssqlserver +``` NAME VERSION STATUS AGE sample-mssqlserver 2022-cu12 Ready 13m -``` Now, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mssqlserver" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mssqlserver" +``` NAME READY STATUS RESTARTS AGE restored-mssqlserver-0 1/1 Running 0 16m -``` And copy the username and password of the `sa` user to access into `mssqlserver` shell. ```bash -$ kubectl get secret -n dev sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n dev sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n dev sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d -Ag9qi8zQiFew0xHo⏎ +```bash +kubectl get secret -n dev sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d ``` +Ag9qi8zQiFew0xHo⏎ Now, Lets exec into the `Pod` to enter into `mssqlserver` shell and verify restored data, ```bash -$ kubectl exec -it -n dev sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "Ag9qi8zQiFew0xHo" -No +kubectl exec -it -n dev sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "Ag9qi8zQiFew0xHo" -No +``` 1> SELECT name from sys.databases; 2> GO name @@ -790,7 +803,6 @@ id type quant color (3 rows affected) > exit -``` Based on the output above, we can confirm that the `playground` database and the `equipment` table, which were previously created in the original database, have now been successfully restored. diff --git a/docs/guides/mssqlserver/backup/auto-backup/index.md b/docs/guides/mssqlserver/backup/auto-backup/index.md index 3d57b72ebb..483d4a2593 100644 --- a/docs/guides/mssqlserver/backup/auto-backup/index.md +++ b/docs/guides/mssqlserver/backup/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mssqlserver/backup/auto-backup/examples](/docs/guides/mssqlserver/backup/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -54,13 +54,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -89,9 +95,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -122,9 +128,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Prepare Issuer/ClusterIssuer @@ -139,15 +145,15 @@ By following the below steps, we are going to create our desired issuer, - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" ``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, @@ -165,9 +171,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created ## Auto-backup with default configurations @@ -228,9 +234,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/mssqlserver-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mssqlserver-default-backup-blueprint created Now, we are ready to backup our `Microsoft SQL Server` databases using few annotations. @@ -283,24 +289,24 @@ Here, Let's create the `MSSQLServer` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/sample-mssqlserver.yaml -mssqlserver.kubedb.com/sample-mssqlserver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/sample-mssqlserver.yaml ``` +mssqlserver.kubedb.com/sample-mssqlserver created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MSSQLServer in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mssqlserver Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mssqlserver -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mssqlserver -o yaml ``` ```yaml @@ -411,10 +417,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mssqlserver-frequent-backup-1727329837 BackupConfiguration appbinding-sample-mssqlserver Succeeded 23s 6m40s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -423,18 +429,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 1.559 KiB Ready 80s 7m32s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-samrver-frequent-backup-1727329837 default-blueprint frequent-backup 2024-09-05T10:53:59Z Delete Succeeded 7m48s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -447,7 +453,7 @@ default-blueprint-appbinding-samrver-frequent-backup-1727329837 default-bluepr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-samrver-frequent-backup-1727329837 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-samrver-frequent-backup-1727329837 -oyaml ``` ```yaml @@ -590,9 +596,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/mssqlserver-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mssqlserver-customize-backup-blueprint created Now, we are ready to backup our `Microsoft SQL Server` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -653,24 +659,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `MSSQLServer` object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/sample-mssqlserver-2.yaml -mssqlserver.kubedb.com/sample-mssqlserver-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/auto-backup/examples/sample-mssqlserver-2.yaml ``` +mssqlserver.kubedb.com/sample-mssqlserver-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MSSQLServer in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mssqlserver-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mssqlserver-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mssqlserver-2 -o yaml ``` ```yaml @@ -787,10 +793,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mssqlserver-2-frequent-backup-1727333656 BackupConfiguration appbinding-sample-mssqlserver-2 Succeeded 1m18s 2m48s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -799,18 +805,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-ser-2-frequent-backup-1727333656 customize-blueprint frequent-backup 2024-09-26T06:54:26Z Delete Succeeded 4m52s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -824,7 +830,7 @@ customize-blueprint-appbinding-ser-2-frequent-backup-1727333656 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-ser-2-frequent-backup-1727333656 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-ser-2-frequent-backup-1727333656 -oyaml ``` ```yaml diff --git a/docs/guides/mssqlserver/backup/customization/index.md b/docs/guides/mssqlserver/backup/customization/index.md index fccb27328a..e15cbfc6e9 100644 --- a/docs/guides/mssqlserver/backup/customization/index.md +++ b/docs/guides/mssqlserver/backup/customization/index.md @@ -227,12 +227,12 @@ Here, You can also restore a specific snapshot. At first, list the available snapshot as bellow, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1727355681 gcs-mssqlserver-repo frequent-backup 2024-09-26T13:01:22Z Delete Succeeded 5m8s gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1727355730 gcs-mssqlserver-repo frequent-backup 2024-09-26T13:02:10Z Delete Succeeded 4m20s gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1727355900 gcs-mssqlserver-repo frequent-backup 2024-09-26T13:05:00Z Delete Succeeded 90s -``` The below example shows how you can pass a specific snapshot name in `.dataSource` section. diff --git a/docs/guides/mssqlserver/backup/logical/index.md b/docs/guides/mssqlserver/backup/logical/index.md index 70ed644fe4..cc7c407245 100644 --- a/docs/guides/mssqlserver/backup/logical/index.md +++ b/docs/guides/mssqlserver/backup/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mssqlserver/backup/logical/examples](/docs/guides/mssqlserver/backup/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -63,15 +63,15 @@ By following the below steps, we are going to create our desired issuer, - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" ``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` CR using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, @@ -89,9 +89,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created **Create MSSQLServer CR:** @@ -134,34 +134,36 @@ spec: Create the above `MSSQLServer` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/sample-mssqlserver.yaml -mssqlserver.kubedb.com/sample-mssqlserver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/sample-mssqlserver.yaml ``` +mssqlserver.kubedb.com/sample-mssqlserver created KubeDB will deploy a `Microsoft SQL Server` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mssqlserver -n demo sample-mssqlserver +kubectl get mssqlserver -n demo sample-mssqlserver +``` NAME VERSION STATUS AGE sample-mssqlserver 2022-cu12 Ready 3m27 -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE mssqlserver-ca kubernetes.io/tls 2 2d20h sample-mssqlserver-auth kubernetes.io/basic-auth 2 3m44s sample-mssqlserver-client-cert kubernetes.io/tls 3 3m14s sample-mssqlserver-server-cert kubernetes.io/tls 3 3m14s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mssqlserver +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mssqlserver +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mssqlserver ClusterIP 10.96.165.94 1433/TCP 4m32s sample-mssqlserver-pods ClusterIP None 1433/TCP 4m32s -``` Here, we have to use service `sample-mssqlserver` and secret `sample-mssqlserver-auth` to connect with the database. `KubeDB` creates an AppBinding CR that holds the necessary information to connect with the database. @@ -170,15 +172,15 @@ Here, we have to use service `sample-mssqlserver` and secret `sample-mssqlserver Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-mssqlserver kubedb.com/mssqlserver 2022 4m18s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mssqlserver -o yaml +kubectl get appbindings -n demo sample-mssqlserver -o yaml ``` ```yaml @@ -239,25 +241,28 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mssqlserver" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mssqlserver" +``` NAME READY STATUS RESTARTS AGE sample-mssqlserver-0 1/1 Running 0 4m44s -``` And copy the username and password of the `sa` user to access into `mssqlserver` shell. ```bash -$ kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d -kkvAFfl8sIxRO2i3⏎ +```bash +kubectl get secret -n demo sample-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d ``` +kkvAFfl8sIxRO2i3⏎ Now, Lets exec into the `Pod` to enter into `mssqlserver` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "kkvAFfl8sIxRO2i3" -No +kubectl exec -it -n demo sample-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver -U sa -P "kkvAFfl8sIxRO2i3" -No +``` # list available databases 1> SELECT name from sys.databases; 2> GO @@ -311,7 +316,6 @@ id type quant color # exit from the pod 1> exit -``` Now, we are ready to backup the database. @@ -324,13 +328,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -359,9 +369,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -392,9 +402,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -450,27 +460,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mssqlserver-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mssqlserver-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mssqlserver-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mssqlserver-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mssqlserver` directory. @@ -481,20 +491,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mssqlserver-backup-frequent-backup */5 * * * * False 0 4m52s 15m -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mssqlserver-backup-frequent-backup-1725449400 BackupConfiguration sample-mssqlserver-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -503,18 +513,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `gcs-mssqlserver-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mssqlserver-repo +kubectl get repository -n demo gcs-mssqlserver-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mssqlserver-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mssqlserver-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 gcs-mssqlserver-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -527,7 +537,7 @@ gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 gcs-mssqlserve If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-mssqlserver-repo-sample-mssqckup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -649,17 +659,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/restored-mssqlserver.yaml -mssqlserver.kubedb.com/restored-mssqlserver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/restored-mssqlserver.yaml ``` +mssqlserver.kubedb.com/restored-mssqlserver created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get mssqlserver -n demo restored-mssqlserver +kubectl get mssqlserver -n demo restored-mssqlserver +``` NAME VERSION STATUS AGE restored-mssqlserver 2022-cu12 Provisioning 7m37 -``` #### Create RestoreSession: @@ -703,18 +713,18 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-mssqlserver-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/backup/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-mssqlserver-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-mssql-restore gcs-mssqlserver-repo Succeeded 12s 8m7s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -725,33 +735,36 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get mssqlserver -n demo restored-mssqlserver +kubectl get mssqlserver -n demo restored-mssqlserver +``` NAME VERSION STATUS AGE restored-mssqlserver 2022-cu12 Ready 13m -``` Now, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mssqlserver" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mssqlserver" +``` NAME READY STATUS RESTARTS AGE restored-mssqlserver-0 1/1 Running 0 16m -``` And copy the username and password of the `sa` user to access into `mssqlserver` shell. ```bash -$ kubectl get secret -n demo restored-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo restored-mssqlserver-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n demo restored-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d -Ag9qi8zQiFew0xHo⏎ +```bash +kubectl get secret -n demo restored-mssqlserver-auth -o jsonpath='{.data.password}'| base64 -d ``` +Ag9qi8zQiFew0xHo⏎ Now, Lets exec into the `Pod` to enter into `mssqlserver` shell and verify restored data, ```bash -$ kubectl exec -it -n demo restored-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S restored-mssqlserver -U sa -P "Ag9qi8zQiFew0xHo" -No +kubectl exec -it -n demo restored-mssqlserver-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S restored-mssqlserver -U sa -P "Ag9qi8zQiFew0xHo" -No +``` 1> SELECT name from sys.databases; 2> GO name @@ -785,7 +798,6 @@ id type quant color (3 rows affected) > exit -``` So, from the above output, we can see that the `playground` database and the `equipment` table we have created earlier in the original database and now, they are restored successfully. ## Cleanup diff --git a/docs/guides/mssqlserver/clustering/ag_cluster.md b/docs/guides/mssqlserver/clustering/ag_cluster.md index 3df4e84df5..b9d6a1ff90 100644 --- a/docs/guides/mssqlserver/clustering/ag_cluster.md +++ b/docs/guides/mssqlserver/clustering/ag_cluster.md @@ -27,24 +27,25 @@ This tutorial will show you how to use KubeDB to run Microsoft SQL Server Availa - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d20h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available Microsoft SQL Server Versions When you have installed KubeDB, it has created `MSSQLServerVersion` CR for all supported Microsoft SQL Server versions. Check it by using the `kubectl get mssqlserverversions`. You can also use `msversion` shorthand instead of `mssqlserverversions`. ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 7d19h 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 7d19h @@ -53,8 +54,6 @@ NAME VERSION DB_IMAGE DE 2022-cu22 2022 mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04 7d19h 2025-cu0 2025 mcr.microsoft.com/mssql/server:2025-RTM-ubuntu-22.04 7d19h -``` - > Note: The yaml files used in this tutorial are stored in [docs/examples/mssqlserver/ag-cluster/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -74,9 +73,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -92,9 +91,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Configuring Environment Variables for SQL Server on Linux You can use environment variables to configure SQL Server on Linux containers. @@ -176,9 +175,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created Here, @@ -197,8 +196,8 @@ KubeDB operator watches for `MSSQLServer` objects using Kubernetes api. When a ` Let's see the sql server resources that are created. ```bash -$ kubectl get ms,petset,pod,svc,secret,issuer,pvc -n demo - +kubectl get ms,petset,pod,svc,secret,issuer,pvc -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssqlserver-ag-cluster 2022-cu12 Ready 178m @@ -228,12 +227,11 @@ NAME STATUS VOLUME persistentvolumeclaim/data-mssqlserver-ag-cluster-0 Bound pvc-33ae1829-c559-407b-a148-1792c22b52a6 1Gi RWO standard 177m persistentvolumeclaim/data-mssqlserver-ag-cluster-1 Bound pvc-b697b7ad-8348-431f-b2c7-01620bec4f8d 1Gi RWO standard 177m persistentvolumeclaim/data-mssqlserver-ag-cluster-2 Bound pvc-b486a79c-a8ae-449a-bc15-74491f062573 1Gi RWO standard 177m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created and is able to accept client connections. Run the following command to see the modified MSSQLServer object: ```bash -$ kubectl get ms -n demo mssqlserver-ag-cluster -o yaml +kubectl get ms -n demo mssqlserver-ag-cluster -o yaml ``` ```yaml @@ -408,12 +406,14 @@ If you want to use an existing secret please specify that when creating the MSSQ Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `mssqlserver-ag-cluster-auth` secret holds username and password ```bash -$ kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d -wFKDGnWgFP5Rdv92 +```bash +kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d ``` +wFKDGnWgFP5Rdv92 We can exec into the pod `mssqlserver-ag-cluster-0` using the following command: ```bash kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash @@ -458,7 +458,8 @@ usage: sqlcmd [-U login id] [-P password] Now, connect to the database using username and password, check the name of the created availability group, replicas of the availability group and see if databases are added to the availability group. ```bash -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "wFKDGnWgFP5Rdv92" -No 1> select name from sys.databases 2> go @@ -497,23 +498,22 @@ agdb2 (2 rows affected) -``` - Now, to check the redundancy and data availability in secondary members. Let's insert some data into the primary database of sql server availability group and see if data replication is working fine. First we have to determine the primary replica, as data writes are only permitted on the primary node. ```bash -$ kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +``` mssqlserver-ag-cluster-0 primary mssqlserver-ag-cluster-1 secondary mssqlserver-ag-cluster-2 secondary -``` From the output above, we can see that mssqlserver-ag-cluster-0 is the primary node. To insert data, log into the primary MSSQLServer pod. Use the following command, ```bash -$ kubectl exec -it mssqlserver-ag-cluster-0 -c mssql -n demo -- bash +kubectl exec -it mssqlserver-ag-cluster-0 -c mssql -n demo -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "wFKDGnWgFP5Rdv92" -No 1> SELECT database_name FROM sys.availability_databases_cluster 2> go @@ -540,13 +540,13 @@ ID NAME AGE (2 rows affected) 1> -``` Now, Let's verify that the data inserted into the primary node has been replicated to the secondary nodes. ### Access the inserted data from secondaries Access the secondary node (Node 2) to verify that the data is present. ```bash -$ kubectl exec -it mssqlserver-ag-cluster-1 -c mssql -n demo -- bash +kubectl exec -it mssqlserver-ag-cluster-1 -c mssql -n demo -- bash +``` mssql@mssqlserver-ag-cluster-1:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "wFKDGnWgFP5Rdv92" -No 1> SELECT database_name FROM sys.availability_databases_cluster 2> go @@ -568,12 +568,12 @@ ID NAME AGE (2 rows affected) 1> -``` Now access the secondary node (Node 3) to verify that the data is present. ```bash -$ kubectl exec -it mssqlserver-ag-cluster-2 -c mssql -n demo -- bash +kubectl exec -it mssqlserver-ag-cluster-2 -c mssql -n demo -- bash +``` mssql@mssqlserver-ag-cluster-2:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "wFKDGnWgFP5Rdv92" -No 1> SELECT database_name FROM sys.availability_databases_cluster 2> go @@ -595,42 +595,46 @@ ID NAME AGE (2 rows affected) 1> -``` ## Automatic Failover To test automatic failover, we will force the primary member to restart. As the primary member (pod) becomes unavailable, the rest of the members will elect a primary member by election. ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mssqlserver-ag-cluster-0 2/2 Running 0 129m mssqlserver-ag-cluster-1 2/2 Running 0 129m mssqlserver-ag-cluster-2 2/2 Running 0 129m -$ kubectl delete pod -n demo mssqlserver-ag-cluster-0 +```bash +kubectl delete pod -n demo mssqlserver-ag-cluster-0 +``` pod "mssqlserver-ag-cluster-0" deleted -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mssqlserver-ag-cluster-0 2/2 Running 0 7s mssqlserver-ag-cluster-1 2/2 Running 0 130m mssqlserver-ag-cluster-2 2/2 Running 0 130m -``` Now find the new primary pod by running this command. ```bash -$ kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +``` mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 primary mssqlserver-ag-cluster-2 secondary -``` We can see that, the primary node is now is `mssqlserver-ag-cluster-1`. The old primary pod `mssqlserver-ag-cluster-0` role is still pending. It will be set when old primary joins with the new primary as secondary. Lets exec into this new primary and see the availability replica role. ```bash -$ kubectl exec -it mssqlserver-ag-cluster-1 -c mssql -n demo -- bash +kubectl exec -it mssqlserver-ag-cluster-1 -c mssql -n demo -- bash +``` mssql@mssqlserver-ag-cluster-1:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "wFKDGnWgFP5Rdv92" -No 1> SELECT ar.replica_server_name, ars.role_desc 2> FROM sys.dm_hadr_availability_replica_states ars @@ -644,20 +648,18 @@ mssqlserver-ag-cluster-2 (3 rows affected) -``` - We can see that new primary is `mssqlserver-ag-cluster-1` and the old primary `mssqlserver-ag-cluster-0` joined the availability group cluster as secondary. MSSQLServer status is `Ready` now. We can see the updated pod labels. ```bash -$ kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +kubectl get pods -n demo --selector=app.kubernetes.io/instance=mssqlserver-ag-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +``` mssqlserver-ag-cluster-0 secondary mssqlserver-ag-cluster-1 primary mssqlserver-ag-cluster-2 secondary -```` Run the following command to see the created appbinding object: ```bash -$ kubectl get appbinding -n demo -oyaml +kubectl get appbinding -n demo -oyaml ``` ```yaml @@ -718,12 +720,14 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-ag-cluster patched -$ kubectl delete ms -n demo mssqlserver-ag-cluster -The MSSQLServer "mssqlserver-ag-cluster" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-ag-cluster": Can not delete as deletionPolicy is set to "DoNotTerminate" +```bash +kubectl delete ms -n demo mssqlserver-ag-cluster ``` +The MSSQLServer "mssqlserver-ag-cluster" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-ag-cluster": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"` to set `spec.deletionPolicy` to `Halt` (which deletes the mssqlserver object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -738,14 +742,15 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd At first, run `kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"`. Then delete the mssqlserver object, ```bash -$ kubectl delete ms -n demo mssqlserver-ag-cluster -mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted +kubectl delete ms -n demo mssqlserver-ag-cluster ``` +mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted Now, run the following command to get mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ag-cluster-auth kubernetes.io/basic-auth 2 3h6m secret/mssqlserver-ag-cluster-client-cert kubernetes.io/tls 3 3h6m @@ -760,7 +765,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-mssqlserver-ag-cluster-0 Bound pvc-33ae1829-c559-407b-a148-1792c22b52a6 1Gi RWO standard 3h6m persistentvolumeclaim/data-mssqlserver-ag-cluster-1 Bound pvc-b697b7ad-8348-431f-b2c7-01620bec4f8d 1Gi RWO standard 3h6m persistentvolumeclaim/data-mssqlserver-ag-cluster-2 Bound pvc-b486a79c-a8ae-449a-bc15-74491f062573 1Gi RWO standard 3h5m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your mssqlserver again using these resources. @@ -773,16 +777,20 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-ag-cluster patched -$ kubectl delete ms -n demo mssqlserver-ag-cluster -mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted + +```bash +kubectl delete ms -n demo mssqlserver-ag-cluster ``` +mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ag-cluster-auth kubernetes.io/basic-auth 2 3h6m secret/mssqlserver-ag-cluster-client-cert kubernetes.io/tls 3 3h6m @@ -792,7 +800,6 @@ secret/mssqlserver-ag-cluster-endpoint-cert kubernetes.io/tls 3 secret/mssqlserver-ag-cluster-master-key kubernetes.io/basic-auth 1 3h6m secret/mssqlserver-ag-cluster-server-cert kubernetes.io/tls 3 3h6m secret/mssqlserver-ca kubernetes.io/tls 2 3h8m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, `PVCs` etc.) are deleted except `Secret`. You can initialize your mssqlserver using `snapshots`(if previously taken) and `Secrets`. @@ -815,10 +822,10 @@ mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 3h8m -``` From the above output, you can see that all mssqlserver resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `WipeOut`. diff --git a/docs/guides/mssqlserver/clustering/arbiter.md b/docs/guides/mssqlserver/clustering/arbiter.md index 07f0b197c5..629cf8fa92 100644 --- a/docs/guides/mssqlserver/clustering/arbiter.md +++ b/docs/guides/mssqlserver/clustering/arbiter.md @@ -45,9 +45,9 @@ Here we will show how to use KubeDB to provision a SQL Server even-sized Availab To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created @@ -65,9 +65,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -83,9 +83,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, Let's apply the following YAML for a Two-Node Cluster (with Arbiter): @@ -186,15 +186,18 @@ KubeDB operator has created a new Secret called `ms-even-cluster-auth` *(format: Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `ms-even-cluster-auth` secret holds username and password ```bash -$ kubectl get secret -n demo ms-even-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo ms-even-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo ms-even-cluster-auth -o jsonpath='{.data.\password}' | base64 -d -AgciggjkiIaSkDs1 +```bash +kubectl get secret -n demo ms-even-cluster-auth -o jsonpath='{.data.\password}' | base64 -d ``` +AgciggjkiIaSkDs1 We can exec into the pod `ms-even-cluster-0` using the following command: ```bash -$ kubectl exec -it -n demo ms-even-cluster-0 -c mssql -- bash +kubectl exec -it -n demo ms-even-cluster-0 -c mssql -- bash +``` mssql@ms-even-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "AgciggjkiIaSkDs1" -No 1> select name from sys.databases 2> go @@ -232,20 +235,19 @@ agdb2 (2 rows affected) -``` - See the pod roles: ```bash -$ kubectl get pods -n demo --selector=app.kubernetes.io/instance=ms-even-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +kubectl get pods -n demo --selector=app.kubernetes.io/instance=ms-even-cluster -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.kubedb\.com/role}{"\n"}{end}' +``` ms-even-cluster-0 primary ms-even-cluster-1 secondary ms-even-cluster-arbiter-0 arbiter -``` From the output above, we can see that ms-even-cluster-0 is the primary node. To insert data, log into the primary MSSQLServer pod. Use the following command, ```bash -$ kubectl exec -it ms-even-cluster-0 -c mssql -n demo -- bash +kubectl exec -it ms-even-cluster-0 -c mssql -n demo -- bash +``` mssql@ms-even-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "AgciggjkiIaSkDs1" -No 1> SELECT database_name FROM sys.availability_databases_cluster 2> go @@ -272,14 +274,14 @@ ID NAME AGE (2 rows affected) 1> -``` Now, Let's verify that the data inserted into the primary node has been replicated to the secondary node. ### Access the inserted data from secondaries Access the secondary node (Node 2) to verify that the data is present. ```bash -$ kubectl exec -it ms-even-cluster-1 -c mssql -n demo -- bash +kubectl exec -it ms-even-cluster-1 -c mssql -n demo -- bash +``` mssql@ms-even-cluster-1:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "AgciggjkiIaSkDs1" -No 1> SELECT database_name FROM sys.availability_databases_cluster 2> go @@ -301,7 +303,6 @@ ID NAME AGE (2 rows affected) 1> -``` ## Why do we need arbiter node? diff --git a/docs/guides/mssqlserver/clustering/dag_cluster.md b/docs/guides/mssqlserver/clustering/dag_cluster.md index a89ac28884..831f0aa4a4 100644 --- a/docs/guides/mssqlserver/clustering/dag_cluster.md +++ b/docs/guides/mssqlserver/clustering/dag_cluster.md @@ -21,11 +21,11 @@ This tutorial will show you how to use KubeDB to run a Microsoft SQL Server Dist - Each cluster must have KubeDB installed. Follow the steps [here](/docs/setup/README.md), ensuring you enable the MSSQLServer feature gate: `--set global.featureGates.MSSQLServer=true`. - To configure TLS/SSL in `MSSQLServer`, `KubeDB` uses `cert-manager` to issue certificates. - Each cluster must have `cert-manager` installed. Follow the steps [here](https://cert-manager.io/docs/installation/kubernetes/). - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in both clusters. -```bash - $ kubectl get storageclasses + ```bash + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 4h48m -``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. @@ -44,13 +44,13 @@ local-path (default) rancher.io/local-path Delete WaitForFirstConsu When you have installed KubeDB, it has created `MSSQLServerVersion` CR for all supported Microsoft SQL Server versions. Check it by using the `kubectl get mssqlserverversions`. You can also use `msversion` shorthand instead of `mssqlserverversions`. ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 161m 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 161m 2022-cu16 2022 mcr.microsoft.com/mssql/server:2022-CU16-ubuntu-22.04 161m 2022-cu19 2022 mcr.microsoft.com/mssql/server:2022-CU19-ubuntu-22.04 161m -``` ## Deploy Microsoft SQL Server Distributed Availability Group Cluster @@ -72,9 +72,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -90,9 +90,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Configuring Environment Variables for SQL Server on Linux You can use environment variables to configure SQL Server on Linux containers. @@ -218,20 +218,22 @@ spec: Deploy `ag1` primary service to your first cluster: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/ag1-primary-svc.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/ag1-primary-svc.yaml +``` service/ag1 created created -$ kubectl get svc -n demo ag1 +```bash +kubectl get svc -n demo ag1 +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ag1 LoadBalancer 10.43.117.2 10.2.0.236 1433:31485/TCP,5022:32511/TCP 122m -``` Deploy `ag1` to your first cluster: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/ag1.yaml -mssqlserver.kubedb.com/ag1 created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/dag-cluster/ag1.yaml ``` +mssqlserver.kubedb.com/ag1 created diff --git a/docs/guides/mssqlserver/clustering/standalone.md b/docs/guides/mssqlserver/clustering/standalone.md index 933beeb666..fbd52f27ef 100644 --- a/docs/guides/mssqlserver/clustering/standalone.md +++ b/docs/guides/mssqlserver/clustering/standalone.md @@ -28,24 +28,25 @@ This tutorial will show you how to use KubeDB to run a Standalone SQL Server dat - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d20h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available Microsoft SQL Server Versions When you have installed KubeDB, it has created `MSSQLServerVersion` CR for all supported Microsoft SQL Server versions. Check it by using the `kubectl get mssqlserverversions`. You can also use `msversion` shorthand instead of `mssqlserverversions`. ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 7d19h 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 7d19h @@ -54,8 +55,6 @@ NAME VERSION DB_IMAGE DE 2022-cu22 2022 mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04 7d19h 2025-cu0 2025 mcr.microsoft.com/mssql/server:2025-RTM-ubuntu-22.04 7d19h -``` - > Note: The yaml files used in this tutorial are stored in [docs/examples/mssqlserver/standalone/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -76,9 +75,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -94,9 +93,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Configuring Environment Variables for SQL Server on Linux You can use environment variables to configure SQL Server on Linux containers. @@ -172,9 +171,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-standalone.yaml -mssqlserver.kubedb.com/mssqlserver-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-standalone.yaml ``` +mssqlserver.kubedb.com/mssqlserver-standalone created Here, @@ -189,17 +188,20 @@ Here, KubeDB operator watches for `MSSQLServer` objects using Kubernetes api. When a `MSSQLServer` object is created, KubeDB operator will create a new PetSet and a Service with the matching MSSQLServer object name. KubeDB operator will also create a governing service for PetSets with the name `-pods`, if one is not already present. ```bash -$ kubectl get petset -n demo mssqlserver-standalone +kubectl get petset -n demo mssqlserver-standalone +``` NAME AGE mssqlserver-standalone 13m - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-mssqlserver-standalone-0 Bound pvc-ccbba9d2-5556-49cd-9ce8-23c28ad56f12 1Gi RWO standard 15m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ccbba9d2-5556-49cd-9ce8-23c28ad56f12 1Gi RWO Delete Bound demo/data-mssqlserver-standalone-0 standard 15m @@ -209,12 +211,10 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) mssqlserver-standalone ClusterIP 10.96.128.61 1433/TCP 15m mssqlserver-standalone-pods ClusterIP None 1433/TCP 15m -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created and is able to accept client connections. Run the following command to see the modified MSSQLServer object: ```bash -$ kubectl get ms -n demo mssqlserver-standalone -o yaml +kubectl get ms -n demo mssqlserver-standalone -o yaml ``` ```yaml @@ -362,12 +362,14 @@ If you want to use an existing secret please specify that when creating the MSSQ Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `mssqlserver-standalone-auth` secret holds username and password ```bash -$ kubectl get secret -n demo mssqlserver-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo mssqlserver-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo mssqlserver-standalone-auth -o jsonpath='{.data.\password}' | base64 -d -axgXHj4oRIVQ1ocK +```bash +kubectl get secret -n demo mssqlserver-standalone-auth -o jsonpath='{.data.\password}' | base64 -d ``` +axgXHj4oRIVQ1ocK We can exec into the pod `mssqlserver-standalone-0` using the following command: ```bash kubectl exec -it -n demo mssqlserver-standalone-0 -c mssql -- bash @@ -431,7 +433,7 @@ kubedb_system Run the following command to see the created appbinding object: ```bash -$ kubectl get appbinding -n demo -oyaml +kubectl get appbinding -n demo -oyaml ``` ```yaml @@ -495,12 +497,14 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-standalone patched -$ kubectl delete ms -n demo mssqlserver-standalone -The MSSQLServer "mssqlserver-standalone" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-standalone": Can not delete as deletionPolicy is set to "DoNotTerminate" +```bash +kubectl delete ms -n demo mssqlserver-standalone ``` +The MSSQLServer "mssqlserver-standalone" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-standalone": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"` to set `spec.deletionPolicy` to `Halt` (which deletes the mssqlserver object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -515,14 +519,15 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd At first, run `kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"`. Then delete the mssqlserver object, ```bash -$ kubectl delete ms -n demo mssqlserver-standalone -mssqlserver.kubedb.com "mssqlserver-standalone" deleted +kubectl delete ms -n demo mssqlserver-standalone ``` +mssqlserver.kubedb.com "mssqlserver-standalone" deleted Now, run the following command to get mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 40m secret/mssqlserver-standalone-auth kubernetes.io/basic-auth 2 30m @@ -532,7 +537,6 @@ secret/mssqlserver-standalone-server-cert kubernetes.io/tls 3 30 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-mssqlserver-standalone-0 Bound pvc-656e3bd1-65da-441c-851f-2ae076f8ebbd 1Gi RWO standard 29m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your mssqlserver again using these resources. @@ -545,23 +549,26 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-standalone -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-standalone patched -$ kubectl delete ms -n demo mssqlserver-standalone -mssqlserver.kubedb.com "mssqlserver-standalone" deleted + +```bash +kubectl delete ms -n demo mssqlserver-standalone ``` +mssqlserver.kubedb.com "mssqlserver-standalone" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 49m secret/mssqlserver-standalone-auth kubernetes.io/basic-auth 2 39m secret/mssqlserver-standalone-client-cert kubernetes.io/tls 3 39m secret/mssqlserver-standalone-config Opaque 1 39m secret/mssqlserver-standalone-server-cert kubernetes.io/tls 3 39m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, `PVCs` etc.) are deleted except `Secret`. You can initialize your mssqlserver using `snapshots`(if previously taken) and `Secrets`. @@ -584,10 +591,10 @@ mssqlserver.kubedb.com "mssqlserver-standalone" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 53m -``` From the above output, you can see that all mssqlserver resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `WipeOut`. diff --git a/docs/guides/mssqlserver/concepts/mssqlserver.md b/docs/guides/mssqlserver/concepts/mssqlserver.md index b9fb8457ab..990714c368 100644 --- a/docs/guides/mssqlserver/concepts/mssqlserver.md +++ b/docs/guides/mssqlserver/concepts/mssqlserver.md @@ -188,11 +188,11 @@ spec: `spec.version` is a required field that specifies the name of the [MSSQLServerVersion](/docs/guides/mssqlserver/concepts/catalog.md) crd where the docker images are specified. Currently, when you install KubeDB, it creates the following `MSSQLServerVersion` resources, ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 2d 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 2d -``` ### spec.replicas `spec.replicas` specifies the total number of primary and secondary nodes in SQL Server Availability Group cluster configuration. One pod is selected as Primary and others act as secondary replicas. KubeDB uses `PodDisruptionBudget` to ensure that majority of the replicas are available during [voluntary disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#voluntary-and-involuntary-disruptions). @@ -208,14 +208,15 @@ If you want to use an existing or custom secret, please specify that when creati Example: ```bash -$ kubectl create secret generic mssqlserver-auth -n demo \ +kubectl create secret generic mssqlserver-auth -n demo \ --from-literal=username='sa' \ --from-literal=password='Pa55w0rd!' -secret/mssqlserver-auth created ``` +secret/mssqlserver-auth created ```bash -$ kubectl get secret -n demo mssqlserver-auth -oyaml +kubectl get secret -n demo mssqlserver-auth -oyaml +``` apiVersion: v1 data: password: UGE1NXcwcmQh @@ -228,7 +229,6 @@ metadata: resourceVersion: "315403" uid: dafcce02-b6a2-4e65-bdd1-db6b9b6d4913 type: Opaque -``` ### spec.storageType diff --git a/docs/guides/mssqlserver/configuration/using-config-file.md b/docs/guides/mssqlserver/configuration/using-config-file.md index 3b8ebcecd7..15fac08745 100644 --- a/docs/guides/mssqlserver/configuration/using-config-file.md +++ b/docs/guides/mssqlserver/configuration/using-config-file.md @@ -27,9 +27,9 @@ KubeDB supports providing custom configuration for MSSQLServer. This tutorial wi - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -72,13 +72,13 @@ Here we have set Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf -secret/ms-custom-config created +kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf ``` +secret/ms-custom-config created Verify the secret has the configuration file. ```bash -$ kubectl get secret -n demo ms-custom-config -oyaml +kubectl get secret -n demo ms-custom-config -oyaml ``` ```yaml @@ -110,9 +110,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -128,9 +128,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created @@ -174,32 +174,37 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/configuration/mssql-custom-config.yaml -mssqlserver.kubedb.com/mssql-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/configuration/mssql-custom-config.yaml ``` +mssqlserver.kubedb.com/mssql-custom-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secrets etc. If everything goes well, we will see that a pod with the name `mssql-custom-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo mssql-custom-config-0 +kubectl get pod -n demo mssql-custom-config-0 +``` NAME READY STATUS RESTARTS AGE mssql-custom-config-0 1/1 Running 0 94s -``` Now, we will check if the database has started with the custom configuration we have provided. Now, Let's connect to the MSSQLServer from inside the pod. ```bash -$ kubectl get secrets -n demo mssql-custom-config-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo mssql-custom-config-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo mssql-custom-config-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo mssql-custom-config-auth -o jsonpath='{.data.\password}' | base64 -d +``` AqRe6WIuqwKXLaWc -$ kubectl exec -it mssql-custom-config-0 -n demo -c mssql -- bash +```bash +kubectl exec -it mssql-custom-config-0 -n demo -c mssql -- bash +``` mssql@mssql-custom-config-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1036 @@ -230,7 +235,6 @@ physical_memory_mb 2304 (1 rows affected) 1> -``` As we can see from the configuration of running sql server, the configuration given in the config secret has been set successfully. @@ -240,16 +244,20 @@ As we can see from the configuration of running sql server, the configuration gi To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ms/mssql-custom-config -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ms/mssql-custom-config -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete -n demo ms/mssql-custom-config +```bash +kubectl delete -n demo ms/mssql-custom-config +``` mssqlserver.kubedb.com "mssql-custom-config" deleted -$ kubectl delete -n demo secret ms-custom-config +```bash +kubectl delete -n demo secret ms-custom-config +``` mssqlserver.kubedb.com "mssql-custom-config" deleted kubectl delete ns demo -``` ## Next Steps diff --git a/docs/guides/mssqlserver/configuration/using-podtemplate.md b/docs/guides/mssqlserver/configuration/using-podtemplate.md index 12a3e89e33..d0b0a4ff02 100644 --- a/docs/guides/mssqlserver/configuration/using-podtemplate.md +++ b/docs/guides/mssqlserver/configuration/using-podtemplate.md @@ -27,9 +27,9 @@ KubeDB supports providing custom configuration for MSSQLServer via [PodTemplate] - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/configuration) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -92,9 +92,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -110,9 +110,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Create MSSQLServer CR with Custom Configuration using PodTemplate @@ -163,24 +163,25 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/configuration/custom-config-podtemplate.yaml -mssqlserver.kubedb.com/custom-config-podtemplate created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/configuration/custom-config-podtemplate.yaml ``` +mssqlserver.kubedb.com/custom-config-podtemplate created Now, wait a few minutes. KubeDB operator will create necessary Petset, PVCs, Services, Secrets etc. If everything goes well, we will see that a pod with the name `custom-config-podtemplate-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE custom-config-podtemplate-0 1/1 Running 0 16m -``` Now, check if the database has started with the custom configuration we have provided. ```bash -$ kubectl get pod -n demo custom-config-podtemplate-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo custom-config-podtemplate-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "3", @@ -192,14 +193,19 @@ $ kubectl get pod -n demo custom-config-podtemplate-0 -o json | jq '.spec.contai } } - -$ kubectl get secrets -n demo custom-config-podtemplate-auth -o jsonpath='{.data.\username}' | base64 -d +```bash +kubectl get secrets -n demo custom-config-podtemplate-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo custom-config-podtemplate-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo custom-config-podtemplate-auth -o jsonpath='{.data.\password}' | base64 -d +``` 3K7lJibYg3y6ICXc -$ kubectl exec -it custom-config-podtemplate-0 -n demo -c mssql -- bash +```bash +kubectl exec -it custom-config-podtemplate-0 -n demo -c mssql -- bash +``` mssql@custom-config-podtemplate-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P 3K7lJibYg3y6ICXc -No 1> SELECT physical_memory_kb / 1024 AS physical_memory_mb FROM sys.dm_os_sys_info; 2> go @@ -224,7 +230,6 @@ Microsoft SQL Server 2022 (RTM-CU12) (KB5033663) - 16.0.4115.5 (X64) Enterprise Evaluation Edition (64-bit) on Linux (Ubuntu 22.04.4 LTS) (1 rows affected) -``` You can see that our desired configuration is applied successfully. diff --git a/docs/guides/mssqlserver/failover/guide.md b/docs/guides/mssqlserver/failover/guide.md index 53bfcbce83..9866c5d80b 100644 --- a/docs/guides/mssqlserver/failover/guide.md +++ b/docs/guides/mssqlserver/failover/guide.md @@ -50,32 +50,31 @@ to 45 seconds. But that is a bit rare though. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d20h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available Microsoft SQL Server Versions When you have installed KubeDB, it has created `MSSQLServerVersion` CR for all supported Microsoft SQL Server versions. Check it by using the `kubectl get mssqlserverversions`. You can also use `msversion` shorthand instead of `mssqlserverversions`. ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 9m38s 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 9m38s 2022-cu16 2022 mcr.microsoft.com/mssql/server:2022-CU16-ubuntu-22.04 9m38s 2022-cu19 2022 mcr.microsoft.com/mssql/server:2022-CU19-ubuntu-22.04 9m38s -``` - > Note: The yaml files used in this tutorial are stored in [docs/examples/mssqlserver/ag-cluster/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Deploy Microsoft SQL Server Availability Group Cluster @@ -94,9 +93,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -112,9 +111,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Step 1: Create a High-Availability MSSQLServer Cluster @@ -170,14 +169,16 @@ spec: Now, create the namespace and apply the manifest: -```shell # Create the namespace if it doesn't exist -$ kubectl create ns demo +```bash +kubectl create ns demo +``` # Apply the manifest to deploy the cluster -$ kubectl apply -f mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +```bash +kubectl apply -f mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created You can monitor the status until all pods are ready: ```shell @@ -185,8 +186,9 @@ watch kubectl get ms,petset,pods -n demo ``` See the database is ready. -```shell -$ kubectl get ms,petset,pods -n demo +```bash +kubectl get ms,petset,pods -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssqlserver-ag-cluster 2022-cu16 Ready 11m @@ -198,34 +200,40 @@ pod/mssqlserver-ag-cluster-0 2/2 Running 0 10m pod/mssqlserver-ag-cluster-1 2/2 Running 0 8m47s pod/mssqlserver-ag-cluster-2 2/2 Running 0 8m40s -``` - Inspect who is primary and who is secondary. -```shell # you can inspect who is primary # and who is secondary like below - -$ kubectl get pods -n demo --show-labels | grep role +```bash +kubectl get pods -n demo --show-labels | grep role +``` mssqlserver-ag-cluster-0 2/2 Running 0 12m app.kubernetes.io/component=database,app.kubernetes.io/instance=mssqlserver-ag-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mssqlservers.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=mssqlserver-ag-cluster-5c944b9596,kubedb.com/role=primary,statefulset.kubernetes.io/pod-name=mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 2/2 Running 0 11m app.kubernetes.io/component=database,app.kubernetes.io/instance=mssqlserver-ag-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mssqlservers.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=mssqlserver-ag-cluster-5c944b9596,kubedb.com/role=secondary,statefulset.kubernetes.io/pod-name=mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 2/2 Running 0 10m app.kubernetes.io/component=database,app.kubernetes.io/instance=mssqlserver-ag-cluster,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mssqlservers.kubedb.com,apps.kubernetes.io/pod-index=2,controller-revision-hash=mssqlserver-ag-cluster-5c944b9596,kubedb.com/role=secondary,statefulset.kubernetes.io/pod-name=mssqlserver-ag-cluster-2 - -``` The pod having `kubedb.com/role=primary` is the primary and `kubedb.com/role=secondary` are the secondaries. Let's create a table in the primary. -```shell # find the primary pod -$ kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +```bash +kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +``` mssqlserver-ag-cluster-0 -$ kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa⏎ -$ kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d + +```bash +kubectl get secret -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d +``` tZQpzrowQQ20xbCf⏎ -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash + +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> select name from sys.databases 2> go @@ -265,12 +273,11 @@ id name (2 rows affected) -``` - Verify the table creation in secondary's. -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-1 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-1 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-1:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> select name from sys.databases 2> go @@ -295,8 +302,6 @@ id name 2 Bob 2025-07-31 05:51:06.847 (2 rows affected) - -``` ### Step 2: Simulating a Failover Before simulating failover, let's discuss how we handle these failover scenarios in KubeDB-managed @@ -323,10 +328,10 @@ mssqlserver-ag-cluster-2 secondary Let's delete the current primary and see how the role change happens almost immediately. -```shell -$ kubectl delete pods -n demo mssqlserver-ag-cluster-0 -pod "mssqlserver-ag-cluster-0" deleted +```bash +kubectl delete pods -n demo mssqlserver-ag-cluster-0 ``` +pod "mssqlserver-ag-cluster-0" deleted ```shell mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 secondary @@ -344,8 +349,9 @@ You see almost immediately the failover happened. Here's what happened internall Now we know how failover is done, let's check if the new primary `mssqlserver-ag-cluster-2` is working. -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-2 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-2 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-2:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> use agdb1 2> go @@ -369,8 +375,6 @@ data1 (2 rows affected) -``` - You will see the deleted pod (`mssqlserver-ag-cluster-0`) is brought back by the kubedb operator and it is now assigned to `secondary role`. @@ -384,8 +388,9 @@ mssqlserver-ag-cluster-2 primary Let's check if the secondary(`mssqlserver-ag-cluster-0`) got the updated data from new primary `mssqlserver-ag-cluster-2`. -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> use agdb1 2> go @@ -403,14 +408,12 @@ data1 Msg 3906, Level 16, State 2, Server mssqlserver-ag-cluster-1, Line 1 Failed to update database "agdb1" because the database is read-only. -``` - #### Case 2: Delete the current primary and one secondary -```shell -$ kubectl delete pods -n demo mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +```bash +kubectl delete pods -n demo mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +``` pod "mssqlserver-ag-cluster-1" deleted pod "mssqlserver-ag-cluster-2" deleted -``` Again we can see the failover happened pretty quickly. ```shell mssqlserver-ag-cluster-0 secondary @@ -428,8 +431,9 @@ mssqlserver-ag-cluster-2 secondary Let's validate the cluster state from new primary(`mssqlserver-ag-cluster-0`). -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> use agdb1 2> go @@ -438,18 +442,15 @@ Changed database context to 'agdb1'. 1> CREATE TABLE data2 (id INT PRIMARY KEY, name NVARCHAR(100), created_at DATETIME DEFAULT GETDATE()); 2> go -``` - #### Case3: Delete any of the replica's Let's delete both of the secondary's. -```shell -$ kubectl delete pods -n demo mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +```bash +kubectl delete pods -n demo mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +``` pod "mssqlserver-ag-cluster-1" deleted pod "mssqlserver-ag-cluster-2" deleted - -``` ```shell mssqlserver-ag-cluster-0 primary mssqlserver-ag-cluster-1 @@ -465,8 +466,9 @@ mssqlserver-ag-cluster-2 secondary ``` Let's verify cluster state. -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> use agdb1 2> go @@ -482,19 +484,16 @@ C4FADE0D-BC82-4D16-95E2-50AA6BE5BD8F BBCC64C9-E0E3-5985-6F01-884248E3DDC6 (3 rows affected) -``` - #### Case 4: Delete both primary and all replicas Let's delete all the pods. -```shell -$ kubectl delete pods -n demo mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +```bash +kubectl delete pods -n demo mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 mssqlserver-ag-cluster-2 +``` pod "mssqlserver-ag-cluster-0" deleted pod "mssqlserver-ag-cluster-1" deleted pod "mssqlserver-ag-cluster-2" deleted - -``` ```shell mssqlserver-ag-cluster-0 mssqlserver-ag-cluster-1 @@ -510,8 +509,9 @@ mssqlserver-ag-cluster-2 secondary ``` Let's verify the cluster state now. -```shell -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +```bash + kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "tZQpzrowQQ20xbCf" -No 1> use agdb1 2> go @@ -525,8 +525,6 @@ C4FADE0D-BC82-4D16-95E2-50AA6BE5BD8F BBCC64C9-E0E3-5985-6F01-884248E3DDC6 (3 rows affected) -``` - > **We make sure the pod with highest lsn for all databases (you can think lsn as the highest data point available in the databases) always run as primary, so if a case occur where the pod with highest lsn is being terminated, we will not perform the failover until the highest lsn pod is back online. @@ -568,10 +566,13 @@ It depends on your `StorageClass`. If your storageclass supports online volume e ## CleanUp -```shell -$ kubectl delete ms -n demo mssqlserver-ag-cluster +```bash +kubectl delete ms -n demo mssqlserver-ag-cluster +``` + # Or, delete the demo -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mssqlserver/gitops/gitops.md b/docs/guides/mssqlserver/gitops/gitops.md index b760296304..7cffa861b5 100644 --- a/docs/guides/mssqlserver/gitops/gitops.md +++ b/docs/guides/mssqlserver/gitops/gitops.md @@ -28,12 +28,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create Mssqlserv - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Mssqlserver) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -81,9 +83,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -98,7 +100,8 @@ spec: ``` Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── ms-issuer.yaml 1 directories, 1 files @@ -107,7 +110,6 @@ Now, we are going to deploy a `MSSQLServer` availability group with version `202 ### Create a Mssqlserver GitOps CR -```yaml apiVersion: gitops.kubedb.com/v1alpha1 kind: MSSQLServer metadata: @@ -165,18 +167,19 @@ Our `gitops` operator will create an actual `Mssqlserver` database CR in the clu ```bash -$ kubectl get mssqlserver.gitops.kubedb.com,mssqlserver.kubedb.com -n demo +kubectl get mssqlserver.gitops.kubedb.com,mssqlserver.kubedb.com -n demo +``` NAME AGE mssqlserver.gitops.kubedb.com/mssql-gitops 19h NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 19h -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` Mssqlserver. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/mssql-gitops 19h petset.apps.k8s.appscode.com/mssql-gitops-arbiter 19h @@ -204,7 +207,6 @@ service/mssql-gitops-secondary ClusterIP 10.43.53.184 1433/ NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/mssql-gitops kubedb.com/mssqlserver 2022-cu19 19h -``` ## Update Mssqlserver Database using GitOps @@ -255,7 +257,8 @@ Scale down the `replicas` to `3`. Commit the changes and push to your Git reposi Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` mssqlserverOpsRequest to update the `Mssqlserver` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 19h @@ -264,16 +267,15 @@ mssqlserver.gitops.kubedb.com/mssql-gitops 19h NAME TYPE STATUS AGE mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-horizontalscaling-28njbi HorizontalScaling Successful 15m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +``` NAME READY STATUS RESTARTS AGE mssql-gitops-0 2/2 Running 0 19h mssql-gitops-1 2/2 Running 0 19h mssql-gitops-2 2/2 Running 0 19h -``` We can also scale down the replicas by updating the `replicas` fields. @@ -282,7 +284,8 @@ We can also scale down the replicas by updating the `replicas` fields. Before the Ops Request reaches the `Successful` state, the configured memory limits are as follows: ```bash -$ kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "4Gi" @@ -292,7 +295,6 @@ $ kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resou "memory": "2Gi" } } -``` Update the `mssqlserver.yaml` with the following, ```yaml apiVersion: gitops.kubedb.com/v1alpha1 @@ -347,7 +349,8 @@ Resource Requests and Limits are updated to `2` CPU and `2Gi` Memory. Commit the Now, `gitops` operator will detect the resource changes and create a `mssqlserverOpsRequest` to update the `Mssqlserver` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 19h @@ -357,11 +360,11 @@ mssqlserver.gitops.kubedb.com/mssql-gitops 19h NAME TYPE STATUS AGE mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-horizontalscaling-28njbi HorizontalScaling Successful 25m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 5m2s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "2", @@ -373,8 +376,6 @@ $ kubectl get pod -n demo mssql-gitops-0 -o json | jq '.spec.containers[0].resou } } -``` - ### Expand Mssqlserver Volume @@ -432,7 +433,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` mssqlserverOpsRequest to update the `Mssqlserver` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 20h @@ -443,16 +445,15 @@ NAME TYP mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-horizontalscaling-28njbi HorizontalScaling Successful 51m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 30m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 15m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=mssql-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-mssql-gitops-0 Bound pvc-481caac3-7849-422c-9d8f-704ef82b3bc6 2Gi RWO longhorn 20h data-mssql-gitops-1 Bound pvc-49ea234d-e7e2-4a3b-9372-b430d72fee5e 2Gi RWO longhorn 19h data-mssql-gitops-2 Bound pvc-c72d4562-81d2-405b-ae8d-52816e59767f 2Gi RWO longhorn 19h -``` ## Reconfigure Mssqlserver @@ -474,13 +475,13 @@ stringData: Now, we will add this file to `kubedb/ms-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├──ms-issuer.yaml │ ├──ms-configuration.yaml │ └──mssql.yaml 1 directories, 3 files -``` Update the `mssqlserver.yaml` with `spec.configuration.secretName` as the following, ```yaml @@ -538,7 +539,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` mssqlserverOpsRequest to update the `Mssqlserver` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 20h @@ -550,7 +552,6 @@ mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-horizontalscaling-28njbi Hor mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-reconfigure-6i2hvt Reconfigure Successful 6m24s mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 50m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 35m -``` @@ -575,14 +576,14 @@ stringData: ``` Let's add that to our `kubedb/md-auth.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├──ms-issuer.yaml │ ├── ms-configuration.yaml │ ├── ms-auth.yaml │ └── mssql.yaml 1 directories, 4 files -``` Update the `mssql.yaml` ading `authsecret` as the following, ```yaml @@ -643,7 +644,8 @@ Add the `authSecret.kind` and `authSecret.name` field to `mssqlserver-auth`. Com Now, `gitops` operator will detect the auth changes and create a `RotateAuth` mssqlserverOpsRequest to update the `Mssqlserver` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu19 Ready 21h @@ -656,7 +658,6 @@ mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-reconfigure-6i2hvt Rec mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-rotate-auth-otytes RotateAuth Successful 77m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 133m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 117m -``` ### Update Version @@ -724,7 +725,8 @@ Update the `version` field to `2025-cu0`. Commit the changes and push to your Gi Now, `gitops` operator will detect the version changes and create a `VersionUpdate` mssqlserverOpsRequest to update the `Mssqlserver` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,mssqlserver,msops -n demo +kubectl get ms,mssqlserver,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu22 Ready 22h @@ -738,21 +740,24 @@ mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-rotate-auth-otytes Rot mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-versionupdate-mlq0kn UpdateVersion Successful 13m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 3h1m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 165m -``` Now, we are going to verify whether the `Mssqlserver`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get mssqlserver -n demo mssql-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get mssqlserver -n demo mssql-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` 2022-cu22 -$ kubectl get petset -n demo mssql-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mssql-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04@sha256:db9a8fe3098b7e8bbde41106bdc7caee942e97124e5fdb71b872ca208de3092d -$ kubectl get pod -n demo mssql-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04@sha256:db9a8fe3098b7e8bbde41106bdc7caee942e97124e5fdb71b872ca208de3092d +```bash +kubectl get pod -n demo mssql-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04@sha256:db9a8fe3098b7e8bbde41106bdc7caee942e97124e5fdb71b872ca208de3092d ### Enable Monitoring @@ -835,7 +840,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` mssqlserverOpsRequest to add the `Mssqlserver` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,msops -n demo +kubectl get ms,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu22 Ready 11m @@ -847,7 +853,6 @@ mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-rotate-auth-otytes Rot mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-versionupdate-mlq0kn UpdateVersion Successful 120m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 4h48m mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 4h33m -``` Verify the monitoring is enabled by checking the prometheus targets. @@ -928,7 +933,8 @@ Convert `spec.tls.clientTLS` to `true`. Commit the changes and push to your Git Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` mssqlserverOpsRequest to update the `Mssqlserver` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get ms,msops -n demo +kubectl get ms,msops -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-gitops 2022-cu22 Ready 20m @@ -941,7 +947,6 @@ mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-rotate-auth-otytes Rot mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-versionupdate-mlq0kn UpdateVersion Successful 20h mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-verticalscaling-yi3db5 VerticalScaling Successful 23h mssqlserveropsrequest.ops.kubedb.com/mssql-gitops-volumeexpansion-rsa80j VolumeExpansion Successful 23h -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can change the value of the `.spec.tls.clientTLS` field for Mssqlserver. diff --git a/docs/guides/mssqlserver/initialization/index.md b/docs/guides/mssqlserver/initialization/index.md index 2690421bde..463ba09ddf 100644 --- a/docs/guides/mssqlserver/initialization/index.md +++ b/docs/guides/mssqlserver/initialization/index.md @@ -33,9 +33,9 @@ In this tutorial, we will use .sql script stored in GitHub repository [kubedb/ms - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Prepare Initialization Scripts @@ -48,10 +48,10 @@ At first, we will create a ConfigMap with `init.sql` file. Then, we will provide Let's create a ConfigMap with the `init.sql` initialization script, ```bash -$ kubectl create configmap -n demo mssql-init-scripts \ +kubectl create configmap -n demo mssql-init-scripts \ --from-literal=init.sql="$(curl -fsSL https://github.com/kubedb/mssqlserver-init-scripts/raw/master/init.sql)" -configmap/mssql-init-scripts created ``` +configmap/mssql-init-scripts created ## Deploy the Microsoft SQL Server database @@ -68,9 +68,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -86,9 +86,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Deploy a Microsoft SQL Server database with Init-Script KubeDB implements a `MSSQLServer` CRD to define the specification of a Microsoft SQL Server database. Below is the `MSSQLServer` object created in this tutorial. @@ -150,9 +150,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/initialization/initialize-standalone.yaml -mssqlserver.kubedb.com/ms-init created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/initialization/initialize-standalone.yaml ``` +mssqlserver.kubedb.com/ms-init created @@ -208,9 +208,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/initialization/initialize-ag-cluster.yaml -mssqlsever.kubedb.com/ms-ag-init created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/initialization/initialize-ag-cluster.yaml ``` +mssqlsever.kubedb.com/ms-ag-init created @@ -225,7 +225,8 @@ Here, KubeDB operator watches for `MSSQLServer` objects using Kubernetes API. When a `MSSQLServer` object is created, KubeDB operator will create a PetSet and Services, Secrets, and other necessary resouces for this `MSSQLServer` Database. ```bash -$ kubectl dba describe ms -n demo ms-init +kubectl dba describe ms -n demo ms-init +``` Name: ms-init Namespace: demo Labels: @@ -368,23 +369,23 @@ Status: Status: True Type: Provisioned Phase: Ready -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. KubeDB operator has created a new Secret called `ms-init-auth` for storing the password for MSSQLServer SA user. ```bash -$ kubectl view-secret -n demo ms-init-auth -a +kubectl view-secret -n demo ms-init-auth -a +``` password='9jtGBoona46wUYmL' username='sa' -``` Let's connect ot the database pod and verify the `init.sql` script is executed successfully or not. -```bash -$ kubectl exec -it -n demo ms-init-0 -- bash +```bash +kubectl exec -it -n demo ms-init-0 -- bash +``` Defaulted container "mssql" out of: mssql, mssql-init (init) mssql@ms-init-0:/$ cd init-database/ mssql@ms-init-0:/init-database$ ls @@ -469,7 +470,6 @@ id name 8 name8 2025-08-06 10:36:49.5645412 (8 rows affected) -``` diff --git a/docs/guides/mssqlserver/monitoring/using-prometheus-operator.md b/docs/guides/mssqlserver/monitoring/using-prometheus-operator.md index c37d8de17a..a52dd5bffe 100644 --- a/docs/guides/mssqlserver/monitoring/using-prometheus-operator.md +++ b/docs/guides/mssqlserver/monitoring/using-prometheus-operator.md @@ -29,12 +29,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, you can deploy one using this helm chart [here](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack). @@ -48,17 +50,17 @@ We need to know the labels used to select `ServiceMonitor` by `Prometheus` Opera At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 16d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus-kube-prometheus-prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -183,9 +185,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -201,9 +203,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, let's deploy an MSSQLServer with monitoring enabled. Below is the MSSQLServer object that we are going to create. @@ -278,27 +280,27 @@ Here, Let's create the MSSQLServer object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/monitoring/mssql-monitoring.yaml -mssqlserverql.kubedb.com/mssql-monitoring created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/monitoring/mssql-monitoring.yaml ``` +mssqlserverql.kubedb.com/mssql-monitoring created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get ms -n demo mssql-monitoring +kubectl get ms -n demo mssql-monitoring +``` NAME VERSION STATUS AGE mssql-monitoring 2022-cu12 Ready 108m -``` KubeDB will create a separate stats service with name `{mssqlserver cr name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=mssql-monitoring" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=mssql-monitoring" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mssql-monitoring ClusterIP 10.96.225.130 1433/TCP 108m mssql-monitoring-pods ClusterIP None 1433/TCP 108m mssql-monitoring-stats ClusterIP 10.96.147.93 9399/TCP 108m -``` Here, `mssql-monitoring-stats` service has been created for monitoring purpose. @@ -306,7 +308,7 @@ Let's describe this stats service. ```bash -$ kubectl describe svc -n demo mssql-monitoring-stats +kubectl describe svc -n demo mssql-monitoring-stats ``` ```yaml Name: mssql-monitoring-stats @@ -335,15 +337,15 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` CR in `demo` namespace that select the endpoints of `mssql-monitoring-stats` service. Verify that the `ServiceMonitor` CR has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE mssql-monitoring-stats 110m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of MSSQLServer CR. ```bash -$ kubectl get servicemonitor -n demo mssql-monitoring-stats -o yaml +kubectl get servicemonitor -n demo mssql-monitoring-stats -o yaml ``` ```yaml @@ -396,20 +398,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus-kube-prometheus-prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 16d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `mssql-monitoring-stats` service as one of the targets. diff --git a/docs/guides/mssqlserver/pitr/archiver.md b/docs/guides/mssqlserver/pitr/archiver.md index 6c507f5538..636a04b95f 100644 --- a/docs/guides/mssqlserver/pitr/archiver.md +++ b/docs/guides/mssqlserver/pitr/archiver.md @@ -27,9 +27,9 @@ Now, To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mssqlserver/pitr/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Continuous Archiving @@ -45,13 +45,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -79,9 +85,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created **Create RetentionPolicy:** @@ -109,20 +115,23 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Encryption Secret** Let’s create a secret called encrypt-secret with the `Restic` password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create MSSQLServerArchiver CR:** @@ -182,9 +191,9 @@ spec: Let’s create the above `MSSQLServerArchiver`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/sample-mssqlserverarchiver.yaml -mssqlserverarchiver.archiver.kubedb.com/sample-mssqlserverarchiver created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/sample-mssqlserverarchiver.yaml ``` +mssqlserverarchiver.archiver.kubedb.com/sample-mssqlserverarchiver created Here, - The `databases` field within `spec.fullBackup.task.params` specifies the target databases for the archive. If no database list is provided, the archiver will target all non-system databases by default. @@ -205,15 +214,15 @@ By following the below steps, we are going to create our desired issuer, - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mssqlserver/O=kubedb" ``` - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` CR using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, @@ -231,9 +240,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer.yaml created **Create MSSQLServer CR:** @@ -292,20 +301,20 @@ Here, Create the above `MSSQLServer` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/sample-mssqlserver-ag.yaml -mssqlserver.kubedb.com/sample-mssqlserver-ag created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mssqlserver/pitr/examples/sample-mssqlserver-ag.yaml ``` +mssqlserver.kubedb.com/sample-mssqlserver-ag created Let’s check the pods which are related to the backup, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE sample-mssqlserver-ag-0 2/2 Running 0 6m18s sample-mssqlserver-ag-1 2/2 Running 0 6m12s sample-mssqlserver-ag-archiver-full-backup-1728973299-7gmh5 1/1 Running 0 41s sample-mssqlserver-ag-sidekick 1/1 Running 0 17s -``` Here, - Pod `sample-mssqlserver-ag-archiver-full-backup-1728973299-7gmh5` is responsible for application backup. i.e (target databases and manifest) @@ -319,41 +328,46 @@ If everything goes well, kubedb provisioner will create a `BackupConfiguration` Let’s verify the Phase of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mssqlserver-ag-archiver Ready 7m49s -``` ***Verify BackupSession:*** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mssqlserver-ag-archiver-full-backup-1728973299 BackupConfiguration sample-mssqlserver-ag-archiver Succeeded 51s 8m31s -``` ***Verify Snapshot:*** ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=sample-mssqlserver-ag-archiver +kubectl get snapshots -n demo -l=kubestash.com/repo-name=sample-mssqlserver-ag-archiver +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE sample-mssqlserver-ag-archiver-sarchiver-full-backup-1728973299 sample-mssqlserver-ag-archiver full-backup 2024-10-15T06:21:39Z Delete Succeeded 10m -``` ### Insert Some Data Every successful transaction log will be recorded during the log backup by Sidekick. By default, log backups occur at `25-second` intervals. ```bash -$ kubectl get secret -n demo sample-mssqlserver-ag-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mssqlserver-ag-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n demo sample-mssqlserver-ag-auth -o jsonpath='{.data.password}'| base64 -d +```bash +kubectl get secret -n demo sample-mssqlserver-ag-auth -o jsonpath='{.data.password}'| base64 -d +``` XhGrsDvJ7ATrPp7n⏎ -$ kubectl exec -it -n demo sample-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver-ag -U sa -P "XhGrsDvJ7ATrPp7n" -No +```bash +kubectl exec -it -n demo sample-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver-ag -U sa -P "XhGrsDvJ7ATrPp7n" -No +``` 1> SELECT name from sys.databases; 2> GO name @@ -422,7 +436,6 @@ id type quant color # exit from the pod 1> exit -``` ### Point-in-time Recovery @@ -431,7 +444,8 @@ Point-In-Time Recovery allows you to restore a `Microsoft SQL Server` database t Let’s say accidentally drops the table `equipment`. ```bash -$ kubectl exec -it -n demo sample-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver-ag -U sa -P "XhGrsDvJ7ATrPp7n" -No +kubectl exec -it -n demo sample-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S sample-mssqlserver-ag -U sa -P "XhGrsDvJ7ATrPp7n" -No +``` 1> use demo 2> DROP table equipment; 3> GO @@ -444,7 +458,6 @@ name -------------------------------------------------------------------------------------------------------------------------------- (0 rows affected) # It confirms that no tables are exist in `demo` database. -``` We can’t restore from a full backup since at this point no full backup was perform. So we can choose a specific time in which time we want to restore. @@ -505,21 +518,21 @@ spec: ``` ```bash -$ kubectl apply -f restored-mssqlserver-ag.yaml -mssqlserver.kubedb.com/restored-mssqlserver-ag created +kubectl apply -f restored-mssqlserver-ag.yaml ``` +mssqlserver.kubedb.com/restored-mssqlserver-ag created Let’s check the pods which are related to the restore, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE restored-mssqlserver-ag-0 2/2 Running 0 2m10s restored-mssqlserver-ag-1 2/2 Running 0 2m3s restored-mssqlserver-ag-full-backup-restorer-7kpn8 0/1 Completed 0 65s restored-mssqlserver-ag-log-restorer-d9sjd 1/1 Running 0 11s restored-mssqlserver-ag-manifest-restorer-7kpn8 0/1 Completed 0 2m31s -``` Here, - Pod `restored-mssqlserver-ag-manifest-restorer-7kpn8` is responsible for manifest restore. @@ -533,21 +546,26 @@ Here, At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get mssqlserver -n demo restored-mssqlserver-ag +kubectl get mssqlserver -n demo restored-mssqlserver-ag +``` NAME VERSION STATUS AGE restored-mssqlserver-ag 2022-cu12 Ready 10m -``` Now, Lets exec into the Pod to enter into mssqlserver shell and verify restored data, ```bash -$ kubectl get secret -n demo restored-mssqlserver-ag-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo restored-mssqlserver-ag-auth -o jsonpath='{.data.username}'| base64 -d +``` sa⏎ -$ kubectl get secret -n demo restored-mssqlserver-ag-auth -o jsonpath='{.data.password}'| base64 -d +```bash +kubectl get secret -n demo restored-mssqlserver-ag-auth -o jsonpath='{.data.password}'| base64 -d +``` Q2YKiGgqr5ju62NL⏎ -$ kubectl exec -it -n demo restored-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S restored-mssqlserver-ag -U sa -P "Q2YKiGgqr5ju62NL" -No +```bash +kubectl exec -it -n demo restored-mssqlserver-ag-0 -c mssql -- /opt/mssql-tools18/bin/sqlcmd -S restored-mssqlserver-ag -U sa -P "Q2YKiGgqr5ju62NL" -No +``` 1> SELECT name from sys.databases; 2> GO name @@ -593,7 +611,6 @@ id type quant color (1 rows affected) 1> exit -``` So, we are able to successfully recover from a disaster. diff --git a/docs/guides/mssqlserver/quickstart/quickstart.md b/docs/guides/mssqlserver/quickstart/quickstart.md index 8d2af53398..9ae5bb7141 100644 --- a/docs/guides/mssqlserver/quickstart/quickstart.md +++ b/docs/guides/mssqlserver/quickstart/quickstart.md @@ -31,24 +31,25 @@ This tutorial will show you how to use KubeDB to run a Microsoft SQL Server data - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 5d20h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available Microsoft SQL Server Versions When you have installed KubeDB, it has created `MSSQLServerVersion` CR for all supported Microsoft SQL Server versions. Check it by using the `kubectl get mssqlserverversions`. You can also use `msversion` shorthand instead of `mssqlserverversions`. ```bash -$ kubectl get msversion +kubectl get msversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022-cu12 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 7d19h 2022-cu14 2022-cu14 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 7d19h @@ -57,8 +58,6 @@ NAME VERSION DB_IMAGE 2022-cu22 2022-cu22 mcr.microsoft.com/mssql/server:2022-CU22-ubuntu-22.04 7d19h 2025-cu0 2025-cu0 mcr.microsoft.com/mssql/server:2025-RTM-ubuntu-22.04 7d19h -``` - > Note: The yaml files used in this tutorial are stored in [docs/examples/mssqlserver/quickstart/](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,9 +78,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -97,9 +96,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Configuring Environment Variables for SQL Server on Linux You can use environment variables to configure SQL Server on Linux containers. @@ -176,9 +175,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-quickstart.yaml -mssqlserver.kubedb.com/mssqlserver-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-quickstart.yaml ``` +mssqlserver.kubedb.com/mssqlserver-quickstart created Here, @@ -193,17 +192,20 @@ Here, KubeDB operator watches for `MSSQLServer` objects using Kubernetes api. When a `MSSQLServer` object is created, KubeDB operator will create a new PetSet and a Service with the matching MSSQLServer object name. KubeDB operator will also create a governing service for PetSets with the name `-pods`, if one is not already present. ```bash -$ kubectl get petset -n demo mssqlserver-quickstart +kubectl get petset -n demo mssqlserver-quickstart +``` NAME AGE mssqlserver-quickstart 13m - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-mssqlserver-quickstart-0 Bound pvc-ccbba9d2-5556-49cd-9ce8-23c28ad56f12 1Gi RWO standard 15m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ccbba9d2-5556-49cd-9ce8-23c28ad56f12 1Gi RWO Delete Bound demo/data-mssqlserver-quickstart-0 standard 15m @@ -213,12 +215,10 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) mssqlserver-quickstart ClusterIP 10.96.128.61 1433/TCP 15m mssqlserver-quickstart-pods ClusterIP None 1433/TCP 15m -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created and is able to accept client connections. Run the following command to see the modified MSSQLServer object: ```bash -$ kubectl get ms -n demo mssqlserver-quickstart -o yaml +kubectl get ms -n demo mssqlserver-quickstart -o yaml ``` ```yaml @@ -366,12 +366,14 @@ If you want to use an existing secret please specify that when creating the MSSQ Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `mssqlserver-quickstart-auth` secret holds username and password ```bash -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.\password}' | base64 -d -axgXHj4oRIVQ1ocK +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.\password}' | base64 -d ``` +axgXHj4oRIVQ1ocK We can exec into the pod `mssqlserver-quickstart-0` using the following command: ```bash kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash @@ -435,7 +437,7 @@ kubedb_system Run the following command to see the created appbinding object: ```bash -$ kubectl get appbinding -n demo -oyaml +kubectl get appbinding -n demo -oyaml ``` ```yaml @@ -499,12 +501,14 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-quickstart patched -$ kubectl delete ms -n demo mssqlserver-quickstart -The MSSQLServer "mssqlserver-quickstart" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" +```bash +kubectl delete ms -n demo mssqlserver-quickstart ``` +The MSSQLServer "mssqlserver-quickstart" is invalid: spec.deletionPolicy: Invalid value: "mssqlserver-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"` to set `spec.deletionPolicy` to `Halt` (which deletes the mssqlserver object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -519,14 +523,15 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd At first, run `kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"`. Then delete the mssqlserver object, ```bash -$ kubectl delete ms -n demo mssqlserver-quickstart -mssqlserver.kubedb.com "mssqlserver-quickstart" deleted +kubectl delete ms -n demo mssqlserver-quickstart ``` +mssqlserver.kubedb.com "mssqlserver-quickstart" deleted Now, run the following command to get mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 40m secret/mssqlserver-quickstart-auth kubernetes.io/basic-auth 2 30m @@ -536,7 +541,6 @@ secret/mssqlserver-quickstart-server-cert kubernetes.io/tls 3 30 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-mssqlserver-quickstart-0 Bound pvc-656e3bd1-65da-441c-851f-2ae076f8ebbd 1Gi RWO standard 29m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your mssqlserver again using these resources. @@ -549,23 +553,26 @@ When the [DeletionPolicy](/docs/guides/mssqlserver/concepts/mssqlserver.md#specd Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +kubectl patch -n demo ms mssqlserver-quickstart -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-quickstart patched -$ kubectl delete ms -n demo mssqlserver-quickstart -mssqlserver.kubedb.com "mssqlserver-quickstart" deleted + +```bash +kubectl delete ms -n demo mssqlserver-quickstart ``` +mssqlserver.kubedb.com "mssqlserver-quickstart" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 49m secret/mssqlserver-quickstart-auth kubernetes.io/basic-auth 2 39m secret/mssqlserver-quickstart-client-cert kubernetes.io/tls 3 39m secret/mssqlserver-quickstart-config Opaque 1 39m secret/mssqlserver-quickstart-server-cert kubernetes.io/tls 3 39m -``` From the above output, you can see that all mssqlserver resources(`MSSQLServer`, `PetSet`, `Pod`, `Service`, `PVCs` etc.) are deleted except `Secret`. You can initialize your mssqlserver using `snapshots`(if previously taken) and `Secrets`. @@ -588,10 +595,10 @@ mssqlserver.kubedb.com "mssqlserver-quickstart" deleted Now, run the following command to get all mssqlserver resources in `demo` namespaces, ```bash -$ kubectl get ms,petset,pod,svc,secret,pvc -n demo +kubectl get ms,petset,pod,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/mssqlserver-ca kubernetes.io/tls 2 53m -``` From the above output, you can see that all mssqlserver resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `WipeOut`. diff --git a/docs/guides/mssqlserver/reconfigure-tls/ag_cluster.md b/docs/guides/mssqlserver/reconfigure-tls/ag_cluster.md index 8688e9194e..2e61c114c6 100644 --- a/docs/guides/mssqlserver/reconfigure-tls/ag_cluster.md +++ b/docs/guides/mssqlserver/reconfigure-tls/ag_cluster.md @@ -30,9 +30,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -53,9 +53,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -71,9 +71,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Deploy MSSQLServer without TLS @@ -129,17 +129,17 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/mssql-ag-cluster.yaml -mssqlserver.kubedb.com/mssql-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/mssql-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssql-ag-cluster created Now, wait until `mssql-ag-cluster` has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE mssql-ag-cluster 2022-cu12 Ready 4m38s -``` Now, connect to this database by exec into a pod and verify the TLS is disabled. @@ -147,13 +147,18 @@ Now, connect to this database by exec into a pod and verify the TLS is disabled. ```bash -$ kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d +``` Q9kDWVQMnawLcnZq -$ kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +``` mssql@mssql-ag-cluster-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -164,7 +169,6 @@ Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Client unable to establ So Now, we have to connect with -C [Trust Server Certificate] mssql@mssql-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "Q9kDWVQMnawLcnZq" -N -C 1> -``` We can verify from the above output that TLS is disabled for this database, `mssql.conf` file has no tls configuration. @@ -210,25 +214,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-add-tls.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-ag-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-add-tls.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-ag-add-tls created #### Verify TLS Enabled Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ watch kubectl get msops -n demo +watch kubectl get msops -n demo +``` Every 2.0s: kubectl get msops -n demo NAME TYPE STATUS AGE msops-ag-add-tls ReconfigureTLS Successful 3m32s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-ag-add-tls +kubectl describe mssqlserveropsrequest -n demo msops-ag-add-tls +``` Name: msops-ag-add-tls Namespace: demo Labels: @@ -359,12 +364,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Let's exec into a database node ```bash -$ kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +``` mssql@mssql-ag-cluster-0:/$ ls /var/opt/mssql/tls mssql@mssql-ag-cluster-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -subject -nameopt RFC2253 -noout subject=CN=mssql,OU=client,O=mssqlserver @@ -378,7 +383,6 @@ tlskey = /var/opt/mssql/tls/server.key tlsprotocols = 1.2,1.1,1.0 mssql@mssql-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Q9kDWVQMnawLcnZq -N 1> -``` We can verify from the above output that TLS is enabled for this database, `mssql.conf` file has tls configurations. So, TLS is enabled successfully to this database. @@ -388,11 +392,11 @@ We can verify from the above output that TLS is enabled for this database, `mssq Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +``` mssql@mssql-ag-cluster-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 16 14:13:49 2025 GMT mssql@mssql-ag-cluster-0:/$ -``` So, the certificate will expire on this time `Feb 16 13:11:02 2025 GMT`. @@ -426,25 +430,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-rotate.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-ag-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-rotate.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-ag-rotate created #### Verify Certificate Rotated Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-ag-rotate ReconfigureTLS Successful 5m14s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-ag-rotate +kubectl describe mssqlserveropsrequest -n demo msops-ag-rotate +``` Name: msops-ag-rotate Namespace: demo Labels: @@ -570,15 +575,14 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +kubectl exec -it mssql-ag-cluster-0 -n demo -c mssql -- bash +``` mssql@mssql-ag-cluster-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 16 14:36:54 2025 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -589,23 +593,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 mssqlserver-new-ca \ +kubectl create secret tls mssqlserver-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/mssqlserver-new-ca created ``` +secret/mssqlserver-new-ca created Now, Let's create a new `Issuer` using the `mssqlserver-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -623,9 +627,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/mssqlserver-new-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-new-ca-issuer created ### Create MSSQLServerOpsRequest @@ -657,25 +661,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-change-issuer.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-ag-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-change-issuer.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-ag-change-issuer created #### Verify Issuer is changed successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-ag-change-issuer ReconfigureTLS Successful 3m56s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-ag-change-issuer +kubectl describe mssqlserveropsrequest -n demo msops-ag-change-issuer +``` Name: msops-ag-change-issuer Namespace: demo Labels: @@ -797,15 +802,14 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Lets exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it mssql-ag-cluster-2 -n demo -c mssql -- bash +kubectl exec -it mssql-ag-cluster-2 -n demo -c mssql -- bash +``` mssql@mssql-ag-cluster-2:/$ openssl x509 -in /var/opt/mssql/tls/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -840,25 +844,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-remove.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-ag-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-ag-remove.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-ag-remove created #### Verify TLS Removed Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo +watch kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-ag-remove ReconfigureTLS Successful 5m17s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-ag-remove +kubectl describe mssqlserveropsrequest -n demo msops-ag-remove +``` Name: msops-ag-remove Namespace: demo Labels: @@ -956,12 +961,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Lets exec into the database node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo mssql-ag-cluster-1 -c mssql -- bash +kubectl exec -it -n demo mssql-ag-cluster-1 -c mssql -- bash +``` mssql@mssql-ag-cluster-1:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -973,7 +978,6 @@ Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Client unable to establ So Now, we have to connect with -C [Trust Server Certificate] mssql@mssql-ag-cluster-1:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Q9kDWVQMnawLcnZq -N -C 1> -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/mssqlserver/reconfigure-tls/standalone.md b/docs/guides/mssqlserver/reconfigure-tls/standalone.md index a58c23e65b..47e21f2886 100644 --- a/docs/guides/mssqlserver/reconfigure-tls/standalone.md +++ b/docs/guides/mssqlserver/reconfigure-tls/standalone.md @@ -29,9 +29,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -52,9 +52,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -70,9 +70,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Deploy MSSQLServer without TLS @@ -116,18 +116,21 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/ms-standalone.yaml -mssqlserver.kubedb.com/ms-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/ms-standalone.yaml ``` +mssqlserver.kubedb.com/ms-standalone created Now, wait until `ms-standalone` has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE ms-standalone 2022-cu12 Ready 4m3s -$ kubectl describe ms -n demo ms-standalone +```bash +kubectl describe ms -n demo ms-standalone +``` Name: ms-standalone Namespace: demo Labels: @@ -270,21 +273,24 @@ Events: Normal Successful 4m20s KubeDB Ops-manager Operator Successfully created MSSQLServer server certificates Normal Successful 4m20s KubeDB Ops-manager Operator Successfully created MSSQLServer client certificates -``` - Now, connect to this database by exec into a pod and verify the TLS is disabled. > when we connect using the sqlcmd tool, the -N option is available with [s|m|o] parameters, where 's' stands for strict, 'm' for mandatory, and 'o' for optional. The default setting is mandatory. ```bash -$ kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\password}' | base64 -d +``` b1HLv9EV4CaSalX6 -$ kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +```bash +kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +``` mssql@ms-standalone-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -296,7 +302,6 @@ Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Client unable to establ So Now, we have to connect with -C [Trust Server Certificate] mssql@ms-standalone-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "b1HLv9EV4CaSalX6" -N -C 1> -``` We can verify from the above output that TLS is disabled for this database, `mssql.conf` file has no tls configuration. @@ -342,26 +347,27 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-add-tls.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-add-tls.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ watch kubectl get msops -n demo +watch kubectl get msops -n demo +``` Every 2.0s: kubectl get msops -n demo NAME TYPE STATUS AGE msops-add-tls ReconfigureTLS Successful 115s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-add-tls +kubectl describe mssqlserveropsrequest -n demo msops-add-tls +``` Name: msops-add-tls Namespace: demo Labels: @@ -462,14 +468,14 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Let's exec into a database node ```bash -$ kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +``` mssql@ms-standalone-0:/$ ls /var/opt/mssql/tls ca.crt client.crt client.key server.crt server.key mssql@ms-standalone-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -subject -nameopt RFC2253 -noout @@ -484,7 +490,6 @@ tlskey = /var/opt/mssql/tls/server.key tlsprotocols = 1.2,1.1,1.0 mssql@ms-standalone-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P l2mGQRMETAS96QRb -N 1> -``` We can verify from the above output that TLS is enabled for this database, `mssql.conf` file has tls configurations. So, TLS is enabled successfully to this database. @@ -494,11 +499,11 @@ We can verify from the above output that TLS is enabled for this database, `mssq Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +``` mssql@ms-standalone-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 16 13:11:02 2025 GMT mssql@ms-standalone-0:/$ -``` So, the certificate will expire on this time `Feb 16 13:11:02 2025 GMT`. @@ -532,25 +537,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-rotate.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-rotate.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-rotate ReconfigureTLS Successful 2m47s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-rotate +kubectl describe mssqlserveropsrequest -n demo msops-rotate +``` Name: msops-rotate Namespace: demo Labels: @@ -646,15 +652,14 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +``` mssql@ms-standalone-0:/$ openssl x509 -in /var/opt/mssql/tls/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 16 13:17:50 2025 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -665,23 +670,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 mssqlserver-new-ca \ +kubectl create secret tls mssqlserver-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/mssqlserver-new-ca created ``` +secret/mssqlserver-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -699,9 +704,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/mssqlserver-new-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-new-ca-issuer created ### Create MSSQLServerOpsRequest @@ -733,25 +738,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-change-issuer.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-change-issuer.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-change-issuer created #### Verify Issuer is changed successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-change-issuer ReconfigureTLS Successful 3m28s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-change-issuer +kubectl describe mssqlserveropsrequest -n demo msops-change-issuer +``` Name: msops-change-issuer Namespace: demo Labels: @@ -843,15 +849,14 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Lets exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +kubectl exec -it ms-standalone-0 -n demo -c mssql -- bash +``` mssql@ms-standalone-0:/$ openssl x509 -in /var/opt/mssql/tls/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -886,25 +891,26 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-remove.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure-tls/msops-remove.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-remove created #### Verify TLS Removed Successfully Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CRO, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo +watch kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-remove ReconfigureTLS Successful 2m36s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-remove +kubectl describe mssqlserveropsrequest -n demo msops-remove +``` Name: msops-remove Namespace: demo Labels: @@ -972,12 +978,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, Lets exec into the pod find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +``` mssql@ms-standalone-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -988,7 +994,6 @@ Sqlcmd: Error: Microsoft ODBC Driver 17 for SQL Server : Client unable to establ So Now, we have to connect with -C [Trust Server Certificate] mssql@ms-standalone-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P b1HLv9EV4CaSalX6 -N -C 1> -``` We can verify from the above output that TLS is disabled for this database, `mssql.conf` file has no tls configuration. diff --git a/docs/guides/mssqlserver/reconfigure/ag_cluster.md b/docs/guides/mssqlserver/reconfigure/ag_cluster.md index 644efca1fd..8c06d3fb06 100644 --- a/docs/guides/mssqlserver/reconfigure/ag_cluster.md +++ b/docs/guides/mssqlserver/reconfigure/ag_cluster.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver](/docs/examples/mssqlserver/reconfigure) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -60,9 +60,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -78,9 +78,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, we will create `mssql.conf` file containing required configuration settings. ```ini @@ -93,9 +93,9 @@ Here, `memorylimitmb` is set to `2048`, whereas the default value is `12280`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf -secret/ms-custom-config created +kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf ``` +secret/ms-custom-config created In this section, we are going to create a MSSQLServer object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -145,33 +145,36 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/mssqlserver-ag-cluster.yaml -MSSQLServer.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/mssqlserver-ag-cluster.yaml ``` +MSSQLServer.kubedb.com/mssqlserver-ag-cluster created Now, wait until `mssqlserver-ag-cluster` has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 5m47s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a MSSQLServer instance, ```bash -$ kubectl get secrets -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d -gkBGX7RE0ap4yjHt +```bash +kubectl get secrets -n demo mssqlserver-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d ``` +gkBGX7RE0ap4yjHt Now let's connect to the SQL Server instance and run internal command to check the configuration we have provided. ```bash -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -185,7 +188,6 @@ physical_memory_mb 2048 (1 rows affected) -``` As we can see from the configuration of running MSSQLServer, the value of `physical_memory_mb` has been set to `2048`. @@ -204,9 +206,9 @@ memorylimitmb = 2560 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./mssql.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./mssql.conf ``` +secret/new-custom-config created #### Create MSSQLServerOpsRequest @@ -239,9 +241,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-ag.yaml -MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-ag created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-ag.yaml ``` +MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-ag created #### Verify the new configuration is working @@ -250,15 +252,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get MSSQLServeropsrequest -n demo +watch kubectl get MSSQLServeropsrequest -n demo +``` NAME TYPE STATUS AGE msops-reconfigure-ag Reconfigure Successful 4m1s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-ag +kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-ag +``` Name: msops-reconfigure-ag Namespace: demo Labels: @@ -352,12 +355,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now let's connect to SQL Server instance and run internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -371,7 +374,6 @@ physical_memory_mb 2560 (1 rows affected) -``` As we can see from the configuration of running SQL Server, the value of `physical_memory_mb` has been changed from `2048` to `2560`. So the reconfiguration of the database is successful. @@ -411,9 +413,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-ag-apply.yaml -MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-ag-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-ag-apply.yaml ``` +MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-ag-apply created #### Verify the new configuration is working @@ -425,14 +427,15 @@ Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following co ```bash -$ watch kubectl get MSSQLServeropsrequest -n demo -msops-reconfigure-ag-apply Reconfigure Successful 3m34s +watch kubectl get MSSQLServeropsrequest -n demo ``` +msops-reconfigure-ag-apply Reconfigure Successful 3m34s We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-ag-apply +kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-ag-apply +``` Name: msops-reconfigure-ag-apply Namespace: demo Labels: @@ -533,12 +536,12 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now let's connect to the SQL Server instance and run a internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-ag-cluster-0 -c mssql -- bash +``` mssql@mssqlserver-ag-cluster-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -552,7 +555,6 @@ physical_memory_mb 3072 (1 rows affected) -``` As we can see from the configuration of running SQL Server, the value of `physical_memory_mb` has been changed from `2560` to `3072`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/mssqlserver/reconfigure/standalone.md b/docs/guides/mssqlserver/reconfigure/standalone.md index 05081a1507..4df7e9aef9 100644 --- a/docs/guides/mssqlserver/reconfigure/standalone.md +++ b/docs/guides/mssqlserver/reconfigure/standalone.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver](/docs/examples/mssqlserver/reconfigure) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -59,9 +59,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -77,9 +77,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, we will create `mssql.conf` file containing required configuration settings. @@ -93,9 +93,9 @@ Here, `memorylimitmb` is set to `2048`, whereas the default value is `12280`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf -secret/ms-custom-config created +kubectl create secret generic -n demo ms-custom-config --from-file=./mssql.conf ``` +secret/ms-custom-config created In this section, we are going to create a MSSQLServer object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -139,33 +139,36 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/ms-standalone.yaml -MSSQLServer.kubedb.com/ms-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/ms-standalone.yaml ``` +MSSQLServer.kubedb.com/ms-standalone created Now, wait until `ms-standalone` has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE ms-standalone 4.4.26 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a MSSQLServer instance, ```bash -$ kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\password}' | base64 -d -SERtEyH1RMMEsvE0 +```bash +kubectl get secrets -n demo ms-standalone-auth -o jsonpath='{.data.\password}' | base64 -d ``` +SERtEyH1RMMEsvE0 Now let's connect to the SQL Server instance and run internal command to check the configuration we have provided. ```bash -$ kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +``` mssql@ms-standalone-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -180,7 +183,6 @@ physical_memory_mb (1 rows affected) 1> -``` As we can see from the configuration of running MSSQLServer, the value of `physical_memory_mb` has been set to `2048`. @@ -199,9 +201,9 @@ memorylimitmb = 2560 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./mssql.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./mssql.conf ``` +secret/new-custom-config created #### Create MSSQLServerOpsRequest @@ -234,9 +236,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-standalone.yaml -MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-standalone.yaml ``` +MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-standalone created #### Verify the new configuration is working @@ -245,17 +247,18 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get MSSQLServeropsrequest -n demo +watch kubectl get MSSQLServeropsrequest -n demo +``` Every 2.0s: kubectl get MSSQLServeropsrequest -n demo NAME TYPE STATUS AGE msops-reconfigure-standalone Reconfigure Successful 2m42s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-standalone +kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-standalone +``` Name: msops-reconfigure-standalone Namespace: demo Labels: @@ -333,12 +336,12 @@ Events: Normal RestartPods 2m41s KubeDB Ops-manager Operator Successfully Restarted Pods after reconfiguration Normal Starting 2m41s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/ms-standalone Normal Successful 2m41s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/ms-standalone for MSSQLServerOpsRequest: msops-reconfigure-standalone -``` Now let's connect to SQL Server instance and run a internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +``` mssql@ms-standalone-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -353,7 +356,6 @@ physical_memory_mb (1 rows affected) 1> -``` As we can see from the configuration of running SQL Server, the value of `physical_memory_mb` has been changed from `2048` to `2560`. So the reconfiguration of the database is successful. @@ -394,9 +396,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-standalone-apply.yaml -MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-standalone-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/reconfigure/msops-reconfigure-standalone-apply.yaml ``` +MSSQLServeropsrequest.ops.kubedb.com/msops-reconfigure-standalone-apply created #### Verify the new configuration is working @@ -405,17 +407,18 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get MSSQLServeropsrequest -n demo +watch kubectl get MSSQLServeropsrequest -n demo +``` Every 2.0s: kubectl get MSSQLServeropsrequest -n demo NAME TYPE STATUS AGE msops-reconfigure-standalone-apply Reconfigure Successful 2m2s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-standalone-apply +kubectl describe MSSQLServeropsrequest -n demo msops-reconfigure-standalone-apply +``` Name: msops-reconfigure-standalone-apply Namespace: demo Labels: @@ -500,12 +503,12 @@ Events: Normal RestartPods 107s KubeDB Ops-manager Operator Successfully Restarted Pods after reconfiguration Normal Starting 107s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/ms-standalone Normal Successful 107s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/ms-standalone for MSSQLServerOpsRequest: msops-reconfigure-standalone-apply -``` Now let's connect to the SQL Server instance and run a internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +kubectl exec -it -n demo ms-standalone-0 -c mssql -- bash +``` mssql@ms-standalone-0:/$ cat /var/opt/mssql/mssql.conf [language] lcid = 1033 @@ -520,7 +523,6 @@ physical_memory_mb (1 rows affected) 1> -``` As we can see from the configuration of running SQL Server, the value of `physical_memory_mb` has been changed from `2560` to `3072`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/mssqlserver/restart/restart.md b/docs/guides/mssqlserver/restart/restart.md index de20062918..5b4bf764e2 100644 --- a/docs/guides/mssqlserver/restart/restart.md +++ b/docs/guides/mssqlserver/restart/restart.md @@ -26,10 +26,10 @@ KubeDB supports restarting the MSSQLServer via a MSSQLServerOpsRequest. Restarti - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,9 +47,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -65,9 +65,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created In this section, we are going to deploy a MSSQLServer database using KubeDB. @@ -115,16 +115,16 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/restart/mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/restart/mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created Check the database is provisioned successfully ```bash -$ kubectl get ms -n demo mssqlserver-ag-cluster +kubectl get ms -n demo mssqlserver-ag-cluster +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 4m -``` ## Apply Restart opsRequest @@ -152,18 +152,21 @@ spec: Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/restart/msops-restart.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/restart/msops-restart.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-restart created Now the Ops-manager operator will first restart the general secondary pods and lastly will restart the Primary pod of the database. -```shell -$ kubectl get msops -n demo msops-restart +```bash +kubectl get msops -n demo msops-restart +``` NAME TYPE STATUS AGE msops-restart Restart Successful 5m23s -$ kubectl get msops -n demo msops-restart -oyaml +```bash +kubectl get msops -n demo msops-restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: MSSQLServerOpsRequest metadata: @@ -249,14 +252,13 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` We can see that, the database is ready after restarting the pods ```bash -$ kubectl get ms -n demo mssqlserver-ag-cluster +kubectl get ms -n demo mssqlserver-ag-cluster +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 14m -``` ## Cleaning up diff --git a/docs/guides/mssqlserver/rotate-auth/rotateauth.md b/docs/guides/mssqlserver/rotate-auth/rotateauth.md index 21a6eedce3..8f30f38e94 100644 --- a/docs/guides/mssqlserver/rotate-auth/rotateauth.md +++ b/docs/guides/mssqlserver/rotate-auth/rotateauth.md @@ -33,9 +33,9 @@ section_menu_id: guides To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver](/docs/examples/mssqlserver/rotate-auth) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -54,9 +54,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -72,9 +72,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Deploy Standalone Microsoft SQL Server KubeDB implements a `MSSQLServer` CRD to define the specification of a Microsoft SQL Server database. Below is the `MSSQLServer` object created in this tutorial. @@ -119,16 +119,16 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-quickstart.yaml -mssqlserver.kubedb.com/mssqlserver-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/quickstart/mssqlserver-quickstart.yaml ``` +mssqlserver.kubedb.com/mssqlserver-quickstart created Now, wait until mssqlserver-quickstart has status Ready. i.e, -```shell -$ kubectl get ms -n demo -w +```bash + kubectl get ms -n demo -w +``` NAME VERSION STATUS AGE mssqlserver-quickstart 2022-cu12 Ready 75m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an example showing how to retrieve the credentials from the secret. @@ -142,7 +142,8 @@ $ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.pas ```` Now, you can exec into the pod `mssqlserver-quickstart-0` and connect to database using `username` and `password` ```bash -$ kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +``` mssql@mssqlserver-quickstart-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "9ycCSYznZpZRxs9U" -No 1> select name from sys.databases 2> go @@ -160,7 +161,6 @@ kubedb_system mssql@mssqlserver-quickstart-0:/$ exit exit ⏎ -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth MSSQLServerOpsRequest @@ -187,19 +187,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on MSSQLServer. Let's create the `MSSQLServerOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mssqlserver/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mssqlserver/rotate-auth/rotate-auth-generated.yaml + ``` MSSQLServeropsrequest.ops.kubedb.com/msops-rotate-auth-generated created -``` Let's wait for `MSSQLServerOpsrequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsrequest` CRO -```shell - $ kubectl get MSSQLServeropsrequest -n demo + ```bash + kubectl get MSSQLServeropsrequest -n demo + ``` NAME TYPE STATUS AGE msops-rotate-auth-generated RotateAuth Successful 7m47s -``` If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe MSSQLServeropsrequest -n demo msops-rotate-auth-generated +```bash +kubectl describe MSSQLServeropsrequest -n demo msops-rotate-auth-generated +``` Name: msops-rotate-auth-generated Namespace: demo Labels: @@ -287,21 +288,26 @@ Events: Normal Starting 17m KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssqlserver-quickstart Normal Successful 17m KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssqlserver-quickstart for MSSQLServerOpsRequest: msops-rotate-auth-generated Normal UpdatePetSets 17m KubeDB Ops-manager Operator successfully reconciled the MSSQLServer with updated credentials - -``` **Verify Auth is rotated** -```shell -$ kubectl get ms -n demo mssqlserver-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get ms -n demo mssqlserver-quickstart -ojson | jq .spec.authSecret.name +``` "mssqlserver-quickstart-auth" -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` sa⏎ -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -zTBVvzgoEb2qUe3X⏎ + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +zTBVvzgoEb2qUe3X⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +``` mssql@mssqlserver-quickstart-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "zTBVvzgoEb2qUe3X" -No 1> select name from sys.databases 2> go @@ -318,16 +324,18 @@ kubedb_system mssql@mssqlserver-quickstart-0:/$ exit exit ⏎ -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` sa⏎ -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -9ycCSYznZpZRxs9U⏎ + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +9ycCSYznZpZRxs9U⏎ Let's confirm that the previous credentials no longer work. ```shell kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash @@ -341,14 +349,13 @@ The above output shows that the password has been changed successfully. The prev At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > Note: The `username` must be fixed as `sa`. The `password` must include uppercase letters, lowercase letters, and numbers -```shell -$ kubectl create secret generic mssqlserver-quickstart-auth-user -n demo \ +```bash +kubectl create secret generic mssqlserver-quickstart-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=sa \ --from-literal=password=Mssqlserver2 -secret/mssqlserver-quickstart-auth-user created - ``` +secret/mssqlserver-quickstart-auth-user created Now create a `MSSQLServerOpsRequest` with `RotateAuth` type. Below is the YAML of the `MSSQLServerOpsRequest` that we are going to create, ```shell @@ -377,21 +384,22 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mssqlserver/rotate-auth/rotate-auth-user.yaml -MSSQLServeropsrequest.ops.kubedb.com/msops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/mssqlserver/rotate-auth/rotate-auth-user.yaml ``` +MSSQLServeropsrequest.ops.kubedb.com/msops-rotate-auth-user created Let’s wait for `MSSQLServerOpsRequest` to be Successful. Run the following command to watch `MSSQLServerOpsRequest` CRO: -```shell -$ kubectl get MSSQLServeropsrequest -n demo +```bash +kubectl get MSSQLServeropsrequest -n demo +``` NAME TYPE STATUS AGE msops-rotate-auth-generated RotateAuth Successful 19h msops-rotate-auth-user RotateAuth Successful 7m44s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe MSSQLServeropsrequest -n demo msops-rotate-auth-user +```bash +kubectl describe MSSQLServeropsrequest -n demo msops-rotate-auth-user +``` Name: msops-rotate-auth-user Namespace: demo Labels: @@ -481,21 +489,26 @@ Events: Normal RestartNodes 14m KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 14m KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssqlserver-quickstart Normal Successful 14m KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssqlserver-quickstart for MSSQLServerOpsRequest: msops-rotate-auth-user - -``` **Verify auth is rotate** -```shell -$ kubectl get ms -n demo mssqlserver-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get ms -n demo mssqlserver-quickstart -ojson | jq .spec.authSecret.name +``` "mssqlserver-quickstart-auth " -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o=jsonpath='{.data.username}' | base64 -d +``` sa⏎ -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -Mssqlserver2⏎ + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +Mssqlserver2⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +```bash +kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash +``` mssql@mssqlserver-quickstart-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "Mssqlserver2" -No 1> SELECT name FROM sys.databases 2> go @@ -509,14 +522,16 @@ kubedb_system (5 rows affected) 1> -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` sa⏎ -$ kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -zTBVvzgoEb2qUe3X⏎ + +```bash +kubectl get secret -n demo mssqlserver-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +zTBVvzgoEb2qUe3X⏎ Let's confirm that the previous credentials no longer work. ```shell kubectl exec -it -n demo mssqlserver-quickstart-0 -c mssql -- bash @@ -532,15 +547,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete MSSQLServeropsrequest msops-rotate-auth-generated msops-rotate-auth-user -n demo +```bash +kubectl delete MSSQLServeropsrequest msops-rotate-auth-generated msops-rotate-auth-user -n demo +``` MSSQLServeropsrequest.ops.kubedb.com "msops-rotate-auth-generated" "msops-rotate-auth-user" deleted -$ kubectl delete secret -n demo mssqlserver-quickstart-auth-user + +```bash +kubectl delete secret -n demo mssqlserver-quickstart-auth-user +``` secret "mssqlserver-quickstart-auth-user" deleted -$ kubectl delete secret -n demo mssqlserver-quickstart-auth -secret "mssqlserver-quickstart-auth" deleted +```bash +kubectl delete secret -n demo mssqlserver-quickstart-auth ``` +secret "mssqlserver-quickstart-auth" deleted ## Next Steps diff --git a/docs/guides/mssqlserver/scaling/horizontal-scaling/mssqlserver.md b/docs/guides/mssqlserver/scaling/horizontal-scaling/mssqlserver.md index 723dfb05dc..d81ed0658d 100644 --- a/docs/guides/mssqlserver/scaling/horizontal-scaling/mssqlserver.md +++ b/docs/guides/mssqlserver/scaling/horizontal-scaling/mssqlserver.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops Manager to increase/decrease th To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver/scaling/horizontal-scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -51,11 +51,11 @@ At first, we are going to deploy a Cluster server with 2 replicas. Then, we are When you have installed `KubeDB`, it has created `MSSQLServerVersion` CR for all supported `MSSQLServer` versions. Let's check the supported MSSQLServer versions, ```bash -$ kubectl get mssqlserverversion +kubectl get mssqlserverversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 176m 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 176m -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MSSQLServer`. You can use any non-deprecated version. Here, we are going to create a MSSQLServer Cluster using `MSSQLServer` `2025-cu0`. @@ -74,9 +74,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -92,9 +92,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created In this section, we are going to deploy a MSSQLServer Cluster with 2 replicas. Then, in the next section we will scale up the cluster using horizontal scaling. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -149,9 +149,9 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/mssql-ag-cluster.yaml -mssqlserver.kubedb.com/mssql-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/mssql-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssql-ag-cluster created **Wait for the cluster to be ready:** @@ -159,7 +159,8 @@ mssqlserver.kubedb.com/mssql-ag-cluster created Now, watch `MSSQLServer` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch kubectl get ms,petset,pods -n demo +watch kubectl get ms,petset,pods -n demo +``` Every 2.0s: kubectl get ms,petset,pods -n demo NAME VERSION STATUS AGE @@ -172,20 +173,22 @@ NAME READY STATUS RESTARTS AGE pod/mssql-ag-cluster-0 2/2 Running 0 2m11s pod/mssql-ag-cluster-1 2/2 Running 0 2m6s -``` - Let's verify that the PetSet's pods have created the availability group cluster successfully, ```bash -$ kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d -123KKxgOXuOkP206 + +```bash +kubectl get secrets -n demo mssql-ag-cluster-auth -o jsonpath='{.data.\password}' | base64 -d ``` +123KKxgOXuOkP206 Now, connect to the database using username and password, check the name of the created availability group, replicas of the availability group and see if databases are added to the availability group. ```bash -$ kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +``` mssql@mssql-ag-cluster-2:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "123KKxgOXuOkP206" -No 1> select name from sys.databases 2> go @@ -223,8 +226,6 @@ agdb2 (2 rows affected) -``` - So, we can see that our cluster has 2 replicas. Now, we are ready to apply the horizontal scale to this MSSQLServer cluster. @@ -259,9 +260,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/msops-hscale-up.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-hscale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/msops-hscale-up.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-hscale-up created **Verify Scale-Up Succeeded:** @@ -270,14 +271,13 @@ If everything goes well, `KubeDB` Ops Manager will scale up the PetSet's `Pod`. First, we will wait for `MSSQLServerOpsRequest` to be successful. Run the following command to watch `MSSQLServerOpsRequest` cr, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo msops-hscale-up +watch kubectl get mssqlserveropsrequest -n demo msops-hscale-up +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo msops-hscale-up NAME TYPE STATUS AGE msops-hscale-up HorizontalScaling Successful 76s -``` - You can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest`, we will see that the `MSSQLServer` cluster is scaled up. ```bash @@ -420,7 +420,8 @@ Events: Now, we are going to verify whether the number of replicas has increased to meet up the desired state. So let's check the new pods coordinator container's logs to see if this is joined in the cluster as new replica. ```bash -$ kubectl logs -f -n demo mssql-ag-cluster-2 -c mssql-coordinator +kubectl logs -f -n demo mssql-ag-cluster-2 -c mssql-coordinator +``` raft2024/10/24 15:09:55 INFO: 3 switched to configuration voters=(1 2 3) raft2024/10/24 15:09:55 INFO: 3 switched to configuration voters=(1 2 3) raft2024/10/24 15:09:55 INFO: 3 switched to configuration voters=(1 2 3) @@ -444,12 +445,12 @@ I1024 15:10:18.127336 1 ag.go:79] Joining Availability Group... I1024 15:10:24.638144 1 on_leader_change.go:94] Successfully patched label of demo/mssql-ag-cluster-2 to secondary I1024 15:10:24.650611 1 health.go:50] Sequence Number updated. new sequenceNumber = 4294967322, previous sequenceNumber = 0 I1024 15:10:24.650632 1 health.go:51] 1:1A (4294967322) -``` Now, connect to the database, check updated configurations of the availability group cluster. ```bash -$ kubectl exec -it -n demo mssql-ag-cluster-2 -c mssql -- bash +kubectl exec -it -n demo mssql-ag-cluster-2 -c mssql -- bash +``` mssql@mssql-ag-cluster-2:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "123KKxgOXuOkP206" -No 1> SELECT name FROM sys.availability_groups 2> go @@ -476,7 +477,6 @@ agdb1 agdb2 (2 rows affected) -``` #### Scale Down @@ -503,9 +503,9 @@ spec: Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/msops-hscale-down.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-hscale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/horizontal-scaling/msops-hscale-down.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-hscale-down created **Verify Scale-down Succeeded:** @@ -514,17 +514,18 @@ If everything goes well, `KubeDB` Ops Manager will scale down the PetSet's `Pod` Now, we will wait for `MSSQLServerOpsRequest` to be successful. Run the following command to watch `MSSQLServerOpsRequest` cr, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo msops-hscale-down +watch kubectl get mssqlserveropsrequest -n demo msops-hscale-down +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo msops-hscale-down NAME TYPE STATUS AGE msops-hscale-down HorizontalScaling Successful 98s -``` You can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest`, we shall see that the `MSSQLServer` cluster is scaled down. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-hscale-down +kubectl describe mssqlserveropsrequest -n demo msops-hscale-down +``` Name: msops-hscale-down Namespace: demo Labels: @@ -659,12 +660,12 @@ Events: Normal Starting 44s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssql-ag-cluster Normal Successful 44s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssql-ag-cluster for MSSQLServerOpsRequest: msops-hscale-down Normal UpdateDatabase 44s KubeDB Ops-manager Operator Successfully updated MSSQLServer -``` Now, we are going to verify whether the number of replicas has decreased to meet up the desired state, Let's check, the mssqlserver status if it's ready then the scale-down is successful. ```bash -$ kubectl get ms,petset,pods -n demo +kubectl get ms,petset,pods -n demo +``` NAME VERSION STATUS AGE mssqlserver.kubedb.com/mssql-ag-cluster 2022-cu12 Ready 39m @@ -674,12 +675,12 @@ petset.apps.k8s.appscode.com/mssql-ag-cluster 38m NAME READY STATUS RESTARTS AGE pod/mssql-ag-cluster-0 2/2 Running 0 38m pod/mssql-ag-cluster-1 2/2 Running 0 38m -``` Now, connect to the database, check updated configurations of the availability group cluster. ```bash -$ kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +kubectl exec -it -n demo mssql-ag-cluster-0 -c mssql -- bash +``` mssql@mssql-ag-cluster-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "123KKxgOXuOkP206" -No 1> SELECT name FROM sys.availability_groups 2> go @@ -696,7 +697,6 @@ mssql-ag-cluster-0 mssql-ag-cluster-1 (2 rows affected) -``` You can see above that our `MSSQLServer` cluster now has a total of 2 replicas. It verifies that we have successfully scaled down. diff --git a/docs/guides/mssqlserver/scaling/vertical-scaling/ag_cluster.md b/docs/guides/mssqlserver/scaling/vertical-scaling/ag_cluster.md index 5243332f0f..6116679498 100644 --- a/docs/guides/mssqlserver/scaling/vertical-scaling/ag_cluster.md +++ b/docs/guides/mssqlserver/scaling/vertical-scaling/ag_cluster.md @@ -33,9 +33,9 @@ This guide will show you how to use `kubeDB-Ops-Manager` to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver/scaling/vertical-scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ Here, we are going to deploy a `MSSQLServer` instance using a supported version When you have installed `KubeDB`, it has created `MSSQLServerVersion` CR for all supported `MSSQLServer` versions. Let's check the supported MSSQLServer versions, ```bash -$ kubectl get mssqlserverversion +kubectl get mssqlserverversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 3d21h 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 3d21h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MSSQLServer`. You can use any non-deprecated version. Here, we are going to create a mssqlserver using non-deprecated `MSSQLServer` version `2025-cu0`. @@ -70,9 +70,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -142,9 +142,9 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mssql-ag-cluster.yaml -mssqlserver.kubedb.com/mssql-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mssql-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssql-ag-cluster created **Check mssqlserver Ready to Scale:** @@ -154,7 +154,8 @@ Now, watch `MSSQLServer` is going to be in `Running` state and also watch `PetSe ```bash -$ watch kubectl get ms,petset,pods -n demo +watch kubectl get ms,petset,pods -n demo +``` Every 2.0s: kubectl get ms,petset,pods -n demo NAME VERSION STATUS AGE @@ -167,12 +168,12 @@ NAME READY STATUS RESTARTS AGE pod/mssql-ag-cluster-0 2/2 Running 0 3m57s pod/mssql-ag-cluster-1 2/2 Running 0 3m51s pod/mssql-ag-cluster-2 2/2 Running 0 3m46s -``` Let's check pod's `mssql` container's resources, `mssql` container is the first container So it's index will be 0. ```bash -$ kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -183,7 +184,10 @@ $ kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].r "memory": "1536Mi" } } -$ kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -194,7 +198,10 @@ $ kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].r "memory": "1536Mi" } } -$ kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -205,7 +212,6 @@ $ kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].r "memory": "1536Mi" } } -``` Now, We are ready to apply a vertical scale on this mssqlserver database. @@ -248,9 +254,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mops-vscale-ag-cluster.yaml -mssqlserveropsrequest.ops.kubedb.com/mops-vscale-ag-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mops-vscale-ag-cluster.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/mops-vscale-ag-cluster created **Verify MSSQLServer resources updated successfully:** @@ -259,17 +265,18 @@ If everything goes well, `KubeDB-Ops-Manager` will update the resources of the P First, we will wait for `MSSQLServerOpsRequest` to be successful. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo mops-vscale-ag-cluster +watch kubectl get mssqlserveropsrequest -n demo mops-vscale-ag-cluster +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo mops-vscale-ag-cluster NAME TYPE STATUS AGE mops-vscale-ag-cluster VerticalScaling Successful 7m17s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest`, we will see that the mssqlserver resources are updated. ```bash -$ kubectl describe mssqlserveropsrequest -n demo mops-vscale-ag-cluster +kubectl describe mssqlserveropsrequest -n demo mops-vscale-ag-cluster +``` Name: mops-vscale-ag-cluster Namespace: demo Labels: @@ -396,12 +403,12 @@ Events: Normal RestartPods 5m38s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 5m38s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssql-ag-cluster Normal Successful 5m38s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssql-ag-cluster for MSSQLServerOpsRequest: mops-vscale-ag-cluster -``` Now, we are going to verify whether the resources of the mssqlserver instance has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "2", @@ -412,7 +419,10 @@ $ kubectl get pod -n demo mssql-ag-cluster-0 -o json | jq '.spec.containers[0].r "memory": "1825361100800m" } } -$ kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "2", @@ -423,7 +433,10 @@ $ kubectl get pod -n demo mssql-ag-cluster-1 -o json | jq '.spec.containers[0].r "memory": "1825361100800m" } } -$ kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].resources' + +```bash +kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "2", @@ -434,7 +447,6 @@ $ kubectl get pod -n demo mssql-ag-cluster-2 -o json | jq '.spec.containers[0].r "memory": "1825361100800m" } } -``` The above output verifies that we have successfully scaled up the resources of the MSSQLServer. diff --git a/docs/guides/mssqlserver/scaling/vertical-scaling/standalone.md b/docs/guides/mssqlserver/scaling/vertical-scaling/standalone.md index d41bcf4815..32571aecec 100644 --- a/docs/guides/mssqlserver/scaling/vertical-scaling/standalone.md +++ b/docs/guides/mssqlserver/scaling/vertical-scaling/standalone.md @@ -33,9 +33,9 @@ This guide will show you how to use `kubeDB-Ops-Manager` to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver/scaling/vertical-scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ Here, we are going to deploy a `MSSQLServer` instance using a supported version When you have installed `KubeDB`, it has created `MSSQLServerVersion` CR for all supported `MSSQLServer` versions. Let's check the supported MSSQLServer versions, ```bash -$ kubectl get mssqlserverversion +kubectl get mssqlserverversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2022-cu12 2022 mcr.microsoft.com/mssql/server:2022-CU12-ubuntu-22.04 3d21h 2022-cu14 2022 mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 3d21h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MSSQLServer`. You can use any non-deprecated version. Here, we are going to create a mssqlserver using non-deprecated `MSSQLServer` version `2025-cu0`. @@ -70,9 +70,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -129,9 +129,9 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mssql-standalone.yaml -mssqlserver.kubedb.com/mssql-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mssql-standalone.yaml ``` +mssqlserver.kubedb.com/mssql-standalone created **Check mssqlserver Ready to Scale:** @@ -144,7 +144,8 @@ Now, watch `MSSQLServer` is going to be in `Running` state and also watch `PetSe ```bash -$ watch kubectl get ms,petset,pods -n demo +watch kubectl get ms,petset,pods -n demo +``` Every 2.0s: kubectl get ms,petset,pods -n demo NAME VERSION STATUS AGE @@ -155,12 +156,12 @@ petset.apps.k8s.appscode.com/mssql-standalone 3m33s NAME READY STATUS RESTARTS AGE pod/mssql-standalone-0 1/1 Running 0 3m33s -``` Let's check the `mssql-standalone-0` pod's `mssql` container's resources, `mssql` container is the first container So it's index will be 0. ```bash -$ kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "4Gi" @@ -170,7 +171,6 @@ $ kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].r "memory": "4Gi" } } -``` Now, We are ready to apply a vertical scale on this mssqlserver database. @@ -211,9 +211,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mops-vscale-standalone.yaml -mssqlserveropsrequest.ops.kubedb.com/mops-vscale-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/scaling/vertical-scaling/mops-vscale-standalone.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/mops-vscale-standalone created **Verify MSSQLServer resources updated successfully:** @@ -222,17 +222,18 @@ If everything goes well, `KubeDB-Ops-Manager` will update the resources of the P First, we will wait for `MSSQLServerOpsRequest` to be successful. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo mops-vscale-standalone +watch kubectl get mssqlserveropsrequest -n demo mops-vscale-standalone +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo mops-vscale-standalone NAME TYPE STATUS AGE mops-vscale-standalone VerticalScaling Successful 3m22s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest`, we will see that the mssqlserver resources are updated. ```bash -$ kubectl describe mssqlserveropsrequest -n demo mops-vscale-standalone +kubectl describe mssqlserveropsrequest -n demo mops-vscale-standalone +``` Name: mops-vscale-standalone Namespace: demo Labels: @@ -321,12 +322,12 @@ Events: Normal RestartPods 2m43s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 2m43s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssql-standalone Normal Successful 2m43s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssql-standalone for MSSQLServerOpsRequest: mops-vscale-standalone -``` Now, we are going to verify whether the resources of the mssqlserver instance has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "5Gi" @@ -336,7 +337,6 @@ $ kubectl get pod -n demo mssql-standalone-0 -o json | jq '.spec.containers[0].r "memory": "5Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the MSSQLServer. diff --git a/docs/guides/mssqlserver/tls/ag_cluster.md b/docs/guides/mssqlserver/tls/ag_cluster.md index becfa71c74..32b061f37f 100644 --- a/docs/guides/mssqlserver/tls/ag_cluster.md +++ b/docs/guides/mssqlserver/tls/ag_cluster.md @@ -29,9 +29,9 @@ KubeDB supports providing TLS/SSL encryption for MSSQLServer. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver/tls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -96,9 +96,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ## TLS/SSL encryption in SQL Server Availability Group @@ -147,18 +147,18 @@ spec: ### Deploy MSSQLServer in Availability Group Mode ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/mssql-ag-tls.yaml -ms.kubedb.com/mssql-ag-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/mssql-ag-tls.yaml ``` +ms.kubedb.com/mssql-ag-tls created Now, wait until `mssql-ag-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get ms -n demo +watch kubectl get ms -n demo +``` Every 2.0s: kubectl get ms -n demo NAME VERSION STATUS AGE mssql-ag-tls 2022-cu12 Ready 4m26s -``` ### Verify TLS/SSL in MSSQLServer in Availability Group Mode @@ -166,7 +166,8 @@ mssql-ag-tls 2022-cu12 Ready 4m26s 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 mssql-ag-tls-client-cert +kubectl describe secret -n demo mssql-ag-tls-client-cert +``` Name: mssql-ag-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -192,21 +193,23 @@ Data tls.crt: 1180 bytes tls.key: 1675 bytes ca.crt: 1164 bytes -``` Now, we can connect with tls to the mssqlserver and write some data ```bash -$ kubectl get secret -n demo mssql-ag-tls-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo mssql-ag-tls-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo mssql-ag-tls-auth -o jsonpath='{.data.\password}' | base64 -d -Ng1DaJSNjZkgXXFX +```bash +kubectl get secret -n demo mssql-ag-tls-auth -o jsonpath='{.data.\password}' | base64 -d ``` +Ng1DaJSNjZkgXXFX ```bash -$ kubectl exec -it -n demo mssql-ag-tls-0 -c mssql -- bash +kubectl exec -it -n demo mssql-ag-tls-0 -c mssql -- bash +``` mssql@mssql-ag-tls-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P Ng1DaJSNjZkgXXFX -N 1> select name from sys.databases 2> go @@ -245,22 +248,24 @@ agdb2 (2 rows affected) -``` - ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mssqlserver/mssql-ag-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mssqlserver/mssql-ag-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` mssqlserver.kubedb.com/mssql-ag-tls patched -$ kubectl delete -n demo mssqlserver mssql-ag-tls +```bash +kubectl delete -n demo mssqlserver mssql-ag-tls +``` mssqlserver.kubedb.com "mssql-ag-tls" deleted -$ kubectl delete issuer mssqlserver-ca-issuer -clusterissuer.cert-manager.io "mssqlserver-ca-issuer" deleted +```bash +kubectl delete issuer mssqlserver-ca-issuer ``` +clusterissuer.cert-manager.io "mssqlserver-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/mssqlserver/tls/standalone.md b/docs/guides/mssqlserver/tls/standalone.md index 55ce07f8fc..3e94950c40 100644 --- a/docs/guides/mssqlserver/tls/standalone.md +++ b/docs/guides/mssqlserver/tls/standalone.md @@ -29,9 +29,9 @@ KubeDB supports providing TLS/SSL encryption for MSSQLServer. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mssqlserver/tls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mssqlserver/tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -96,9 +96,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ## TLS/SSL encryption in MSSQLServer Standalone @@ -142,26 +142,27 @@ spec: ### Deploy MSSQLServer Standalone ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/mssql-standalone-tls.yaml -mssqlserver.kubedb.com/mssql-standalone-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/tls/mssql-standalone-tls.yaml ``` +mssqlserver.kubedb.com/mssql-standalone-tls created Now, wait until `mssql-standalone-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get ms -n demo +watch kubectl get ms -n demo +``` Every 2.0s: kubectl get ms -n demo NAME VERSION STATUS AGE mssql-standalone-tls 2022-cu12 Ready 3m30s -``` ### Verify TLS/SSL in MSSQLServer Standalone 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 mssql-standalone-tls-client-cert +kubectl describe secret -n demo mssql-standalone-tls-client-cert +``` Name: mssql-standalone-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -187,20 +188,22 @@ Data ca.crt: 1164 bytes tls.crt: 1180 bytes tls.key: 1679 bytes -``` Now, we can connect with tls to the mssqlserver and write some data ```bash -$ kubectl get secret -n demo mssql-standalone-tls-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secret -n demo mssql-standalone-tls-auth -o jsonpath='{.data.\username}' | base64 -d +``` sa -$ kubectl get secret -n demo mssql-standalone-tls-auth -o jsonpath='{.data.\password}' | base64 -d -C2vU3HOCWY0hQHaj +```bash +kubectl get secret -n demo mssql-standalone-tls-auth -o jsonpath='{.data.\password}' | base64 -d ``` +C2vU3HOCWY0hQHaj ```bash -$ kubectl exec -it -n demo mssql-standalone-tls-0 -c mssql -- bash +kubectl exec -it -n demo mssql-standalone-tls-0 -c mssql -- bash +``` mssql@mssql-standalone-tls-0:/$ /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "C2vU3HOCWY0hQHaj" -N 1> select name from sys.databases 2> go @@ -231,22 +234,25 @@ ID NAME 2 Jane Smith 30 (2 rows affected) 1> -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo mssqlserver/mssql-standalone-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo mssqlserver/mssql-standalone-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` mssqlserver.kubedb.com/mssql-standalone-tls patched -$ kubectl delete -n demo mssqlserver mssql-standalone-tls +```bash +kubectl delete -n demo mssqlserver mssql-standalone-tls +``` mssqlserver.kubedb.com "mssql-standalone-tls" deleted -$ kubectl delete issuer -n demo mssqlserver-ca-issuer -issuer.cert-manager.io "mssqlserver-ca-issuer" deleted +```bash +kubectl delete issuer -n demo mssqlserver-ca-issuer ``` +issuer.cert-manager.io "mssqlserver-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/mssqlserver/update-version/ag_cluster.md b/docs/guides/mssqlserver/update-version/ag_cluster.md index d5c2ad4c83..c6ef961ead 100644 --- a/docs/guides/mssqlserver/update-version/ag_cluster.md +++ b/docs/guides/mssqlserver/update-version/ag_cluster.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver](/docs/examples/mssqlserver/update-version) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -53,9 +53,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -71,9 +71,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created Now, we are going to deploy a `MSSQLServer` availability group with version `2022-cu22`. @@ -133,17 +133,17 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/mssql-ag-cluster.yaml -mssqlserver.kubedb.com/mssql-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/mssql-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssql-ag-cluster created Now, wait until `mssql-ag-cluster` created has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE mssql-ag-cluster 2022-cu12 Ready 4m -``` We are now ready to apply the `MSSQLServerOpsRequest` CR to update this database. @@ -182,9 +182,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/msops-update-ag-cluster .yaml -mssqlserveropsrequest.ops.kubedb.com/msops-update-ag-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/msops-update-ag-cluster .yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-update-ag-cluster created #### Verify MSSQLServer version updated successfully @@ -193,15 +193,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo +watch kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE msops-update-ag-cluster UpdateVersion Successful 2m33s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-update-ag-cluster +kubectl describe mssqlserveropsrequest -n demo msops-update-ag-cluster +``` Name: msops-update-ag-cluster Namespace: demo Labels: @@ -322,20 +323,23 @@ Events: Normal RestartPods 5m21s KubeDB Ops-manager Operator Successfully Restarted MSSQLServer pods Normal Starting 5m21s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssql-ag-cluster Normal Successful 5m21s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssql-ag-cluster for MSSQLServerOpsRequest: msops-update-ag-cluster -``` Now, we are going to verify whether the `MSSQLServer` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get ms -n demo mssql-ag-cluster -o=jsonpath='{.spec.version}{"\n"}' +kubectl get ms -n demo mssql-ag-cluster -o=jsonpath='{.spec.version}{"\n"}' +``` 2022-cu14 -$ kubectl get petset -n demo mssql-ag-cluster -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mssql-ag-cluster -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04@sha256:c1aa8afe9b06eab64c9774a4802dcd032205d1be785b1fd51e1c0151e7586b74 -$ kubectl get pods -n demo mssql-ag-cluster-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 +```bash +kubectl get pods -n demo mssql-ag-cluster-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 You can see from above, our `MSSQLServer` ag database cluster has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/mssqlserver/update-version/standalone.md b/docs/guides/mssqlserver/update-version/standalone.md index 6e576bc5ef..6fa8fba70c 100644 --- a/docs/guides/mssqlserver/update-version/standalone.md +++ b/docs/guides/mssqlserver/update-version/standalone.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/mssqlserver](/docs/examples/mssqlserver/update-version) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -59,9 +59,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -77,9 +77,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created ### Create MSSSQLServer @@ -124,17 +124,17 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/mssql-standalone.yaml -mssqlserver.kubedb.com/mssql-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/mssql-standalone.yaml ``` +mssqlserver.kubedb.com/mssql-standalone created Now, wait until `mssql-standalone` created has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo +kubectl get ms -n demo +``` NAME VERSION STATUS AGE mssql-standalone 2022-cu12 Ready 3m8s -``` We are now ready to apply the `MSSQLServerOpsRequest` CR to update this database. @@ -173,9 +173,9 @@ Here, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/msops-update-standalone.yaml -mssqlserveropsrequest.ops.kubedb.com/msops-update-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/update-version/msops-update-standalone.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/msops-update-standalone created #### Verify MSSQLServer version updated successfully : @@ -184,16 +184,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ watch kubectl get mssqlserveropsrequest -n demo +watch kubectl get mssqlserveropsrequest -n demo +``` Every 2.0s: kubectl get mssqlserveropsrequest -n demo NAME TYPE STATUS AGE msops-update-standalone UpdateVersion Successful 2m28s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to update the database. ```bash -$ kubectl describe mssqlserveropsrequest -n demo msops-update-standalone +kubectl describe mssqlserveropsrequest -n demo msops-update-standalone +``` Name: msops-update-standalone Namespace: demo Labels: @@ -276,20 +277,23 @@ Events: Normal RestartPods 28s KubeDB Ops-manager Operator Successfully Restarted MSSQLServer pods Normal Starting 28s KubeDB Ops-manager Operator Resuming MSSQLServer database: demo/mssql-standalone Normal Successful 28s KubeDB Ops-manager Operator Successfully resumed MSSQLServer database: demo/mssql-standalone for MSSQLServerOpsRequest: msops-update-standalone -``` Now, we are going to verify whether the `MSSQLServer` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get ms -n demo mssql-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get ms -n demo mssql-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 2022-cu14 -$ kubectl get petset -n demo mssql-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo mssql-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04@sha256:c1aa8afe9b06eab64c9774a4802dcd032205d1be785b1fd51e1c0151e7586b74 -$ kubectl get pods -n demo mssql-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 +```bash +kubectl get pods -n demo mssql-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04 You can see from above, our `MSSQLServer` standalone database has been updated with the new version. So, the update process is successfully completed. diff --git a/docs/guides/mssqlserver/volume-expansion/ag_cluster.md b/docs/guides/mssqlserver/volume-expansion/ag_cluster.md index edd2e7c631..277e3c80d7 100644 --- a/docs/guides/mssqlserver/volume-expansion/ag_cluster.md +++ b/docs/guides/mssqlserver/volume-expansion/ag_cluster.md @@ -34,9 +34,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of MSSQLServer Availability Group Cluster @@ -47,12 +47,12 @@ Here, we are going to deploy a `MSSQLServer` cluster using a supported version At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 2d standard (default) driver.standard.io Delete Immediate true 3m25s standard-static driver.standard.io Delete Immediate true 3m19s -``` We can see from the output that `standard (default)` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. @@ -73,9 +73,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -91,9 +91,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/ag-cluster/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created In this section, we are going to deploy a MSSQLServer Cluster with 1GB volume. Then, in the next section we will expand its volume to 2GB using `MSSQLServerOpsRequest` CRD. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -141,30 +141,32 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mssqlserver-ag-cluster.yaml -mssqlserver.kubedb.com/mssqlserver-ag-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mssqlserver-ag-cluster.yaml ``` +mssqlserver.kubedb.com/mssqlserver-ag-cluster created Now, wait until `mssqlserver-ag-cluster` has status `Ready`. i.e, ```bash -$ kubectl get mssqlserver -n demo mssqlserver-ag-cluster +kubectl get mssqlserver -n demo mssqlserver-ag-cluster +``` NAME VERSION STATUS AGE mssqlserver-ag-cluster 2022-cu12 Ready 5m1s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-059f186a-01a4-441d-85f1-95aef34934be 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-0 standard 82s pvc-87bea35f-4a55-4aa5-903a-e4da9f548241 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-1 standard 52s pvc-9d1c3c9c-f928-4fa2-a2e1-becf2ab9c564 1Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-2 standard 35s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -208,9 +210,9 @@ During `Online` VolumeExpansion KubeDB expands volume without deleting the pods, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mops-volume-exp-ag-cluster.yaml -mssqlserveropsrequest.ops.kubedb.com/mops-volume-exp-ag-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mops-volume-exp-ag-cluster.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/mops-volume-exp-ag-cluster created #### Verify MSSQLServer volume expanded successfully @@ -219,25 +221,27 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE mops-volume-exp-ag-cluster VolumeExpansion Successful 8m30s -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssqlserver-ag-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-059f186a-01a4-441d-85f1-95aef34934be 2Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-0 standard 29m pvc-87bea35f-4a55-4aa5-903a-e4da9f548241 2Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-1 standard 29m pvc-9d1c3c9c-f928-4fa2-a2e1-becf2ab9c564 2Gi RWO Delete Bound demo/data-mssqlserver-ag-cluster-2 standard 29m -``` The above output verifies that we have successfully expanded the volume of the MSSQLServer database. @@ -252,19 +256,23 @@ To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ms/mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ms/mssqlserver-ag-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` mssqlserver.kubedb.com/mssqlserver-ag-cluster patched -$ kubectl delete -n demo mssqlserver mssqlserver-ag-cluster +```bash +kubectl delete -n demo mssqlserver mssqlserver-ag-cluster +``` mssqlserver.kubedb.com "mssqlserver-ag-cluster" deleted -$ kubectl delete -n demo mssqlserveropsrequest mops-volume-exp-ag-cluster +```bash +kubectl delete -n demo mssqlserveropsrequest mops-volume-exp-ag-cluster +``` mssqlserveropsrequest.ops.kubedb.com "mops-volume-exp-ag-cluster" deleted kubectl delete issuer -n demo mssqlserver-ca-issuer kubectl delete secret -n demo mssqlserver-ca kubectl delete ns demo -``` ## Next Steps diff --git a/docs/guides/mssqlserver/volume-expansion/standalone.md b/docs/guides/mssqlserver/volume-expansion/standalone.md index 20cfe4f0f6..779851b48d 100644 --- a/docs/guides/mssqlserver/volume-expansion/standalone.md +++ b/docs/guides/mssqlserver/volume-expansion/standalone.md @@ -34,9 +34,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of MSSQLServer @@ -47,12 +47,12 @@ Here, we are going to deploy a `MSSQLServer` standalone using a supported versi At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 2d standard (default) driver.standard.io Delete Immediate true 3m25s standard-static driver.standard.io Delete Immediate true 3m19s -``` We can see from the output that `standard (default)` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. @@ -73,9 +73,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c ``` - Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/mssqlserver-ca created +kubectl create secret tls mssqlserver-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/mssqlserver-ca created Now, we are going to create an `Issuer` using the `mssqlserver-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` CR that we are going to create, ```yaml @@ -91,9 +91,9 @@ spec: Let’s create the `Issuer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml -issuer.cert-manager.io/mssqlserver-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/standalone/mssqlserver-ca-issuer.yaml ``` +issuer.cert-manager.io/mssqlserver-ca-issuer created In this section, we are going to deploy a MSSQLServer Standalone with 1GB volume. Then, in the next section we will expand its volume to 2GB using `MSSQLServerOpsRequest` CRD. Below is the YAML of the `MSSQLServer` CR that we are going to create, @@ -141,28 +141,30 @@ spec: Let's create the `MSSQLServer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mssql-standalone.yaml -mssqlserver.kubedb.com/mssql-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mssql-standalone.yaml ``` +mssqlserver.kubedb.com/mssql-standalone created Now, wait until `mssql-standalone` has status `Ready`. i.e, ```bash -$ kubectl get ms -n demo mssql-standalone +kubectl get ms -n demo mssql-standalone +``` NAME VERSION STATUS AGE mssql-standalone 2022-cu12 Ready 5m -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo mssql-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssql-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-7e7ed996-b682-4d84-8450-4c06fe92b11f 1Gi RWO Delete Bound demo/data-mssql-standalone-0 standard 5m29s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -206,9 +208,9 @@ During `Online` VolumeExpansion KubeDB expands volume without deleting the pods, Let's create the `MSSQLServerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mops-volume-exp-std.yaml -mssqlserveropsrequest.ops.kubedb.com/mops-volume-exp-std created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mssqlserver/volume-expansion/mops-volume-exp-std.yaml ``` +mssqlserveropsrequest.ops.kubedb.com/mops-volume-exp-std created #### Verify MSSQLServer volume expanded successfully @@ -217,15 +219,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `MSSQLServerOpsRequest` to be `Successful`. Run the following command to watch `MSSQLServerOpsRequest` CR, ```bash -$ kubectl get mssqlserveropsrequest -n demo +kubectl get mssqlserveropsrequest -n demo +``` NAME TYPE STATUS AGE mops-volume-exp-std VolumeExpansion Successful 9m -``` We can see from the above output that the `MSSQLServerOpsRequest` has succeeded. If we describe the `MSSQLServerOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe msops -n demo mops-volume-exp-std +kubectl describe msops -n demo mops-volume-exp-std +``` Name: mops-volume-exp-std Namespace: demo Labels: @@ -340,18 +343,19 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo mssql-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo mssql-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-7e7ed996-b682-4d84-8450-4c06fe92b11f 2Gi RWO Delete Bound demo/data-mssql-standalone-0 standard 26m -``` The above output verifies that we have successfully expanded the volume of the MSSQLServer Standalone database. @@ -361,19 +365,23 @@ To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo ms/mssql-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo ms/mssql-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` mssqlserver.kubedb.com/mssql-standalone patched -$ kubectl delete -n demo mssqlserver mssql-standalone +```bash +kubectl delete -n demo mssqlserver mssql-standalone +``` mssqlserver.kubedb.com "mssql-standalone" deleted -$ kubectl delete -n demo mssqlserveropsrequest mops-volume-exp-std +```bash +kubectl delete -n demo mssqlserveropsrequest mops-volume-exp-std +``` mssqlserveropsrequest.ops.kubedb.com "mops-volume-exp-std" deleted kubectl delete issuer -n demo mssqlserver-ca-issuer kubectl delete secret -n demo mssqlserver-ca kubectl delete ns demo -``` ## Next Steps diff --git a/docs/guides/mysql/autoscaler/compute/cluster/index.md b/docs/guides/mysql/autoscaler/compute/cluster/index.md index 0936854e2f..1df2b9593f 100644 --- a/docs/guides/mysql/autoscaler/compute/cluster/index.md +++ b/docs/guides/mysql/autoscaler/compute/cluster/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Cluster Database Here, we are going to deploy a `MySQL` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `MySQLAutoscaler` to set up autoscaling. @@ -81,22 +81,23 @@ spec: Let's create the `MySQL` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/compute/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/compute/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created Now, wait until `sample-mysql` has status `Ready`. i.e, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.4.8 Ready 14m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -107,11 +108,11 @@ $ kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resour "memory": "300Mi" } } -``` Let's check the MySQL resources, ```bash -$ kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mysql") | .resources' +kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mysql") | .resources' +``` { "limits": { "cpu": "200m", @@ -122,7 +123,6 @@ $ kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.co "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the mysql. @@ -183,20 +183,23 @@ If a step doesn't finish within the specified timeout, the ops request will resu Let's create the `MySQLAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/compute/cluster/examples/my-as-compute.yaml -mysqlautoscaler.autoscaling.kubedb.com/my-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/compute/cluster/examples/my-as-compute.yaml ``` +mysqlautoscaler.autoscaling.kubedb.com/my-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `mysqlautoscaler` resource is created successfully, ```bash -$ kubectl get mysqlautoscaler -n demo +kubectl get mysqlautoscaler -n demo +``` NAME AGE my-as-compute 5m56s -$ kubectl describe mysqlautoscaler my-as-compute -n demo +```bash +kubectl describe mysqlautoscaler my-as-compute -n demo +``` Name: my-as-compute Namespace: demo Labels: @@ -300,8 +303,6 @@ Status: Memory: 1Gi Vpa Name: sample-mysql Events: - -``` So, the `mysqlautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -311,23 +312,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `mysqlopsrequest` in the demo namespace to see if any `mysqlopsrequest` object is created. After some time you'll see that a `mysqlopsrequest` will be created based on the recommendation. ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE myops-sample-mysql-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE myops-vpa-sample-mysql-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-vpa-sample-mysql-z43wc8 +kubectl describe mysqlopsrequest -n demo myops-vpa-sample-mysql-z43wc8 +``` Name: myops-sample-mysql-6xc1kc Namespace: demo Labels: @@ -404,12 +406,12 @@ Events: Normal Starting 5m8s KubeDB Enterprise Operator Resuming MySQL database: demo/sample-mysql Normal Successful 5m8s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/sample-mysql Normal Successful 5m8s KubeDB Enterprise Operator Controller has Successfully scaled the MySQL database: demo/sample-mysql -``` Now, we are going to verify from the Pod, and the MySQL yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -421,7 +423,9 @@ $ kubectl get pod -n demo sample-mysql-0 -o json | jq '.spec.containers[].resour } } -$ kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mysql") | .resources' +```bash +kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "mysql") | .resources' +``` { "limits": { "cpu": "250m", @@ -432,7 +436,6 @@ $ kubectl get mysql -n demo sample-mysql -o json | jq '.spec.podTemplate.spec.co "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the MySQL replicaset database. diff --git a/docs/guides/mysql/autoscaler/storage/cluster/index.md b/docs/guides/mysql/autoscaler/storage/cluster/index.md index 7f63599168..458b7dd333 100644 --- a/docs/guides/mysql/autoscaler/storage/cluster/index.md +++ b/docs/guides/mysql/autoscaler/storage/cluster/index.md @@ -37,20 +37,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a MySQL To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -87,30 +87,32 @@ spec: Let's create the `MySQL` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/storage/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/storage/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created Now, wait until `sample-mysql` has status `Ready`. i.e, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE sample-mysql 10.5.23 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-sample-mysql-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-sample-mysql-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-mysql-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -152,20 +154,23 @@ Here, Let's create the `MySQLAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/storage/cluster/examples/my-as-storage.yaml -mysqlautoscaler.autoscaling.kubedb.com/my-as-st created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/autoscaler/storage/cluster/examples/my-as-storage.yaml ``` +mysqlautoscaler.autoscaling.kubedb.com/my-as-st created #### Storage Autoscaling is set up successfully Let's check that the `mysqlautoscaler` resource is created successfully, ```bash -$ kubectl get mysqlautoscaler -n demo +kubectl get mysqlautoscaler -n demo +``` NAME AGE my-as-st 33s -$ kubectl describe mysqlautoscaler my-as-st -n demo +```bash +kubectl describe mysqlautoscaler my-as-st -n demo +``` Name: my-as-st Namespace: demo Labels: @@ -187,7 +192,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `mysqlautoscaler` resource is created successfully. @@ -196,7 +200,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume(`var/lib/mysql`) using the following commands: ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- bash +kubectl exec -it -n demo sample-mysql-0 -- bash +``` root@sample-mysql-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 357M 658M 36% /var/lib/mysql @@ -207,30 +212,30 @@ root@sample-mysql-0:/ dd if=/dev/zero of=/var/lib/mysql/file.img bs=500M count=1 root@sample-mysql-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 857M 158M 85% /var/lib/mysql -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 20%. Let's watch the `mysqlopsrequest` in the demo namespace to see if any `mysqlopsrequest` object is created. After some time you'll see that a `mysqlopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-mysql-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-mysql-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mysqlopsrequest -n demo mops-sample-mysql-xojkua +kubectl describe mysqlopsrequest -n demo mops-sample-mysql-xojkua +``` Name: mops-sample-mysql-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -293,19 +298,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming MySQL database: demo/sample-mysql Normal Successful 103s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/sample-mysql Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of MySQL: demo/sample-mysql -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-sample-mysql-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-sample-mysql-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-sample-mysql-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the MySQL replicaset database. diff --git a/docs/guides/mysql/backup/kubestash/application-level/index.md b/docs/guides/mysql/backup/kubestash/application-level/index.md index d8cd217096..6347c07503 100644 --- a/docs/guides/mysql/backup/kubestash/application-level/index.md +++ b/docs/guides/mysql/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/backup/kubestash/application-level/examples](docs/guides/mysql/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -86,33 +86,35 @@ Here, Create the above `MySQL` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created KubeDB will deploy a MySQL database according to the above specification. It will also create the necessary Secrets and Services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mysqls.kubedb.com -n demo +kubectl get mysqls.kubedb.com -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.2.0 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-mysql-auth Opaque 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mysql ClusterIP 10.96.55.61 3306/TCP 97s sample-mysql-pods ClusterIP None 3306/TCP 97s sample-mysql-standby ClusterIP 10.96.211.186 3306/TCP 97 -``` Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mysql/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. @@ -121,15 +123,15 @@ Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to co Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mysql 9m24s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mysql -o yaml +kubectl get appbindings -n demo sample-mysql -o yaml ``` ```yaml @@ -184,27 +186,30 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, we are going to exec into the database pod and create some sample data. At first, find out the database Pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +``` NAME READY STATUS RESTARTS AGE sample-mysql-0 2/2 Running 0 33m sample-mysql-1 2/2 Running 0 33m sample-mysql-2 2/2 Running 0 33m -``` And copy the username and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d -DZfmUZd14fNEEOU4⏎ +```bash +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +DZfmUZd14fNEEOU4⏎ Now, Lets exec into the Pod to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=DZfmUZd14fNEEOU4 +kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=DZfmUZd14fNEEOU4 +``` Defaulted container "mysql" out of: mysql, mysql-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -258,7 +263,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` Now, we are ready to backup the database. ### Prepare Backend @@ -270,13 +274,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -305,9 +315,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -338,9 +348,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -353,11 +363,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create BackupConfiguration:** @@ -410,27 +423,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mysql-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mysql-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mysql-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mysql-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mysql` directory. @@ -441,10 +454,10 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mysql-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** @@ -453,11 +466,10 @@ KubeStash triggers an instant backup as soon as the `BackupConfiguration` is rea Run the following command to watch `BackupSession` CR, ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mysql-backup-frequent-backup-1724065200 BackupConfiguration sample-mysql-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -466,18 +478,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-mysql-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mysql-repo +kubectl get repository -n demo gcs-mysql-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mysql-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mysql-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mysql-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mysql-repo-sample-mysql-backup-frequent-backup-1725359100 gcs-mysql-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -490,7 +502,7 @@ gcs-mysql-repo-sample-mysql-backup-frequent-backup-1725359100 gcs-mysql-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-mysql-repo-sample-mysql-backup-frequent-backup-1725359100 -oyaml +kubectl get snapshots -n demo gcs-mysql-repo-sample-mysql-backup-frequent-backup-1725359100 -oyaml ``` ```yaml @@ -594,9 +606,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -638,19 +650,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-mysql-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-mysql-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. #### Verify Restored MySQL Manifest: @@ -658,10 +670,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `MySQL` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get mysqls.kubedb.com -n dev +kubectl get mysqls.kubedb.com -n dev +``` NAME VERSION STATUS AGE sample-mysql 8.2.0 Ready 39m -``` The output confirms that the `MySQL` database has been successfully created with the same configuration as it had at the time of backup. @@ -672,33 +684,36 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get my -n dev sample-mysql +kubectl get my -n dev sample-mysql +``` NAME VERSION STATUS AGE sample-mysql 8.2.0 Ready 4m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mysql" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-mysql" +``` NAME READY STATUS RESTARTS AGE sample-mysql-0 2/2 Running 0 2m sample-mysql-1 2/2 Running 0 2m sample-mysql-2 2/2 Running 0 2m -``` And then copy the username and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n dev sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n dev sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root -$ kubectl get secret -n dev sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d -QMm1hi0T*7QFz_yh +```bash +kubectl get secret -n dev sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +QMm1hi0T*7QFz_yh ```bash -$ kubectl exec -it -n dev sample-mysql-0 -- mysql --user=root --password='QMm1hi0T*7QFz_yh' +kubectl exec -it -n dev sample-mysql-0 -- mysql --user=root --password='QMm1hi0T*7QFz_yh' +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -743,7 +758,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` So, from the above output, we can see that the `playground` database and the `equipment` table we have created earlier in the original database and now, they are restored successfully. diff --git a/docs/guides/mysql/backup/kubestash/auto-backup/index.md b/docs/guides/mysql/backup/kubestash/auto-backup/index.md index 25d91dce61..974392771b 100644 --- a/docs/guides/mysql/backup/kubestash/auto-backup/index.md +++ b/docs/guides/mysql/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare Backend @@ -51,13 +51,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -86,9 +92,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created **Create RetentionPolicy:** @@ -117,9 +123,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -128,11 +134,14 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created ## Auto-backup with default configurations @@ -192,9 +201,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/mysql-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mysql-default-backup-blueprint created Now, we are ready to backup our `MySQL` databases using few annotations. @@ -233,24 +242,24 @@ Here, Let's create the `MySQL` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MySQL in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mysql Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mysql -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mysql -o yaml ``` ```yaml @@ -315,11 +324,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mysql-frequent-backup-1724236500 BackupConfiguration appbinding-sample-mysql Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -328,18 +336,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-sampleysql-frequent-backup-1724236500 default-blueprint frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -353,7 +361,7 @@ default-blueprint-appbinding-sampleysql-frequent-backup-1724236500 default-blu If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-sampleysql-frequent-backup-1724236500 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-sampleysql-frequent-backup-1724236500 -oyaml ``` ```yaml @@ -490,9 +498,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/mysql-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/mysql-customize-backup-blueprint created Now, we are ready to backup our `MySQL` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -533,24 +541,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `MySQL` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/sample-mysql-2.yaml -mysql.kubedb.com/sample-mysql-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/auto-backup/examples/sample-mysql-2.yaml ``` +mysql.kubedb.com/sample-mysql-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our MySQL in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-mysql-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-mysql-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-mysql-2 -o yaml ``` ```yaml @@ -617,11 +625,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-mysql-2-frequent-backup-1725007200 BackupConfiguration appbinding-sample-mysql-2 Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -630,18 +637,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-sql-2-frequent-backup-1725007200 customize-blueprint frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -655,7 +662,7 @@ customize-blueprint-appbinding-sql-2-frequent-backup-1725007200 customize-blu If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725007200 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725007200 -oyaml ``` ```yaml diff --git a/docs/guides/mysql/backup/kubestash/logical/index.md b/docs/guides/mysql/backup/kubestash/logical/index.md index 0ac2390f86..f2fa3231de 100644 --- a/docs/guides/mysql/backup/kubestash/logical/index.md +++ b/docs/guides/mysql/backup/kubestash/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/backup/kubestash/logical/examples](docs/guides/mysql/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -86,33 +86,35 @@ Here, Create the above `MySQL` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created KubeDB will deploy a MySQL database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get mysqls.kubedb.com -n demo +kubectl get mysqls.kubedb.com -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.2.0 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mysql +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mysql +``` NAME TYPE DATA AGE sample-mysql-auth Opaque 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mysql ClusterIP 10.96.55.61 3306/TCP 97s sample-mysql-pods ClusterIP None 3306/TCP 97s sample-mysql-standby ClusterIP 10.96.211.186 3306/TCP 97 -``` Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mysql/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. @@ -121,15 +123,15 @@ Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to co Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mysql 9m24s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-mysql -o yaml +kubectl get appbindings -n demo sample-mysql -o yaml ``` ```yaml @@ -184,27 +186,30 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, we are going to exec into the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +``` NAME READY STATUS RESTARTS AGE sample-mysql-0 2/2 Running 0 2m41s sample-mysql-1 2/2 Running 0 2m35s sample-mysql-2 2/2 Running 0 2m29s -``` And copy the username and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d -DZfmUZd14fNEEOU4⏎ +```bash +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +DZfmUZd14fNEEOU4⏎ Now, Lets exec into the `Pod` to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=DZfmUZd14fNEEOU4 +kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=DZfmUZd14fNEEOU4 +``` Defaulted container "mysql" out of: mysql, mysql-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -258,7 +263,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` Now, we are ready to backup the database. @@ -271,13 +275,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -306,9 +316,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -339,9 +349,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -354,11 +364,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create BackupConfiguration:** @@ -409,27 +422,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-mysql-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-mysql-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-mysql-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mysql-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/mysql` directory. @@ -440,21 +453,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-mysql-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-mysql-backup-frequent-backup-1724065200 BackupConfiguration sample-mysql-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -463,18 +475,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-mysql-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-mysql-repo +kubectl get repository -n demo gcs-mysql-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-mysql-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mysql-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-mysql-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-mysql-repo-sample-mysql-backup-frequent-backup-1724065200 gcs-mysql-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -487,7 +499,7 @@ gcs-mysql-repo-sample-mysql-backup-frequent-backup-1724065200 gcs-mysql-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-mysql-repo-sample-mysql-backup-frequent-backup-1724065200 -oyaml +kubectl get snapshots -n demo gcs-mysql-repo-sample-mysql-backup-frequent-backup-1724065200 -oyaml ``` ```yaml @@ -591,17 +603,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/restored-mysql.yaml -mysql.kubedb.com/restored-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/restored-mysql.yaml ``` +mysql.kubedb.com/restored-mysql created If you check the database status, you will see it is stuck in `Provisioning` state. ```bash -$ kubectl get my -n demo restored-mysql +kubectl get my -n demo restored-mysql +``` NAME VERSION STATUS AGE restored-mysql 8.2.0 Provisioning 61s -``` #### Create RestoreSession: @@ -642,19 +654,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-mysql-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-mysql-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -666,33 +678,36 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get my -n demo restored-mysql +kubectl get my -n demo restored-mysql +``` NAME VERSION STATUS AGE restored-mysql 8.2.0 Ready 34m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mysql" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mysql" +``` NAME READY STATUS RESTARTS AGE restored-mysql-0 1/1 Running 0 39m -``` And then copy the user name and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo restored-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo restored-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root -$ kubectl get secret -n demo restored-mysql-auth -o jsonpath='{.data.password}'| base64 -d -QMm1hi0T*7QFz_yh +```bash +kubectl get secret -n demo restored-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +QMm1hi0T*7QFz_yh Now, let's exec into the Pod to enter into `mysql` shell and verify restored data, ```bash -$ kubectl exec -it -n demo restored-mysql-0 -- mysql --user=root --password='QMm1hi0T*7QFz_yh' +kubectl exec -it -n demo restored-mysql-0 -- mysql --user=root --password='QMm1hi0T*7QFz_yh' +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -737,7 +752,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` So, from the above output, we can see that the `playground` database and the `equipment` table we have created earlier in the original database and now, they are restored successfully. diff --git a/docs/guides/mysql/backup/stash/standalone/index.md b/docs/guides/mysql/backup/stash/standalone/index.md index cc10824ade..570fe525a0 100644 --- a/docs/guides/mysql/backup/stash/standalone/index.md +++ b/docs/guides/mysql/backup/stash/standalone/index.md @@ -34,9 +34,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create `demo` namespace if you haven't created yet. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup MySQL @@ -72,32 +72,34 @@ spec: Create the above `MySQL` CRD, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created KubeDB will deploy a MySQL database according to the above specification. It will also create the necessary Secrets and Services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get my -n demo sample-mysql +kubectl get my -n demo sample-mysql +``` NAME VERSION STATUS AGE sample-mysql 8.4.8 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a Secret and a Service for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mysql +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-mysql +``` NAME TYPE DATA AGE sample-mysql-auth Opaque 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-mysql +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-mysql ClusterIP 10.101.2.138 3306/TCP 5m33s sample-mysql-pods ClusterIP None 3306/TCP 5m33s -``` Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to connect with the database. KubeDB creates an [AppBinding](/docs/guides/mysql/concepts/appbinding/index.md) CRD that holds the necessary information to connect with the database. @@ -106,15 +108,15 @@ Here, we have to use service `sample-mysql` and secret `sample-mysql-auth` to co Verify that the AppBinding has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-mysql 9m24s -``` Let's check the YAML of the above AppBinding, ```bash -$ kubectl get appbindings -n demo sample-mysql -o yaml +kubectl get appbindings -n demo sample-mysql -o yaml ``` ```yaml @@ -180,25 +182,28 @@ Stash uses the AppBinding CRD to connect with the target database. It requires t Now, we are going to exec into the database pod and create some sample data. At first, find out the database Pod using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-mysql" +``` NAME READY STATUS RESTARTS AGE sample-mysql-0 1/1 Running 0 33m -``` And copy the user name and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d -5HEqoozyjgaMO97N⏎ +```bash +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +5HEqoozyjgaMO97N⏎ Now, let's exec into the Pod to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=5HEqoozyjgaMO97N +kubectl exec -it -n demo sample-mysql-0 -- mysql --user=root --password=5HEqoozyjgaMO97N +``` mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 @@ -251,7 +256,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` Now, we are ready to backup the database. @@ -264,15 +268,24 @@ We are going to store our backed up data into a GCS bucket. At first, we need to Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -295,9 +308,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database to our desired backend. @@ -338,19 +351,19 @@ Here, Let's create the `BackupConfiguration` CRD we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-mysql-backup created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-mysql-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mysql-backup mysql-backup-8.0.21 */5 * * * * Ready 11s -``` **Verify CronJob:** @@ -359,10 +372,10 @@ Stash will create a CronJob with the schedule specified in `spec.schedule` field Verify that the CronJob has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE sample-mysql-backup */5 * * * * False 0 27s -``` **Wait for BackupSession:** @@ -371,11 +384,10 @@ The `sample-mysql-backup` CronJob will trigger a backup on each scheduled slot b Wait for a schedule to appear. Run the following command to watch `BackupSession` CRD, ```bash -$ watch -n 1 kubectl get backupsession -n demo -l=stash.appscode.com/backup-configuration=sample-mysql-backup - +watch -n 1 kubectl get backupsession -n demo -l=stash.appscode.com/backup-configuration=sample-mysql-backup +``` NAME INVOKER-TYPE INVOKER-NAME PHASE AGE sample-mysql-backup-1569561245 BackupConfiguration sample-mysql-backup Succeeded 38s -``` Here, the phase **`Succeeded`** means that the backupsession has been succeeded. @@ -386,10 +398,10 @@ Here, the phase **`Succeeded`** means that the backupsession has been succeeded. Now, we are going to verify whether the backed up data is in the backend. Once a backup is completed, Stash will update the respective `Repository` CRD to reflect the backup completion. Check that the repository `gcs-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo +kubectl get repository -n demo gcs-repo +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo true 6.815 MiB 1 3m39s 30m -``` Now, if we navigate to the GCS bucket, we will see the backed up data has been stored in `demo/mysql/sample-mysql` directory as specified by `.spec.backend.gcs.prefix` field of Repository CRD. @@ -410,23 +422,23 @@ At first, let's stop taking any further backup of the old database so that no ba Let's pause the `sample-mysql-backup` BackupConfiguration, ```bash -$ kubectl patch backupconfiguration -n demo sample-mysql-backup --type="merge" --patch='{"spec": {"paused": true}}' -backupconfiguration.stash.appscode.com/sample-mysql-backup patched +kubectl patch backupconfiguration -n demo sample-mysql-backup --type="merge" --patch='{"spec": {"paused": true}}' ``` +backupconfiguration.stash.appscode.com/sample-mysql-backup patched Or you can use the Stash `kubectl` plugin to pause the ` BackupConfiguration`, ```bash -$ kubectl stash pause backup -n demo --backupconfig=sample-mysql-backup -BackupConfiguration demo/sample-mysql-backup has been paused successfully. +kubectl stash pause backup -n demo --backupconfig=sample-mysql-backup ``` +BackupConfiguration demo/sample-mysql-backup has been paused successfully. Now, wait for a moment. Stash will pause the BackupConfiguration. Verify that the BackupConfiguration has been paused, -```console -$ kubectl get backupconfiguration -n demo sample-mysql-backup +```bash +kubectl get backupconfiguration -n demo sample-mysql-backup +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-mysql-backup mysql-backup-8.0.21 */5 * * * * true Ready 26m -``` Notice the `PAUSED` column. Value `true` for this field means that the BackupConfiguration has been paused. @@ -462,17 +474,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/restored-mysql.yaml -mysql.kubedb.com/restored-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/restored-mysql.yaml ``` +mysql.kubedb.com/restored-mysql created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get my -n demo restored-mysql +kubectl get my -n demo restored-mysql +``` NAME VERSION STATUS AGE restored-mysql 8.4.8 Provisioning 61s -``` #### Create RestoreSession: @@ -481,10 +493,10 @@ Now, we need to create a RestoreSession CRD pointing to the AppBinding for this Using the following command, check that another AppBinding object has been created for the `restored-mysql` object, ```bash -$ kubectl get appbindings -n demo restored-mysql +kubectl get appbindings -n demo restored-mysql +``` NAME AGE restored-mysql 6m6s -``` Below, is the contents of YAML file of the `RestoreSession` object that we are going to create to restore backed up data into the newly created database provisioned by MySQL CRD named `restored-mysql`. @@ -515,21 +527,20 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-mysql-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/backup/stash/standalone/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-mysql-restore created Once, you have created the RestoreSession object, Stash will create a restore Job. We can watch the phase of the RestoreSession object to check whether the restore process has succeeded or not. Run the following command to watch the phase of the RestoreSession object, ```bash -$ watch -n 1 kubectl get restoresession -n demo restore-sample-mysql - +watch -n 1 kubectl get restoresession -n demo restore-sample-mysql +``` Every 1.0s: kubectl get restoresession -n demo restore-sample-mysql workstation: Fri Sep 27 11:18:51 2019 NAMESPACE NAME REPOSITORY-NAME PHASE AGE demo restore-sample-mysql gcs-repo Succeeded 59s -``` Here, we can see from the output of the above command that the restore process succeeded. @@ -540,33 +551,36 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get my -n demo restored-mysql +kubectl get my -n demo restored-mysql +``` NAME VERSION STATUS AGE restored-mysql 8.0.21 Ready 34m -``` Now, find out the database Pod by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mysql" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-mysql" +``` NAME READY STATUS RESTARTS AGE restored-mysql-0 1/1 Running 0 39m -``` And then copy the user name and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.username}'| base64 -d +``` root -$ kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d -5HEqoozyjgaMO97N +```bash +kubectl get secret -n demo sample-mysql-auth -o jsonpath='{.data.password}'| base64 -d ``` +5HEqoozyjgaMO97N Now, let's exec into the Pod to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo restored-mysql-0 -- mysql --user=root --password=5HEqoozyjgaMO97N +kubectl exec -it -n demo restored-mysql-0 -- mysql --user=root --password=5HEqoozyjgaMO97N +``` mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 @@ -610,7 +624,6 @@ mysql> SELECT * FROM playground.equipment; mysql> exit Bye -``` So, from the above output, we can see that the `playground` database and the `equipment` table we created earlier in the original database and now, they are restored successfully. diff --git a/docs/guides/mysql/cli/index.md b/docs/guides/mysql/cli/index.md index 6a555c79fa..48c19628e5 100644 --- a/docs/guides/mysql/cli/index.md +++ b/docs/guides/mysql/cli/index.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a MySQL object as specified in `mysql.yaml`. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/cli/yamls/mysql-demo.yaml -mysql.kubedb.com/mysql-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/cli/yamls/mysql-demo.yaml ``` +mysql.kubedb.com/mysql-demo created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/cli/yamls/mysql-demo.yaml --namespace=kube-system -mysql.kubedb.com/mysql-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/cli/yamls/mysql-demo.yaml --namespace=kube-system ``` +mysql.kubedb.com/mysql-demo created `kubectl create` command also considers `stdin` as input. @@ -45,11 +45,11 @@ cat mysql-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all MySQL objects in `default` namespace, run the following command: ```bash -$ kubectl get mysql +kubectl get mysql +``` NAME VERSION STATUS AGE mysql-demo 8.4.8 Running 5m1s mysql-dev 8.4.8 Running 10m1s -``` To get YAML of an object, use `--output=yaml` flag. @@ -124,7 +124,8 @@ kubectl get mysql mysql-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get all -n demo -o wide +kubectl get all -n demo -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/mysql-demo-0 1/1 Running 0 2m17s 10.244.0.13 kind-control-plane 1/1 @@ -140,7 +141,6 @@ appbinding.appcatalog.appscode.com/mysql-demo kubedb.com/mysql 8.4.8 2m17 NAME VERSION STATUS AGE mysql.kubedb.com/mysql-demo 8.4.8 Ready 2m17s -``` Flag `--output=wide` is used to print additional information. @@ -151,19 +151,20 @@ List command supports short names for each object types. You can use it like `ku To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` mysql/mysql-demo mysql/mysql-dev mysql/mysql-prod mysql/mysql-qa -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe MySQL database `mysql-demo` with relevant information. ```bash -$ kubectl dba describe my -n demo +kubectl dba describe my -n demo +``` Name: mysql-demo Namespace: demo CreationTimestamp: Mon, 15 Mar 2021 17:53:48 +0600 @@ -271,7 +272,6 @@ Events: Normal Successful 5m KubeDB Operator Successfully created service for primary/standalone Normal Successful 5m KubeDB Operator Successfully created database auth secret Normal Successful 5m KubeDB Operator Successfully created PetSet -``` `kubectl dba describe` command provides following basic information about a MySQL database. @@ -316,8 +316,8 @@ To learn about various options of `describe` command, please visit [here](/docs/ Lets edit an existing running MySQL object to setup database [Halted](/docs/guides/mysql/concepts/database/index.md#spechalted). The following command will open MySQL `mysql-demo` in editor. ```bash -$ kubectl edit my -n demo mysql-quickstart - +kubectl edit my -n demo mysql-quickstart +``` spec: .... authSecret: @@ -327,7 +327,6 @@ spec: .... mysql.kubedb.com/mysql-quickstart edited -``` #### Edit Restrictions @@ -353,16 +352,16 @@ For DormantDatabase, `spec.origin` can't be edited using `kubectl edit` `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a MySQL `mysql-dev` in default namespace ```bash -$ kubectl delete mysql mysql-dev -mysql.kubedb.com "mysql-dev" deleted +kubectl delete mysql mysql-dev ``` +mysql.kubedb.com "mysql-dev" deleted You can also use YAML files to delete objects. The following command will delete a mysql using the type and name specified in `mysql.yaml`. ```bash -$ kubectl delete -f mysql-demo.yaml -mysql.kubedb.com "mysql-dev" deleted +kubectl delete -f mysql-demo.yaml ``` +mysql.kubedb.com "mysql-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -380,16 +379,23 @@ kubectl delete mysql -l mysql.app.kubernetes.io/instance=mysql-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # Create objects -$ kubectl create -f +```bash +kubectl create -f +``` # List objects -$ kubectl get mysql -$ kubectl get mysql.kubedb.com +```bash +kubectl get mysql +``` + +```bash +kubectl get mysql.kubedb.com +``` # Delete objects -$ kubectl delete mysql +```bash +kubectl delete mysql ``` ## Next Steps diff --git a/docs/guides/mysql/clients/index.md b/docs/guides/mysql/clients/index.md index f232c6663a..6059371c47 100644 --- a/docs/guides/mysql/clients/index.md +++ b/docs/guides/mysql/clients/index.md @@ -27,9 +27,9 @@ KubeDB creates separate services for primary and secondary replicas. In this tut - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - You need to have a mysql client. If you don't have a mysql client install in your local machine, you can install from [here](https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/) @@ -68,9 +68,9 @@ spec: Let's create the MySQL CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clients/yamls/group-replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clients/yamls/group-replication.yaml ``` +mysql.kubedb.com/my-group created KubeDB operator watches for `MySQL` objects using Kubernetes API. When a `MySQL` object is created, KubeDB operator will create a new PetSet and two separate Services for client connection with the cluster. The services have the following format: @@ -80,28 +80,33 @@ KubeDB operator watches for `MySQL` objects using Kubernetes API. When a `MySQL` Now, wait for the `MySQL` is going to `Running` state and also wait for `SatefulSet` and `services` going to the `Ready` state. ```bash -$ watch -n 3 kubectl get my -n demo my-group +watch -n 3 kubectl get my -n demo my-group +``` Every 3.0s: kubectl get my -n demo my-group suaas-appscode: Wed Sep 9 10:54:34 2020 NAME VERSION STATUS AGE my-group 8.4.8 Running 16m -$ watch -n 3 kubectl get petset -n demo my-group +```bash +watch -n 3 kubectl get petset -n demo my-group +``` ery 3.0s: kubectl get petset -n demo my-group suaas-appscode: Wed Sep 9 10:53:52 2020 NAME READY AGE my-group 3/3 15m -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` my-group ClusterIP 10.109.133.141 3306/TCP 31s my-group-pods ClusterIP None 3306/TCP 31s my-group-standby ClusterIP 10.110.47.184 3306/TCP 31s -``` If you describe the object, you can find more details here, ```bash -$ kubectl dba describe my -n demo my-group +kubectl dba describe my -n demo my-group +``` Name: my-group Namespace: demo CreationTimestamp: Mon, 15 Mar 2021 18:18:35 +0600 @@ -228,7 +233,6 @@ Events: Normal Successful 2m KubeDB Operator Successfully created PetSet Normal Successful 2m KubeDB Operator Successfully created appbinding Normal Successful 2m KubeDB Operator Successfully patched PetSet -``` Our database cluster is ready to connect. @@ -242,12 +246,12 @@ Our database cluster is ready to connect. Let's verify that the `mysql.kubedb.com/role:` label are added into the PetSet's replicas, ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -A -o=custom-columns='Name:.metadata.name,Labels:metadata.labels,PodIP:.status.podIP' +kubectl get pods -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -A -o=custom-columns='Name:.metadata.name,Labels:metadata.labels,PodIP:.status.podIP' +``` Name Labels PodIP my-group-0 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:primary petset.kubernetes.io/pod-name:my-group-0] 10.244.1.8 my-group-1 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:secondary petset.kubernetes.io/pod-name:my-group-1] 10.244.2.11 my-group-2 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:secondary petset.kubernetes.io/pod-name:my-group-2] 10.244.2.13 -``` You can see from the above output that the `my-group-0` pod is selected as a primary member in our existing database cluster. It has the `mysql.kubedb.com/role:primary` label and the podIP is `10.244.1.8`. Besides, the rest of the replicas are selected as a secondary member which has `mysql.kubedb.com/role:secondary` label. @@ -256,42 +260,42 @@ KubeDB creates two separate services(already shown above) to connect with the da You can find the service which selects for primary replica have the following selector, ```bash -$ kubectl get svc -n demo my-group -o json | jq '.spec.selector' +kubectl get svc -n demo my-group -o json | jq '.spec.selector' +``` { "app.kubernetes.io/instance": "my-group", "app.kubernetes.io/managed-by": "kubedb.com", "app.kubernetes.io/name": "mysqls.kubedb.com", "kubedb.com/role": "primary" } -``` If you get the endpoint of the above service, you will see the podIP of the primary replica, ```bash -$ kubectl get endpoints -n demo my-group +kubectl get endpoints -n demo my-group +``` NAME ENDPOINTS AGE my-group 10.244.1.8:3306 5h49m -``` You can also find the service which selects for secondary replicas have the following selector, ```bash -$ kubectl get svc -n demo my-group-standby -o json | jq '.spec.selector' +kubectl get svc -n demo my-group-standby -o json | jq '.spec.selector' +``` { "app.kubernetes.io/instance": "my-group", "app.kubernetes.io/managed-by": "kubedb.com", "app.kubernetes.io/name": "mysqls.kubedb.com", "kubedb.com/role": "standby" } -``` If you get the endpoint of the above service, you will see the podIP of the secondary replicas, ```bash -$ kubectl get endpoints -n demo my-group-standby +kubectl get endpoints -n demo my-group-standby +``` NAME ENDPOINTS AGE my-group-standby 10.244.2.11:3306,10.244.2.13:3306 5h53m -``` ## Connecting Information @@ -300,12 +304,14 @@ KubeDB operator has created a new Secret called `my-group-auth` **(format: {mysq Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d -RmxLjEomvE6tVj4- +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d ``` +RmxLjEomvE6tVj4- You can connect to any of these group members. In that case, you just need to specify the hostname of that member Pod (either PodIP or the fully-qualified-domain-name for that Pod using any of the services) by `--host` flag. @@ -318,43 +324,45 @@ At first, we are going to port-forward the service to connect to the database cl Let's port-forward the `my-group` service using the following command, ```bash -$ kubectl port-forward service/my-group -n demo 8081:3306 +kubectl port-forward service/my-group -n demo 8081:3306 +``` Forwarding from 127.0.0.1:8081 -> 3306 Forwarding from [::1]:8081 -> 3306 -``` >For testing purpose, we need to have a mysql client to connect with the cluster. If you don't have a client in your local machine, you can install from [here](https://dev.mysql.com/doc/mysql-installation-excerpt/8.0/en/) **Write Operation :** -```bash # create a database on cluster -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "CREATE DATABASE playground;" +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # create a table -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" -mysql: [Warning] Using a password on the command line interface can be insecure. +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" ``` +mysql: [Warning] Using a password on the command line interface can be insecure. **Read Operation :** -```bash # read data from cluster -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "SELECT * FROM playground.equipment;" +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8081 --host=127.0.0.1 -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` You can see from the above output that both write and read operations are performed successfully using primary pod selector service named `my-group`. @@ -367,33 +375,33 @@ At first, we are going to port-forward the service to connect to the database cl Let's port-forward the `my-group-standby` service using the following command, ```bash -$ kubectl port-forward service/my-group-standby -n demo 8080:3306 +kubectl port-forward service/my-group-standby -n demo 8080:3306 +``` Forwarding from 127.0.0.1:8080 -> 3306 Forwarding from [::1]:8080 -> 3306 -``` **Write Operation:** -```bash # in our database cluster we have created a database and a table named playground and equipment respectively. so we will try to insert data into it. # insert a row -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8080 --host=127.0.0.1 -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 3, 'black');" +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8080 --host=127.0.0.1 -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 3, 'black');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement -``` **Read Operation:** -```bash # read data from cluster -$ mysql -uroot -pRmxLjEomvE6tVj4- --port=8080 --host=127.0.0.1 -e "SELECT * FROM playground.equipment;" +```bash +mysql -uroot -pRmxLjEomvE6tVj4- --port=8080 --host=127.0.0.1 -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` You can see from the above output that only read operations are performed successfully using secondary pod selector service named `my-group-standby`. No data is inserted by using this service. The error `--super-read-only` indicates that the secondary pod has only read permission. @@ -404,47 +412,52 @@ To test automatic failover, we will force the primary Pod to restart. Since the First, delete the primary pod `my-gorup-0` using the following command, ```bash -$ kubectl delete pod my-group-0 -n demo -pod "my-group-0" deleted +kubectl delete pod my-group-0 -n demo ``` +pod "my-group-0" deleted Now wait for a few minute to automatically elect the primary replica and also wait for the services endpoint update for new primary and secondary replicas, ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -A -o=custom-columns='Name:.metadata.name,Labels:metadata.labels,PodIP:.status.podIP' +kubectl get pods -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -A -o=custom-columns='Name:.metadata.name,Labels:metadata.labels,PodIP:.status.podIP' +``` Name Labels PodIP my-group-0 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:secondary petset.kubernetes.io/pod-name:my-group-0] 10.244.2.18 my-group-1 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:secondary petset.kubernetes.io/pod-name:my-group-1] 10.244.2.11 my-group-2 map[controller-revision-hash:my-group-55b9f49f98 app.kubernetes.io/name:mysqls.kubedb.com app.kubernetes.io/instance:my-group mysql.kubedb.com/role:primary petset.kubernetes.io/pod-name:my-group-2] 10.244.2.13 -``` You can see from the above output that `my-group-2` pod is elected as a primary automatically and the others become secondary. If you get the endpoint of the `my-group` service, you will see the podIP of the primary replica, ```bash -$ kubectl get endpoints -n demo my-group +kubectl get endpoints -n demo my-group +``` NAME ENDPOINTS AGE my-group 10.244.2.13:3306 111m -``` If you get the endpoint of the `my-group-standby` service, you will see the podIP of the secondary replicas, ```bash -$ kubectl get endpoints -n demo my-group-standby +kubectl get endpoints -n demo my-group-standby +``` NAME ENDPOINTS AGE my-group-standby 10.244.2.11:3306,10.244.2.18:3306 112m -``` ## Cleaning up Clean what you created in this tutorial. ```bash -$ kubectl patch -n demo my/my-group -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo my/my-group +kubectl patch -n demo my/my-group -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo my/my-group +``` -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mysql/clustering/group-replication/index.md b/docs/guides/mysql/clustering/group-replication/index.md index 3736a6004c..95daf64e3f 100644 --- a/docs/guides/mysql/clustering/group-replication/index.md +++ b/docs/guides/mysql/clustering/group-replication/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/clustering/group-replication/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/clustering/group-replication/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -66,9 +66,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/group-replication/yamls/group-replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/group-replication/yamls/group-replication.yaml ``` +mysql.kubedb.com/my-group created Here, @@ -82,7 +82,8 @@ Here, KubeDB operator watches for `MySQL` objects using Kubernetes API. When a `MySQL` object is created, KubeDB operator will create a new PetSet and a Service with the matching MySQL object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl dba describe my -n demo my-group +kubectl dba describe my -n demo my-group +``` Name: my-group Namespace: demo CreationTimestamp: Tue, 28 Jun 2022 17:54:10 +0600 @@ -210,36 +211,41 @@ Events: Normal Successful 1m Kubedb operator Successfully created MySQL Normal Successful 1m Kubedb operator Successfully created appbinding - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE my-group 3/3 3m47s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-my-group-0 Bound pvc-4f8538f6-a6ce-4233-b533-8566852f5b98 1Gi RWO standard 4m16s data-my-group-1 Bound pvc-8823d3ad-d614-4172-89ac-c2284a17f502 1Gi RWO standard 4m11s data-my-group-2 Bound pvc-94f1c312-50e3-41e1-94a8-a820be0abc08 1Gi RWO standard 4m7s s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-4f8538f6-a6ce-4233-b533-8566852f5b98 1Gi RWO Delete Bound demo/data-my-group-0 standard 4m39s pvc-8823d3ad-d614-4172-89ac-c2284a17f502 1Gi RWO Delete Bound demo/data-my-group-1 standard 4m35s pvc-94f1c312-50e3-41e1-94a8-a820be0abc08 1Gi RWO Delete Bound demo/data-my-group-2 standard 4m31s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-group ClusterIP 10.96.223.45 3306/TCP 5m13s my-group-pods ClusterIP None 3306/TCP 5m13s my-group-standby ClusterIP 10.96.70.224 3306/TCP 5m13s -``` - KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified `MySQL` object: ```bash -$ kubectl get my -n demo my-group -o yaml | kubectl neat +kubectl get my -n demo my-group -o yaml | kubectl neat ``` ```yaml @@ -283,44 +289,49 @@ If you want to use an existing secret please specify that when creating the MySQ Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d -d)q2MVmJK$Oex=mW +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d ``` +d)q2MVmJK$Oex=mW The operator creates a group according to the newly created `MySQL` object. This group has 3 members (one primary and two secondary). You can connect to any of these group members. In that case you just need to specify the host name of that member Pod (either PodIP or the fully-qualified-domain-name for that Pod using the governing service named `-pods`) by `--host` flag. -```bash # first list the mysql pods list -$ kubectl get pods -n demo -l app.kubernetes.io/instance=my-group +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=my-group +``` NAME READY STATUS RESTARTS AGE my-group-0 2/2 Running 0 8m23s my-group-1 2/2 Running 0 8m18s my-group-2 2/2 Running 0 8m14s - # get the governing service -$ kubectl get service my-group-pods -n demo +```bash +kubectl get service my-group-pods -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-group-pods ClusterIP None 3306/TCP 8m49s # list the pods with PodIP -$ kubectl get pods -n demo -l app.kubernetes.io/instance=my-group -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.my-group-pods.{.metadata.namespace}{"\\n"}{end}' +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=my-group -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.my-group-pods.{.metadata.namespace}{"\\n"}{end}' +``` my-group-0 ........... 10.244.0.44 ............ my-group-0.my-group-pods.demo my-group-1 ........... 10.244.0.46 ............ my-group-1.my-group-pods.demo my-group-2 ........... 10.244.0.48 ............ my-group-2.my-group-pods.demo -``` - Now you can connect to these database using the above info. Ignore the warning message. It is happening for using password in the command. -```bash # connect to the 1st server -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -329,7 +340,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 2nd server -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -338,21 +351,23 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 3rd server -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | +---+ | 1 | +---+ -``` ## Check the Group Status Now, you are ready to check newly created group status. Connect and run the following commands from any of the hosts and you will get the same results. ```bash -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "show status like '%primary%'" +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "show status like '%primary%'" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----------------------------------+--------------------------------------+ | Variable_name | Value | @@ -360,12 +375,11 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_primary_member | 1ace16b5-f6d9-11ec-9a26-9ae7d6def698 | +----------------------------------+--------------------------------------+ -``` - The value **1ace16b5-f6d9-11ec-9a26-9ae7d6def698** in the above table is the ID of the primary member of the group. ```bash -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -375,41 +389,45 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 1ace16b5-f6d9-11ec-9a26-9ae7d6def698 | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | PRIMARY | 8.4.8 | XCom | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ -``` - ## Data Availability In a MySQL group, only the primary member can write not the secondary. But you can read data from any member. In this tutorial, we will insert data from primary, and we will see whether we can get the data from any other member. > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # create a database on primary -$ kubectl exec -it -n demo my-group-0 -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "CREATE DATABASE playground;" +```bash +kubectl exec -it -n demo my-group-0 -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # create a table -$ kubectl exec -it -n demo my-group-0 -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +kubectl exec -it -n demo my-group-0 -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +```bash + kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # read from primary -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` In the previous step we have inserted into the primary pod. In the next step we will read from secondary pods to determine whether the data has been successfully copied to the secondary pods. -```bash # read from secondary-1 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -418,32 +436,35 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read from secondary-2 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Write on Secondary Should Fail Only, primary member preserves the write permission. No secondary can write data. -```bash # try to write on secondary-1 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 # try to write on secondary-2 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 -``` ## Automatic Failover @@ -451,13 +472,16 @@ To test automatic failover, we will force the primary Pod to restart. Since the > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # delete the primary Pod my-group-0 -$ kubectl delete pod my-group-0 -n demo +```bash +kubectl delete pod my-group-0 -n demo +``` pod "my-group-0" deleted # check the new primary ID -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "show status like '%primary%'" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "show status like '%primary%'" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----------------------------------+--------------------------------------+ | Variable_name | Value | @@ -465,9 +489,10 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_primary_member | 1739589f-f6d9-11ec-956c-c2c213efafa8| +----------------------------------+--------------------------------------+ - # now check the group status -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -477,20 +502,21 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 1ace16b5-f6d9-11ec-9a26-9ae7d6def698 | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | SECONDARY | 8.4.8 | XCom | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ - # read data from new primary my-group-1.my-group-pods.demo -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-1.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` Now Let's read the data from secondary pods to see if the data is consistant. -```bash # read data from secondary-1 my-group-0.my-group-pods.demo -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-0.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -499,14 +525,15 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read data from secondary-2 my-group-2.my-group-pods.demo -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='d)q2MVmJK$Oex=mW' --host=my-group-2.my-group-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 7 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Cleaning up diff --git a/docs/guides/mysql/clustering/innodb-cluster/index.md b/docs/guides/mysql/clustering/innodb-cluster/index.md index 074b383f43..6ac8558553 100644 --- a/docs/guides/mysql/clustering/innodb-cluster/index.md +++ b/docs/guides/mysql/clustering/innodb-cluster/index.md @@ -28,9 +28,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created @@ -66,9 +66,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/innodb-cluster/yamls/innodb.yaml -mysql.kubedb.com/innodb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/innodb-cluster/yamls/innodb.yaml ``` +mysql.kubedb.com/innodb created Here, @@ -81,7 +81,8 @@ Here, KubeDB operator watches for `MySQL` objects using Kubernetes API. When a `MySQL` object is created, KubeDB operator will create a new PetSet and a Service with the matching MySQL object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl dba describe my -n demo innodb +kubectl dba describe my -n demo innodb +``` Name: innodb Namespace: demo CreationTimestamp: Tue, 15 Nov 2022 15:14:42 +0600 @@ -217,31 +218,37 @@ Events: Normal Successful 27s MySQL operator Successfully created MySQL Normal Successful 27s MySQL operator Successfully created appbinding -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE NAME READY AGE innodb 3/3 2m17s innodb-router 1/1 2m17s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-innodb-0 Bound pvc-6f7f8ebd-0b56-45fb-b91a-fe133bfae594 1Gi RWO standard 2m47s data-innodb-1 Bound pvc-16f9d6df-ce46-49da-9720-415d7f7d8b69 1Gi RWO standard 113s data-innodb-2 Bound pvc-8cfcb761-eb63-4a12-bc7e-5d86f727330e 1Gi RWO standard 88s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-6f7f8ebd-0b56-45fb-b91a-fe133bfae594 1Gi RWO Delete Bound demo/data-innodb-0 standard 3m50s pvc-16f9d6df-ce46-49da-9720-415d7f7d8b69 1Gi RWO Delete Bound demo/data-innodb-1 standard 2m38s pvc-8cfcb761-eb63-4a12-bc7e-5d86f727330e 1Gi RWO Delete Bound demo/data-innodb-2 standard 2m32s - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE innodb ClusterIP 10.96.244.213 3306/TCP 5m23s innodb-pods ClusterIP None 3306/TCP 5m23s innodb-standby ClusterIP 10.96.146.147 3306/TCP 5m23s -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified `MySQL` object: @@ -296,46 +303,50 @@ If you want to use an existing secret please specify that when creating the MySQ Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo innodb-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo innodb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo innodb-auth -o jsonpath='{.data.password}' | base64 -d -ny5jSirIzVtWDcZ7 +```bash +kubectl get secrets -n demo innodb-auth -o jsonpath='{.data.password}' | base64 -d ``` +ny5jSirIzVtWDcZ7 The operator creates a cluster according to the newly created `MySQL` object. This group has 3 members (one primary and two secondary). You can connect to any of these cluster members. In that case you just need to specify the host name of that member Pod (either PodIP or the fully-qualified-domain-name for that Pod using the governing service named `-pods`) by `--host` flag. -```bash # first list the mysql pods list -$ kubectl get pods -n demo -l app.kubernetes.io/instance=innodb +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=innodb +``` NAME READY STATUS RESTARTS AGE innodb-0 2/2 Running 0 15m innodb-1 2/2 Running 0 14m innodb-2 2/2 Running 0 14m innodb-router-0 1/1 Running 0 15m - - # get the governing service -$ kubectl get service innodb-pods -n demo +```bash +kubectl get service innodb-pods -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE innodb-pods ClusterIP None 3306/TCP 16m # list the pods with PodIP -$ kubectl get pods -n demo -l app.kubernetes.io/instance=innodb -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.innodb-pods.{.metadata.namespace}{"\\n"}{end}' +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=innodb -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.innodb-pods.{.metadata.namespace}{"\\n"}{end}' +``` innodb-0 ........... 10.244.0.26 ............ innodb-0.innodb-pods.demo innodb-1 ........... 10.244.0.28 ............ innodb-1.innodb-pods.demo innodb-2 ........... 10.244.0.30 ............ innodb-2.innodb-pods.demo -``` - Now you can connect to this database using the above info. Ignore the warning message. It is happening for using password in the command. -```bash # connect to the 1st server -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -344,7 +355,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 2nd server -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -353,14 +366,15 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 3rd server -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | +---+ | 1 | +---+ -``` ## Check the Innodb Cluster status @@ -369,8 +383,8 @@ Let's exec into one of the pod to see the cluster status. ```bash -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysqlsh -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo - +kubectl exec -it -n demo innodb-0 -c mysql -- mysqlsh -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo +``` MySQL innodb-0.innodb-pods.demo:33060+ ssl JS > dba.getCluster().status() { "clusterName": "innodb", @@ -417,42 +431,45 @@ $ kubectl exec -it -n demo innodb-0 -c mysql -- mysqlsh -u root --password='ny5j "groupInformationSourceMember": "innodb-0.innodb-pods.demo.svc:3306" } - -``` - ## Data Availability In a MySQL Cluster, only the primary member can write not the secondary. But you can read data from any member. In this tutorial, we will insert data from primary, and we will see whether we can get the data from any other member. > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # create a database on primary -$ kubectl exec -it -n demo innodb-0 -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "CREATE DATABASE playground;" +```bash +kubectl exec -it -n demo innodb-0 -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # create a table -$ kubectl exec -it -n demo innodb-0 -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +kubectl exec -it -n demo innodb-0 -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +```bash + kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # read from primary -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` In the previous step we have inserted into the primary pod. In the next step we will read from secondary pods to determine whether the data has been successfully copied to the secondary pods. -```bash # read from secondary-1 -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -461,32 +478,35 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read from secondary-2 -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Write on Secondary Should Fail Only, primary member preserves the write permission. No secondary can write data. -```bash # try to write on secondary-1 -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 # try to write on secondary-2 -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 -``` ## Automatic Failover @@ -494,13 +514,16 @@ To test automatic failover, we will force the primary Pod to restart. Since the > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # delete the primary Pod innodb-0 -$ kubectl delete pod innodb-0 -n demo +```bash +kubectl delete pod innodb-0 -n demo +``` pod "innodb-0" deleted # check the new primary ID -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "show status like '%primary%'" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "show status like '%primary%'" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----------------------------------+--------------------------------------+ | Variable_name | Value | @@ -508,9 +531,10 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_primary_member | 2b77185f-64c6-11ed-9621-e21f33a1cdb1| +----------------------------------+--------------------------------------+ - # now check the cluster status for underlying group replication -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -520,20 +544,21 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 2f0da15c-64c6-11ed-951a-fa8d12ce91a2 | innodb-2.innodb-pods.demo.svc | 3306 | ONLINE | SECONDARY | 8.4.8 | MySQL | +---------------------------+--------------------------------------+-------------------------------+-------------+--------------+-------------+----------------+----------------------------+ - # read data from new primary innodb-1.innodb-pods.demo -$ kubectl exec -it -n demo innodb-1 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-1 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-1.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` Now Let's read the data from secondary pods to see if the data is consistent. -```bash # read data from secondary-1 innodb-0.innodb-pods.demo -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-0.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -542,14 +567,15 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read data from secondary-2 innodb-2.innodb-pods.demo -$ kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo innodb-0 -c mysql -- mysql -u root --password='ny5jSirIzVtWDcZ7' --host=innodb-2.innodb-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 7 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Cleaning up diff --git a/docs/guides/mysql/clustering/remote-replica/index.md b/docs/guides/mysql/clustering/remote-replica/index.md index f6b8adc56c..eb1f3b36c7 100644 --- a/docs/guides/mysql/clustering/remote-replica/index.md +++ b/docs/guides/mysql/clustering/remote-replica/index.md @@ -29,10 +29,10 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/clustering/remote-replica/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/clustering/group-replication/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Remote Replica @@ -99,10 +99,10 @@ metadata: namespace: demo type: kubernetes.io/basic-auth ``` -```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-singapore-auth.yaml -secret/mysql-singapore-auth created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-singapore-auth.yaml ``` +secret/mysql-singapore-auth created ## Deploy MySQL with TLS/SSL configuration ```yaml @@ -146,29 +146,31 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-singapore.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-singapore.yaml ``` +mysql.kubedb.com/mysql created KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-singapore 8.4.8 Ready 22h -``` ## Connect with MySQL database Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.password}' | base64 -d -pass +```bash +kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.password}' | base64 -d ``` +pass The operator creates a standalone mysql server for the newly created `MySQL` object. @@ -180,35 +182,43 @@ Now you can connect to the database using the above info. Ignore the warning mes Let's insert some data to the newly created mysql server . we can use the primary service or governing service to connect with the database > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # create a database on primary -$ kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE DATABASE playground;" +```bash +kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # create a table -$ kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +```bash + kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # read from primary -$ kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` # Exposing to outside world For Now we will expose our mysql with ingress with to outside world ```bash -$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx -$ helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +``` + +```bash +helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ --namespace demo --create-namespace \ --set tcp.3306="demo/mysql-singapore:3306" ``` @@ -234,19 +244,22 @@ spec: pathType: Prefix ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-ingress.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-ingress.yaml +``` ingress.networking.k8s.io/mysql-singapore created -$ kubectl get ingress -n demo + +```bash +kubectl get ingress -n demo +``` NAME CLASS HOSTS ADDRESS PORTS AGE mysql-singapore nginx mysql-singapore.something.org 172.104.37.147 80 22h -``` Now will be able to communicate from another cluster to our source database # Prepare for Remote Replica We wil use the [kubedb_plugin](/docs/setup/README.md) for generating configuration for remote replica. It will create the appbinding and and necessary secrets to connect with source server ```bash -$ kubectl dba remote-config mysql -n demo mysql-singapore -uremote -ppass -d 172.104.37.147 -y -home/mehedi/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml +kubectl dba remote-config mysql -n demo mysql-singapore -uremote -ppass -d 172.104.37.147 -y ``` +home/mehedi/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml # Create Remote Replica We have prepared another cluster in london region for replicating across cluster. follow the installation instruction [above](/docs/README.md). @@ -255,16 +268,17 @@ We have prepared another cluster in london region for replicating across cluster We will apply the generated config from kubeDB plugin to create the source refs and secrets for it ```bash -$ kubectl apply -f /home/mehedi/go/src/kubedb.dev/yamls/bank_abc/mysql/mysql-singapore-remote-config.yaml - +kubectl apply -f /home/mehedi/go/src/kubedb.dev/yamls/bank_abc/mysql/mysql-singapore-remote-config.yaml +``` secret/mysql-singapore-remote-replica-auth created secret/mysql-singapore-client-cert-remote created appbinding.appcatalog.appscode.com/mysql-singapore created -$ kubectl get appbinding -n demo +```bash +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE mysql-singapore kubedb.com/mysql 8.4.8 4m17s -``` ### Create remote replica auth We will need to use the same auth secrets for remote replicas as well since operations like clone also replicated the auth-secrets from source server @@ -324,24 +338,25 @@ Here, - `spec.topology.remoteReplica.sourceref` we are referring to source to read. The mysql instance we previously created. - `spec.deletionPolicy` specifies what KubeDB should do when a user try to delete the operation of MySQL CR. *Wipeout* means that the database will be deleted without restrictions. It can also be "Halt", "Delete" and "DoNotTerminate". Learn More about these [HERE](https://kubedb.com/docs/latest/guides/mysql/concepts/database/#specdeletionpolicy). ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-london.yaml -mysql.kubedb.com/mysql-london created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/remote-replica/yamls/mysql-london.yaml ``` +mysql.kubedb.com/mysql-london created Now we will be able to see kubedb will provision a Remote Replica from the source mysql instance. Lets checkout out the petSet , pvc , pv and services associated with it . KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified `MySQL` object: ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-london 8.4.8 Ready 7m17s -``` ## Validate Remote Replica Since both source and replica database are in the ready state. we can validate Remote Replica is working properly by checking the replication status ```bash -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +``` mysql: [Warning] Using a password on the command line interface can be insecure. *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event @@ -357,20 +372,19 @@ mysql: [Warning] Using a password on the command line interface can be insecure. Slave_IO_Running: Yes Slave_SQL_Running: Yes .... -``` # Read Data In the previous step we have inserted into the primary pod. In the next step we will read from secondary pods to determine whether the data has been successfully copied to the secondary pods. -```bash # read from secondary-1 -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Write on Secondary Should Fail @@ -382,13 +396,16 @@ To test automatic failover, we will force the primary Pod to restart. Since the > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # delete the primary Pod mysql-london-0 -$ kubectl delete pod mysql-london-0 -n demo +```bash +kubectl delete pod mysql-london-0 -n demo +``` pod "mysql-london-0" deleted # check the new primary ID -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +```bash +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +``` mysql: [Warning] Using a password on the command line interface can be insecure. *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event @@ -406,14 +423,15 @@ mysql: [Warning] Using a password on the command line interface can be insecure. ... # read data after recovery -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-read-2.mysql-read-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-read-2.mysql-read-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 7 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Cleaning up diff --git a/docs/guides/mysql/clustering/semi-sync/index.md b/docs/guides/mysql/clustering/semi-sync/index.md index 7919f57666..c2440fe9a4 100644 --- a/docs/guides/mysql/clustering/semi-sync/index.md +++ b/docs/guides/mysql/clustering/semi-sync/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/clustering/semi-sync/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/clustering/semi-sync/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,9 +69,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/semi-sync/yamls/semi-sync.yaml -mysql.kubedb.com/semi-sync-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/clustering/semi-sync/yamls/semi-sync.yaml ``` +mysql.kubedb.com/semi-sync-mysql created Here, @@ -86,7 +86,8 @@ Here, KubeDB operator watches for `MySQL` objects using Kubernetes API. When a `MySQL` object is created, KubeDB operator will create a new PetSet and a Service with the matching MySQL object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl dba describe my -n demo semi-sync-mysql +kubectl dba describe my -n demo semi-sync-mysql +``` Name: semi-sync-mysql Namespace: demo CreationTimestamp: Wed, 16 Nov 2022 11:45:53 +0600 @@ -233,40 +234,45 @@ Events: Normal Successful 5m MySQL operator Successfully patched governing service g - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE semi-sync-mysql 3/3 3m47s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-semi-sync-mysql-0 Bound pvc-4f8538f6-a6ce-4233-b533-8566852f5b98 1Gi RWO standard 4m16s data-semi-sync-mysql-1 Bound pvc-8823d3ad-d614-4172-89ac-c2284a17f502 1Gi RWO standard 4m11s data-semi-sync-mysql-2 Bound pvc-94f1c312-50e3-41e1-94a8-a820be0abc08 1Gi RWO standard 4m7s s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-4f8538f6-a6ce-4233-b533-8566852f5b98 1Gi RWO Delete Bound demo/data-semi-sync-mysql-0 standard 4m39s pvc-8823d3ad-d614-4172-89ac-c2284a17f502 1Gi RWO Delete Bound demo/data-semi-sync-mysql-1 standard 4m35s pvc-94f1c312-50e3-41e1-94a8-a820be0abc08 1Gi RWO Delete Bound demo/data-semi-sync-mysql-2 standard 4m31s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE semi-sync-mysql ClusterIP 10.96.121.252 3306/TCP 10m semi-sync-mysql-pods ClusterIP None 3306/TCP,2380/TCP,2379/TCP 10m semi-sync-mysql-standby ClusterIP 10.96.133.61 3306/TCP 10m -``` - KubeDB operator sets the `status.phase` to `Ready` once the database is successfully provisioned. Run the following command to see the modified `MySQL` object: ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE semi-sync-mysql 8.4.8 Ready 16m -``` ```yaml $ kubectl get my -n demo semi-sync-mysql -o yaml | kubectl neat @@ -326,42 +332,49 @@ If you want to use an existing secret please specify that when creating the MySQ Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo semi-sync-mysql-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo semi-sync-mysql-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo semi-sync-mysql-auth -o jsonpath='{.data.password}' | base64 -d -y~EC~984Et1Yfs~i +```bash +kubectl get secrets -n demo semi-sync-mysql-auth -o jsonpath='{.data.password}' | base64 -d ``` +y~EC~984Et1Yfs~i The operator creates a cluster according to the newly created `MySQL` object. This cluster has 3 members (one primary and two secondary). You can connect to any of these cluster members. In that case you just need to specify the host name of that member Pod (either PodIP or the fully-qualified-domain-name for that Pod using the governing service named `-pods`) by `--host` flag. -```bash # first list the mysql pods list -$ kubectl get pods -n demo -l app.kubernetes.io/instance=semi-sync-mysql +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=semi-sync-mysql +``` NAME READY STATUS RESTARTS AGE semi-sync-mysql-0 2/2 Running 0 21m semi-sync-mysql-1 2/2 Running 0 20m semi-sync-mysql-2 2/2 Running 0 20m # get the governing service -$ kubectl get service semi-sync-mysql-pods -n demo +```bash +kubectl get service semi-sync-mysql-pods -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE semi-sync-mysql-pods ClusterIP None 3306/TCP,2380/TCP,2379/TCP 21m # list the pods with PodIP -$ kubectl get pods -n demo -l app.kubernetes.io/instance=semi-sync-mysql -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.semi-sync-mysql-pods.{.metadata.namespace}{"\\n"}{end}' +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=semi-sync-mysql -o jsonpath='{range.items[*]}{.metadata.name} ........... {.status.podIP} ............ {.metadata.name}.semi-sync-mysql-pods.{.metadata.namespace}{"\\n"}{end}' +``` semi-sync-mysql-0 ........... 10.244.0.18 ............ semi-sync-mysql-0.semi-sync-mysql-pods.demo semi-sync-mysql-1 ........... 10.244.0.20 ............ semi-sync-mysql-1.semi-sync-mysql-pods.demo semi-sync-mysql-2 ........... 10.244.0.22 ............ semi-sync-mysql-2.semi-sync-mysql-pods.demo -``` Now you can connect to these database using the above info. Ignore the warning message. It is happening for using password in the command. -```bash # connect to the 1st server -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -370,7 +383,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 2nd server -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | @@ -379,22 +394,23 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +---+ # connect to the 3rd server -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "select 1;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "select 1;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---+ | 1 | +---+ | 1 | +---+ -``` ## Check the Semi-sync cluster Status Now, you are ready to check newly created semi-sync. Connect and run the following commands from any of the hosts and you will get the same results. ```bash - -$ kubectl get pods -n demo --show-labels +kubectl get pods -n demo --show-labels +``` NAME READY STATUS RESTARTS AGE LABELS semi-sync-mysql-0 2/2 Running 0 171m app.kubernetes.io/component=database,app.kubernetes.io/instance=semi-sync-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,controller-revision-hash=semi-sync-mysql-77775485f8,kubedb.com/role=primary,petset.kubernetes.io/pod-name=semi-sync-mysql-0 semi-sync-mysql-1 2/2 Running 0 170m app.kubernetes.io/component=database,app.kubernetes.io/instance=semi-sync-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,controller-revision-hash=semi-sync-mysql-77775485f8,kubedb.com/role=standby,petset.kubernetes.io/pod-name=semi-sync-mysql-1 @@ -402,7 +418,9 @@ semi-sync-mysql-2 2/2 Running 0 169m app.kubernetes.io/compon From the labels we can see that the `semi-sync-mysql-0` is running as primary and the rest are running as standby.Lets validate with the mysql semisync status -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -411,8 +429,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_slave_status | OFF | +-----------------------------+-------+ - -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -421,8 +440,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_slave_status | ON | +-----------------------------+-------+ - -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -431,41 +451,45 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_slave_status | ON | +-----------------------------+-------+ -``` - ## Data Availability In a MySQL semi-sync cluster, only the primary member can write not the secondary. But you can read data from any member. In this tutorial, we will insert data from primary, and we will see whether we can get the data from any other member. > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # create a database on primary -$ kubectl exec -it -n demo semi-sync-mysql-0 -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "CREATE DATABASE playground;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # create a table -$ kubectl exec -it -n demo semi-sync-mysql-0 -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +```bash + kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # read from primary -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` In the previous step we have inserted into the primary pod. In the next step we will read from secondary pods to determine whether the data has been successfully copied to the secondary pods. -```bash # read from secondary-1 -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -474,32 +498,35 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read from secondary-2 -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Write on Secondary Should Fail Only, primary member preserves the write permission. No secondary can write data. -```bash # try to write on secondary-1 -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 # try to write on secondary-2 -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('mango', 5, 'yellow');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1290 (HY000) at line 1: The MySQL server is running with the --super-read-only option so it cannot execute this statement command terminated with exit code 1 -``` ## Automatic Failover @@ -507,17 +534,22 @@ To test automatic failover, we will force the primary Pod to restart. Since the > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # delete the primary Pod semi-sync-mysql-0 -$ kubectl delete pod semi-sync-mysql-0 -n demo +```bash +kubectl delete pod semi-sync-mysql-0 -n demo +``` pod "semi-sync-mysql-0" deleted # check the new primary ID -$ kubectl get pod -n demo --show-labels | grep primary +```bash +kubectl get pod -n demo --show-labels | grep primary +``` semi-sync-mysql-1 2/2 Running 0 3h9m app.kubernetes.io/component=database,app.kubernetes.io/instance=semi-sync-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,controller-revision-hash=semi-sync-mysql-77775485f8,kubedb.com/role=primary,petset.kubernetes.io/pod-name=semi-sync-mysql-1 # now check the cluster status -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -525,7 +557,10 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_master_status | OFF | | Rpl_semi_sync_slave_status | ON | +-----------------------------+-------+ -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" + +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -534,7 +569,9 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_slave_status | OFF | +-----------------------------+-------+ -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "show status like 'Rpl%_status';" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +-----------------------------+-------+ | Variable_name | Value | @@ -542,20 +579,21 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | Rpl_semi_sync_master_status | OFF | | Rpl_semi_sync_slave_status | ON | - # read data from new primary semi-sync-mysql-1.semi-sync-mysql-pods.demo -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-1.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` Now Let's read the data from secondary pods to see if the data is consistant. -```bash # read data from secondary-1 semi-sync-mysql-0.semi-sync-mysql-pods.demo -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-0.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | @@ -564,14 +602,15 @@ mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ # read data from secondary-2 semi-sync-mysql-2.semi-sync-mysql-pods.demo -$ kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo semi-sync-mysql-0 -c mysql -- mysql -u root --password='y~EC~984Et1Yfs~i' --host=semi-sync-mysql-2.semi-sync-mysql-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 7 | slide | 2 | blue | +----+-------+-------+-------+ -``` ## Cleaning up diff --git a/docs/guides/mysql/concepts/database/index.md b/docs/guides/mysql/concepts/database/index.md index 6502d60e43..7a1e708256 100644 --- a/docs/guides/mysql/concepts/database/index.md +++ b/docs/guides/mysql/concepts/database/index.md @@ -161,11 +161,11 @@ Secrets provided by users are not managed by KubeDB, and therefore, won't be mod Example: ```bash -$ kubectl create secret generic m1-auth -n demo \ +kubectl create secret generic m1-auth -n demo \ --from-literal=user=root \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "m1-auth" created ``` +secret "m1-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/mysql/configuration/config-file/index.md b/docs/guides/mysql/configuration/config-file/index.md index d0913862ba..04acf4933a 100644 --- a/docs/guides/mysql/configuration/config-file/index.md +++ b/docs/guides/mysql/configuration/config-file/index.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for MySQL. This tutorial will sho - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - - $ kubectl get ns demo + + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/configuration/config-file/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/configuration/config-file/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -66,9 +68,9 @@ Here, `read_buffer_size` is set to 1MB in bytes. Now, create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo my-configuration --from-file=./my-config.cnf -configmap/my-configuration created +kubectl create secret generic -n demo my-configuration --from-file=./my-config.cnf ``` +configmap/my-configuration created Verify the secret has the configuration file. @@ -91,9 +93,9 @@ type: Opaque Now, create MySQL crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/config-file/yamls/mysql-custom.yaml -mysql.kubedb.com/custom-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/config-file/yamls/mysql-custom.yaml ``` +mysql.kubedb.com/custom-mysql created Below is the YAML for the MySQL crd we just created. @@ -121,15 +123,16 @@ Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, serv Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE custom-mysql-0 1/1 Running 0 44s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo custom-mysql-0 +kubectl logs -f -n demo custom-mysql-0 +``` 2022-06-28 13:22:10+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.4.8-1debian10 started. 2022-06-28 13:22:10+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' .... @@ -153,7 +156,6 @@ $ kubectl logs -f -n demo custom-mysql-0 2022-06-28T13:22:26.076407Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.8' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL. .... -``` Once we see `[Note] /usr/sbin/mysqld: ready for connections.` in the log, the database is ready. @@ -161,19 +163,22 @@ Now, we will check if the database has started with the custom configuration we First, deploy [phpMyAdmin](https://hub.docker.com/r/phpmyadmin/phpmyadmin/) to connect with the MySQL database we have just created. -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/config-file/yamls/phpmyadmin.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/config-file/yamls/phpmyadmin.yaml + ``` deployment.extensions/myadmin created service/myadmin created -``` Then, open your browser and go to the following URL: _http://{node-ip}:{myadmin-svc-nodeport}_. For kind cluster, you can get this URL by running the following command: ```bash -$ kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +``` 30942 -$ kubectl get node -o json | jq '.items[].status.addresses[].address' +```bash +kubectl get node -o json | jq '.items[].status.addresses[].address' +``` "172.18.0.3" "kind-control-plane" "172.18.0.4" @@ -183,21 +188,24 @@ $ kubectl get node -o json | jq '.items[].status.addresses[].address' # expected url will be: url: http://172.18.0.4:30942 -``` Now, let's connect to the database from the phpMyAdmin dashboard using the database pod IP and MySQL user password. ```bash -$ kubectl get pods custom-mysql-0 -n demo -o yaml | grep IP +kubectl get pods custom-mysql-0 -n demo -o yaml | grep IP +``` hostIP: 10.0.2.15 podIP: 172.17.0.6 -$ kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.password}' | base64 -d -MLO5_fPVKcqPiEu9 +```bash +kubectl get secrets -n demo custom-mysql-auth -o jsonpath='{.data.password}' | base64 -d ``` +MLO5_fPVKcqPiEu9 Once, you have connected to the database with phpMyAdmin go to **Variables** tab and search for `max_connections` and `read_buffer_size`. Here are some screenshot showing those configured variables. ![max_connections](/docs/images/mysql/max_connection.png) diff --git a/docs/guides/mysql/configuration/podtemplating/index.md b/docs/guides/mysql/configuration/podtemplating/index.md index ae2d552f90..32f7dc843f 100644 --- a/docs/guides/mysql/configuration/podtemplating/index.md +++ b/docs/guides/mysql/configuration/podtemplating/index.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for MySQL via [PodTemplate](/docs - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/configuration/podtemplating/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/configuration/podtemplating/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -104,24 +104,25 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/podtemplating/yamls/mysql-misc-config.yaml -mysql.kubedb.com/mysql-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/podtemplating/yamls/mysql-misc-config.yaml ``` +mysql.kubedb.com/mysql-misc-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `mysql-misc-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=mysql-misc-config +kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=mysql-misc-config +``` NAME READY STATUS RESTARTS AGE mysql-misc-config-0 1/1 Running 0 9m28s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo mysql-misc-config-0 +kubectl logs -f -n demo mysql-misc-config-0 +``` Initializing database ..... Database initialized @@ -135,7 +136,6 @@ MySQL init process done. Ready for start up. 2022-06-28T13:22:26.076407Z 0 [Note] mysqld: ready for connections. Version: '8.4.8' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) .... -``` Once we see `[Note] /usr/sbin/mysqld: ready for connections.` in the log, the database is ready. @@ -144,18 +144,21 @@ Now, we will check if the database has started with the custom configuration we First, deploy [phpMyAdmin](https://hub.docker.com/r/phpmyadmin/phpmyadmin/) to connect with the MySQL database we have just created. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/podtemplating/yamls/phpmyadmin.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/configuration/podtemplating/yamls/phpmyadmin.yaml +``` deployment.extensions/myadmin created service/myadmin created -``` Then, open your browser and go to the following URL: _http://{node-ip}:{myadmin-svc-nodeport}_. For kind cluster, you can get this URL by running the following command: ```bash -$ kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +``` 30942 -$ kubectl get node -o json | jq '.items[].status.addresses[].address' +```bash +kubectl get node -o json | jq '.items[].status.addresses[].address' +``` "172.18.0.3" "kind-control-plane" "172.18.0.4" @@ -165,22 +168,25 @@ $ kubectl get node -o json | jq '.items[].status.addresses[].address' # expected url will be: url: http://172.18.0.4:30942 -``` Now, let's connect to the database from the phpMyAdmin dashboard using the database pod IP and MySQL user password. ```bash -$ kubectl get pods mysql-misc-config-0 -n demo -o yaml | grep IP +kubectl get pods mysql-misc-config-0 -n demo -o yaml | grep IP +``` ... hostIP: 10.0.2.15 podIP: 172.17.0.6 -$ kubectl get secrets -n demo mysql-misc-config-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secrets -n demo mysql-misc-config-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-misc-config-auth -o jsonpath='{.data.password}' | base64 -d -MLO5_fPVKcqPiEu9 +```bash +kubectl get secrets -n demo mysql-misc-config-auth -o jsonpath='{.data.password}' | base64 -d ``` +MLO5_fPVKcqPiEu9 Once, you have connected to the database with phpMyAdmin go to **SQL** tab and run sql to see all databases `SHOW DATABASES;` and to see charcter-set configuration `SHOW VARIABLES LIKE 'char%';`. You will see a database called `myDB` is created and also all the character-set is set to `utf8mb4`. diff --git a/docs/guides/mysql/custom-rbac/index.md b/docs/guides/mysql/custom-rbac/index.md index 0eb2f1bdd3..217d26af6e 100644 --- a/docs/guides/mysql/custom-rbac/index.md +++ b/docs/guides/mysql/custom-rbac/index.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/custom-rbac/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the MySQL instance named `quick-mysql`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -98,10 +98,9 @@ This permission is required for MySQL pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -129,9 +128,9 @@ subjects: Now, create a MySQL crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-db.yaml -mysql.kubedb.com/quick-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-db.yaml ``` +mysql.kubedb.com/quick-mysql created Below is the YAML for the MySQL crd we just created. @@ -162,15 +161,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, PetSet, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo quick-mysql-0 +kubectl get pod -n demo quick-mysql-0 +``` NAME READY STATUS RESTARTS AGE quick-mysql-0 1/1 Running 0 2m44s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo quick-mysql-0 +kubectl logs -f -n demo quick-mysql-0 +``` ... 2022-06-28 13:46:46+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.4.8-1debian10 started. 2022-06-28 13:46:46+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql' @@ -180,8 +180,6 @@ $ kubectl logs -f -n demo quick-mysql-0 2022-06-28T13:47:02.915445Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock 2022-06-28T13:47:02.915504Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.4.8' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server - GPL. -``` - Once we see `MySQL init process done. Ready for start up.` in the log, the database is ready. ## Reusing Service Account @@ -191,9 +189,9 @@ An existing service account can be reused in another MySQL instance. No new acce Now, create MySQL crd `minute-mysql` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-db-two.yaml -mysql.kubedb.com/quick-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/custom-rbac/yamls/my-custom-db-two.yaml ``` +mysql.kubedb.com/quick-mysql created Below is the YAML for the MySQL crd we just created. @@ -225,10 +223,10 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo minute-mysql-0 +kubectl get pod -n demo minute-mysql-0 +``` NAME READY STATUS RESTARTS AGE minute-mysql-0 1/1 Running 0 14m -``` Check the pod's log to see if the database is ready diff --git a/docs/guides/mysql/failure-and-disaster-recovery/overview.md b/docs/guides/mysql/failure-and-disaster-recovery/overview.md index 63f6795695..4617d2f941 100644 --- a/docs/guides/mysql/failure-and-disaster-recovery/overview.md +++ b/docs/guides/mysql/failure-and-disaster-recovery/overview.md @@ -42,17 +42,17 @@ But that is a bit rare though. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ### Step 1: Create a High-Availability MySQL Cluster @@ -87,24 +87,27 @@ spec: Now, create the namespace and apply the manifest: -```shell # Create the namespace if it doesn't exist -$ kubectl create ns demo +```bash +kubectl create ns demo +``` namespace/demo created # Apply the manifest to deploy the cluster -$ kubectl apply -f ha-mysql.yaml -mysql.kubedb.com/ha-mysql created +```bash +kubectl apply -f ha-mysql.yaml ``` +mysql.kubedb.com/ha-mysql created You can monitor on another terminal the status until all pods are ready: -```shell -$ watch kubectl get my,petset,pods -n demo +```bash +watch kubectl get my,petset,pods -n demo ``` See the database is ready. -```shell -$ kubectl get my,petset,pods -n demo +```bash +kubectl get my,petset,pods -n demo +``` NAME VERSION STATUS AGE mysql.kubedb.com/ha-mysql 8.2.0 Ready 19h @@ -116,32 +119,31 @@ pod/ha-mysql-0 2/2 Running 3 (24m ago) 16h pod/ha-mysql-1 2/2 Running 2 (24m ago) 16h pod/ha-mysql-2 2/2 Running 3 (24m ago) 16h -``` - Inspect who is primary and who is standby. -```shell # you can inspect who is primary # and who is secondary like below - -$ kubectl get pods -n demo --show-labels | grep role +```bash +kubectl get pods -n demo --show-labels | grep role +``` ha-mysql-0 2/2 Running 0 34m app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=ha-mysql-7f595bb48b,kubedb.com/role=primary,statefulset.kubernetes.io/pod-name=ha-mysql-0 ha-mysql-1 2/2 Running 0 34m app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=ha-mysql-7f595bb48b,kubedb.com/role=standby,statefulset.kubernetes.io/pod-name=ha-mysql-1 ha-mysql-2 2/2 Running 0 34m app.kubernetes.io/component=database,app.kubernetes.io/instance=ha-mysql,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=mysqls.kubedb.com,apps.kubernetes.io/pod-index=2,controller-revision-hash=ha-mysql-7f595bb48b,kubedb.com/role=standby,statefulset.kubernetes.io/pod-name=ha-mysql-2 - -``` The pod having `kubedb.com/role=primary` is the primary and `kubedb.com/role=standby` are the standby's. Let's create a table in the primary. -```shell # find the primary pod -$ kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +```bash +kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +``` ha-mysql-0 # exec into the primary pod -$ kubectl exec -it -n demo ha-mysql-0 -- bash +```bash +kubectl exec -it -n demo ha-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -173,13 +175,12 @@ mysql> show Databases; +--------------------+ 6 rows in set (0.09 sec) -``` - Verify that the table has been created on the standby nodes. Note that standby pods have read-only access, so you won't be able to perform any write operations. -```shell -$ kubectl exec -it -n demo ha-mysql-1 -- bash +```bash +kubectl exec -it -n demo ha-mysql-1 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -210,8 +211,6 @@ mysql> show databases; mysql> create database Hi; ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement - -``` ### Step 2: Simulating a Failover Before simulating failover, let’s discuss how KubeDB-managed MySQL handles such scenarios. @@ -241,10 +240,10 @@ ha-mysql-2 standby Let's delete the current primary and see how the role change happens almost immediately. -```shell -$ kubectl delete pods -n demo ha-mysql-0 -pod "ha-mysql-0" deleted +```bash +kubectl delete pods -n demo ha-mysql-0 ``` +pod "ha-mysql-0" deleted You see almost immediately the failover happened. ```shell ha-mysql-0 @@ -289,8 +288,9 @@ A healthy replica is promoted as the new primary, and it resumes accepting write Now we know how failover is done, let's check if the new primary is working. -```shell -$ kubectl exec -it -n demo ha-mysql-1 -- bash +```bash +kubectl exec -it -n demo ha-mysql-1 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -308,7 +308,6 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE DATABASE hi; Query OK, 1 row affected (0.16 sec) -``` You will see the deleted pod (ha-mysql-0) is brought back by the kubedb operator and it is now assigned to standby role. @@ -320,9 +319,9 @@ ha-mysql-2 standby Lets check if the standby(`ha-mysql-0`) got the updated data from new primary `ha-mysql-1`. -```shell -$ kubectl exec -it -n demo ha-mysql-1 -- bash - +```bash +kubectl exec -it -n demo ha-mysql-1 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -352,15 +351,13 @@ mysql> Show Databases; +--------------------+ 7 rows in set (0.12 sec) -``` - #### Case 2: Delete the current primary and One replica -```shell -$ kubectl delete pods -n demo ha-mysql-1 ha-mysql-2 +```bash +kubectl delete pods -n demo ha-mysql-1 ha-mysql-2 +``` pod "ha-mysql-1" deleted pod "ha-mysql-2" deleted -``` Again we can see the failover happened pretty quickly. ```shell @@ -378,8 +375,9 @@ ha-mysql-2 standby ``` Lets validate the cluster state from new primary(`ha-mysql-0`). -```shell -$ kubectl exec -it -n demo ha-mysql-0 -- bash +```bash +kubectl exec -it -n demo ha-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -405,19 +403,16 @@ mysql> SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE FROM performan +---------------------------------------------+-------------+--------------+-------------+ 3 rows in set (0.00 sec) -``` - #### Case3: Delete any of the replica's Let's delete both of the standby's. -```shell -$ kubectl delete pods -n demo ha-mysql-1 ha-mysql-2 +```bash +kubectl delete pods -n demo ha-mysql-1 ha-mysql-2 +``` pod "ha-mysql-1" deleted pod "ha-mysql-2" deleted -``` - ```shell ha-mysql-0 primary ha-mysql-1 @@ -433,8 +428,9 @@ ha-mysql-2 standby ``` Lets verify cluster state. -```shell -$ kubectl exec -it -n demo ha-mysql-0 -- bash +```bash +kubectl exec -it -n demo ha-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -459,18 +455,17 @@ mysql> SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE FROM performan | ha-mysql-2.ha-mysql-pods.demo.svc | 3306 | ONLINE | SECONDARY | +---------------------------------------------+-------------+--------------+-------------+ 3 rows in set (0.01 sec) -``` #### Case 4: Delete both primary and all replicas Let's delete all the pods. -```shell -$ kubectl delete pods -n demo ha-mysql-0 ha-mysql-1 ha-mysql-2 +```bash +kubectl delete pods -n demo ha-mysql-0 ha-mysql-1 ha-mysql-2 +``` pod "ha-mysql-0" deleted pod "ha-mysql-1" deleted pod "ha-mysql-2" deleted -``` ```bash ha-mysql-0 ha-mysql-1 @@ -487,8 +482,9 @@ ha-mysql-2 standby Lets verify the cluster state now. -```shell -$ kubectl exec -it -n demo ha-mysql-0 -- bash +```bash +kubectl exec -it -n demo ha-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -513,7 +509,6 @@ mysql> SELECT MEMBER_HOST, MEMBER_PORT, MEMBER_STATE, MEMBER_ROLE FROM performan | ha-mysql-2.ha-mysql-pods.demo.svc | 3306 | ONLINE | SECONDARY | +---------------------------------------------+-------------+--------------+-------------+ 3 rows in set (0.00 sec) -``` ## A Guide to Handling MySQL Storage @@ -560,9 +555,12 @@ It depends on your `StorageClass`. If your storageclass supports online volume e ## CleanUp To clean up the Kubernetes resources created by this tutorial, run: -```shell -$ kubectl delete my -n demo ha-mysql -$ kubectl delete ns demo +```bash +kubectl delete my -n demo ha-mysql +``` + +```bash +kubectl delete ns demo ``` ### Next Steps diff --git a/docs/guides/mysql/gitops/gitops.md b/docs/guides/mysql/gitops/gitops.md index 807c41b720..faff5cb7e9 100644 --- a/docs/guides/mysql/gitops/gitops.md +++ b/docs/guides/mysql/gitops/gitops.md @@ -25,12 +25,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create MySQL dat - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mysql](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mysql) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -95,11 +97,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── MySQL.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `MySQL` CR is created in your cluster. @@ -107,18 +109,19 @@ Our `gitops` operator will create an actual `MySQL` database CR in the cluster. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 76m NAME VERSION STATUS AGE mysql.kubedb.com/my-gitops 9.4.0 Ready 76m -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` MySQL. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=my-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=my-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/my-gitops 78m @@ -137,7 +140,6 @@ service/my-gitops-standby ClusterIP 10.43.239.55 3306/TCP NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/my-gitops kubedb.com/mysql 9.4.0 78m -``` ## Update MySQL Database using GitOps @@ -184,7 +186,8 @@ Resource requests have been updated to `700m` CPU and `1536Mi` memory, and the m Now, `gitops` operator will detect the resource changes and create a `MySQLOpsRequest` to update the `MySQL` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 178m @@ -193,11 +196,11 @@ mysql.kubedb.com/my-gitops 9.4.0 Ready 178m NAME TYPE STATUS AGE mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-mw8s6j VerticalScaling Successful 144m -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo my-gitops-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo my-gitops-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1536Mi" @@ -207,7 +210,6 @@ $ kubectl get pod -n demo my-gitops-0 -o json | jq '.spec.containers[0].resource "memory": "1536Mi" } } -``` ### Scale MySQL Replicas Update the `MySQL.yaml` with the following, @@ -249,7 +251,8 @@ Update the `replicas` to `4`. Commit the changes and push to your Git repository Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` MySQLOpsRequest to update the `MySQL` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo + kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 101m @@ -260,17 +263,15 @@ NAME TYPE mysqlopsrequest.ops.kubedb.com/my-gitops-horizontalscaling-h542j4 HorizontalScaling Successful 5m1s mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 19m -``` - After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=my-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=my-gitops' +``` NAME READY STATUS RESTARTS AGE my-gitops-0 2/2 Running 0 15m my-gitops-1 2/2 Running 0 19m my-gitops-2 2/2 Running 0 17m my-gitops-3 2/2 Running 0 5m37s -``` We can also scale down the replicas by updating the `replicas` fields. @@ -316,7 +317,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` MySQLOpsRequest to update the `MySQL` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 104m @@ -328,17 +330,15 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-horizontalscaling-h542j4 HorizontalSc mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 22m mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 112s -``` - After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=my-gitops' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=my-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-my-gitops-0 Bound pvc-c926c69f-ff5e-4f93-be78-1fc1d39da25c 2Gi RWO longhorn 105m data-my-gitops-1 Bound pvc-8bfcf4d8-37fb-4543-96c5-7a656270967a 2Gi RWO longhorn 101m data-my-gitops-2 Bound pvc-238989bc-0a53-4db8-a3c2-2ce77aee4042 2Gi RWO longhorn 101m data-my-gitops-3 Bound pvc-5345bc6a-baad-461a-a1fe-108e75c32a11 2Gi RWO longhorn 8m41s -``` ## Reconfigure MySQL @@ -396,12 +396,12 @@ type: Opaque Now, we will add this file to `kubedb/my-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── my-configuration.yaml │ └── MySQL.yaml 1 directories, 2 files -``` Update the `MySQL.yaml` with the following, ```yaml @@ -445,7 +445,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` MySQLOpsRequest to update the `MySQL` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 126m @@ -457,12 +458,12 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-horizontalscaling-h542j4 HorizontalSc mysqlopsrequest.ops.kubedb.com/my-gitops-reconfigure-yskbt5 Reconfigure Successful 18m mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 44m mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 23m -``` After Ops Request becomes `Succesful`, lets check these parameters, ```bash -$ kubectl exec -it -n demo my-gitops-0 -- bash +kubectl exec -it -n demo my-gitops-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-5.1$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -492,8 +493,6 @@ mysql> show variables like 'read_buffer_size'; +------------------+---------+ | read_buffer_size | 1044480 | +------------------+---------+ - -``` You can check the other pods same way. So we have configured custom parameters. @@ -519,13 +518,13 @@ type: kubernetes.io/basic-auth File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── my-auth.yaml │ ├── my-configuration.yaml │ └── MySQL.yaml 1 directories, 3 files -``` Update the `MySQL.yaml` with the following, ```yaml @@ -571,7 +570,8 @@ Change the `authSecret.name` field to `myauth`. Commit the changes and push to y Now, `gitops` operator will detect the auth changes and create a `RotateAuth` MySQLOpsRequest to update the `MySQL` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 19h @@ -584,11 +584,11 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-reconfigure-b5s92r Reconfigure mysqlopsrequest.ops.kubedb.com/my-gitops-rotate-auth-q2z2vf RotateAuth Successful 24m mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 18h mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 18h -``` After Ops Request becomes `Successful`, We can validate the changes connecting MySQL with new credentials. ```bash -$ kubectl exec -it -n demo my-gitops-0 -c mysql -- bash +kubectl exec -it -n demo my-gitops-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p"mypassword" mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -614,7 +614,6 @@ mysql> SHOW DATABASES; | sys | +--------------------+ 5 rows in set (0.001 sec) -``` ### TLS configuration @@ -631,7 +630,7 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret generic my-ca \ +kubectl create secret generic my-ca \ --from-file=ca.crt=ca.crt \ -n demo ``` @@ -658,7 +657,8 @@ issuer.cert-manager.io/mysql-issuer created Let's add that to our `kubedb/my-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── my-auth.yaml │ ├── my-configuration.yaml @@ -666,7 +666,6 @@ $ tree . │ ├── my-issuer.yaml │ └── MySQL.yaml 1 directories, 5 files -``` Update the `MySQL.yaml` with the following, ```yaml @@ -718,7 +717,8 @@ Add `tls` fields in the spec. Commit the changes and push to your Git repository Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` MySQLOpsRequest to update the `MySQL` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 20h @@ -732,11 +732,11 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-reconfiguretls-8kwaw9 ReconfigureT mysqlopsrequest.ops.kubedb.com/my-gitops-rotate-auth-q2z2vf RotateAuth Successful 38m mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 18h mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 18h -``` After Ops Request becomes `Successful`, We can validate the changes connecting MySQL with new credentials. ```bash -$ kubectl exec -it -n demo my-gitops-0 -c mysql -- bash +kubectl exec -it -n demo my-gitops-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -803,7 +803,6 @@ mysql> SHOW VARIABLES LIKE '%require_secure_transport%'; | require_secure_transport | OFF | +--------------------------+-------+ 1 row in set (0.002 sec) -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for MySQL. @@ -870,7 +869,8 @@ Update the `version` field to `9.6.0`. Commit the changes and push to your Git r Now, `gitops` operator will detect the version changes and create a `VersionUpdate` MySQLOpsRequest to update the `MySQL` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 22h @@ -886,19 +886,24 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-versionupdate-bskr89 UpdateVersio mysqlopsrequest.ops.kubedb.com/my-gitops-versionupdate-g2n3y9 UpdateVersion Successful 132m mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 21h mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 20h -``` Now, we are going to verify whether the `MySQL`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get MySQL -n demo my-gitops -o=jsonpath='{.spec.version}{"\n"}' +kubectl get MySQL -n demo my-gitops -o=jsonpath='{.spec.version}{"\n"}' +``` 9.6.0 -$ kubectl get petset -n demo my-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/mysql:9.6.0-oracle@sha256:16e6b7b93df8aa255d3886ff33c2d78093d1cd2346522d14bf1b9cc0ad03a460 -$ kubectl get pod -n demo my-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' + +```bash +kubectl get petset -n demo my-gitops -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/mysql:9.6.0-oracle@sha256:16e6b7b93df8aa255d3886ff33c2d78093d1cd2346522d14bf1b9cc0ad03a460 + +```bash +kubectl get pod -n demo my-gitops-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/mysql:9.6.0-oracle@sha256:16e6b7b93df8aa255d3886ff33c2d78093d1cd2346522d14bf1b9cc0ad03a460 ### Enable Monitoring @@ -960,7 +965,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` MySQLOpsRequest to add the `MySQL` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +kubectl get mysql.gitops.kubedb.com,mysql.kubedb.com,MySQLopsrequest -n demo +``` NAME AGE mysql.gitops.kubedb.com/my-gitops 22h @@ -976,7 +982,6 @@ mysqlopsrequest.ops.kubedb.com/my-gitops-rotate-auth-q2z2vf RotateAuth mysqlopsrequest.ops.kubedb.com/my-gitops-versionupdate-bskr89 UpdateVersion Successful 158m mysqlopsrequest.ops.kubedb.com/my-gitops-verticalscaling-zbtqnv VerticalScaling Successful 21h mysqlopsrequest.ops.kubedb.com/my-gitops-volumeexpansion-tzncw1 VolumeExpansion Successful 21h -``` Verify the monitoring is enabled by checking the prometheus targets. diff --git a/docs/guides/mysql/initialization/gitsync.md b/docs/guides/mysql/initialization/gitsync.md index 13c0ac62bb..a4af5adecd 100644 --- a/docs/guides/mysql/initialization/gitsync.md +++ b/docs/guides/mysql/initialization/gitsync.md @@ -25,9 +25,9 @@ In this example, we will initialize MySQL using a `.sql` script from the GitHub To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## From Public Git Repository @@ -78,16 +78,16 @@ The `--link` argument creates a symlink that always points to the latest synced Now, wait until `sample-mysql` has status `Ready`. i.e, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.4.8 Ready 42m -``` Next, we will connect to the MySQL database and verify the data inserted from the `*.sql` script stored in the Git repository. ```bash - -$ kubectl exec -it -n demo sample-mysql-0 -- bash + kubectl exec -it -n demo sample-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-init (init), git-sync (init) bash-5.1$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -139,10 +139,6 @@ mysql> select * from kubedb_table; | 3 | name3 | +----+-------+ 3 rows in set (0.00 sec) - - - -``` ## From Private Git Repository ### 1. Using SSH Key @@ -152,7 +148,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -167,7 +163,7 @@ This secret will be used by git-sync to authenticate with the Git repository. >Here, we are using the default SSH key file located at `$HOME/.ssh/id_rsa`. If your SSH key is stored in a different location, please update the command accordingly. Also you can use any name instead of `git-creds` to create the secret. ```bash -$ kubectl create secret generic -n demo git-creds \ +kubectl create secret generic -n demo git-creds \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -220,7 +216,7 @@ First, create a `Personal Access Token (PAT)` on your Git host server with the r Then create a Kubernetes secret using the `Personal Access Token (PAT)`: > Here, you can use any key name instead of `git-pat` to store the token in the secret. ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -271,7 +267,13 @@ Once the database reaches the `Ready` state, you can verify the data using the m To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete MySQL -n demo sample-mysql -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete MySQL -n demo sample-mysql +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/mysql/initialization/using_script.md b/docs/guides/mysql/initialization/using_script.md index ed395a1af4..128c108489 100644 --- a/docs/guides/mysql/initialization/using_script.md +++ b/docs/guides/mysql/initialization/using_script.md @@ -28,29 +28,38 @@ In this tutorial we will use .sql script stored in GitHub repository [kubedb/mys - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. This tutorial will also use a phpMyAdmin to connect and test MySQL database, once it is running. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/phpmyadmin.yaml + + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/phpmyadmin.yaml + ``` deployment.extensions/myadmin created service/myadmin created - - $ kubectl get pods -n demo + + ```bash + kubectl get pods -n demo + ``` NAME READY STATUS RESTARTS AGE myadmin-66cc8d4c77-wkwht 1/1 Running 0 5m20s - - $ kubectl get service -n demo + + ```bash + kubectl get service -n demo + ``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE myadmin LoadBalancer 10.104.142.213 80:31529/TCP 3m14s - ``` Then, open your browser and go to the following URL: _http://{node-ip}:{myadmin-svc-nodeport}_. For kind cluster, you can get this URL by running the following command: ```bash - $ kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' + kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' + ``` 31529 - - $ kubectl get node -o json | jq '.items[].status.addresses[].address' + + ```bash + kubectl get node -o json | jq '.items[].status.addresses[].address' + ``` "172.18.0.3" "kind-control-plane" "172.18.0.4" @@ -60,7 +69,6 @@ In this tutorial we will use .sql script stored in GitHub repository [kubedb/mys # expected url will be: url: http://172.18.0.4:31529 - ``` ## Prepare Initialization Scripts @@ -73,10 +81,10 @@ At first, we will create a ConfigMap from `init.sql` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo my-init-script \ +kubectl create configmap -n demo my-init-script \ --from-literal=init.sql="$(curl -fsSL https://github.com/kubedb/mysql-init-scripts/raw/master/init.sql)" -configmap/my-init-script created ``` +configmap/my-init-script created ## Create a MySQL database with Init-Script @@ -131,9 +139,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-gr.yaml -mysql.kubedb.com/mysql-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-gr.yaml ``` +mysql.kubedb.com/mysql-init-script created @@ -168,9 +176,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-innodb.yaml -mysql.kubedb.com/mysql-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-innodb.yaml ``` +mysql.kubedb.com/mysql-init-script created
@@ -205,9 +213,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-semi-sync.yaml -mysql.kubedb.com/mysql-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-semi-sync.yaml ``` +mysql.kubedb.com/mysql-init-script created
@@ -235,9 +243,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-standalone.yaml -mysql.kubedb.com/mysql-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/initialization/yamls/initialize-standalone.yaml ``` +mysql.kubedb.com/mysql-init-script created @@ -250,7 +258,8 @@ Here, KubeDB operator watches for `MySQL` objects using Kubernetes api. When a `MySQL` object is created, KubeDB operator will create a new PetSet and a Service with the matching MySQL object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. No MySQL specific RBAC roles are required for [RBAC enabled clusters](/docs/setup/README.md#using-yaml). ```bash -$ kubectl dba describe my -n demo mysql-init-scrip +kubectl dba describe my -n demo mysql-init-scrip +``` Name: mysql-init-script Namespace: demo CreationTimestamp: Thu, 30 Jun 2022 12:21:15 +0600 @@ -371,25 +380,31 @@ Events: Normal Successful 10s KubeDB operator Successfully created MySQL Normal Successful 10s KubeDB operator Successfully created appbinding - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mysql-init-script 1/1 2m24s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-mysql-init-script-0 Bound pvc-32a59975-2972-4122-9635-22fe19483145 1Gi RWO standard 3m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-32a59975-2972-4122-9635-22fe19483145 1Gi RWO Delete Bound demo/data-mysql-init-script-0 standard 3m25s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE myadmin LoadBalancer 10.104.142.213 80:31529/TCP 23m mysql-init-script ClusterIP 10.103.202.117 3306/TCP 3m49s mysql-init-script-pods ClusterIP None 3306/TCP 3m49s -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified MySQL object: @@ -464,16 +479,20 @@ If you want to use an existing secret please specify that when creating the MySQ Now, you can connect to this database from the phpMyAdmin dashboard using the database pod IP and `mysql` user password. ```bash -$ kubectl get pods mysql-init-script-0 -n demo -o yaml | grep IP +kubectl get pods mysql-init-script-0 -n demo -o yaml | grep IP +``` hostIP: 10.0.2.15 podIP: 10.244.2.9 -$ kubectl get secrets -n demo mysql-init-script-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secrets -n demo mysql-init-script-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-init-script-auth -o jsonpath='{.data.password}' | base64 -d -1Pc7bwSygrv1MX1Q +```bash +kubectl get secrets -n demo mysql-init-script-auth -o jsonpath='{.data.password}' | base64 -d ``` +1Pc7bwSygrv1MX1Q --- Note: In MySQL: `8.0.14-v1` connection to phpMyAdmin may give error as it is using `caching_sha2_password` and `sha256_password` authentication plugins over `mysql_native_password`. If the error happens do the following for work around. But, It's not recommended to change authentication plugins. See [here](https://stackoverflow.com/questions/49948350/phpmyadmin-on-mysql-8-0) for alternative solutions. diff --git a/docs/guides/mysql/migration/databaseMigration.md b/docs/guides/mysql/migration/databaseMigration.md index 1149a35271..bd72186eac 100644 --- a/docs/guides/mysql/migration/databaseMigration.md +++ b/docs/guides/mysql/migration/databaseMigration.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` Migration to migrate an existing `M To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Source Database @@ -79,7 +79,7 @@ Enable binary logging under **Backups** in the [Cloud Console](https://cloud.goo ### Verify prerequisites ```bash -$ mysql -h .rds.amazonaws.com -u admin -p +mysql -h .rds.amazonaws.com -u admin -p ``` ```sql @@ -165,7 +165,7 @@ SELECT * FROM orders; First, create an authentication secret using the `migrator` user credentials: ```bash -$ kubectl create secret generic source-mysql-auth -n demo \ +kubectl create secret generic source-mysql-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=migrator \ --from-literal=password= @@ -230,9 +230,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/target-mysql.yaml -mysql.kubedb.com/target-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/target-mysql.yaml ``` +mysql.kubedb.com/target-mysql created > Note: Adjust the `resources.requests.storage` based on source database. Wait untill target-mysql has status `Ready` @@ -283,9 +283,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/mysql-migrate.yaml -migration.courier.kubedb.com/mysql-migrate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/mysql-migrate.yaml ``` +migration.courier.kubedb.com/mysql-migrate created Here we scope the migration to the `shop` database (`schema.database: [shop]`), enable both the bulk snapshot and CDC streaming phases, and cap connections at 100 on each side. For a full description of every field, see the [Migration CRD reference](/docs/guides/mysql/concepts/migrator/). @@ -305,7 +305,7 @@ mysql-migrate Running mysql Streaming 0B 100% 4h36m Once the migration reaches the `Streaming` stage, exec into the KubeDB target pod and confirm all seed rows were copied over: ```bash -$ kubectl exec -it -n demo target-mysql-0 -- mysql -u root -p +kubectl exec -it -n demo target-mysql-0 -- mysql -u root -p ``` ```sql @@ -326,7 +326,7 @@ SELECT * FROM orders; With the migration still running, connect to the **source RDS** instance and run some DML: ```bash -$ mysql -h .rds.amazonaws.com -u migrator -p +mysql -h .rds.amazonaws.com -u migrator -p ``` ```sql @@ -365,8 +365,8 @@ Once the `LAG` drops to near zero, stop all writes to the source database. Wait Now delete the `Migration` CR to stop the migration process: ```bash -$ kubectl delete migration -n demo mysql-migrate -migration.courier.kubedb.com "mysql-migrate" deleted +kubectl delete migration -n demo mysql-migrate ``` +migration.courier.kubedb.com "mysql-migrate" deleted Finally, update your application's connection string to point to the target KubeDB-managed `MySQL` database. The migration is complete. diff --git a/docs/guides/mysql/migration/storageMigration.md b/docs/guides/mysql/migration/storageMigration.md index 607f0fb5b8..0f1c426b68 100644 --- a/docs/guides/mysql/migration/storageMigration.md +++ b/docs/guides/mysql/migration/storageMigration.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops Manager to migrate `StorageCla To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MySQL Database @@ -79,13 +79,14 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/sample-mysql.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/sample-mysql.yaml ``` +mysql.kubedb.com/sample-mysql created Now, wait until sample-mysql has status `Ready` and check the `StorageClass`, ```bash -$ kubectl get mysql,pvc -n demo +kubectl get mysql,pvc -n demo +``` NAME VERSION STATUS AGE mysql.kubedb.com/sample-mysql 8.4.8 Ready 101s @@ -93,7 +94,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-sample-mysql-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 1Gi RWO local-path 96s persistentvolumeclaim/data-sample-mysql-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 1Gi RWO local-path 90s persistentvolumeclaim/data-sample-mysql-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 1Gi RWO local-path 85s -``` The database is `Ready` and all the `PersistentVolumeClaim` uses `local-path` StorageClass, Let's create a table in the primary. @@ -204,38 +204,38 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, -``` bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/storage-migration.yaml -mysqlopsrequest.ops.kubedb.com/storage-migration created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/migration/storage-migration.yaml ``` +mysqlopsrequest.ops.kubedb.com/storage-migration created ## Verify the StorageClass Migrated Successfully If everything goes well, `KubeDB` operator will migrate the `StorageClass` along with the data. Let’s wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch MySQLOpsRequest CR, -``` bash -$ watch kubectl get mysqlopsrequest -n demo - +```bash +watch kubectl get mysqlopsrequest -n demo +``` Every 2.0s: kubectl get mysqlopsrequest -n demo NAME TYPE STATUS AGE storage-migration StorageMigration Successful 12m -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. Let's verify the StorageClass. -``` bash -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-sample-mysql-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 1Gi RWO standard-custom 21m data-sample-mysql-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 1Gi RWO standard-custom 21m data-sample-mysql-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 1Gi RWO standard-custom 21m -``` The `PersistentVolumeClaim` StorageClass has changed to `standard-custom`. Now, we will verify that the data remains intact after the `StorageMigration` operation. Let's exec into one of the `MySQL` pod and perform read query. ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- bash +kubectl exec -it -n demo sample-mysql-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) bash-5.1$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -278,8 +278,6 @@ mysql> select * from hello.users; +----+--------+--------------------+ 20 rows in set (0.00 sec) -``` - From the above output we can verify that data remains intact after the `StorageMigration` operation. ## CleanUp @@ -287,7 +285,13 @@ From the above output we can verify that data remains intact after the `StorageM To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mysqlopsrequest -n demo storage-migration -$ kubectl delete mysql -n demo sample-mysql -$ kubectl delete ns demo +kubectl delete mysqlopsrequest -n demo storage-migration +``` + +```bash +kubectl delete mysql -n demo sample-mysql +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mysql/monitoring/builtin-prometheus/index.md b/docs/guides/mysql/monitoring/builtin-prometheus/index.md index 62a7fa0e7c..1666be487d 100644 --- a/docs/guides/mysql/monitoring/builtin-prometheus/index.md +++ b/docs/guides/mysql/monitoring/builtin-prometheus/index.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor MySQL database using builtin [Prometh - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/monitoring/builtin-prometheus/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/monitoring/builtin-prometheus/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,34 +71,35 @@ Here, Let's create the MySQL crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/builtin-prometheus/yamls/builtin-prom-mysql.yaml -mysql.kubedb.com/builtin-prom-mysql created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/builtin-prometheus/yamls/builtin-prom-mysql.yaml ``` +mysql.kubedb.com/builtin-prom-mysql created Now, wait for the database to go into `Running` state. ```bash -$ watch -n 3 kubectl get mysql -n demo builtin-prom-mysql +watch -n 3 kubectl get mysql -n demo builtin-prom-mysql +``` Every 3.0s: kubectl get mysql -n demo builtin-prom-mysql suaas-appscode: Tue Aug 25 16:07:29 2020 NAME VERSION STATUS AGE builtin-prom-mysql 8.4.8 Running 3m33s -``` KubeDB will create a separate stats service with name `{MySQL crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-mysql" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-mysql" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-mysql ClusterIP 10.104.141.73 3306/TCP 4m45s builtin-prom-mysql-gvr ClusterIP None 3306/TCP 4m45s builtin-prom-mysql-stats ClusterIP 10.103.209.43 56790/TCP 2m9s -``` Here, `builtin-prom-mysql-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-mysql-stats +kubectl describe svc -n demo builtin-prom-mysql-stats +``` Name: builtin-prom-mysql-stats Namespace: demo Labels: app.kubernetes.io/name=mysqls.kubedb.com @@ -114,7 +117,6 @@ TargetPort: prom-http/TCP Endpoints: 10.244.1.5:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -278,20 +280,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/builtin-prometheus/yamls/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/builtin-prometheus/yamls/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -302,9 +304,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -313,18 +315,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-mysql-stats` service as one of the targets. diff --git a/docs/guides/mysql/monitoring/prometheus-operator/index.md b/docs/guides/mysql/monitoring/prometheus-operator/index.md index d814d48a9f..deff13d5f5 100644 --- a/docs/guides/mysql/monitoring/prometheus-operator/index.md +++ b/docs/guides/mysql/monitoring/prometheus-operator/index.md @@ -25,9 +25,9 @@ section_menu_id: guides - To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -42,10 +42,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE default prometheus 1 2m19s -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -96,9 +96,9 @@ KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add l Let's add label `prometheus: prometheus` to `demo` namespace, ```bash -$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' -namespace/demo patched +kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' ``` +namespace/demo patched ## Deploy MySQL with Monitoring Enabled @@ -140,29 +140,29 @@ Here, Let's create the MySQL object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/prometheus-operator/yamls/prom-operator-mysql.yaml -mysql.kubedb.com/prom-operator-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/monitoring/prometheus-operator/yamls/prom-operator-mysql.yaml ``` +mysql.kubedb.com/prom-operator-mysql created Now, wait for the database to go into `Running` state. ```bash -$ watch -n 3 kubectl get mysql -n demo coreos-prom-mysql +watch -n 3 kubectl get mysql -n demo coreos-prom-mysql +``` Every 3.0s: kubectl get mysql -n demo coreos-prom-mysql suaas-appscode: Tue Aug 25 11:53:34 2020 NAME VERSION STATUS AGE coreos-prom-mysql 8.4.8 Running 2m53s -``` KubeDB will create a separate stats service with name `{MySQL crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-mysql" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-mysql" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-mysql ClusterIP 10.103.228.135 3306/TCP 3m36s coreos-prom-mysql-gvr ClusterIP None 3306/TCP 3m36s coreos-prom-mysql-stats ClusterIP 10.106.236.14 56790/TCP 50s -``` Here, `coreos-prom-mysql-stats` service has been created for monitoring purpose. @@ -191,10 +191,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-mysql-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE kubedb-demo-coreos-prom-mysql 3m16s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of MySQL crd. @@ -249,20 +249,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n default -l=app=prometheus +kubectl get pod -n default -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 121m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n default prometheus-prometheus-0 9090 +kubectl port-forward -n default prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-mysql-stats` service as one of the targets. diff --git a/docs/guides/mysql/pitr/restic/archiver.md b/docs/guides/mysql/pitr/restic/archiver.md index bb003d375c..1a5fbeba8d 100644 --- a/docs/guides/mysql/pitr/restic/archiver.md +++ b/docs/guides/mysql/pitr/restic/archiver.md @@ -29,9 +29,9 @@ To install the `KubeStash` operator in your cluster, follow the steps outlined [ To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/pitr/restic/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Continuous Archiving @@ -62,10 +62,10 @@ spec: ``` Note: Before applying this yaml, verify that a bucket named `mysql-archiver` is already created on your bucket provider. -```bash - $ kubectl apply -f backupstorage.yaml + ```bash + kubectl apply -f backupstorage.yaml + ``` backupstorage.storage.kubestash.com/storage created -``` ### secrets for backup-storage ```yaml @@ -81,10 +81,10 @@ stringData: AWS_ENDPOINT: s3.amazonaws.com ``` -```bash - $ kubectl apply -f storage-secret.yaml + ```bash + kubectl apply -f storage-secret.yaml + ``` secret/s3-secret created -``` ### Retention policy RetentionPolicy is a CR provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -103,9 +103,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/retention-policy.yaml -retentionpolicy.storage.kubestash.com/mysql-retention-policy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/retention-policy.yaml ``` +retentionpolicy.storage.kubestash.com/mysql-retention-policy created ### MySQLArchiver MySQLArchiver is a CR provided by KubeDB for managing the archiving of MySQL binlog files and performing physical backups. @@ -170,13 +170,15 @@ stringData: RESTIC_PASSWORD: "changeit" ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/encryptionSecret.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/encryptionSecret.yaml + ``` secret/encrypt-secret created - - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysqlarchiver.yaml + + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysqlarchiver.yaml + ``` mysqlarchiver.archiver.kubedb.com/mysqlarchiver-sample created -``` # Deploy MySQL We are now ready with the setup for continuous MySQL archiving. We will deploy a MySQL object that references the MySQL archiver object. @@ -204,24 +206,24 @@ spec: deletionPolicy: WipeOut ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysql.yaml - mysql.kubedb.com/mysql created + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysql.yaml ``` + mysql.kubedb.com/mysql created ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mysql-0 2/2 Running 0 15m mysql-1 2/2 Running 0 15m mysql-2 2/2 Running 0 15m -``` - Once the MySQL database is ready and backup storage is prepared, the MySQL Archiver object will trigger the KubeDB Operator to create a sidekick pod. Subsequently, the KubeStash Operator will generate a full backup along with a manifest backup. ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mysql-0 2/2 Running 0 15m mysql-1 2/2 Running 0 15m @@ -231,7 +233,6 @@ mysql-archiver-manifest-backup-1733120326-9gw4f 0/1 Comple mysql-sidekick 1/1 Running 0 10m retention-policy-mysql-archiver-full-backup-1733120326-7rx9t 0/1 Completed 0 9m31s retention-policy-mysql-archiver-manifest-backup-1733120326l79mb 0/1 Completed 0 9m56s -``` Here, @@ -248,30 +249,31 @@ Here, ### Validate BackupConfiguration and BackupSession ```bash - -$ kubectl get backupconfigurations -n demo - +kubectl get backupconfigurations -n demo +``` NAME PHASE PAUSED AGE mysql-archiver Ready 14m -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mysql-archiver-full-backup-1733120326 BackupConfiguration mysql-archiver Succeeded 50s 14m mysql-archiver-manifest-backup-1733120326 BackupConfiguration mysql-archiver Succeeded 25s 14m -$ kubectl get repository.storage.kubestash.com -n demo +```bash +kubectl get repository.storage.kubestash.com -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE mysql-full true 1 2.073 KiB Ready 14m 14m mysql-manifest true 1 2.073 KiB Ready 14m 14m -``` - ## Data Insert and Switch Binlog File After each and every binlog switch the binlog files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo mysql-0 -- bash - +kubectl exec -it -n demo mysql-0 -- bash +``` bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql> create database hello; @@ -313,8 +315,6 @@ mysql> select count(*) from demo_table; | 10 | +----------+ -``` - > At this point We have 10 rows in our newly created table `demo_table` on database `hello` ## Point-in-time Recovery @@ -322,13 +322,11 @@ Point-In-Time Recovery allows you to restore a MySQL database to a specific poin Let's say accidentally our db drops the table `demo_table` and we want to restore that. ```bash -$ kubectl exec -it -n demo mysql-0 -- bash - +kubectl exec -it -n demo mysql-0 -- bash +``` mysql> drop table demo_table; mysql> flush logs; - -``` We can't restore from a full backup since at this point no full backup was perform. so we can choose a specific time in which time we want to restore.We can get the specific time from the binlog that archived in the backup storage . Go to the binlog file and find where to store. You can parse binlog-files using `mysqlbinlog`. For the demo I will use the previous time we get from `select now()` @@ -399,38 +397,39 @@ spec: ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysql-restore.yaml - mysql.kubedb.com/restore-mysql created + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/restic/yamls/mysql-restore.yaml ``` + mysql.kubedb.com/restore-mysql created **Check for Restored MySQL** ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` data-restore-mysql-0-pvc-restorer-5vtj7 0/1 Completed 0 7m40s restore-mysql-0 2/2 Running 0 6m40s restore-mysql-1 2/2 Running 0 5m37s restore-mysql-2 2/2 Running 0 5m21s restore-mysql-binlog-restorer-0 0/2 Completed 0 5m58s restore-mysql-manifest-restorer-pzx5z 0/1 Completed 0 6m54s -``` The pod `data-restore-mysql-0-pvc-restorer-5vtj7` is responsible for restoring the base backup. The pod `restore-mysql-binlog-restorer-0` is responsible for restoring the binlog file. ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql.kubedb.com/mysql 8.2.0 Ready 32m mysql.kubedb.com/restore-mysql 8.2.0 Ready 2m53s -``` **Validating Data on Restored MySQL** ```bash -$ kubectl exec -it -n demo restore-mysql-0 -- bash +kubectl exec -it -n demo restore-mysql-0 -- bash +``` bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql> use hello @@ -443,8 +442,6 @@ mysql> select count(*) from demo_table; +----------+ 1 row in set (0.00 sec) -``` - **so we are able to successfully recover from a disaster** @@ -453,11 +450,23 @@ mysql> select count(*) from demo_table; To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo mysql/mysql -$ kubectl delete -n demo mysql/restore-mysql -$ kubectl delete -n demo backupstorage.storage.kubestash.com/storage -$ kubectl delete -n demo mysqlarchiver/mysqlarchiver-sample -$ kubectl delete ns demo +kubectl delete -n demo mysql/mysql +``` + +```bash +kubectl delete -n demo mysql/restore-mysql +``` + +```bash +kubectl delete -n demo backupstorage.storage.kubestash.com/storage +``` + +```bash +kubectl delete -n demo mysqlarchiver/mysqlarchiver-sample +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mysql/pitr/volumesnapshot/archiver.md b/docs/guides/mysql/pitr/volumesnapshot/archiver.md index 467522a588..817778d1c3 100644 --- a/docs/guides/mysql/pitr/volumesnapshot/archiver.md +++ b/docs/guides/mysql/pitr/volumesnapshot/archiver.md @@ -29,9 +29,9 @@ To install `External-snapshotter` in your cluster following the steps [here](ht To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/pitr/volumesnapshot/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Continuous Archiving @@ -63,10 +63,10 @@ spec: Note: Before applying this yaml, verify that a bucket named `mysql-archiver` is already created on your bucket provider. -```bash - $ kubectl apply -f backupstorage.yaml + ```bash + kubectl apply -f backupstorage.yaml + ``` backupstorage.storage.kubestash.com/storage created -``` ### secrets for backup-storage ```yaml @@ -82,10 +82,10 @@ stringData: AWS_ENDPOINT: s3.amazonaws.com ``` -```bash - $ kubectl apply -f storage-secret.yaml + ```bash + kubectl apply -f storage-secret.yaml + ``` secret/s3-secret created -``` ### Retention policy RetentionPolicy is a CR provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -104,9 +104,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/retentionPolicy.yaml -retentionpolicy.storage.kubestash.com/mysql-retention-policy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/retentionPolicy.yaml ``` +retentionpolicy.storage.kubestash.com/mysql-retention-policy created ### MySQLArchiver MySQLArchiver is a CR provided by KubeDB for managing the archiving of MySQL binlog files and performing volume-level backups @@ -170,23 +170,23 @@ stringData: RESTIC_PASSWORD: "changeit" ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/encryptionSecret.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/encryptionSecret.yaml + ``` secret/encrypt-secret created - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/mysqlarchiver.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/pitr/volumesnapshot/yamls/mysqlarchiver.yaml + ``` mysqlarchiver.archiver.kubedb.com/mysqlarchiver-sample created -``` - ## Ensure VolumeSnapshotClass ```bash -$ kubectl get volumesnapshotclasses +kubectl get volumesnapshotclasses +``` NAME DRIVER DELETIONPOLICY AGE longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h - -``` If not any, try using `longhorn` or any other [volumeSnapshotClass](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/). ```yaml kind: VolumeSnapshotClass @@ -201,11 +201,13 @@ parameters: ``` ```bash -$ helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +``` -$ kubectl apply -f volumesnapshotclass.yaml - volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged +```bash +kubectl apply -f volumesnapshotclass.yaml ``` + volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged Note: Ensure that the VolumeSnapshotClass is provisioned with the same storage class driver used for provisioning your MySQL database. In our case, we are using the `longhorn` storageclass as our database provisioner, with the driver set to `driver.longhorn.io`. @@ -241,18 +243,18 @@ spec: ``` ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mysql-0 2/2 Running 0 28h mysql-1 2/2 Running 0 28h mysql-2 2/2 Running 0 28h -``` - Once the MySQL database is ready and backup storage is prepared, the MySQL Archiver object will trigger the KubeDB Operator to create a sidekick pod. Subsequently, the KubeStash Operator will generate a full backup along with a manifest backup. ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mysql-0 2/2 Running 0 28h mysql-1 2/2 Running 0 28h @@ -263,8 +265,6 @@ mysql-sidekick 1/1 Runnin retention-policy-mysql-archiver-full-backup-1733206003-b2b42 0/1 Completed 0 28h retention-policy-mysql-archiver-manifest-backup-1733206003skwqc 0/1 Completed 0 28h -``` - `mysql-sidekick` pod is responsible for uploading binlog files `mysql-backup-config-full-backup-1703680982-vqf7c` is the pod of volumes levels backups for MySQL. @@ -280,13 +280,14 @@ retention-policy-mysql-archiver-manifest-backup-1733206003skwqc 0/1 Comple ### Validate BackupConfiguration and VolumeSnapshots ```bash - -$ kubectl get backupconfigurations -n demo - +kubectl get backupconfigurations -n demo +``` NAME PHASE PAUSED AGE mysql-archiver Ready 2m43s -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE mysql-archiver-full-backup-1733206003 BackupConfiguration mysql-backup-config Succeeded 74s mysql-archiver-manifest-backup-1733206003 BackupConfiguration mysql-backup-config Succeeded 74s @@ -295,18 +296,19 @@ kubectl get volumesnapshots -n demo NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE mysql-1702388096 true data-mysql-1 1Gi longhorn-snapshot-vsc snapcontent-735e97ad-1dfa-4b70-b416-33f7270d792c 2m5s 2m5s -$ kubectl get repository.storage.kubestash.com -n demo +```bash +kubectl get repository.storage.kubestash.com -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE mysql-full true 1 2.073 KiB Ready 2m43s 2m43s mysql-manifest true 1 2.073 KiB Ready 2m43s 2m43s -``` ## Data Insert and Switch Binlog File After each and every binlog switch the binlog files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo mysql-0 -- bash - +kubectl exec -it -n demo mysql-0 -- bash +``` bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql> create database hello; @@ -347,8 +349,6 @@ mysql> select count(*) from demo_table; | 10 | +----------+ -``` - > At this point We have 10 rows in our newly created table `demo_table` on database `hello` ## Point-in-time Recovery @@ -356,13 +356,11 @@ Point-In-Time Recovery allows you to restore a MySQL database to a specific poin Let's say accidentally our db drops the table `demo_table` and we want to restore that. ```bash -$ kubectl exec -it -n demo mysql-0 -- bash - +kubectl exec -it -n demo mysql-0 -- bash +``` mysql> drop table demo_table; mysql> flush logs; - -``` We can't restore from a full backup since at this point no full backup was perform. so we can choose a specific time in which time we want to restore.We can get the specfice time from the binlog that archived in the backup storage . Go to the binlog file and find where to store. You can parse binlog-files using `mysqlbinlog`. @@ -439,33 +437,33 @@ spec: ``` ```bash -$ kubectl apply -f restore.yaml -mysql.kubedb.com/restore-mysql created +kubectl apply -f restore.yaml ``` +mysql.kubedb.com/restore-mysql created **check for Restored MySQL** ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` restore-mysql-0 1/1 Running 0 44s restore-mysql-1 1/1 Running 0 42s restore-mysql-2 1/1 Running 0 41s restore-mysql-restorer-z4brz 0/2 Completed 0 113s restore-mysql-restoresession-lk6jq 0/1 Completed 0 2m6s -``` - ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql 8.2.0 Ready 28h restore-mysql 8.2.0 Ready 5m37s -``` **Validating data on Restored MySQL** ```bash -$ kubectl exec -it -n demo restore-mysql-0 -- bash +kubectl exec -it -n demo restore-mysql-0 -- bash +``` bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql> use hello @@ -478,8 +476,6 @@ mysql> select count(*) from demo_table; +----------+ 1 row in set (0.00 sec) -``` - **so we are able to successfully recover from a disaster** @@ -489,11 +485,23 @@ mysql> select count(*) from demo_table; To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo mysql/mysql -$ kubectl delete -n demo mysql/restore-mysql -$ kubectl delete -n demo backupstorage/storage -$ kubectl delete -n demo mysqlarchiver/mysqlarchiver-sample -$ kubectl delete ns demo +kubectl delete -n demo mysql/mysql +``` + +```bash +kubectl delete -n demo mysql/restore-mysql +``` + +```bash +kubectl delete -n demo backupstorage/storage +``` + +```bash +kubectl delete -n demo mysqlarchiver/mysqlarchiver-sample +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/mysql/private-registry/index.md b/docs/guides/mysql/private-registry/index.md index b8615fc373..50a9158768 100644 --- a/docs/guides/mysql/private-registry/index.md +++ b/docs/guides/mysql/private-registry/index.md @@ -27,7 +27,8 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For mysql, push `DB_IMAGE`, `EXPORTER_IMAGE`, `REPLICATION_MODE_DETECTOR_IMAGE`(only required for Group Replication), `INITCONTAINER_IMAGE` of following MySQLVersions, where `deprecated` is not true, to your private registry. ```bash -$ kubectl get mysqlversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,REPLICATION_MODE_DETECTOR_IMAGE:.spec.replicationModeDetector.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +kubectl get mysqlversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,REPLICATION_MODE_DETECTOR_IMAGE:.spec.replicationModeDetector.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +``` NAME VERSION DB_IMAGE EXPORTER_IMAGE REPLICATION_MODE_DETECTOR_IMAGE INITCONTAINER_IMAGE DEPRECATED 5.7.35-v1 5.7.35 mysql:5.7.35 kubedb/mysqld-exporter:v0.13.1 kubedb/replication-mode-detector:v0.13.0 kubedb/mysql-init:5.7-v2 8.4.8 8.4.8 mysql:8.4.8 kubedb/mysqld-exporter:v0.13.1 kubedb/replication-mode-detector:v0.13.0 kubedb/mysql-init:5.7-v2 @@ -37,8 +38,6 @@ NAME VERSION DB_IMAGE EXPORTER_IMAGE 8.4.8 8.4.8 mysql:8.4.8 kubedb/mysqld-exporter:v0.13.1 kubedb/replication-mode-detector:v0.13.0 kubedb/mysql-init:8.4.8_linux_amd64 8.0.3-v4 8.0.3 mysql:8.0.3 kubedb/mysqld-exporter:v0.13.1 kubedb/replication-mode-detector:v0.13.0 kubedb/mysql-init:8.0.3-v1 -``` - Docker hub repositories: - [kubedb/operator](https://hub.docker.com/r/kubedb/operator) - [kubedb/mysql](https://hub.docker.com/r/kubedb/mysql) @@ -84,9 +83,9 @@ spec: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - ``` ## Create ImagePullSecret @@ -95,13 +94,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -140,17 +139,17 @@ spec: Now run the command to deploy this `MySQL` object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/private-registry/yamls/standalone.yaml -mysql.kubedb.com/mysql-pvt-reg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/private-registry/yamls/standalone.yaml ``` +mysql.kubedb.com/mysql-pvt-reg created To check if the images pulled successfully from the repository, see if the `MySQL` is in running state: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mysql-pvt-reg-0 1/1 Running 0 56s -``` ## Cleaning up diff --git a/docs/guides/mysql/quickstart/index.md b/docs/guides/mysql/quickstart/index.md index 45575a58b6..12feedd7b3 100644 --- a/docs/guides/mysql/quickstart/index.md +++ b/docs/guides/mysql/quickstart/index.md @@ -31,24 +31,25 @@ This tutorial will show you how to use KubeDB to run a MySQL database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available MySQLVersion When you have installed KubeDB, it has created `MySQLVersion` crd for all supported MySQL versions. Check it by using the following command, ```bash -$ kubectl get mysqlversions +kubectl get mysqlversions +``` 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 29h 8.4.8 8.4.8 Official ghcr.io/appscode-images/mysql:8.4.8-oracle 29h 8.0.31-innodb 8.0.31 MySQL ghcr.io/appscode-images/mysql:8.0.31-oracle 29h @@ -60,7 +61,6 @@ $ kubectl get mysqlversions 8.4.3 8.4.3 Official ghcr.io/appscode-images/mysql:8.4.3-oracle 29h 9.0.1 9.0.1 Official ghcr.io/appscode-images/mysql:9.0.1-oracle 29h 8.4.8 8.4.8 Official ghcr.io/appscode-images/mysql:8.4.8-oracle 29h -``` ## Create a MySQL database @@ -88,9 +88,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1.yaml -mysql.kubedb.com/mysql-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1.yaml ``` +mysql.kubedb.com/mysql-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -112,9 +112,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1alpha2.yaml -mysql.kubedb.com/mysql-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1alpha2.yaml ``` +mysql.kubedb.com/mysql-quickstart created Here, @@ -128,7 +128,8 @@ Here, KubeDB operator watches for `MySQL` objects using Kubernetes api. When a `MySQL` object is created, KubeDB operator will create a new PetSet and a Service with the matching MySQL object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. ```bash -$ kubectl dba describe my -n demo mysql-quickstart +kubectl dba describe my -n demo mysql-quickstart +``` Name: mysql-quickstart Namespace: demo CreationTimestamp: Fri, 03 Jun 2022 12:50:40 +0600 @@ -242,18 +243,21 @@ Events: Normal Successful 32s KubeDB Operator Successfully created MySQL Normal Successful 32s KubeDB Operator Successfully created appbinding - - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE mysql-quickstart 1/1 3m19s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-mysql-quickstart-0 Bound pvc-ab44ce95-2300-47d7-8f25-3cd7bc5b0091 1Gi RWO standard 3m50s - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-ab44ce95-2300-47d7-8f25-3cd7bc5b0091 1Gi RWO Delete Bound demo/data-mysql-quickstart-0 standard 4m19s @@ -261,7 +265,6 @@ kubectl get service -n demo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-quickstart ClusterIP 10.96.150.194 3306/TCP 5m13s mysql-quickstart-pods ClusterIP None 3306/TCP 5m13s -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified MySQL object: @@ -350,20 +353,24 @@ If you want to use an existing secret please specify that when creating the MySQ Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `mysql-quickstart-auth` secret holds username and password ```bash -$ kubectl get pods mysql-quickstart-0 -n demo -o yaml | grep podIP +kubectl get pods mysql-quickstart-0 -n demo -o yaml | grep podIP +``` podIP: 10.244.0.30 -$ kubectl get secrets -n demo mysql-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +```bash +kubectl get secrets -n demo mysql-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -H(Y.s)pg&cX1Ds3J +```bash +kubectl get secrets -n demo mysql-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +H(Y.s)pg&cX1Ds3J we will exec into the pod `mysql-quickstart-0` and connect to the database using username and password ```bash -$ kubectl exec -it -n demo mysql-quickstart-0 -- bash - +kubectl exec -it -n demo mysql-quickstart-0 -- bash +``` root@mysql-quickstart-0:/# mysql -uroot -p"H(Y.s)pg&cX1Ds3J" Welcome to the MySQL monitor. Commands end with ; or \g. @@ -383,8 +390,6 @@ mysql> show databases; | sys | +--------------------+ 5 rows in set (0.00 sec) - -``` you can also connect with database management tools like [phpmyadmin](https://hub.docker.com/_/phpmyadmin), [dbgate](https://hub.docker.com/r/dbgate/dbgate). __connecting with `phpmyadmin`__ @@ -392,32 +397,35 @@ __connecting with `phpmyadmin`__ lets create a deployment of `phpmyadmin` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/phpmyadmin.yaml - +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/phpmyadmin.yaml +``` deployment/myadmin created service/myadmin created -$ kubectl get pods -n demo --watch +```bash +kubectl get pods -n demo --watch +``` NAME READY STATUS RESTARTS AGE myadmin-85d86cf5b5-f4mq4 1/1 Running 0 8s mysql-quickstart-0 1/1 Running 0 12m - -$ kubectl get svc -n demo +```bash +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE myadmin LoadBalancer 10.96.108.199 80:32634/TCP 51s mysql-quickstart ClusterIP 10.96.150.194 3306/TCP 13m mysql-quickstart-pods ClusterIP None 3306/TCP 13m - - -``` Lets, open your browser and go to the following URL: _http://{node-ip}:{myadmin-svc-nodeport}_. For kind cluster, you can get this URL by running the following command: ```bash -$ kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +kubectl get svc -n demo myadmin -o json | jq '.spec.ports[].nodePort' +``` 30158 -$ kubectl get node -o json | jq '.items[].status.addresses[].address' +```bash +kubectl get node -o json | jq '.items[].status.addresses[].address' +``` "172.18.0.3" "kind-control-plane" "172.18.0.4" @@ -427,7 +435,6 @@ $ kubectl get node -o json | jq '.items[].status.addresses[].address' # expected url will be: url: http://172.18.0.4:30158 -``` According to this example, the URL will be [ http://172.18.0.4:30158]( http://172.18.0.4:30158).You can also use the external-ip of the service.Also port forward your service to connect. @@ -439,34 +446,38 @@ __connecting with `dbgate`__ ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/dbgate.yaml - +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/dbgate.yaml +``` deployment/dbgate created service/dbgate created -$ kubectl get pods -n demo --watch +```bash +kubectl get pods -n demo --watch +``` NAME READY STATUS RESTARTS AGE demo dbgate-77d7fd4889-bfhb9 1/1 Running 0 17m -85d86cf5b5-f4mq4 1/1 Running 0 8s mysql-quickstart-0 1/1 Running 0 12m - -$ kubectl get svc -n demo +```bash +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dbgate LoadBalancer 10.96.226.216 3000:32475/TCP 51s mysql-quickstart ClusterIP 10.96.150.194 3306/TCP 13m mysql-quickstart-pods ClusterIP None 3306/TCP 13m -``` - Lets, open your browser and go to the following URL: _http://{node-ip}:{dbgate-svc-nodeport}_. For kind cluster, you can get this URL by running the following command: ```bash -$ kubectl get svc -n demo dbgate -o json | jq '.spec.ports[].nodePort' +kubectl get svc -n demo dbgate -o json | jq '.spec.ports[].nodePort' +``` 32475 -$ kubectl get node -o json | jq '.items[].status.addresses[].address' +```bash +kubectl get node -o json | jq '.items[].status.addresses[].address' +``` "172.18.0.3" "kind-control-plane" "172.18.0.4" @@ -476,7 +487,6 @@ $ kubectl get node -o json | jq '.items[].status.addresses[].address' # expected url will be: url: http://172.18.0.4:32475 -``` According to this example, the URL will be [ http://172.18.0.4:30158]( http://172.18.0.4:30158).You can also use the external-ip of the service.Also port forward your service to connect. You can connect multiple different database using db gate. To log into MySQL select the MYSQL driver and use server __`mysql-quickstart.demo`__ or __`10.244.0.30`__ , username __`root`__ and password __`H(Y.s)pg&cX1Ds3J`__. @@ -490,9 +500,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete my mysql-quickstart -n demo -Error from server (BadRequest): admission webhook "mysql.validators.kubedb.com" denied the request: mysql "mysql-quickstart" can't be halted. To delete, change spec.deletionPolicy +kubectl delete my mysql-quickstart -n demo ``` +Error from server (BadRequest): admission webhook "mysql.validators.kubedb.com" denied the request: mysql "mysql-quickstart" can't be halted. To delete, change spec.deletionPolicy Now, run `kubectl edit my mysql-quickstart -n demo` to set `spec.deletionPolicy` to `Halt` (which deletes the mysql object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -507,21 +517,21 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele At first, run `kubectl edit my mysql-quickstart -n demo` to set `spec.deletionPolicy` to `Halt`. Then delete the mysql object, ```bash -$ kubectl delete my mysql-quickstart -n demo -mysql.kubedb.com "mysql-quickstart" deleted +kubectl delete my mysql-quickstart -n demo ``` +mysql.kubedb.com "mysql-quickstart" deleted Now, run the following command to get all mysql resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/default-token-lgbjm kubernetes.io/service-account-token 3 23h secret/mysql-quickstart-auth Opaque 2 20h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-mysql-quickstart-0 Bound pvc-716f627c-9aa2-47b6-aa64-a547aab6f55c 1Gi RWO standard 20h -``` From the above output, you can see that all mysql resources(`PetSet`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your mysql again using this resources. @@ -536,18 +546,18 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete my mysql-quickstart -n demo -mysql.kubedb.com "mysql-quickstart" deleted +kubectl delete my mysql-quickstart -n demo ``` +mysql.kubedb.com "mysql-quickstart" deleted Now, run the following command to get all mysql resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/default-token-lgbjm kubernetes.io/service-account-token 3 24h secret/mysql-quickstart-auth Opaque -``` From the above output, you can see that all mysql resources(`PetSet`, `Service`, `PVCs` etc.) are deleted except `Secret`. You can initialize your mysql using `snapshots`(if previously taken) and `secret`. @@ -567,9 +577,9 @@ mysql.kubedb.com "mysql-quickstart" deleted Now, run the following command to get all mysql resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo -No resources found in demo namespace. +kubectl get petset,svc,secret,pvc -n demo ``` +No resources found in demo namespace. From the above output, you can see that all mysql resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. @@ -584,7 +594,8 @@ Suppose we have a database running `mysql-quickstart` in our cluster. Now, we ar Run the following command to get MySQL resources, ```bash -$ kubectl get my,petset,secret,svc,pvc -n demo +kubectl get my,petset,secret,svc,pvc -n demo +``` NAME VERSION STATUS AGE mysql.kubedb.com/mysql-quickstart 8.4.8 Halted 22m @@ -594,7 +605,6 @@ secret/mysql-quickstart-auth Opaque 2 22m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-mysql-quickstart-0 Bound pvc-7ab0ebb0-bb2e-45c1-9af1-4f175672605b 1Gi RWO standard 22m -``` From the above output , you can see that `MySQL` object, `PVCs`, `Secret` are still alive. Then you can recreate your `MySQL` with same configuration. diff --git a/docs/guides/mysql/reconfigure-tls/reconfigure/index.md b/docs/guides/mysql/reconfigure-tls/reconfigure/index.md index 991e8a8e2c..88d1580ea6 100644 --- a/docs/guides/mysql/reconfigure-tls/reconfigure/index.md +++ b/docs/guides/mysql/reconfigure-tls/reconfigure/index.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/reconfigure-tls/reconfigure/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -88,9 +88,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/group-replication.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/group-replication.yaml ``` +mysql.kubedb.com/mysql created @@ -123,9 +123,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/innodb-cluster.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/innodb-cluster.yaml ``` +mysql.kubedb.com/mysql created @@ -160,9 +160,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/semi-sync.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/semi-sync.yaml ``` +mysql.kubedb.com/mysql created @@ -192,9 +192,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/standalone.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/standalone.yaml ``` +mysql.kubedb.com/mysql created @@ -204,11 +204,14 @@ mysql.kubedb.com/mysql created Now, wait until `mysql` has status `Ready`. i.e, ```bash -$ kubectl get my -n demo +kubectl get my -n demo +``` NAME VERSION STATUS AGE mysql 8.4.8 Ready 75s -$ kubectl dba describe mysql mysql -n demo +```bash +kubectl dba describe mysql mysql -n demo +``` Name: mysql Namespace: demo CreationTimestamp: Mon, 21 Nov 2022 16:18:44 +0600 @@ -323,19 +326,22 @@ Events: Normal Successful 1m KubeDB Operator Successfully created appbinding Normal Phase Changed 25s KubeDB Operator phase changed from Provisioning to Ready reason: -``` - Now, we can connect to this database through `mysql-shell` and verify that the TLS is disabled. ```bash -$ kubectl get secrets -n demo mysql-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mysql-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo mysql-auth -o jsonpath='{.data.password}' | base64 -d +``` f8EyKG)mNMIMdS~a -$ kubectl exec -it mysql-0 -n demo -- mysql -u root --password='f8EyKG)mNMIMdS~a' --host=mysql-0.mysql-pods.demo -e "show variables like '%require_secure_transport%';"; +```bash +kubectl exec -it mysql-0 -n demo -- mysql -u root --password='f8EyKG)mNMIMdS~a' --host=mysql-0.mysql-pods.demo -e "show variables like '%require_secure_transport%';"; +``` Defaulted container "mysql" out of: mysql, mysql-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. +--------------------------+-------+ @@ -370,9 +376,6 @@ Uptime: 11 min 44 sec Threads: 2 Questions: 454 Slow queries: 0 Opens: 185 Flush tables: 3 Open tables: 104 Queries per second avg: 0.644 - -``` - We can verify from the above output that TLS is disabled for this database. ### Create Issuer/ ClusterIssuer @@ -382,23 +385,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 my-ca \ +kubectl create secret tls my-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/my-ca created ``` +secret/my-ca created Now, Let's create an `Issuer` using the `my-ca` secret that we have just created. The `YAML` file looks like this: @@ -416,9 +419,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/issuer.yaml -issuer.cert-manager.io/my-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/issuer.yaml ``` +issuer.cert-manager.io/my-issuer created ### Create MySQLOpsRequest @@ -459,24 +462,25 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-add-tls.yaml -mysqlopsrequest.ops.kubedb.com/myops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-add-tls.yaml ``` +mysqlopsrequest.ops.kubedb.com/myops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CRO, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE myops-add-tls ReconfigureTLS Successful 91s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-add-tls +kubectl describe mysqlopsrequest -n demo myops-add-tls +``` Name: myops-add-tls Namespace: demo Labels: @@ -585,8 +589,6 @@ Events: Normal Successful 16m KubeDB Enterprise Operator Successfully resumed MySQL database: demo/mysql Normal Successful 16m KubeDB Enterprise Operator Controller has Successfully Reconfigured TLS -``` - All tls-secret are created by KubeDB ops-manager operator. Default tls-secret name formed as {mysql-object-name}-{cert-alias}-cert. NAME TYPE DATA AGE my-ca kubernetes.io/tls 2 22m @@ -663,10 +665,10 @@ mysql> show variables like '%require_secure_transport%'; Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it mysql-0 -n demo -- bash +kubectl exec -it mysql-0 -n demo -- bash +``` bash-4.4# openssl x509 -in /etc/mysql/certs/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 20 04:09:37 2023 GM -``` So, the certificate will expire on this time `Feb 20 04:09:37 2023 GMT`. @@ -697,25 +699,26 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-rotate.yaml -mysqlopsrequest.ops.kubedb.com/myops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-rotate.yaml ``` +mysqlopsrequest.ops.kubedb.com/myops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CRO, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` Every 2.0s: kubectl get mysqlopsrequest -n demo NAME TYPE STATUS AGE myops-rotate ReconfigureTLS Successful 112s -``` We can see from the above output that the `MysqlOpsRequest` has succeeded. If we describe the `MysqlOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-rotate +kubectl describe mysqlopsrequest -n demo myops-rotate +``` Name: myops-rotate Namespace: demo Labels: @@ -813,17 +816,14 @@ Events: Normal Successful 17s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/mysql Normal Successful 17s KubeDB Enterprise Operator Controller has Successfully Reconfigured TLS -``` - Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it mysql-0 -n demo bash +kubectl exec -it mysql-0 -n demo bash +``` openssl x509 -in /etc/mysql/certs/client.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 20 04:40:08 2023 GMT -``` - As we can see from the above output, the certificate has been rotated successfully. ## Change Issuer/ClusterIssuer @@ -833,23 +833,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 mysql-new-ca \ +kubectl create secret tls mysql-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/mysql-new-ca created ``` +secret/mysql-new-ca created Now, Let's create a new `Issuer` using the `mysql-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -867,9 +867,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/new-issuer.yaml -issuer.cert-manager.io/my-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/new-issuer.yaml ``` +issuer.cert-manager.io/my-new-issuer created ### Create MySQLOpsRequest @@ -901,25 +901,26 @@ Here, Let's create the `MysqlOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-change-issuer.yaml -mysqlopsrequest.ops.kubedb.com/mops-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-change-issuer.yaml ``` +mysqlopsrequest.ops.kubedb.com/mops-change-issuer created #### Verify Issuer is changed successfully Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CRO, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` Every 2.0s: kubectl get mongodbopsrequest -n demo NAME TYPE STATUS AGE myops-change-issuer ReconfigureTLS Successful 87s -``` We can see from the above output that the `MysqlOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-change-issuer +kubectl describe mysqlopsrequest -n demo myops-change-issuer +``` Name: myops-change-issuer Namespace: demo Labels: @@ -1020,15 +1021,13 @@ Events: Normal Successful 108s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/mysql Normal Successful 108s KubeDB Enterprise Operator Controller has Successfully Reconfigured TLS -``` - Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ `kubectl exec -it mysql-0 -n demo -- bash` +`kubectl exec -it mysql-0 -n demo -- bash` +``` root@mgo-rs-tls-2:/$ openssl x509 -in /etc/mysql/certs/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -1063,25 +1062,26 @@ Here, Let's create the `mysqlOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-remove.yaml -mysqlopsrequest.ops.kubedb.com/mops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure-tls/reconfigure/yamls/myops-remove.yaml ``` +mysqlopsrequest.ops.kubedb.com/mops-remove created #### Verify TLS Removed Successfully Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CRO, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` Every 2.0s: kubectl get mysql opsrequest -n demo NAME TYPE STATUS AGE myops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-remove +kubectl describe mysqlopsrequest -n demo myops-remove +``` Name: myops-remove Namespace: demo Labels: @@ -1172,13 +1172,11 @@ Events: Normal Successful 55s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/mysql Normal Successful 55s KubeDB Enterprise Operator Controller has Successfully Reconfigured TLS -``` - Now, Let's exec into the database primary node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo mysql-0 -- mysql -u root -p 'f8EyKG)mNMIMdS~a' - +kubectl exec -it -n demo mysql-0 -- mysql -u root -p 'f8EyKG)mNMIMdS~a' +``` mysql> show variables like '%require_secure_transport%'; +--------------------------+-------+ | Variable_name | Value | @@ -1186,8 +1184,6 @@ mysql> show variables like '%require_secure_transport%'; | require_secure_transport | OFF | +--------------------------+-------+ -``` - So, we can see from the above that, output that tls is disabled successfully. ## Cleaning up diff --git a/docs/guides/mysql/reconfigure/reconfigure-steps/index.md b/docs/guides/mysql/reconfigure/reconfigure-steps/index.md index 90f650ca37..6430320eb0 100644 --- a/docs/guides/mysql/reconfigure/reconfigure-steps/index.md +++ b/docs/guides/mysql/reconfigure/reconfigure-steps/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `MySQL` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `MySQLOpsRequest` to reconfigure its configuration. @@ -56,9 +56,9 @@ Here, `max_connections` is set to `200`, whereas the default value is `151`. Lik Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo my-configuration --from-file=./my-config.cnf -secret/my-configuration created +kubectl create secret generic -n demo my-configuration --from-file=./my-config.cnf ``` +secret/my-configuration created In this section, we are going to create a MySQL object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `MySQL` CR that we are going to create, @@ -111,9 +111,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/group-replication.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/group-replication.yaml ``` +mysql.kubedb.com/sample-mysql created @@ -149,9 +149,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/inndob-cluster.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/inndob-cluster.yaml ``` +mysql.kubedb.com/sample-mysql created @@ -188,9 +188,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/semi-sync.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/semi-sync.yaml ``` +mysql.kubedb.com/sample-mysql created @@ -221,9 +221,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/stand-alone.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/stand-alone.yaml ``` +mysql.kubedb.com/sample-mysql created @@ -232,27 +232,30 @@ mysql.kubedb.com/sample-mysql created Now, wait until `sample-mysql` has status `Ready`. i.e, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.4.8 Ready 5m49s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a mysql instance, ```bash -$ kubectl get secrets -n demo sample-mysql-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-mysql-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-mysql-auth -o jsonpath='{.data.password}' | base64 -d -86TwLJ!2Kpq*vv1y +```bash +kubectl get secrets -n demo sample-mysql-auth -o jsonpath='{.data.password}' | base64 -d ``` +86TwLJ!2Kpq*vv1y Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- bash +kubectl exec -it -n demo sample-mysql-0 -- bash +``` mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -285,8 +288,6 @@ mysql> show variables like 'read_buffer_size'; mysql> -``` - As we can see from the configuration of ready mysql, the value of `max_connections` has been set to `200` and `read_buffer_size` has been set to `1048576`. ### Reconfigure using new config secret @@ -305,9 +306,9 @@ read_buffer_size = 122880 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-my-configuration --from-file=./new-my-config.cnf -secret/new-my-configuration created +kubectl create secret generic -n demo new-my-configuration --from-file=./new-my-config.cnf ``` +secret/new-my-configuration created #### Create MySQLOpsRequest @@ -337,9 +338,9 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/reconfigure-using-secret.yaml -mysqlopsrequest.ops.kubedb.com/myops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/reconfigure-using-secret.yaml ``` +mysqlopsrequest.ops.kubedb.com/myops-reconfigure-config created #### Verify the new configuration is working @@ -348,15 +349,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CR, ```bash -$ kubectl get mysqlopsrequest --all-namespaces +kubectl get mysqlopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo myops-reconfigure-config Reconfigure Successful 3m8s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe mysqlopsrequest -n demo myops-reconfigure-config +kubectl describe mysqlopsrequest -n demo myops-reconfigure-config +``` Name: myops-reconfigure-config Namespace: demo Labels: @@ -445,13 +447,11 @@ Events: Normal Successful 27m KubeDB Enterprise Operator Successfully resumed MySQL database: demo/sample-mysql Normal Successful 27m KubeDB Enterprise Operator Controller has Successfully reconfigure the of MySQL: demo/sample-mysql -``` - Now let's connect to a mysql instance and run a mysql internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- bash - +kubectl exec -it -n demo sample-mysql-0 -- bash +``` bash-4.4# mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -487,8 +487,6 @@ mysql> show variables like 'read_buffer_size'; mysql> -``` - As we can see from the configuration has changed, the value of `max_connections` has been changed from `200` to `250` and and the `read_buffer_size` has been changed `1048576` to `122880`. So the reconfiguration of the database is successful. ### Remove Custom Configuration @@ -522,9 +520,9 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/reconfigure-remove.yaml -mysqlopsrequest.ops.kubedb.com/myops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/reconfigure/reconfigure-steps/yamls/reconfigure-remove.yaml ``` +mysqlopsrequest.ops.kubedb.com/myops-reconfigure-remove created #### Verify the new configuration is working @@ -533,15 +531,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CR, ```bash -$ kubectl get mysqlopsrequest --all-namespaces +kubectl get mysqlopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo myops-reconfigure-remove Reconfigure Successful 2m1s -``` Now let's connect to a mysql instance and run a mysql internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-mysql-0 -- bash +kubectl exec -it -n demo sample-mysql-0 -- bash +``` bash-4.4# mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -576,8 +575,6 @@ mysql> show variables like 'read_buffer_size'; mysql> -``` - As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `MySQLOpsRequest` is successful. ## Cleaning Up @@ -585,7 +582,13 @@ As we can see from the configuration has changed to its default value. So remova To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mysql -n demo sample-mysql -$ kubectl delete mysqlopsrequest -n demo myops-reconfigure-config myops-reconfigure-remove -$ kubectl delete ns demo +kubectl delete mysql -n demo sample-mysql +``` + +```bash +kubectl delete mysqlopsrequest -n demo myops-reconfigure-config myops-reconfigure-remove +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mysql/replication-mode-transform/replication-mode-transform/index.md b/docs/guides/mysql/replication-mode-transform/replication-mode-transform/index.md index 42b6b51ad0..1ccae5d101 100644 --- a/docs/guides/mysql/replication-mode-transform/replication-mode-transform/index.md +++ b/docs/guides/mysql/replication-mode-transform/replication-mode-transform/index.md @@ -31,10 +31,10 @@ At first, we need to provision a MySQL Remote Replica from a KubeDB managed mysq - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/mysql/clustering/remote-replica/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/clustering/group-replication/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ### Remote Replica @@ -101,10 +101,10 @@ metadata: namespace: demo type: kubernetes.io/basic-auth ``` -```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-singapore-auth.yaml -secret/mysql-singapore-auth created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-singapore-auth.yaml ``` +secret/mysql-singapore-auth created ### Deploy MySQL with TLS/SSL configuration ```yaml @@ -148,29 +148,31 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-singapore.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-singapore.yaml ``` +mysql.kubedb.com/mysql created KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-singapore 8.4.8 Ready 22h -``` ### Connect with MySQL database Now, you can connect to this database from your terminal using the `mysql` user and password. ```bash -$ kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.password}' | base64 -d -pass +```bash +kubectl get secrets -n demo mysql-singapore-auth -o jsonpath='{.data.password}' | base64 -d ``` +pass The operator creates a Group Replication MySQL server for the newly created `MySQL` object. @@ -182,35 +184,43 @@ Now you can connect to the database using the above info. Ignore the warning mes Let's insert some data to the newly created mysql server . we can use the primary service or governing service to connect with the database > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # create a database on primary -$ kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE DATABASE playground;" +```bash +kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE DATABASE playground;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # create a table -$ kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +```bash +kubectl exec -it -n demo mysql-singapore-0 -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));" +``` mysql: [Warning] Using a password on the command line interface can be insecure. - # insert a row -$ kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +```bash + kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "INSERT INTO playground.equipment (type, quant, color) VALUES ('slide', 2, 'blue');" +``` mysql: [Warning] Using a password on the command line interface can be insecure. # read from primary -$ kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo mysql-singapore-0 -c mysql -- mysql -u root --password='pass' --host=mysql-singapore-0.mysql-singapore-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ### Exposing to outside world For Now we will expose our mysql with ingress with to outside world ```bash -$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx -$ helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +``` + +```bash +helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ --namespace demo --create-namespace \ --set tcp.3306="demo/mysql-singapore:3306" ``` @@ -236,20 +246,23 @@ spec: pathType: Prefix ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-ingress.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-ingress.yaml +``` ingress.networking.k8s.io/mysql-singapore created -$ kubectl get ingress -n demo + +```bash +kubectl get ingress -n demo +``` NAME CLASS HOSTS ADDRESS PORTS AGE mysql-singapore nginx mysql-singapore.something.org 172.104.37.147 80 22h -``` Now will be able to communicate from another cluster to our source database ### Prepare for Remote Replica We will use the [KubeDB kubectl Plugin](/docs/setup/README.md) for generating configuration for remote replica. It will create the appbinding and and necessary secrets to connect with source server ```bash -$ kubectl dba remote-config mysql -n demo mysql-singapore -uremote -ppass -d 172.104.37.147 -y -home/user/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml +kubectl dba remote-config mysql -n demo mysql-singapore -uremote -ppass -d 172.104.37.147 -y ``` +home/user/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml ### Create Remote Replica We have prepared another cluster in london region for replicating across cluster. follow the installation instruction [above](/docs/README.md). @@ -258,16 +271,17 @@ We have prepared another cluster in london region for replicating across cluster We will apply the generated config from kubeDB plugin to create the source refs and secrets for it ```bash -$ kubectl apply -f /home/user/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml - +kubectl apply -f /home/user/go/src/kubedb.dev/yamls/mysql/mysql-singapore-remote-config.yaml +``` secret/mysql-singapore-remote-replica-auth created secret/mysql-singapore-client-cert-remote created appbinding.appcatalog.appscode.com/mysql-singapore created -$ kubectl get appbinding -n demo +```bash +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE mysql-singapore kubedb.com/mysql 8.4.8 4m17s -``` ### Create remote replica auth We will need to use the same auth secrets for remote replicas as well since operations like clone also replicated the auth-secrets from source server @@ -327,24 +341,25 @@ Here, - `spec.topology.remoteReplica.sourceref` we are referring to source to read. The mysql instance we previously created. - `spec.deletionPolicy` specifies what KubeDB should do when a user try to delete the operation of MySQL CR. *Wipeout* means that the database will be deleted without restrictions. It can also be "Halt", "Delete" and "DoNotTerminate". Learn More about these [HERE](https://kubedb.com/docs/latest/guides/mysql/concepts/database/#specdeletionpolicy). ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-london.yaml -mysql.kubedb.com/mysql-london created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/examples/mysql-london.yaml ``` +mysql.kubedb.com/mysql-london created Now we will be able to see kubedb will provision a Remote Replica from the source mysql instance. Lets checkout out the petSet , pvc , pv and services associated with it . KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified `MySQL` object: ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-london 8.4.8 Ready 7m17s -``` ### Validate Remote Replica Since both source and replica database are in the ready state. we can validate Remote Replica is working properly by checking the replication status ```bash -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "show slave status\G" +``` mysql: [Warning] Using a password on the command line interface can be insecure. *************************** 1. row *************************** Slave_IO_State: Waiting for source to send event @@ -360,20 +375,19 @@ mysql: [Warning] Using a password on the command line interface can be insecure. Slave_IO_Running: Yes Slave_SQL_Running: Yes .... -``` ### Read Data In the previous step we have inserted into the primary pod. In the next step we will read from secondary pods to determine whether the data has been successfully copied to the secondary pods. -```bash # read from secondary-1 -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "SELECT * FROM playground.equipment;" +```bash +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' --host=mysql-london-0.mysql-london-pods.demo -e "SELECT * FROM playground.equipment;" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +----+-------+-------+-------+ | id | type | quant | color | +----+-------+-------+-------+ | 1 | slide | 2 | blue | +----+-------+-------+-------+ -``` ### Replication Mode Transform If primary cluster goes down or, you want to transform remote replica to group replication you can apply replication transform ops-request. @@ -422,9 +436,9 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/mode-transform-ops-request.yaml -mysqlopsrequest.ops.kubedb.com/mysql-replication-mode-transform created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/replication-mode-transform/replication-mode-transform/mode-transform-ops-request.yaml ``` +mysqlopsrequest.ops.kubedb.com/mysql-replication-mode-transform created #### Verify MySQL Replication Transform Mode successfully @@ -433,17 +447,22 @@ If everything goes well, `KubeDB` ops-request operator will transform replicatio Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CR, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE mysql-replication-mode-transform ReplicationModeTransformation Successful 34m -$ kubectl get pod -n demo +```bash +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE mysql-london-0 2/2 Running 0 35m mysql-london-1 2/2 Running 0 34m mysql-london-2 2/2 Running 0 34m -$ kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' +```bash +kubectl exec -it -n demo mysql-london-0 -c mysql -- mysql -u root --password='pass' +``` mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 630 @@ -467,8 +486,6 @@ mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------------------------------------+-------------+--------------+-------------+----------------+----------------------------+ 3 rows in set (0.00 sec) -``` - We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed to transform replication mode of the database. ### Cleaning up diff --git a/docs/guides/mysql/restart/restart.md b/docs/guides/mysql/restart/restart.md index 3fb96c320f..1c6b640bd7 100644 --- a/docs/guides/mysql/restart/restart.md +++ b/docs/guides/mysql/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the MySQL database via a `MySQLOpsRequest`. Restartin - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo + ```bash + kubectl create ns demo + ``` namespace/demo created -``` > Note: YAML files used in this tutorial are stored in [docs/examples/mysql](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mysql) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -59,9 +59,9 @@ spec: Let's create the `mysql` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/restart/mysql.yaml -mysql.kubedb.com/mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/restart/mysql.yaml ``` +mysql.kubedb.com/mysql created ## Apply Restart opsRequest @@ -87,9 +87,9 @@ spec: Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/restart/restart.yaml -MySQLOpsRequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/restart/restart.yaml ``` +MySQLOpsRequest.ops.kubedb.com/restart created In MySQL, pods follow a `primary-standby` architecture: - `Standby` pods are restarted **first**, one by one. @@ -97,12 +97,15 @@ In MySQL, pods follow a `primary-standby` architecture: - During the primary pod restart, one of the standby pods is automatically promoted to primary to ensure continuous availability. Now, let's see the status of the `MySQLOpsRequest` we just created. -```shell -$ kubectl get myops -n demo +```bash +kubectl get myops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 64m -$ kubectl get myops -n demo restart -oyaml +```bash +kubectl get myops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: MySQLOpsRequest metadata: @@ -164,8 +167,6 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning up diff --git a/docs/guides/mysql/rotate-auth/guide.md b/docs/guides/mysql/rotate-auth/guide.md index 72da4d868f..d3618f9f6d 100644 --- a/docs/guides/mysql/rotate-auth/guide.md +++ b/docs/guides/mysql/rotate-auth/guide.md @@ -31,24 +31,25 @@ updates the existing secret with the new credential. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available MySQLVersion When you have installed KubeDB, it has created `MySQLVersion` crd for all supported MySQL versions. Check it by using the following command, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -64,7 +65,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` ## Create a Mysql Database @@ -91,15 +91,15 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1.yaml -mysql.kubedb.com/mysql-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/quickstart/yamls/quickstart-v1.yaml ``` +mysql.kubedb.com/mysql-quickstart created Let's wait for `MySQL` status is `Ready`. Run the following command to watch `MySQL` CRO -```shell -$ kubectl get mysql -n demo -w +```bash +kubectl get mysql -n demo -w +``` NAME VERSION STATUS AGE mysql-quickstart 9.6.0 Ready 30m -``` ## Verify Authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an @@ -115,8 +115,8 @@ H04(Wn6AM_4r6)(k⏎ ```` Now, you can exec into the pod `mysql-quickstart-0` and connect to database using `username` and `password` ```bash -$ kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash - + kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p"H04(Wn6AM_4r6)(k" mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -143,8 +143,6 @@ mysql> SHOW DATABASES; +--------------------+ 5 rows in set (0.01 sec) -``` - If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth MySQLOpsRequest @@ -172,19 +170,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on MySQL. Let's create the `MySQLOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/rotate-auth/rotate-auth-generated.yaml + ``` MySQLOpsRequest.ops.kubedb.com/myops-rotate-auth-generated created -``` Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CRO -```shell - $ kubectl get mysqlopsrequest -n demo + ```bash + kubectl get mysqlopsrequest -n demo + ``` NAME TYPE STATUS AGE myops-rotate-auth-generated RotateAuth Successful 82s -``` If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe mysqlopsrequest -n demo myops-rotate-auth-generated +```bash +kubectl describe mysqlopsrequest -n demo myops-rotate-auth-generated +``` Name: myops-rotate-auth-generated Namespace: demo Labels: @@ -266,22 +265,26 @@ Events: Normal Starting 26m KubeDB Ops-manager Operator Resuming MySQL database: demo/mysql-quickstart Normal Successful 26m KubeDB Ops-manager Operator Successfully resumed MySQL database: demo/mysql-quickstart Normal Successful 26m KubeDB Ops-manager Operator Controller has successfully rotate MySQL auth secret - -``` **Verify Auth is rotated** -```shell -$ kubectl get mysql -n demo mysql-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get mysql -n demo mysql-quickstart -ojson | jq .spec.authSecret.name +``` "mysql-quickstart-auth" -$ kubectl get secret -n demo mysql-quickstart-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo mysql-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mysql-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -vYBjULhCEzPwe5xo⏎ + +```bash +kubectl get secret -n demo mysql-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +vYBjULhCEzPwe5xo⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash - +```bash +kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p"vYBjULhCEzPwe5xo" mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -308,16 +311,17 @@ mysql> SHOW DATABASES; +--------------------+ 5 rows in set (0.00 sec) -``` - Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo mysql-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo mysql-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mysql-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -H04(Wn6AM_4r6)(k⏎ + +```bash +kubectl get secret -n demo mysql-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +H04(Wn6AM_4r6)(k⏎ Let's confirm that the previous credentials no longer work. ```shell kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash @@ -333,13 +337,13 @@ The above output shows that the password has been changed successfully. The prev At first, we need to create a secret with `kubernetes.io/basic-auth` type using custom password. Below is the command to create a secret with `kubernetes.io/basic-auth` type, > Note: The `username` must be fixed as `root`. -```shell -$ kubectl create secret generic mysql-quickstart-auth-user -n demo \ +```bash +kubectl create secret generic mysql-quickstart-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=root \ --from-literal=password=Mysql2 -secret/mysql-quickstart-auth-user created ``` +secret/mysql-quickstart-auth-user created Now create a `MySQLOpsRequest` with `RotateAuth` type. Below is the YAML of the `MySQLOpsRequest` that we are going to create, ```shell @@ -368,21 +372,22 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/rotate-auth/rotate-auth-user.yaml -MySQLOpsRequest.ops.kubedb.com/myops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/mysql/rotate-auth/rotate-auth-user.yaml ``` +MySQLOpsRequest.ops.kubedb.com/myops-rotate-auth-user created Let’s wait for `MySQLOpsRequest` to be Successful. Run the following command to watch `MySQLOpsRequest` CRO: -```shell -$ kubectl get mysqlopsrequest -n demo +```bash +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE myops-rotate-auth-generated RotateAuth Successful 35m myops-rotate-auth-user RotateAuth Successful 2m18s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe mysqlopsrequest -n demo myops-rotate-auth-user +```bash +kubectl describe mysqlopsrequest -n demo myops-rotate-auth-user +``` Name: myops-rotate-auth-user Namespace: demo Labels: @@ -469,21 +474,26 @@ Events: Normal Starting 2m9s KubeDB Ops-manager Operator Resuming MySQL database: demo/mysql-quickstart Normal Successful 2m9s KubeDB Ops-manager Operator Successfully resumed MySQL database: demo/mysql-quickstart Normal Successful 2m9s KubeDB Ops-manager Operator Controller has successfully rotate MySQL auth secret - -``` **Verify auth is rotate** -```shell -$ kubectl get my -n demo mysql-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get my -n demo mysql-quickstart -ojson | jq .spec.authSecret.name +``` "mysql-quickstart-auth-user" -$ kubectl get secret -n demo mysql-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo mysql-quickstart-auth-user -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mysql-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d -Mysql2⏎ + +```bash +kubectl get secret -n demo mysql-quickstart-auth-user -o=jsonpath='{.data.password}' | base64 -d ``` +Mysql2⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +```bash +kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p"Mysql2" mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -509,23 +519,24 @@ mysql> SHOW DATABASES; | sys | +--------------------+ 5 rows in set (0.02 sec) - -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo mysql-quickstart-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo mysql-quickstart-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo mysql-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d -vYBjULhCEzPwe5xo⏎ + +```bash +kubectl get secret -n demo mysql-quickstart-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +vYBjULhCEzPwe5xo⏎ Let's confirm that the previous credentials no longer work. -```shell -$ kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +```bash +kubectl exec -it -n demo mysql-quickstart-0 -c mysql -- bash +``` bash-5.1$ mysql -uroot -p"vYBjULhCEzPwe5xo" mysql: [Warning] Using a password on the command line interface can be insecure. ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES) bash-5.1$ -``` The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. ## Cleaning up @@ -533,15 +544,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Alternatively, you can delete individual resources by name. To do so, run: -```shell -$ kubectl delete mysqlopsrequest myops-rotate-auth-generated myops-rotate-auth-user -n demo +```bash +kubectl delete mysqlopsrequest myops-rotate-auth-generated myops-rotate-auth-user -n demo +``` MySQLOpsRequest.ops.kubedb.com "myops-rotate-auth-generated" "myops-rotate-auth-user" deleted -$ kubectl delete secret -n demo mysql-quickstart-auth-user + +```bash +kubectl delete secret -n demo mysql-quickstart-auth-user +``` secret "mysql-quickstart-auth-user" deleted -$ kubectl delete secret -n demo mysql-quickstart-auth -secret "mysql-quickstart-auth " deleted +```bash +kubectl delete secret -n demo mysql-quickstart-auth ``` +secret "mysql-quickstart-auth " deleted ## Next Steps diff --git a/docs/guides/mysql/scaling/horizontal-scaling/cluster/index.md b/docs/guides/mysql/scaling/horizontal-scaling/cluster/index.md index 609da64104..b6d78bd0d5 100644 --- a/docs/guides/mysql/scaling/horizontal-scaling/cluster/index.md +++ b/docs/guides/mysql/scaling/horizontal-scaling/cluster/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to increase/decrease th To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a group replication server with 3 members. Then When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let's check the supported MySQL versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Here, we are going to create a MySQL Group Replication using `MySQL` `9.6.0`. @@ -123,9 +123,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/group-replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/group-replication.yaml ``` +mysql.kubedb.com/my-group created @@ -164,9 +164,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/innodb.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/innodb.yaml ``` +mysql.kubedb.com/my-group created @@ -206,9 +206,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/semi-sync.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/semi-sync.yaml ``` +mysql.kubedb.com/my-group created @@ -222,37 +222,46 @@ Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its ```bash -$ watch -n 3 kubectl get my -n demo my-group +watch -n 3 kubectl get my -n demo my-group +``` Every 3.0s: kubectl get my -n demo my-group suaas-appscode: Tue Jun 30 22:43:57 2020 NAME VERSION STATUS AGE my-group 8.4.8 Running 16m -$ watch -n 3 kubectl get petset -n demo my-group +```bash +watch -n 3 kubectl get petset -n demo my-group +``` Every 3.0s: kubectl get petset -n demo my-group Every 3.0s: kubectl get petset -n demo my-group suaas-appscode: Tue Jun 30 22:44:35 2020 NAME READY AGE my-group 3/3 16m -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +```bash +watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +``` Every 3.0s: kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com suaas-appscode: Tue Jun 30 22:45:33 2020 NAME READY STATUS RESTARTS AGE my-group-0 2/2 Running 0 17m my-group-1 2/2 Running 0 14m my-group-2 2/2 Running 0 11m -``` Let's verify that the PetSet's pods have joined into a group replication cluster, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` sWfUMoqRpOJyomgb -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=sWfUMoqRpOJyomgb --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=sWfUMoqRpOJyomgb --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | @@ -261,7 +270,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 815974c2-baef-11ea-bd7e-a695cbdbd6cc | my-group-2.my-group-pods.demo | 3306 | ONLINE | SECONDARY | 8.0.23 | | group_replication_applier | ec61cef2-baee-11ea-adb0-9a02630bae5d | my-group-0.my-group-pods.demo | 3306 | ONLINE | PRIMARY | 8.0.23 | +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ -``` So, we can see that our group replication cluster has 3 members. Now, we are ready to apply the horizontal scale to this group replication. @@ -296,9 +304,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/scale_up.yaml -mysqlopsrequest.ops.kubedb.com/my-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/scale_up.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-scale-up created **Verify Scale-Up Succeeded:** @@ -316,8 +324,12 @@ my-scale-up HorizontalScaling Successful 2m55s You can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL` group replication is scaled up. ```bash -$ kubectl describe myops -n demo my-scale-up -$ Name: my-scale-up +kubectl describe myops -n demo my-scale-up +``` + +```bash +Name: my-scale-up +``` Namespace: demo Labels: Annotations: @@ -378,18 +390,22 @@ Events: Normal Starting 26m KubeDB Enterprise Operator Resuming MySQL database: demo/my-group Normal Successful 26m KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-group Normal Successful 26m KubeDB Enterprise Operator Controller has Successfully scaled the MySQL database: demo/my-group -``` Now, we are going to verify whether the number of members has increased to meet up the desired state, Let's check, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` Y28qkWFQ8QHVzq2h -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=Y28qkWFQ8QHVzq2h --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=Y28qkWFQ8QHVzq2h --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | @@ -400,7 +416,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | c9d82f09-bafd-11ea-ab3a-764d326534a6 | my-group-1.my-group-pods.demo | 3306 | ONLINE | SECONDARY | 8.0.23 | | group_replication_applier | eff81073-bafd-11ea-9f3d-ca1e99c33106 | my-group-2.my-group-pods.demo | 3306 | ONLINE | SECONDARY | 8.0.23 | +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ -``` You can see above that our `MySQL` group replication now has a total of 5 members. It verifies that we have successfully scaled up. @@ -429,9 +444,9 @@ spec: Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/scale_down.yaml -mysqlopsrequest.ops.kubedb.com/my-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/horizontal-scaling/cluster/yamls/scale_down.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-scale-down created **Verify Scale-down Succeeded:** @@ -449,7 +464,8 @@ my-scale-down HorizontalScaling Successful 2m55s You can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL` group replication is scaled down. ```bash -$ kubectl describe myops -n demo my-scale-down +kubectl describe myops -n demo my-scale-down +``` Name: my-scale-down Namespace: demo Labels: @@ -511,18 +527,22 @@ Events: Normal Starting 61s KubeDB Enterprise Operator Resuming MySQL database: demo/my-group Normal Successful 61s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-group Normal Successful 61s KubeDB Enterprise Operator Controller has Successfully scaled the MySQL database: demo/my-group -``` Now, we are going to verify whether the number of members has decreased to meet up the desired state, Let's check, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` Y28qkWFQ8QHVzq2h -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=5pwciRRUWHhSJ6qQ --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password=5pwciRRUWHhSJ6qQ --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | @@ -532,7 +552,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | c498302f-ce5b-11ea-96a3-72980d437abc | my-group-3.my-group-pods.demo | 3306 | ONLINE | SECONDARY | 8.0.23 | | group_replication_applier | dfb1633a-ce5a-11ea-a9c8-6e4ef86119d0 | my-group-0.my-group-pods.demo | 3306 | ONLINE | PRIMARY | 8.0.23 | +---------------------------+--------------------------------------+------------------------------+-------------+--------------+-------------+----------------+ -``` You can see above that our `MySQL` group replication now has a total of 4 members. It verifies that we have successfully scaled down. diff --git a/docs/guides/mysql/scaling/vertical-scaling/cluster/index.md b/docs/guides/mysql/scaling/vertical-scaling/cluster/index.md index a4b2f36dd3..69f6f947b7 100644 --- a/docs/guides/mysql/scaling/vertical-scaling/cluster/index.md +++ b/docs/guides/mysql/scaling/vertical-scaling/cluster/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/scaling/vertical-scaling/cluster/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a cluster using a supported `MySQL` version. Th When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let's check the supported MySQL versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Here, we are going to create a MySQL Group Replication using non-deprecated `MySQL` version `9.6.0`. @@ -119,9 +119,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/group-replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/group-replication.yaml ``` +mysql.kubedb.com/my-group created
@@ -155,9 +155,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/innodb.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/innodb.yaml ``` +mysql.kubedb.com/my-group created
@@ -194,9 +194,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/group-replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/group-replication.yaml ``` +mysql.kubedb.com/my-group created @@ -210,33 +210,37 @@ mysql.kubedb.com/my-group created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-group +watch -n 3 kubectl get my -n demo my-group +``` Every 3.0s: kubectl get my -n demo my-group suaas-appscode: Tue Jun 30 22:43:57 2020 NAME VERSION STATUS AGE my-group 8.4.8 Running 16m -$ watch -n 3 kubectl get petset -n demo my-group +```bash +watch -n 3 kubectl get petset -n demo my-group +``` Every 3.0s: kubectl get petset -n demo my-group Every 3.0s: kubectl get petset -n demo my-group suaas-appscode: Tue Jun 30 22:44:35 2020 NAME READY AGE my-group 3/3 16m -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +```bash +watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +``` Every 3.0s: kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com suaas-appscode: Tue Jun 30 22:45:33 2020 NAME READY STATUS RESTARTS AGE my-group-0 2/2 Running 0 17m my-group-1 2/2 Running 0 14m my-group-2 2/2 Running 0 11m -``` Let's check one of the PetSet's pod containers resources, ```bash -$ kubectl get pod -n demo my-group-0 -o json | jq '.spec.containers[1].resources' -{} +kubectl get pod -n demo my-group-0 -o json | jq '.spec.containers[1].resources' ``` +{} You can see that the Pod has empty resources that mean the scheduler will choose a random node to place the container of the Pod on by default. Now, we are ready to apply the vertical scale on this group replication. @@ -278,9 +282,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/my-scale-group.yaml -mysqlopsrequest.ops.kubedb.com/my-scale-group created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/cluster/yamls/my-scale-group.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-scale-group created **Verify MySQL Group Replication resources updated successfully:** @@ -289,17 +293,18 @@ If everything goes well, `KubeDB` Ops Manager will update the resources of the P First, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-scale-group +watch -n 3 kubectl get myops -n demo my-scale-group +``` Every 3.0s: kubectl get myops -n demo my-sc... suaas-appscode: Wed Aug 12 16:49:21 2020 NAME TYPE STATUS AGE my-scale-group VerticalScaling Successful 4m53s -``` You can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the resources of the members of the `MySQL` group replication are updated. ```bash -$ kubectl describe myops -n demo my-scale-group +kubectl describe myops -n demo my-scale-group +``` Name: my-scale-group Namespace: demo Labels: @@ -375,12 +380,12 @@ Events: Normal Starting 5m51s KubeDB Enterprise Operator Resuming MySQL database: demo/my-group Normal Successful 5m51s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-group Normal Successful 5m51s KubeDB Enterprise Operator Controller has Successfully scaled the MySQL database: demo/my-group -``` Now, we are going to verify whether the resources of the members of the cluster have updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo my-group-0 -o json | jq '.spec.containers[1].resources' +kubectl get pod -n demo my-group-0 -o json | jq '.spec.containers[1].resources' +``` { "limits": { "cpu": "700m", @@ -391,7 +396,6 @@ $ kubectl get pod -n demo my-group-0 -o json | jq '.spec.containers[1].resources "memory": "1200Mi" } } -``` The above output verifies that we have successfully updated the resources of the `MySQL` group replication. diff --git a/docs/guides/mysql/scaling/vertical-scaling/standalone/index.md b/docs/guides/mysql/scaling/vertical-scaling/standalone/index.md index effc692e5d..558e2a5d31 100644 --- a/docs/guides/mysql/scaling/vertical-scaling/standalone/index.md +++ b/docs/guides/mysql/scaling/vertical-scaling/standalone/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/scaling/vertical-scaling/standalone/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/standalone/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a standalone using supported `MySQL` version. T When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let's check the supported MySQL versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Here, we are going to create a standalone using non-deprecated `MySQL` version `9.6.0`. @@ -95,9 +95,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/standalone/yamls/standalone.yaml -mysql.kubedb.com/my-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/standalone/yamls/standalone.yaml ``` +mysql.kubedb.com/my-standalone created **Check Standalone Ready to Scale:** @@ -105,31 +105,35 @@ mysql.kubedb.com/my-standalone created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-standalone +watch -n 3 kubectl get my -n demo my-standalone +``` Every 3.0s: kubectl get my -n demo my-standalone suaas-appscode: Wed Jul 1 17:48:14 2020 NAME VERSION STATUS AGE my-standalone 8.4.8 Running 2m58s -$ watch -n 3 kubectl get petset -n demo my-standalone +```bash +watch -n 3 kubectl get petset -n demo my-standalone +``` Every 3.0s: kubectl get petset -n demo my-standalone suaas-appscode: Wed Jul 1 17:48:52 2020 NAME READY AGE my-standalone 1/1 3m36s -$ watch -n 3 kubectl get pod -n demo my-standalone-0 +```bash +watch -n 3 kubectl get pod -n demo my-standalone-0 +``` Every 3.0s: kubectl get pod -n demo my-standalone-0 suaas-appscode: Wed Jul 1 17:50:18 2020 NAME READY STATUS RESTARTS AGE my-standalone-0 1/1 Running 0 5m1s -``` Let's check the above Pod containers resources, ```bash -$ kubectl get pod -n demo my-standalone-0 -o json | jq '.spec.containers[].resources' -{} +kubectl get pod -n demo my-standalone-0 -o json | jq '.spec.containers[].resources' ``` +{} You can see the Pod has empty resources that mean the scheduler will choose a random node to place the container of the Pod on by default @@ -173,9 +177,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/standalone/yamls/my-scale-standalone.yaml -mysqlopsrequest.ops.kubedb.com/my-scale-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/scaling/vertical-scaling/standalone/yamls/my-scale-standalone.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-scale-standalone created **Verify MySQL Standalone resources updated successfully:** @@ -184,17 +188,18 @@ If everything goes well, `KubeDB` Ops Manager will update the resources of the P First, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-scale-standalone +watch -n 3 kubectl get myops -n demo my-scale-standalone +``` Every 3.0s: kubectl get myops -n demo my-sc... suaas-appscode: Wed Aug 12 17:21:42 2020 NAME TYPE STATUS AGE my-scale-standalone VerticalScaling Successful 2m15s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the standalone resources are updated. ```bash -$ kubectl describe myops -n demo my-scale-standalone +kubectl describe myops -n demo my-scale-standalone +``` Name: my-scale-standalone Namespace: demo Labels: @@ -268,12 +273,11 @@ Events: Normal Successful 14s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-standalone Normal Successful 14s KubeDB Enterprise Operator Controller has Successfully scaled the MySQL database: demo/my-standalone -``` - Now, we are going to verify whether the resources of the standalone has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo my-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo my-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "700m", @@ -284,7 +288,6 @@ $ kubectl get pod -n demo my-standalone-0 -o json | jq '.spec.containers[].resou "memory": "1200Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the standalone. diff --git a/docs/guides/mysql/schema-manager/deploy-mysqldatabase/index.md b/docs/guides/mysql/schema-manager/deploy-mysqldatabase/index.md index 15ab1982a0..5b2a199d71 100644 --- a/docs/guides/mysql/schema-manager/deploy-mysqldatabase/index.md +++ b/docs/guides/mysql/schema-manager/deploy-mysqldatabase/index.md @@ -32,9 +32,9 @@ This guide will show you how to create database with MySQL Schema Manager using To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/schema-manager/deploy-mysqldatabase/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/schema-manager/deploy-mysqldatabase/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -82,9 +82,9 @@ Here, Let’s save this yaml configuration into `mysql-server.yaml` Then create the above `MySQL` CR ```bash -$ kubectl apply -f mysql-server.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f mysql-server.yaml ``` +mysql.kubedb.com/mysql-server created ### Deploy Vault Server @@ -138,9 +138,9 @@ Here, Let’s save this yaml configuration into `vault.yaml` Then create the above `VaultServer` CR ```bash -$ kubectl apply -f vault.yaml -vaultserver.kubevault.com/vault created +kubectl apply -f vault.yaml ``` +vaultserver.kubevault.com/vault created ### Create Separate Namespace For Schema Manager In this section, we are going to create a new `Namespace` and we will only allow this namespace for our `Schema Manager`. Let's deploy it using this following yaml, @@ -156,9 +156,9 @@ metadata: Let’s save this yaml configuration into `namespace.yaml` Then create the above `Namespace` ```bash -$ kubectl apply -f namespace.yaml -namespace/demox created +kubectl apply -f namespace.yaml ``` +namespace/demox created ### Deploy Schema Manager @@ -202,17 +202,17 @@ Here, Let’s save this yaml configuration into `schema-manager.yaml` and apply it, ```bash -$ kubectl apply -f schema-manager.yaml -mysqldatabase.schema.kubedb.com/schema-manager created +kubectl apply -f schema-manager.yaml ``` +mysqldatabase.schema.kubedb.com/schema-manager created Let's check the `STATUS` of `Schema Manager`, ```bash -$ kubectl get mysqldatabase -A +kubectl get mysqldatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demox schema-manager mysql-server demo_user Current 27s -``` Here, > In `STATUS` section, `Current` means that the current `Secret` of `Schema Manager` is vaild, and it will automatically `Expired` after it reaches the limit of `defaultTTL` that we've defined in the above yaml. @@ -220,20 +220,23 @@ Here, Now, let's get the secret name from `schema-manager`, and get the login credentials for connecting to the database, ```bash -$ kubectl get mysqldatabase schema-manager -n demox -o=jsonpath='{.status.authSecret.name}' +kubectl get mysqldatabase schema-manager -n demox -o=jsonpath='{.status.authSecret.name}' +``` schema-manager-mysql-req-o2j0jk -$ kubectl view-secret schema-manager-mysql-req-o2j0jk -n demox -a +```bash +kubectl view-secret schema-manager-mysql-req-o2j0jk -n demox -a +``` password=bCfsp77bWztyZwH-i4F6 username=v-kubernetes-k8s.dc833e-txGUfwPa -``` ### Insert Sample Data Here, we are going to connect to the database with the login credentials and insert some sample data into it. ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql --user='v-kubernetes-k8s.dc833e-txGUfwPa' --password='bCfsp77bWztyZwH-i4F6' Welcome to the MySQL monitor. Commands end with ; or \g. @@ -273,27 +276,26 @@ mysql> SELECT * FROM random; mysql> exit Bye -``` Now, Let's check the `STATUS` of `Schema Manager` again, ```bash -$ kubectl get mysqldatabase -A +kubectl get mysqldatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demox schema-manager mysql-server demo_user Expired 5m35s -``` Here, we can see that the `STATUS` of the `schema-manager` is `Expired` because it's exceeded `defaultTTL: "5m"`, which means the current `Secret` of `Schema Manager` isn't vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from `schema-manager`, it won't work. ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql --user='v-kubernetes-k8s.dc833e-txGUfwPa' --password='bCfsp77bWztyZwH-i4F6' ERROR 1045 (28000): Access denied for user 'v-kubernetes-k8s.dc833e-txGUfwPa'@'localhost' (using password: YES) mysql> exit Bye -``` > We can't connect to the database with the login credentials, which is `Expired`. We will not be able to access the database even though we're in the middle of a connected session. ## Alter Database @@ -301,7 +303,8 @@ Bye In this section, we are going to alter database by changing some characteristics of our database. For this demonstration, We have to logged in as a database admin. ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql -uroot -p$MYSQL_ROOT_PASSWORD Welcome to the MySQL monitor. Commands end with ; or \g. @@ -333,7 +336,6 @@ mysql> SHOW CREATE DATABASE demo_user; mysql> exit bye -``` Let's, change the `spec.database.config.characterSet` to `big5`. @@ -368,14 +370,15 @@ spec: Save this yaml configuration and apply it, ```bash -$ kubectl apply -f schema-manager.yaml -mysqldatabase.schema.kubedb.com/schema-manager configured +kubectl apply -f schema-manager.yaml ``` +mysqldatabase.schema.kubedb.com/schema-manager configured Now, let's check the modified characteristics of our database. ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql -uroot -p$MYSQL_ROOT_PASSWORD Welcome to the MySQL monitor. Commands end with ; or \g. @@ -404,7 +407,6 @@ mysql> SHOW CREATE DATABASE demo_user; | demo_user | CREATE DATABASE `demo_user` /*!40100 DEFAULT CHARACTER SET big5 */ /*!80016 DEFAULT ENCRYPTION='N' */ | +-----------+-------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) -``` Here, we can see that the `spec.database.config.characterSet` is changed to `big5`. So, our database altering has been successful. > Note: When the Schema Manager is deleted, the associated database and user will also be deleted. @@ -414,8 +416,11 @@ Here, we can see that the `spec.database.config.characterSet` is changed to `big To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete ns demox -$ kubectl delete ns demo +kubectl delete ns demox +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mysql/schema-manager/initializing-with-script/index.md b/docs/guides/mysql/schema-manager/initializing-with-script/index.md index 85387a8d77..729d4813d8 100644 --- a/docs/guides/mysql/schema-manager/initializing-with-script/index.md +++ b/docs/guides/mysql/schema-manager/initializing-with-script/index.md @@ -32,9 +32,9 @@ This guide will show you how to to create database and initialize Script with My To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/schema-manager/initializing-with-script/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/schema-manager/initializing-with-script/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -83,9 +83,9 @@ Here, Let’s save this yaml configuration into `mysql-server.yaml` Then create the above `MySQL` CR ```bash -$ kubectl apply -f mysql-server.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f mysql-server.yaml ``` +mysql.kubedb.com/mysql-server created ### Deploy Vault Server @@ -139,9 +139,9 @@ Here, Let’s save this yaml configuration into `vault.yaml` Then create the above `VaultServer` CR ```bash -$ kubectl apply -f vault.yaml -vaultserver.kubevault.com/vault created +kubectl apply -f vault.yaml ``` +vaultserver.kubevault.com/vault created ### Create Separate Namespace For Schema Manager In this section, we are going to create a new `Namespace` and we will only allow this namespace for our `Schema Manager`. Let's deploy it using this following yaml, @@ -158,9 +158,9 @@ metadata: Let’s save this yaml configuration into `namespace.yaml` Then create the above `Namespace` ```bash -$ kubectl apply -f namespace.yaml -namespace/demox created +kubectl apply -f namespace.yaml ``` +namespace/demox created ### SQL Script with ConfigMap @@ -179,10 +179,9 @@ data: ``` ```bash -$ kubectl apply -f configmap.yaml -configmap/scripter created - +kubectl apply -f configmap.yaml ``` +configmap/scripter created ### Deploy Schema Manager Initialize with Script @@ -230,17 +229,17 @@ Here, Let’s save this yaml configuration into `schema-manager.yaml` and apply it, ```bash -$ kubectl apply -f schema-script.yaml -mysqldatabase.schema.kubedb.com/schema-script created +kubectl apply -f schema-script.yaml ``` +mysqldatabase.schema.kubedb.com/schema-script created Let's check the `STATUS` of `Schema Manager`, ```bash -$ kubectl get mysqldatabase -A +kubectl get mysqldatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demox schema-script mysql-server demo_script Current 21s -``` Here, > In `STATUS` section, `Current` means that the current `Secret` of `Schema Manager` is vaild, and it will automatically `Expired` after it reaches the limit of `defaultTTL` that we've defined in the above yaml. @@ -248,20 +247,23 @@ Here, Now, let's get the secret name from `schema-manager`, and get the login credentials for connecting to the database, ```bash -$ kubectl get mysqldatabase schema-script -n demox -o=jsonpath='{.status.authSecret.name}' +kubectl get mysqldatabase schema-script -n demox -o=jsonpath='{.status.authSecret.name}' +``` schema-script-mysql-req-s85fuw -$ kubectl view-secret schema-script-mysql-req-s85fuw -n demox -a +```bash +kubectl view-secret schema-script-mysql-req-s85fuw -n demox -a +``` password=DueiiR-JyGpa3rejG2Zd username=v-kubernetes-k8s.dc833e-yb9r7uhs -``` ### Verify Initialization Here, we are going to connect to the database with the login credentials and verify the database initialization, ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql --user='v-kubernetes-k8s.dc833e-yb9r7uhs' --password='DueiiR-JyGpa3rejG2Zd' Welcome to the MySQL monitor. Commands end with ; or \g. @@ -301,27 +303,26 @@ mysql> SELECT * FROM Product; mysql> exit Bye -``` Now, Let's check the `STATUS` of `Schema Manager` again, ```bash -$ kubectl get mysqldatabase -A +kubectl get mysqldatabase -A +``` NAMESPACE NAME DB_SERVER DB_NAME STATUS AGE demox schema-script mysql-server demo_script Expired 5m27s -``` Here, we can see that the `STATUS` of the `schema-manager` is `Expired` because it's exceeded `defaultTTL: "5m"`, which means the current `Secret` of `Schema Manager` isn't vaild anymore. Now, if we try to connect and login with the credentials that we have acquired before from `schema-manager`, it won't work. ```bash -$ kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +kubectl exec -it mysql-server-0 -n demo -c mysql -- bash +``` bash-4.4# mysql --user='v-kubernetes-k8s.dc833e-yb9r7uhs' --password='DueiiR-JyGpa3rejG2Zd' ERROR 1045 (28000): Access denied for user 'v-kubernetes-k8s.dc833e-txGUfwPa'@'localhost' (using password: YES) mysql> exit Bye -``` > We can't connect to the database with the login credentials, which is `Expired`. We will not be able to access the database even though we're in the middle of a connected session. @@ -331,8 +332,11 @@ Bye To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete ns demox -$ kubectl delete ns demo +kubectl delete ns demox +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/mysql/tls/configure/index.md b/docs/guides/mysql/tls/configure/index.md index 78859d0dc1..ea12030261 100644 --- a/docs/guides/mysql/tls/configure/index.md +++ b/docs/guides/mysql/tls/configure/index.md @@ -27,9 +27,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/mysql/tls/configure/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/mysql/tls/configure/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -312,26 +312,30 @@ mysql.kubedb.com/some-mysql created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo some-mysql +watch -n 3 kubectl get my -n demo some-mysql +``` Every 3.0s: kubectl get my -n demo some-mysql suaas-appscode: Thu Aug 13 19:02:15 2020 NAME VERSION STATUS AGE some-mysql 8.4.8 Running 9m41s -$ watch -n 3 kubectl get petset -n demo some-mysql +```bash +watch -n 3 kubectl get petset -n demo some-mysql +``` Every 3.0s: kubectl get petset -n demo some-mysql suaas-appscode: Thu Aug 13 19:02:42 2020 NAME READY AGE some-mysql 3/3 9m51s -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=some-mysql +```bash +watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=some-mysql +``` Every 3.0s: kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com suaas-appscode: Thu Aug 13 19:03:02 2020 NAME READY STATUS RESTARTS AGE some-mysql-0 2/2 Running 0 10m some-mysql-1 2/2 Running 0 4m4s some-mysql-2 2/2 Running 0 2m3s -``` **Verify tls-secrets created successfully :** @@ -342,14 +346,14 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secrets -n demo | grep "some-mysql" +kubectl get secrets -n demo | grep "some-mysql" +``` some-mysql-client-cert kubernetes.io/tls 3 13m some-mysql-auth Opaque 2 13m some-mysql-metrics-exporter-cert kubernetes.io/tls 3 13m some-mysql-metrics-exporter-config Opaque 1 13m some-mysql-server-cert kubernetes.io/tls 3 13m some-mysql-token-49sjm kubernetes.io/service-account-token 3 13m -``` **Verify MySQL Standalone configured to TLS/SSL:** @@ -358,7 +362,8 @@ Now, we are going to connect to the database for verifying the `MySQL` group rep Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo some-mysql-0 -c mysql -- bash +kubectl exec -it -n demo some-mysql-0 -c mysql -- bash +``` root@my-group-0:/# ls /etc/mysql/certs/ ca.crt client.crt client.key server.crt server.key @@ -428,7 +433,6 @@ mysql> SHOW VARIABLES LIKE '%require_secure_transport%'; mysql> exit Bye -``` The above output shows that the `MySQL` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in the `/etc/ mysql/certs/` directory for client and server. @@ -438,10 +442,10 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, -```bash # creating SSL required user -$ kubectl exec -it -n demo some-mysql-0 -c mysql -- bash - +```bash +kubectl exec -it -n demo some-mysql-0 -c mysql -- bash +``` root@my-group-0:/# mysql -uroot -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -495,7 +499,6 @@ switching ssl off as it does not make connection via unix socket any more secure. mysql> exit Bye -``` From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/mysql/certs/` directory. diff --git a/docs/guides/mysql/update-version/majorversion/group-replication/index.md b/docs/guides/mysql/update-version/majorversion/group-replication/index.md index c5245b6adb..ef6d747b2d 100644 --- a/docs/guides/mysql/update-version/majorversion/group-replication/index.md +++ b/docs/guides/mysql/update-version/majorversion/group-replication/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the major ver To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/update-version/majorversion/group-replication/yamls](/docs/guides/mysql/update-version/majorversion/group-replication/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a group replication using supported that `MySQL When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let’s check the supported `MySQL` versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` true is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `MySQLVersion` for `MySQL` group replication that will be possible to update from this version to another version. In the next section, we are going to verify version update constraints. @@ -74,7 +74,8 @@ The version above that does not show `DEPRECATED` true is supported by `KubeDB` Database version update constraints is a constraint that shows whether it is possible or not possible to update from one version to another. Let's check the version update constraints of `MySQL` `8.4.8`, ```bash -$ kubectl get mysqlversion 8.4.8 -o yaml +kubectl get mysqlversion 8.4.8 -o yaml +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: MySQLVersion metadata: @@ -143,7 +144,6 @@ spec: standalone: - < 8.4.8 version: 8.4.8 -``` The above `spec.updateConstraints` of `8.4.8` is showing that for both group replication and standalone, updating below version of `8.4.8` is not possible (denylist) and updating is allowed within the range `>= 8.4.8, <= 9.1.0` (allowlist). Here, we are going to create a `MySQL` Group Replication using MySQL `8.4.8`. Then we are going to update this version to `9.1.0`. @@ -176,9 +176,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/group-replication/yamls/group_replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/group-replication/yamls/group_replication.yaml ``` +mysql.kubedb.com/my-group created **Wait for the cluster to be ready:** @@ -186,49 +186,59 @@ mysql.kubedb.com/my-group created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-group - +watch -n 3 kubectl get my -n demo my-group +``` NAME VERSION STATUS AGE my-group 8.4.8 Running 5m52s -$ watch -n 3 kubectl get petset -n demo my-group - +```bash +watch -n 3 kubectl get petset -n demo my-group +``` NAME READY AGE my-group 3/3 7m12s -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group - +```bash +watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +``` NAME READY STATUS RESTARTS AGE my-group-0 2/2 Running 0 11m my-group-1 2/2 Running 0 9m53s my-group-2 2/2 Running 0 6m48s -``` Let's verify the `MySQL`, the `PetSet` and its `Pod` image version, ```bash -$ kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +``` 8.4.8 -$ kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +```bash +kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +``` "kubedb/mysql:8.4.8" -$ kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +```bash +kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +``` "kubedb/mysql:8.4.8" "kubedb/mysql:8.4.8" "kubedb/mysql:8.4.8" -``` Let's also verify that the PetSet’s pods have joined into a group replication, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` 7gUARa&Jkg.ypJE8 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='7gUARa&Jkg.ypJE8' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='7gUARa&Jkg.ypJE8' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | @@ -238,8 +248,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | b5542a4a-f849-11ec-9a75-3e8abd17fee6 | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+ -``` - We are ready to apply updating on this `MySQL` group replication. #### UpdateVesion @@ -273,9 +281,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/group-replication/yamls/upgrade_major_version_group.yaml -mysqlopsrequest.ops.kubedb.com/my-update-major-group created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/group-replication/yamls/upgrade_major_version_group.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-update-major-group created > Note: During the upgradation of the major version of MySQL group replication, a new PetSet is created by the `KubeDB` Ops Manager and the old one is deleted. The name of the newly created PetSet is formed as follows: `-`. Here, `` is a positive integer number and starts with 1. It's determined as follows: @@ -290,16 +298,16 @@ If everything goes well, `KubeDB` Ops Manager will create a new `PetSet` named ` At first, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-update-major-group - +watch -n 3 kubectl get myops -n demo my-update-major-group +``` NAME TYPE STATUS AGE my-update-major-group UpdateVersion Successful 5m26s -``` You can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL` group replication is updated with new images and the `PetSet` is created with a new image. ```bash -$ kubectl describe myops -n demo my-update-major-group +kubectl describe myops -n demo my-update-major-group +``` Name: my-update-major-group Namespace: demo Labels: @@ -361,33 +369,41 @@ Events: Normal Starting 84s KubeDB Enterprise Operator Resuming MySQL database: demo/my-group Normal Successful 84s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-group Normal Successful 84s KubeDB Enterprise Operator Controller has Successfully updated the version of MySQL : demo/my-group -``` Now, we are going to verify whether the `MySQL` and `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +``` 9.1.0 -$ kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +```bash +kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +``` "kubedb/mysql:9.1.0" -$ kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +```bash +kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +``` "kubedb/mysql:9.1.0" "kubedb/mysql:9.1.0" "kubedb/mysql:9.1.0" -``` Let's also check the PetSet pods have joined the `MySQL` group replication, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` 7gUARa&Jkg.ypJE8 -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='7gUARa&Jkg.ypJE8' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='7gUARa&Jkg.ypJE8' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -397,8 +413,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | b5542a4a-f849-11ec-9a75-3e8abd17fee6 | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | SECONDARY | 9.1.0 | XCom | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ -``` - You can see above that our `MySQL` group replication now has updated members. It verifies that we have successfully updated our cluster. ## Cleaning Up diff --git a/docs/guides/mysql/update-version/majorversion/standalone/index.md b/docs/guides/mysql/update-version/majorversion/standalone/index.md index 1246bf3abf..5fa44e4f69 100644 --- a/docs/guides/mysql/update-version/majorversion/standalone/index.md +++ b/docs/guides/mysql/update-version/majorversion/standalone/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the major ver To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/update-version/majorversion/standalone/yamls](/docs/guides/mysql/update-version/majorversion/standalone/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a standalone using supported that `MySQL` versi When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let's check support versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `MySQLVersion` for `MySQL` standalone that will be possible to update from this version to another version. In the next section, we are going to verify version update constraints. @@ -74,7 +74,8 @@ The version above that does not show `DEPRECATED` `true` is supported by `KubeDB Database version update constraints is a constraint that shows whether it is possible or not possible to update from one version to another. Let's check the version update constraints of `MySQL` `8.4.8`, ```bash -$ kubectl get mysqlversion 8.4.8 -o yaml +kubectl get mysqlversion 8.4.8 -o yaml +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: MySQLVersion metadata: @@ -143,7 +144,6 @@ spec: standalone: - < 8.4.8 version: 8.4.8 -``` The above `spec.updateConstraints` is showing that for both standalone and group replication, updating below version of `8.4.8` is not possible (denylist) and updating is allowed within the range `>= 8.4.8, <= 9.1.0` (allowlist). Here, we are going to create a `MySQL` standalone using MySQL `8.4.8`. Then we are going to update this version to `9.1.0`. @@ -173,9 +173,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/standalone/yamls/standalone.yaml -mysql.kubedb.com/my-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/standalone/yamls/standalone.yaml ``` +mysql.kubedb.com/my-standalone created **Wait for the database to be ready:** @@ -183,34 +183,39 @@ mysql.kubedb.com/my-standalone created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-standalone - +watch -n 3 kubectl get my -n demo my-standalone +``` NAME VERSION STATUS AGE my-standalone 8.4.8 Running 3m -$ watch -n 3 kubectl get petset -n demo my-standalone - +```bash +watch -n 3 kubectl get petset -n demo my-standalone +``` NAME READY AGE my-standalone 1/1 3m42s -$ watch -n 3 kubectl get pod -n demo my-standalone-0 - +```bash +watch -n 3 kubectl get pod -n demo my-standalone-0 +``` NAME READY STATUS RESTARTS AGE my-standalone-0 1/1 Running 0 5m23s -``` Let's verify the `MySQL`, the `PetSet` and its `Pod` image version, ```bash -$ kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 8.4.8 -$ kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` kubedb/my:8.4.8 -$ kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -kubedb/my:8.4.8 +```bash +kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +kubedb/my:8.4.8 We are ready to apply updating on this `MySQL` standalone. @@ -245,9 +250,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/standalone/yamls/upgrade_major_version_standalone.yaml -mysqlopsrequest.ops.kubedb.com/my-update-major-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/majorversion/standalone/yamls/upgrade_major_version_standalone.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-update-major-standalone created **Verify MySQL version updated successfully:** @@ -256,16 +261,16 @@ If everything goes well, `KubeDB` Ops Manager will update the image of `MySQL`, At first, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-update-major-standalone - +watch -n 3 kubectl get myops -n demo my-update-major-standalone +``` NAME TYPE STATUS AGE my-update-major-standalone UpdateVersion Successful 3m57s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL`, `PetSet`, and its `Pod` have updated with a new image. ```bash -$ kubectl describe myops -n demo my-update-major-standalone +kubectl describe myops -n demo my-update-major-standalone +``` Name: my-update-major-standalone Namespace: demo Labels: @@ -324,20 +329,23 @@ Events: Normal Starting 4m47s KubeDB Enterprise Operator Resuming MySQL database: demo/my-standalone Normal Successful 4m47s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-standalone Normal Successful 4m47s KubeDB Enterprise Operator Controller has Successfully updated the version of MySQL : demo/my-standalone -``` Now, we are going to verify whether the `MySQL`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 9.1.0 -$ kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mysql:9.1.0 -$ kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mysql:9.1.0 +```bash +kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mysql:9.1.0 You can see above that our `MySQL`standalone has been updated with the new version. It verifies that we have successfully updated our standalone. diff --git a/docs/guides/mysql/update-version/minorversion/group-replication/index.md b/docs/guides/mysql/update-version/minorversion/group-replication/index.md index 406c9921b9..18a6ea2769 100644 --- a/docs/guides/mysql/update-version/minorversion/group-replication/index.md +++ b/docs/guides/mysql/update-version/minorversion/group-replication/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the minor ver To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/update-version/minorversion/group-replication/yamls](/docs/guides/mysql/update-version/minorversion/group-replication/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a group replication using supported that `MySQL When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let’s check the supported `MySQL` versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` true is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `MySQLVersion` for `MySQL` group replication that will be possible to update from this version to another version. In the next section, we are going to verify version update constraints. @@ -74,7 +74,8 @@ The version above that does not show `DEPRECATED` true is supported by `KubeDB` Database version update constraints is a constraint that shows whether it is possible or not possible to update from one version to another. Let's check the version update constraints of `MySQL` `8.4.8`, ```bash -$ kubectl get mysqlversion 8.4.8 -o yaml +kubectl get mysqlversion 8.4.8 -o yaml +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: MySQLVersion metadata: @@ -143,7 +144,6 @@ spec: standalone: - < 8.4.8 version: 8.4.8 -``` The above `spec.updateConstraints.denylist` of `8.4.8` is showing that updating below version of `8.4.8` is not possible for both group replication and standalone. That means, it is possible to update any version above `8.4.8`. Here, we are going to create a `MySQL` Group Replication using MySQL `9.4.0`. Then we are going to update this version to `9.6.0`. @@ -178,9 +178,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/group-replication/yamls/group_replication.yaml -mysql.kubedb.com/my-group created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/group-replication/yamls/group_replication.yaml ``` +mysql.kubedb.com/my-group created **Wait for the cluster to be ready:** @@ -188,50 +188,59 @@ mysql.kubedb.com/my-group created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-group - - +watch -n 3 kubectl get my -n demo my-group +``` NAME VERSION STATUS AGE my-group 8.0.36 Ready 5m -$ watch -n 3 kubectl get petset -n demo my-group - +```bash +watch -n 3 kubectl get petset -n demo my-group +``` NAME READY AGE my-group 3/3 7m12s -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group - +```bash +watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group +``` NAME READY STATUS RESTARTS AGE my-group-0 2/2 Running 0 11m my-group-1 2/2 Running 0 9m53s my-group-2 2/2 Running 0 6m48s -``` Let's verify the `MySQL`, the `PetSet` and its `Pod` image version, ```bash -$ kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +``` 8.0.36 -$ kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +```bash +kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +``` "mysql:8.0.36" -$ kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +```bash +kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +``` "mysql:8.0.36" "mysql:8.0.36" "mysql:8.0.36" -``` Let's also verify that the PetSet’s pods have joined into the group replication, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` XbUHi_Cp&SLSXTmo -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='XbUHi_Cp&SLSXTmo' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='XbUHi_Cp&SLSXTmo' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -241,8 +250,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 71fdc498-f84d-11ec-a6f3-b2ee89425e4f | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | PRIMARY | 8.0.36 | XCom | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ -``` - We are ready to apply updating on this `MySQL` group replication. #### UpdateVersion @@ -276,9 +283,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/group-replication/yamls/upgrade_minor_version_group.yaml -mysqlopsrequest.ops.kubedb.com/my-update-minor-group created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/group-replication/yamls/upgrade_minor_version_group.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-update-minor-group created **Verify MySQL version updated successfully:** @@ -287,16 +294,16 @@ If everything goes well, `KubeDB` Ops Manager will update the image of `MySQL`, At first, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-update-minor-group +watch -n 3 kubectl get myops -n demo my-update-minor-group +``` NAME TYPE STATUS AGE my-update-minor-group UpdateVersion Successful 5m26s -``` You can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL` group replication is updated with the new version and the `PetSet` is created with a new image. ```bash -$ kubectl describe myops -n demo my-update-minor-group - +kubectl describe myops -n demo my-update-minor-group +``` Name: my-update-minor-group Namespace: demo Labels: @@ -359,34 +366,40 @@ Events: Normal Successful 29m KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-group Normal Successful 29m KubeDB Enterprise Operator Controller has Successfully updated the version of MySQL : demo/my-group - -``` - Now, we are going to verify whether the `MySQL` and `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-group -o=jsonpath='{.spec.version}{"\n"}' +``` 8.4.8 -$ kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +```bash +kubectl get petset -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.template.spec.containers[1].image' +``` "mysql:8.4.8" -$ kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +```bash +kubectl get pod -n demo -l app.kubernetes.io/name=mysqls.kubedb.com,app.kubernetes.io/instance=my-group -o json | jq '.items[].spec.containers[1].image' +``` "mysql:8.4.8" "mysql:8.4.8" "mysql:8.4.8" -``` Let's also check the PetSet pods have joined the `MySQL` group replication, ```bash -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo my-group-auth -o jsonpath='{.data.password}' | base64 -d +``` XbUHi_Cp&SLSXTmo -$ kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='XbUHi_Cp&SLSXTmo' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +```bash +kubectl exec -it -n demo my-group-0 -c mysql -- mysql -u root --password='XbUHi_Cp&SLSXTmo' --host=my-group-0.my-group-pods.demo -e "select * from performance_schema.replication_group_members" +``` mysql: [Warning] Using a password on the command line interface can be insecure. +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK | @@ -396,8 +409,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | group_replication_applier | 71fdc498-f84d-11ec-a6f3-b2ee89425e4f | my-group-0.my-group-pods.demo.svc | 3306 | ONLINE | SECONDARY | 8.4.8 | XCom | +---------------------------+--------------------------------------+-----------------------------------+-------------+--------------+-------------+----------------+----------------------------+ -``` - You can see above that our `MySQL` group replication now has updated members. It verifies that we have successfully updated our cluster. ## Cleaning Up diff --git a/docs/guides/mysql/update-version/minorversion/standalone/index.md b/docs/guides/mysql/update-version/minorversion/standalone/index.md index edef82982f..304881910d 100644 --- a/docs/guides/mysql/update-version/minorversion/standalone/index.md +++ b/docs/guides/mysql/update-version/minorversion/standalone/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the minor ver To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/mysql/update-version/minorversion/standalone/yamls](/docs/guides/mysql/update-version/minorversion/standalone/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a standalone using supported `MySQL` version wh When you have installed `KubeDB`, it has created `MySQLVersion` CR for all supported `MySQL` versions. Let's check support versions, ```bash -$ kubectl get mysqlversion +kubectl get mysqlversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 5.7.42-debian 5.7.42 Official ghcr.io/appscode-images/mysql:5.7.42-debian 45h 5.7.44 5.7.44 Official ghcr.io/appscode-images/mysql:5.7.44-oracle 45h @@ -65,7 +66,6 @@ NAME VERSION DISTRIBUTION DB_IMAGE 9.1.0 9.1.0 Official ghcr.io/appscode-images/mysql:9.1.0-oracle 45h 9.4.0 9.4.0 Official ghcr.io/appscode-images/mysql:9.4.0-oracle 45h 9.6.0 9.6.0 Official ghcr.io/appscode-images/mysql:9.6.0-oracle 45h -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `MySQL`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `MySQLVersion` for `MySQL` standalone that will be possible to update from this version to another version. In the next section, we are going to verify version update constraints. @@ -74,7 +74,8 @@ The version above that does not show `DEPRECATED` `true` is supported by `KubeDB Database version update constraints is a constraint that shows whether it is possible or not possible to update from one version to another. Let's check the version update constraints of `MySQL` `8.4.8`, ```bash -$ kubectl get mysqlversion 8.4.8 -o yaml +kubectl get mysqlversion 8.4.8 -o yaml +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: MySQLVersion metadata: @@ -143,7 +144,6 @@ spec: standalone: - < 8.4.8 version: 8.4.8 -``` The above `spec.updateConstraints.denylist` is showing that updating below version of `8.4.8` is not possible for both standalone and group replication. That means, it is possible to update any version above `8.4.8`. Here, we are going to create a `MySQL` standalone using MySQL `9.4.0`. Then we are going to update this version to `9.6.0`. @@ -173,9 +173,9 @@ spec: Let's create the `MySQL` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/standalone/yamls/standalone.yaml -mysql.kubedb.com/my-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/standalone/yamls/standalone.yaml ``` +mysql.kubedb.com/my-standalone created **Wait for the database to be ready:** @@ -183,34 +183,39 @@ mysql.kubedb.com/my-standalone created Now, watch `MySQL` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get my -n demo my-standalone - +watch -n 3 kubectl get my -n demo my-standalone +``` NAME VERSION STATUS AGE my-standalone 8.4.8 Running 3m -$ watch -n 3 kubectl get petset -n demo my-standalone - +```bash +watch -n 3 kubectl get petset -n demo my-standalone +``` NAME READY AGE my-standalone 1/1 3m42s -$ watch -n 3 kubectl get pod -n demo my-standalone-0 - +```bash +watch -n 3 kubectl get pod -n demo my-standalone-0 +``` NAME READY STATUS RESTARTS AGE my-standalone-0 1/1 Running 0 5m23s -``` Let's verify the `MySQL`, the `PetSet` and its `Pod` image version, ```bash -$ kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 8.4.8 -$ kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` mysql:8.4.8 -$ kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -mysql:8.4.8 +```bash +kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +mysql:8.4.8 We are ready to apply updating on this `MySQL` standalone. @@ -245,9 +250,9 @@ Here, Let's create the `MySQLOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/standalone/yamls/upgrade_minor_version_standalone.yaml -mysqlopsrequest.ops.kubedb.com/my-update-minor-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/update-version/minorversion/standalone/yamls/upgrade_minor_version_standalone.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-update-minor-standalone created **Verify MySQL version updated successfully:** @@ -256,16 +261,16 @@ If everything goes well, `KubeDB` Ops Manager will update the image of `MySQL`, At first, we will wait for `MySQLOpsRequest` to be successful. Run the following command to watch `MySQlOpsRequest` cr, ```bash -$ watch -n 3 kubectl get myops -n demo my-update-minor-standalone - +watch -n 3 kubectl get myops -n demo my-update-minor-standalone +``` NAME TYPE STATUS AGE my-update-minor-standalone UpdateVersion Successful 3m57s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest`, we shall see that the `MySQL`, `PetSet`, and its `Pod` have updated with a new image. ```bash -$ kubectl describe myops -n demo my-update-minor-standalone +kubectl describe myops -n demo my-update-minor-standalone +``` Name: my-update-minor-standalone Namespace: demo Labels: @@ -324,20 +329,22 @@ Events: Normal Successful 67s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/my-standalone Normal Successful 67s KubeDB Enterprise Operator Controller has Successfully updated the version of MySQL : demo/my-standalone -``` - Now, we are going to verify whether the `MySQL`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +kubectl get my -n demo my-standalone -o=jsonpath='{.spec.version}{"\n"}' +``` 9.0.1 -$ kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo my-standalone -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` kubedb/my:9.0.1 -$ kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -kubedb/my:9.0.1 +```bash +kubectl get pod -n demo my-standalone-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +kubedb/my:9.0.1 You can see above that our `MySQL`standalone has been updated with the new version. It verifies that we have successfully updated our standalone. diff --git a/docs/guides/mysql/volume-expansion/volume-expansion/index.md b/docs/guides/mysql/volume-expansion/volume-expansion/index.md index 3c688cbc67..214c0f8202 100644 --- a/docs/guides/mysql/volume-expansion/volume-expansion/index.md +++ b/docs/guides/mysql/volume-expansion/volume-expansion/index.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to expand the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of MySQL @@ -45,13 +45,12 @@ Here, we are going to deploy a `MySQL` cluster using a supported version by `Ku At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 69s topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 37s -``` - We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. You can install topolvm from [here](https://github.com/topolvm/topolvm). Now, we are going to deploy a `MySQL` database of 3 replicas with version `9.6.0`. @@ -108,9 +107,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/group_replication.yaml -mysql.kubedb.com/sample-mysql created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/group_replication.yaml ``` +mysql.kubedb.com/sample-mysql created
@@ -143,9 +142,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/innodb.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/innodb.yaml +``` mysql.kubedb.com/sample-mysql created -````
@@ -179,9 +178,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/semi-sync.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/semi-sync.yaml +``` mysql.kubedb.com/sample-mysql created -````
@@ -209,9 +208,9 @@ spec: Let's create the `MySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/standalone.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/standalone.yaml +``` mysql.kubedb.com/sample-mysql created -```` @@ -219,23 +218,25 @@ mysql.kubedb.com/sample-mysql created Now, wait until `sample-mysql` has status `Ready`. i.e, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE sample-mysql 8.4.8 Ready 5m4s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 1Gi RWO Delete Bound demo/data-sample-mysql-0 topolvm-provisioner 63s pvc-b90179f8-c40a-4273-ad77-74ca8470b782 1Gi RWO Delete Bound demo/data-sample-mysql-1 topolvm-provisioner 62s pvc-f72411a4-80d5-4d32-b713-cb30ec662180 1Gi RWO Delete Bound demo/data-sample-mysql-2 topolvm-provisioner 62s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -276,9 +277,9 @@ Here, Let's create the `MySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/online-volume-expansion.yaml -mysqlopsrequest.ops.kubedb.com/my-online-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/mysql/volume-expansion/volume-expansion/example/online-volume-expansion.yaml ``` +mysqlopsrequest.ops.kubedb.com/my-online-volume-expansion created #### Verify MySQL volume expanded successfully @@ -287,15 +288,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the volume siz Let's wait for `MySQLOpsRequest` to be `Successful`. Run the following command to watch `MySQLOpsRequest` CR, ```bash -$ kubectl get mysqlopsrequest -n demo +kubectl get mysqlopsrequest -n demo +``` NAME TYPE STATUS AGE my-online-volume-expansion VolumeExpansion Successful 96s -``` We can see from the above output that the `MySQLOpsRequest` has succeeded. If we describe the `MySQLOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe mysqlopsrequest -n demo my-online-volume-expansion +kubectl describe mysqlopsrequest -n demo my-online-volume-expansion +``` Name: my-online-volume-expansion Namespace: demo Labels: @@ -344,21 +346,21 @@ Events: Normal Starting 41s KubeDB Enterprise Operator Resuming MySQL database: demo/sample-mysql Normal Successful 41s KubeDB Enterprise Operator Successfully resumed MySQL database: demo/sample-mysql Normal Successful 41s KubeDB Enterprise Operator Controller has Successfully expand the volume of MySQL: demo/sample-mysql - -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-mysql -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 2Gi RWO Delete Bound demo/data-sample-mysql-0 topolvm-provisioner 12m pvc-b90179f8-c40a-4273-ad77-74ca8470b782 2Gi RWO Delete Bound demo/data-sample-mysql-1 topolvm-provisioner 12m pvc-f72411a4-80d5-4d32-b713-cb30ec662180 2Gi RWO Delete Bound demo/data-sample-mysql-2 topolvm-provisioner 12m -``` The above output verifies that we have successfully expanded the volume of the MySQL database. @@ -367,6 +369,9 @@ The above output verifies that we have successfully expanded the volume of the M To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete mysql -n demo sample-mysql -$ kubectl delete mysqlopsrequest -n demo my-online-volume-expansion +kubectl delete mysql -n demo sample-mysql +``` + +```bash +kubectl delete mysqlopsrequest -n demo my-online-volume-expansion ``` diff --git a/docs/guides/neo4j/backup/kubestash/customization/index.md b/docs/guides/neo4j/backup/kubestash/customization/index.md index 1265d07a80..929acc67a1 100644 --- a/docs/guides/neo4j/backup/kubestash/customization/index.md +++ b/docs/guides/neo4j/backup/kubestash/customization/index.md @@ -264,13 +264,13 @@ spec: You can also restore a specific snapshot. At first, list the available snapshots as below, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=s3-neo4j-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=s3-neo4j-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1725257849 s3-neo4j-repo frequent-backup 2024-09-02T06:18:01Z Delete Succeeded 15m s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1725258000 s3-neo4j-repo frequent-backup 2024-09-02T06:20:00Z Delete Succeeded 13m s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1725258300 s3-neo4j-repo frequent-backup 2024-09-02T06:25:00Z Delete Succeeded 8m34s s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1725258600 s3-neo4j-repo frequent-backup 2024-09-02T06:30:00Z Delete Succeeded 3m34s -``` The below example shows how you can pass a specific snapshot name in the `.spec.dataSource` section. diff --git a/docs/guides/neo4j/backup/kubestash/logical/index.md b/docs/guides/neo4j/backup/kubestash/logical/index.md index a37d3d3c14..901973ba73 100644 --- a/docs/guides/neo4j/backup/kubestash/logical/index.md +++ b/docs/guides/neo4j/backup/kubestash/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/neo4j/backup/kubestash/logical/examples](/docs/guides/neo4j/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,34 +80,36 @@ spec: Create the above `Neo4j` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/sample-neo4j.yaml -neo4j.kubedb.com/sample-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/sample-neo4j.yaml ``` +neo4j.kubedb.com/sample-neo4j created KubeDB will deploy a `Neo4j` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get neo4j -n demo sample-neo4j +kubectl get neo4j -n demo sample-neo4j +``` NAME VERSION STATUS AGE sample-neo4j 2025.12.1 Ready 5m1s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-neo4j +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-neo4j +``` NAME TYPE DATA AGE sample-neo4j-auth Opaque 2 5m20s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-neo4j +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-neo4j +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-neo4j ClusterIP 10.43.214.193 6362/TCP,7687/TCP,7474/TCP 5m55s sample-neo4j-0 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 5m55s sample-neo4j-1 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 5m55s sample-neo4j-2 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 5m55s -``` Here, we have to use service `sample-neo4j` and secret `sample-neo4j-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/neo4j/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -116,15 +118,15 @@ Here, we have to use service `sample-neo4j` and secret `sample-neo4j-auth` to co Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-neo4j kubedb.com/Neo4j 2025.12.1-enterprise 86s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-neo4j -o yaml +kubectl get appbindings -n demo sample-neo4j -o yaml ``` ```yaml @@ -182,31 +184,36 @@ Here, Now, we are going to exec into one of the database pods and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-neo4j" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-neo4j" +``` NAME READY STATUS RESTARTS AGE sample-neo4j-0 1/1 Running 0 118s sample-neo4j-1 1/1 Running 0 112s sample-neo4j-2 1/1 Running 0 106s -``` Retrieve the auth credentials so we can connect using `cypher-shell`, ```bash -$ kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.username}' | base64 -d +``` neo4j -$ kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.password}' | base64 -d -UEke.988YxVdJbGq +```bash +kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.password}' | base64 -d ``` +UEke.988YxVdJbGq Now, let's exec into the pod and create some nodes, ```bash -$ export PASS=$(kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.password}' | base64 -d) +export PASS=$(kubectl get secret -n demo sample-neo4j-auth -o jsonpath='{.data.password}' | base64 -d) +``` # create a few Person nodes and a relationship in the default "neo4j" database -$ kubectl exec -it -n demo sample-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -it -n demo sample-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ "CREATE (alice:Person {name: 'Alice', age: 30}) +``` CREATE (bob:Person {name: 'Bob', age: 25}) CREATE (alice)-[:KNOWS]->(bob);" 0 rows @@ -214,8 +221,10 @@ ready to start consuming query after 25 ms, results consumed after another 0 ms Added 2 nodes, Created 1 relationships, Set 4 properties, Added 2 labels # verify that the data has been inserted -$ kubectl exec -it -n demo sample-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -it -n demo sample-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ "MATCH (p:Person) RETURN p.name AS name, p.age AS age ORDER BY name;" +``` +---------------+ | name | age | +---------------+ @@ -224,7 +233,6 @@ $ kubectl exec -it -n demo sample-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ +---------------+ 2 rows -``` Now, we are ready to backup the database. @@ -237,13 +245,19 @@ We are going to store our backed up data into an `S3` bucket. We have to create Let's create a secret called `s3-secret` with access credentials to our desired S3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -274,9 +288,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -307,9 +321,9 @@ spec: Let's create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -363,27 +377,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-neo4j-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-neo4j-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-neo4j-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-neo4j-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the S3 bucket, we will see the `Repository` YAML stored in the `demo/backup` directory. @@ -394,21 +408,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-neo4j-backup-frequent-backup */5 * * * * False 0 2m18s -``` - **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-neo4j-backup-frequent-backup-1782108669 BackupConfiguration sample-neo4j-backup Succeeded 44s 119s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -417,18 +430,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `s3-neo4j-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-neo4j-repo +kubectl get repository -n demo s3-neo4j-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-neo4j-repo 1 0 B Ready 2m46s 2m57s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-neo4j-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-neo4j-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1782108669 s3-neo4j-repo frequent-backup 2026-06-22T06:11:20Z Delete Succeeded 3m2s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -442,7 +455,7 @@ s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1782108669 s3-neo4j-repo f If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1782108669 -oyaml +kubectl get snapshots -n demo s3-neo4j-repo-sample-neo4j-backup-frequent-backup-1782108669 -oyaml ``` ```yaml @@ -563,17 +576,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/restored-neo4j.yaml -neo4j.kubedb.com/restored-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/restored-neo4j.yaml ``` +neo4j.kubedb.com/restored-neo4j created Let's wait for the database to be ready to use, ```bash -$ kubectl get neo4j -n demo restored-neo4j +kubectl get neo4j -n demo restored-neo4j +``` NAME VERSION STATUS AGE restored-neo4j 2025.12.1 Ready 5m1s -``` The database is `Ready`. Now, we are going to restore the backed up data into this database. @@ -630,18 +643,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-neo4j-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/neo4j/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-neo4j-restore created Once you have created the `RestoreSession` object, KubeStash will create a restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restoresession -n demo NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-neo4j-restore s3-neo4j-repo Succeeded 18s 116s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -652,29 +665,32 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get neo4j -n demo restored-neo4j +kubectl get neo4j -n demo restored-neo4j +``` NAME VERSION STATUS AGE restored-neo4j 2025.12.1 Ready 6m31s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-neo4j" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-neo4j" +``` NAME READY STATUS RESTARTS AGE restored-neo4j-0 1/1 Running 0 6m7s restored-neo4j-1 1/1 Running 0 6m1s restored-neo4j-2 1/1 Running 0 5m55s -``` Now, let's exec into one of the `Pod` and verify the restored data. ```bash -$ export PASS=$(kubectl get secret -n demo restored-neo4j-auth -o jsonpath='{.data.password}' | base64 -d) +export PASS=$(kubectl get secret -n demo restored-neo4j-auth -o jsonpath='{.data.password}' | base64 -d) +``` # verify that the Person nodes have been restored -$ kubectl exec -it -n demo restored-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -it -n demo restored-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" \ "MATCH (p:Person) RETURN p.name AS name, p.age AS age ORDER BY name;" +``` +---------------+ | name | age | +---------------+ @@ -683,7 +699,6 @@ $ kubectl exec -it -n demo restored-neo4j-0 -- cypher-shell -u neo4j -p "$PASS" +---------------+ 2 rows -``` So, from the above output, we can see the nodes we had created in the original database `sample-neo4j` have been restored in the `restored-neo4j` database. diff --git a/docs/guides/neo4j/clustering/architecture-overview.md b/docs/guides/neo4j/clustering/architecture-overview.md index e19816493a..01c5f8bc0b 100644 --- a/docs/guides/neo4j/clustering/architecture-overview.md +++ b/docs/guides/neo4j/clustering/architecture-overview.md @@ -101,7 +101,7 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml +kubectl apply -f https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml ``` When applied: @@ -112,16 +112,18 @@ When applied: 4. Once the quorum is established, `status.phase` moves to `Ready`. ```bash -$ kubectl get neo4j -n demo neo4j-test +kubectl get neo4j -n demo neo4j-test +``` NAME VERSION STATUS AGE neo4j-test 2025.12.1 Ready 3m -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` NAME READY STATUS RESTARTS AGE neo4j-test-0 1/1 Running 0 3m neo4j-test-1 1/1 Running 0 2m neo4j-test-2 1/1 Running 0 2m -``` ## Failover Behavior @@ -144,13 +146,15 @@ When a Neo4j pod becomes unavailable (node failure, eviction, rolling update), t Once the cluster is ready, connect via `cypher-shell` and inspect the cluster topology: ```bash -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ kubectl exec -n demo neo4j-test-0 -- \ +```bash +kubectl exec -n demo neo4j-test-0 -- \ cypher-shell -u neo4j -p "$PASS" \ "SHOW SERVERS YIELD serverId, name, address, state, health, hosting - RETURN serverId, name, address, state, health, hosting;" ``` + RETURN serverId, name, address, state, health, hosting;" Expected output (3-server cluster, all `Enabled` and `Available`): @@ -167,12 +171,12 @@ Expected output (3-server cluster, all `Enabled` and `Available`): Check database allocation and current leaders: ```bash -$ kubectl exec -n demo neo4j-test-0 -- \ +kubectl exec -n demo neo4j-test-0 -- \ cypher-shell -u neo4j -p "$PASS" \ "SHOW DATABASES YIELD name, role, writer, currentStatus, address +``` RETURN name, role, writer, currentStatus, address ORDER BY name, role;" -``` ## Next Steps diff --git a/docs/guides/neo4j/concepts/appbinding.md b/docs/guides/neo4j/concepts/appbinding.md index b82912039a..ce98f79846 100644 --- a/docs/guides/neo4j/concepts/appbinding.md +++ b/docs/guides/neo4j/concepts/appbinding.md @@ -105,7 +105,7 @@ For in-cluster Neo4j deployments, KubeDB sets `spec.clientConfig.service`. You can inspect the generated AppBinding with: ```bash -$ kubectl get appbinding -n demo neo4j-test -o yaml +kubectl get appbinding -n demo neo4j-test -o yaml ``` ## Next Steps diff --git a/docs/guides/neo4j/concepts/catalog.md b/docs/guides/neo4j/concepts/catalog.md index 3d60ffb084..6ef11d569b 100644 --- a/docs/guides/neo4j/concepts/catalog.md +++ b/docs/guides/neo4j/concepts/catalog.md @@ -48,12 +48,12 @@ spec: ## List available versions and check for deprecated ones ```bash -$ kubectl get neo4jversions +kubectl get neo4jversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2025.10.1 2025.10.1-enterprise docker.io/library/neo4j:2025.10.1-enterprise 12d 2025.11.2 2025.11.2-enterprise docker.io/library/neo4j:2025.11.2-enterprise 12d 2025.12.1 2025.12.1-enterprise docker.io/library/neo4j:2025.12.1-enterprise 12d -``` If the `DEPRECATED` column shows `true` for a version you are currently using, upgrade to a supported version via [UpdateVersion](/docs/guides/neo4j/update-version/versionupgrading/). diff --git a/docs/guides/neo4j/concepts/neo4j.md b/docs/guides/neo4j/concepts/neo4j.md index 488be96a17..ae684dd670 100644 --- a/docs/guides/neo4j/concepts/neo4j.md +++ b/docs/guides/neo4j/concepts/neo4j.md @@ -74,12 +74,12 @@ spec: To see available versions in your cluster: ```bash -$ kubectl get neo4jversions +kubectl get neo4jversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2025.10.1 2025.10.1-enterprise docker.io/library/neo4j:2025.10.1-enterprise 12d 2025.11.2 2025.11.2-enterprise docker.io/library/neo4j:2025.11.2-enterprise 12d 2025.12.1 2025.12.1-enterprise docker.io/library/neo4j:2025.12.1-enterprise 12d -``` ### spec.replicas @@ -105,7 +105,7 @@ If `spec.storageType` is `Durable` (or not explicitly set), `spec.storage` is re To check available StorageClass resources: ```bash -$ kubectl get storageclass +kubectl get storageclass ``` ### spec.configuration diff --git a/docs/guides/neo4j/configuration/using-config-file.md b/docs/guides/neo4j/configuration/using-config-file.md index 3ba1978f1e..a191790a54 100644 --- a/docs/guides/neo4j/configuration/using-config-file.md +++ b/docs/guides/neo4j/configuration/using-config-file.md @@ -21,9 +21,9 @@ KubeDB supports providing custom configuration for Neo4j. This tutorial will sho > Prerequisites: A running Kubernetes cluster with KubeDB installed. See the [quickstart guide](/docs/guides/neo4j/quickstart/quickstart.md) if you need to set up your environment. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Overview @@ -65,17 +65,17 @@ metadata: ``` ```bash -$ kubectl apply -f neo4j-configuration-secret.yaml -secret/neo4j-configuration created +kubectl apply -f neo4j-configuration-secret.yaml ``` +secret/neo4j-configuration created Verify the Secret was created: ```bash -$ kubectl get secret -n demo neo4j-configuration +kubectl get secret -n demo neo4j-configuration +``` NAME TYPE DATA AGE neo4j-configuration Opaque 3 10s -``` Now, create the Neo4j CRD specifying `spec.configuration.secretName`: @@ -102,39 +102,39 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/configuration/neo4j-configuration.yaml -neo4j.kubedb.com/custom-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/configuration/neo4j-configuration.yaml ``` +neo4j.kubedb.com/custom-neo4j created Now, wait for the Neo4j cluster to be ready: ```bash -$ kubectl get neo4j -n demo custom-neo4j -w +kubectl get neo4j -n demo custom-neo4j -w +``` NAME VERSION STATUS AGE custom-neo4j 2025.12.1 Ready 3m -``` ## Verify the Applied Configuration To confirm the settings are active, connect to Neo4j via `cypher-shell` and run a `SHOW SETTINGS` query. First, get the default auth credentials: ```bash -$ kubectl get secret -n demo custom-neo4j-auth \ +kubectl get secret -n demo custom-neo4j-auth \ -o jsonpath='{.data.password}' | base64 -d - ``` + Then exec into a Neo4j pod and run `cypher-shell`: ```bash -$ kubectl exec -it -n demo custom-neo4j-0 -- \ +kubectl exec -it -n demo custom-neo4j-0 -- \ cypher-shell -u neo4j -p \ "SHOW SETTINGS +``` YIELD name, value WHERE name STARTS WITH 'dbms.logs.query' RETURN name, value ORDER BY name;" -``` Expected output: @@ -152,15 +152,15 @@ Expected output: You can also query other setting groups. For example, to check the Neo4j data directory paths: ```bash -$ kubectl exec -it -n demo custom-neo4j-0 -- \ +kubectl exec -it -n demo custom-neo4j-0 -- \ cypher-shell -u neo4j -p \ "SHOW SETTINGS +``` YIELD name, value WHERE name STARTS WITH 'server.jvm.additional' RETURN name, value ORDER BY name LIMIT 3;" -``` Expected output: diff --git a/docs/guides/neo4j/custom-rbac/using-custom-rbac.md b/docs/guides/neo4j/custom-rbac/using-custom-rbac.md index 535d291525..57216ce4f5 100644 --- a/docs/guides/neo4j/custom-rbac/using-custom-rbac.md +++ b/docs/guides/neo4j/custom-rbac/using-custom-rbac.md @@ -21,9 +21,9 @@ KubeDB supports finer user control over role based access permissions provided t > Prerequisites: A running Kubernetes cluster with KubeDB installed. See the [quickstart guide](/docs/guides/neo4j/quickstart/quickstart.md) if you need to set up your environment. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Overview @@ -34,9 +34,9 @@ KubeDB allows users to provide custom RBAC resources, namely, `ServiceAccount`, At first, let's create a `Service Account` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created Now, we need to create a role that has necessary access permissions for the Neo4j database named `quick-neo4j`. @@ -87,19 +87,19 @@ rules: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/custom-rbac/neo4j-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/custom-rbac/neo4j-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding \ +kubectl create rolebinding my-custom-rolebinding \ --role=my-custom-role \ --serviceaccount=demo:my-custom-serviceaccount \ --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created Now, create a Neo4j CRD specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. @@ -127,17 +127,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/custom-rbac/neo4j-custom-db.yaml -neo4j.kubedb.com/quick-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/custom-rbac/neo4j-custom-db.yaml ``` +neo4j.kubedb.com/quick-neo4j created Check that the pod is running: ```bash -$ kubectl get pod -n demo quick-neo4j-0 +kubectl get pod -n demo quick-neo4j-0 +``` NAME READY STATUS RESTARTS AGE quick-neo4j-0 1/1 Running 0 3m -``` ## Cleaning up diff --git a/docs/guides/neo4j/migration/storageMigration.md b/docs/guides/neo4j/migration/storageMigration.md index b7729b1a9b..8bd1a966e7 100644 --- a/docs/guides/neo4j/migration/storageMigration.md +++ b/docs/guides/neo4j/migration/storageMigration.md @@ -25,22 +25,22 @@ This guide shows how to migrate the `StorageClass` of a KubeDB-managed Neo4j clu Use a dedicated namespace for this walkthrough: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Neo4j Database First, verify available storage classes: ```bash -$ kubectl get sc +kubectl get sc +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE custom-longhorn driver.longhorn.io Delete WaitForFirstConsumer true 3h38m local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 4h26m longhorn (default) driver.longhorn.io Delete Immediate true 3h43m longhorn-static driver.longhorn.io Delete Immediate true 3h43m -``` We will deploy Neo4j with `local-path`, then migrate to `custom-longhorn`. @@ -49,7 +49,7 @@ We will deploy Neo4j with `local-path`, then migrate to `custom-longhorn`. Apply the Neo4j database manifest: ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: kubedb.com/v1alpha2 kind: Neo4j metadata: @@ -67,9 +67,12 @@ spec: requests: storage: 2Gi EOF +``` neo4j.kubedb.com/neo4j-test created -$ kubectl get neo4j,pvc -n demo +```bash +kubectl get neo4j,pvc -n demo +``` NAME VERSION STATUS AGE neo4j.kubedb.com/neo4j-test 2025.12.1 Ready 2m @@ -77,7 +80,6 @@ NAME STATUS VOLUME CAPACITY ACCESS MODES S persistentvolumeclaim/data-neo4j-test-0 Bound ... 2Gi RWO local-path 2m persistentvolumeclaim/data-neo4j-test-1 Bound ... 2Gi RWO local-path 2m persistentvolumeclaim/data-neo4j-test-2 Bound ... 2Gi RWO local-path 2m -``` The database is `Ready` and all the `PersistentVolumeClaim` uses `local-path` StorageClass, Let's create a database and seed some data. @@ -121,7 +123,7 @@ totalUsers To migrate `StorageClass`, create a `Neo4jOpsRequest`: ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -136,8 +138,8 @@ spec: oldPVReclaimPolicy: Delete timeout: 3000s EOF -neo4jopsrequest.ops.kubedb.com/storage-migration created ``` +neo4jopsrequest.ops.kubedb.com/storage-migration created Here, @@ -153,32 +155,34 @@ Here, Watch the OpsRequest status: ```bash -$ kubectl get neo4jopsrequest -n demo -w +kubectl get neo4jopsrequest -n demo -w +``` NAME TYPE STATUS AGE storage-migration StorageMigration Successful 8m -``` Check PVC storage class after migration: ```bash -$ kubectl get pvc -n demo +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-neo4j-test-0 Bound ... 2Gi RWO custom-longhorn 14m data-neo4j-test-1 Bound ... 2Gi RWO custom-longhorn 14m data-neo4j-test-2 Bound ... 2Gi RWO custom-longhorn 14m -``` The PVCs now use `custom-longhorn`, which confirms successful StorageClass migration. ```bash -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ kubectl exec -n demo neo4j-test-0 -- \ +```bash +kubectl exec -n demo neo4j-test-0 -- \ cypher-shell -d appdb -u neo4j -p "$PASS" \ "MATCH (u:User) RETURN count(u) AS totalUsers" +``` totalUsers 2000 -``` From the above output we can verify that data remains intact after the `StorageMigration` operation. @@ -186,7 +190,13 @@ From the above output we can verify that data remains intact after the `StorageM ## Cleanup ```bash -$ kubectl delete neo4jopsrequest -n demo storage-migration -$ kubectl delete neo4j -n demo neo4j-test -$ kubectl delete ns demo +kubectl delete neo4jopsrequest -n demo storage-migration +``` + +```bash +kubectl delete neo4j -n demo neo4j-test +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/neo4j/monitoring/using-builtin-prometheus.md b/docs/guides/neo4j/monitoring/using-builtin-prometheus.md index 9a976223a3..fca074cf5b 100644 --- a/docs/guides/neo4j/monitoring/using-builtin-prometheus.md +++ b/docs/guides/neo4j/monitoring/using-builtin-prometheus.md @@ -27,12 +27,14 @@ This tutorial will show you how to monitor a Neo4j database using builtin [Prome - Prometheus resources will be deployed in the `monitoring` namespace; the database will be in the `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in the [docs/examples/neo4j](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/neo4j) folder in the GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -68,34 +70,34 @@ Here, Let's create the Neo4j CR: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/monitoring/builtin-prom-neo4j.yaml -neo4j.kubedb.com/builtin-prom-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/monitoring/builtin-prom-neo4j.yaml ``` +neo4j.kubedb.com/builtin-prom-neo4j created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get neo4j -n demo builtin-prom-neo4j +kubectl get neo4j -n demo builtin-prom-neo4j +``` NAME VERSION STATUS AGE builtin-prom-neo4j 2025.12.1 Ready 2m -``` KubeDB will create a separate stats service with the name `{Neo4j CR name}-stats` for monitoring purposes. ```bash -$ kubectl get svc -n demo +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-neo4j ClusterIP 10.43.110.23 6362/TCP,7687/TCP,7474/TCP 4m12s builtin-prom-neo4j-0 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 4m12s builtin-prom-neo4j-1 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 4m12s builtin-prom-neo4j-2 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 4m12s builtin-prom-neo4j-stats ClusterIP 10.43.245.51 2004/TCP 4m12s -``` Here, `builtin-prom-neo4j-stats` service has been created for monitoring purposes. Let's describe this stats service: ```bash -$ kubectl get svc -n demo builtin-prom-neo4j-stats -o yaml +kubectl get svc -n demo builtin-prom-neo4j-stats -o yaml ``` ```yaml @@ -281,20 +283,20 @@ data: Let's create the ConfigMap: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC resources for Prometheus: ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` > YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -303,9 +305,9 @@ clusterrolebinding.rbac.authorization.k8s.io/prometheus created Now, we are ready to deploy the Prometheus server. Let's deploy it using the following deployment: ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -314,18 +316,18 @@ The Prometheus server is listening on port `9090`. We are going to use [port for At first, let's check if the Prometheus pod is in `Running` state: ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8597f664fd-2sl48 1/1 Running 0 6m58s -``` Now, run the following command in a separate terminal to forward port 9090: ```bash -$ kubectl port-forward -n monitoring prometheus-8597f664fd-2sl48 9090 +kubectl port-forward -n monitoring prometheus-8597f664fd-2sl48 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. Navigate to **Status → Targets** and you should see the endpoint of `builtin-prom-neo4j-stats` service as one of the active targets. @@ -342,17 +344,35 @@ Now, you can view the collected metrics and create graphs from the Prometheus ho To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo neo4j/builtin-prom-neo4j -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo neo4j/builtin-prom-neo4j +kubectl patch -n demo neo4j/builtin-prom-neo4j -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo neo4j/builtin-prom-neo4j +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` + +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/neo4j/monitoring/using-prometheus-operator.md b/docs/guides/neo4j/monitoring/using-prometheus-operator.md index be24524fe2..f7a0524096 100644 --- a/docs/guides/neo4j/monitoring/using-prometheus-operator.md +++ b/docs/guides/neo4j/monitoring/using-prometheus-operator.md @@ -25,12 +25,14 @@ section_menu_id: guides - Prometheus resources will be deployed in the `monitoring` namespace; the database will be in the `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - A running [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance is required. If you don't have one, deploy it following [these docs](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -45,17 +47,17 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` CR. Let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v3.11.3-distroless 1 1 True True 10m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in the **Before You Begin** section. Now, let's view the YAML of the available Prometheus server in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml ``` ```yaml @@ -117,29 +119,29 @@ Here, Let's create the Neo4j object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/monitoring/coreos-prom-neo4j.yaml -neo4j.kubedb.com/coreos-prom-neo4j created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/monitoring/coreos-prom-neo4j.yaml ``` +neo4j.kubedb.com/coreos-prom-neo4j created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get neo4j -n demo coreos-prom-neo4j +kubectl get neo4j -n demo coreos-prom-neo4j +``` NAME VERSION STATUS AGE coreos-prom-neo4j 2025.12.1 Ready 3m -``` KubeDB will create a separate stats service with the name `{Neo4j CR name}-stats` for monitoring purposes. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-neo4j" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-neo4j" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-neo4j ClusterIP 10.43.124.250 6362/TCP,7687/TCP,7474/TCP 3m55s coreos-prom-neo4j-0 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 3m55s coreos-prom-neo4j-1 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 3m55s coreos-prom-neo4j-2 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 3m55s coreos-prom-neo4j-stats ClusterIP 10.43.214.74 2004/TCP 3m55s -``` Here, `coreos-prom-neo4j-stats` service has been created for monitoring purposes. It exposes metrics on port `2004`. @@ -148,15 +150,15 @@ Here, `coreos-prom-neo4j-stats` service has been created for monitoring purposes KubeDB will also create a `ServiceMonitor` CR in the `demo` namespace that selects the endpoints of `coreos-prom-neo4j-stats` service. Verify that the `ServiceMonitor` has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-neo4j-stats 6m8s -``` Let's verify the `ServiceMonitor` YAML. ```bash -$ kubectl get servicemonitor -n demo coreos-prom-neo4j-stats -o yaml +kubectl get servicemonitor -n demo coreos-prom-neo4j-stats -o yaml ``` ```yaml @@ -204,20 +206,20 @@ The `ServiceMonitor` selects the `coreos-prom-neo4j-stats` service by matching i Let's find out the Prometheus pod for our Prometheus server. ```bash -$ kubectl get pod -n monitoring -l app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 15m -``` The Prometheus server is listening on port `9090`. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access the Prometheus dashboard. Run the following command in a separate terminal to forward port 9090: ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, open [http://localhost:9090](http://localhost:9090) in your browser. Navigate to **Status → Targets** and you should see the `coreos-prom-neo4j-stats` endpoint listed as an active scrape target. diff --git a/docs/guides/neo4j/private-registry/using-private-registry.md b/docs/guides/neo4j/private-registry/using-private-registry.md index b7a2619cf0..7c84fc658d 100644 --- a/docs/guides/neo4j/private-registry/using-private-registry.md +++ b/docs/guides/neo4j/private-registry/using-private-registry.md @@ -21,9 +21,9 @@ KubeDB supports using private Docker registries. This tutorial will show you how > Prerequisites: A running Kubernetes cluster with KubeDB installed. See the [quickstart guide](/docs/guides/neo4j/quickstart/quickstart.md) if you need to set up your environment. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Private Docker Registry @@ -32,23 +32,23 @@ namespace/demo created - Push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For Neo4j, push the `DB_IMAGE` of the following Neo4jVersions, where `deprecated` is not true. ```bash - $ kubectl get neo4jversions -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,DEPRECATED:.spec.deprecated + kubectl get neo4jversions -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,DEPRECATED:.spec.deprecated + ``` NAME VERSION DB_IMAGE DEPRECATED 2025.12.1 2025.12.1 kubedb/neo4j:2025.12.1 - ``` ## Create ImagePullSecret Run the following command to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created ## Install KubeDB Operator @@ -70,9 +70,9 @@ spec: ``` ```bash -$ kubectl apply -f pvt-neo4jversion.yaml -neo4jversion.catalog.kubedb.com/2025.12.1 created +kubectl apply -f pvt-neo4jversion.yaml ``` +neo4jversion.catalog.kubedb.com/2025.12.1 created ## Deploy Neo4j from Private Registry @@ -101,17 +101,17 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/private-registry/pvt-reg-neo4j.yaml -neo4j.kubedb.com/pvt-reg-neo4j created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/private-registry/pvt-reg-neo4j.yaml ``` +neo4j.kubedb.com/pvt-reg-neo4j created Check that the Neo4j is in Running state: ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-neo4j" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-neo4j" +``` NAME READY STATUS RESTARTS AGE pvt-reg-neo4j-0 1/1 Running 0 3m -``` ## Cleaning up diff --git a/docs/guides/neo4j/quickstart/quickstart.md b/docs/guides/neo4j/quickstart/quickstart.md index 586b6a98cb..96afb0f903 100644 --- a/docs/guides/neo4j/quickstart/quickstart.md +++ b/docs/guides/neo4j/quickstart/quickstart.md @@ -31,19 +31,19 @@ Now, install KubeDB CLI on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Find Available StorageClass You will need to provide a `StorageClass` in the Neo4j CR specification. Check the available `StorageClass` in your cluster using the following command: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 12d -``` Here, we have `local-path` as the default StorageClass in our cluster. @@ -52,12 +52,12 @@ Here, we have `local-path` as the default StorageClass in our cluster. When KubeDB is installed, it creates `Neo4jVersion` CRDs for all supported Neo4j versions. Check the available versions by running: ```bash -$ kubectl get neo4jversions +kubectl get neo4jversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 2025.10.1 2025.10.1-enterprise docker.io/library/neo4j:2025.10.1-enterprise 12d 2025.11.2 2025.11.2-enterprise docker.io/library/neo4j:2025.11.2-enterprise 12d 2025.12.1 2025.12.1-enterprise docker.io/library/neo4j:2025.12.1-enterprise 12d -``` Notice the `DEPRECATED` column. A `true` value means that version is deprecated for the current KubeDB release and should be avoided. In this tutorial, we will use `2025.12.1`. @@ -94,14 +94,16 @@ Here, Now apply the manifest and watch the cluster come up: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml +``` neo4j.kubedb.com/neo4j-test created -$ kubectl get neo4j -n demo neo4j-test -w +```bash +kubectl get neo4j -n demo neo4j-test -w +``` NAME VERSION STATUS AGE neo4j-test 2025.12.1 Provisioning 10s neo4j-test 2025.12.1 Ready 2m -``` > If the status stays `Provisioning` for more than a few minutes, run `kubectl describe neo4j -n demo neo4j-test` and check the `Events` section for errors. Common causes are insufficient cluster resources or a missing StorageClass. @@ -112,27 +114,29 @@ KubeDB operator watches for `Neo4j` objects using the Kubernetes API. When a `Ne Once `status.phase` is `Ready`, all three pods are running and the cluster has formed. Let's verify: ```bash -$ kubectl get neo4j -n demo +kubectl get neo4j -n demo +``` NAME VERSION STATUS AGE neo4j-test 2025.12.1 Ready 3m -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` NAME READY STATUS RESTARTS AGE neo4j-test-0 1/1 Running 0 3m neo4j-test-1 1/1 Running 0 2m neo4j-test-2 1/1 Running 0 2m -``` KubeDB also creates two Services for the Neo4j cluster: ```bash -$ kubectl get service -n demo -l app.kubernetes.io/instance=neo4j-test +kubectl get service -n demo -l app.kubernetes.io/instance=neo4j-test +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE neo4j-test ClusterIP 10.43.86.203 6362/TCP,7687/TCP,7474/TCP 11m neo4j-test-0 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 11m neo4j-test-1 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 11m neo4j-test-2 ClusterIP None 6362/TCP,7687/TCP,7474/TCP,7688/TCP,7000/TCP,6000/TCP 11m -``` - **`neo4j-test`** — the primary ClusterIP Service exposing HTTP (`7474`), Bolt (`7687`), and backup (`6362`) for client access. - **`neo4j-test-0`, `neo4j-test-1`, `neo4j-test-2`** — per-pod headless Services exposing all cluster-internal ports including inter-node communication (`7000`), cluster discovery (`6000`), and intra-cluster Bolt (`7688`). @@ -146,37 +150,41 @@ KubeDB creates a Secret named `{neo4j-name}-auth` containing the `neo4j` superus Retrieve the credentials: ```bash -$ kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.username}' | base64 -d +``` neo4j -$ kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d -Xk9mR2qLpTz3vYwB +```bash +kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d ``` +Xk9mR2qLpTz3vYwB ### Connect via cypher-shell Exec into any pod and use `cypher-shell` to verify the cluster is accepting queries: ```bash -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" "RETURN 'connected' AS status" +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" "RETURN 'connected' AS status" +``` +-------------+ | status | +-------------+ | "connected" | +-------------+ -``` ### Connect via Neo4j Browser You can access the Neo4j Browser UI from your local machine by port-forwarding the cluster service: ```bash -$ kubectl port-forward -n demo svc/neo4j-test 7474:7474 7687:7687 +kubectl port-forward -n demo svc/neo4j-test 7474:7474 7687:7687 +``` Forwarding from 127.0.0.1:7474 -> 7474 Forwarding from 127.0.0.1:7687 -> 7687 -``` Now open your browser and navigate to: @@ -212,12 +220,14 @@ After a successful login, you will land on the Neo4j Browser home. You can run C To remove all resources created by this tutorial: ```bash -$ kubectl delete neo4j -n demo neo4j-test +kubectl delete neo4j -n demo neo4j-test +``` neo4j.kubedb.com "neo4j-test" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted > Note: Since `deletionPolicy` is set to `WipeOut`, deleting the `Neo4j` CR also removes all associated PVCs and the auth Secret. diff --git a/docs/guides/neo4j/reconfigure-tls/reconfigure-tls.md b/docs/guides/neo4j/reconfigure-tls/reconfigure-tls.md index 3378405764..611f51ee2a 100644 --- a/docs/guides/neo4j/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/neo4j/reconfigure-tls/reconfigure-tls.md @@ -24,9 +24,9 @@ KubeDB supports TLS reconfiguration for existing `Neo4j` databases through `Neo4 - This guide uses namespace `demo`. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created This guide assumes a running Neo4j database named `tls-neo4j` in namespace `demo`. @@ -37,25 +37,25 @@ If you already have an `Issuer`/`ClusterIssuer`, you can skip this section. Generate a CA certificate and private key: ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=neo4j-ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=neo4j-ca/O=kubedb" +``` Generating a RSA private key ...+++++ ...+++++ writing new private key to 'ca.key' ----- -``` Create a TLS secret from the generated CA files: ```bash -$ kubectl create secret tls neo4j-ca --cert=ca.crt --key=ca.key -n demo -secret/neo4j-ca created +kubectl create secret tls neo4j-ca --cert=ca.crt --key=ca.key -n demo ``` +secret/neo4j-ca created Create an `Issuer` using that secret: ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: Issuer metadata: @@ -65,12 +65,14 @@ spec: ca: secretName: neo4j-ca EOF +``` issuer.cert-manager.io/neo4j-ca-issuer created -$ kubectl get issuer -n demo neo4j-ca-issuer +```bash +kubectl get issuer -n demo neo4j-ca-issuer +``` NAME READY AGE neo4j-ca-issuer True 10s -``` ## Add TLS to Neo4j @@ -100,7 +102,7 @@ Here, - `spec.tls.issuerRef` defines which issuer should sign/re-issue certificates. ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -116,45 +118,55 @@ spec: kind: Issuer name: neo4j-ca-issuer EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-add-tls created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-add-tls -n demo --timeout=600s -neo4jopsrequest.ops.kubedb.com/neo4j-add-tls condition met +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-add-tls -n demo --timeout=600s ``` +neo4jopsrequest.ops.kubedb.com/neo4j-add-tls condition met Verify request status, generated certs, and encrypted connection via `neo4j+s`: ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-add-tls +kubectl get neo4jopsrequest -n demo neo4j-add-tls +``` NAME TYPE STATUS AGE neo4j-add-tls ReconfigureTLS Successful 2m -$ kubectl get secret -n demo tls-neo4j-server-cert +```bash +kubectl get secret -n demo tls-neo4j-server-cert +``` NAME TYPE DATA AGE tls-neo4j-server-cert kubernetes.io/tls 3 2m -$ kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +```bash +kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` notBefore=May 15 07:10:28 2026 GMT notAfter=Aug 13 07:10:28 2026 GMT -$ kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.password}' | base64 -d && echo +```bash +kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.password}' | base64 -d && echo +``` 8pyn3zno7QbX4iQn -$ kubectl exec -it -n demo tls-neo4j-0 -- cypher-shell -a neo4j+s://tls-neo4j-0.demo.svc.cluster.local:7687 -u neo4j -p '8pyn3zno7QbX4iQn' +```bash +kubectl exec -it -n demo tls-neo4j-0 -- cypher-shell -a neo4j+s://tls-neo4j-0.demo.svc.cluster.local:7687 -u neo4j -p '8pyn3zno7QbX4iQn' +``` Connected to Neo4j using Bolt protocol version 6.0 at neo4j+s://tls-neo4j-0.demo.svc.cluster.local:7687 as user neo4j. Type :help for a list of available commands or :exit to exit the shell. Note that Cypher queries must end with a semicolon. -``` ## Rotate TLS Certificates Before rotation, check current certificate validity window: ```bash -$ kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` notBefore=May 15 07:10:28 2026 GMT notAfter=Aug 13 07:10:28 2026 GMT -``` Now rotate certificates and update Bolt TLS mode: @@ -175,7 +187,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -190,19 +202,25 @@ spec: bolt: mode: mTLS EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-reconfigure-tls created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-reconfigure-tls -n demo --timeout=600s +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-reconfigure-tls -n demo --timeout=600s +``` neo4jopsrequest.ops.kubedb.com/neo4j-reconfigure-tls condition met -$ kubectl get neo4jopsrequest -n demo neo4j-reconfigure-tls +```bash +kubectl get neo4jopsrequest -n demo neo4j-reconfigure-tls +``` NAME TYPE STATUS AGE neo4j-reconfigure-tls ReconfigureTLS Successful 2m -$ kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +```bash +kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` notBefore=May 15 07:24:11 2026 GMT notAfter=Aug 13 07:24:11 2026 GMT -``` The changed certificate timestamp confirms rotation happened successfully. @@ -211,17 +229,21 @@ The changed certificate timestamp confirms rotation happened successfully. Create a new CA and issuer: ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout new-ca.key -out new-ca.crt -subj "/CN=neo4j-ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout new-ca.key -out new-ca.crt -subj "/CN=neo4j-ca-updated/O=kubedb-updated" +``` Generating a RSA private key ...+++++ ...+++++ writing new private key to 'new-ca.key' ----- -$ kubectl create secret tls neo4j-new-ca --cert=new-ca.crt --key=new-ca.key -n demo +```bash +kubectl create secret tls neo4j-new-ca --cert=new-ca.crt --key=new-ca.key -n demo +``` secret/neo4j-new-ca created -$ cat <<'EOF' | kubectl apply -f - +```bash +cat <<'EOF' | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: Issuer metadata: @@ -231,8 +253,8 @@ spec: ca: secretName: neo4j-new-ca EOF -issuer.cert-manager.io/neo4j-new-ca-issuer created ``` +issuer.cert-manager.io/neo4j-new-ca-issuer created Apply an OpsRequest that points to the new issuer: @@ -254,7 +276,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -270,14 +292,18 @@ spec: kind: Issuer name: neo4j-new-ca-issuer EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-change-issuer created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-change-issuer -n demo --timeout=600s +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-change-issuer -n demo --timeout=600s +``` neo4jopsrequest.ops.kubedb.com/neo4j-change-issuer condition met -$ kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject -subject=CN = neo4j-ca-updated, O = kubedb-updated +```bash +kubectl get secret -n demo tls-neo4j-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject ``` +subject=CN = neo4j-ca-updated, O = kubedb-updated ## Remove TLS from Neo4j @@ -298,7 +324,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -311,45 +337,55 @@ spec: tls: remove: true EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-remove-tls created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-remove-tls -n demo --timeout=600s +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-remove-tls -n demo --timeout=600s +``` neo4jopsrequest.ops.kubedb.com/neo4j-remove-tls condition met -$ kubectl get neo4jopsrequest -n demo neo4j-remove-tls +```bash +kubectl get neo4jopsrequest -n demo neo4j-remove-tls +``` NAME TYPE STATUS AGE neo4j-remove-tls ReconfigureTLS Successful 1m -``` ## Verify All Requests ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-reconfigure-tls +kubectl get neo4jopsrequest -n demo neo4j-reconfigure-tls +``` NAME TYPE STATUS AGE neo4j-reconfigure-tls ReconfigureTLS Successful 2m -$ kubectl get neo4jopsrequest -n demo neo4j-remove-tls +```bash +kubectl get neo4jopsrequest -n demo neo4j-remove-tls +``` NAME TYPE STATUS AGE neo4j-remove-tls ReconfigureTLS Successful 1m -$ kubectl get neo4jopsrequest -n demo neo4j-add-tls +```bash +kubectl get neo4jopsrequest -n demo neo4j-add-tls +``` NAME TYPE STATUS AGE neo4j-add-tls ReconfigureTLS Successful 1m -$ kubectl get neo4jopsrequest -n demo neo4j-change-issuer +```bash +kubectl get neo4jopsrequest -n demo neo4j-change-issuer +``` NAME TYPE STATUS AGE neo4j-change-issuer ReconfigureTLS Successful 1m -``` ## Cleaning up ```bash -$ kubectl delete neo4jopsrequest -n demo neo4j-add-tls neo4j-reconfigure-tls neo4j-change-issuer neo4j-remove-tls +kubectl delete neo4jopsrequest -n demo neo4j-add-tls neo4j-reconfigure-tls neo4j-change-issuer neo4j-remove-tls +``` neo4jopsrequest.ops.kubedb.com "neo4j-add-tls" deleted neo4jopsrequest.ops.kubedb.com "neo4j-reconfigure-tls" deleted neo4jopsrequest.ops.kubedb.com "neo4j-change-issuer" deleted neo4jopsrequest.ops.kubedb.com "neo4j-remove-tls" deleted -``` ## Next Steps diff --git a/docs/guides/neo4j/reconfigure/reconfigure.md b/docs/guides/neo4j/reconfigure/reconfigure.md index 54ea0b2330..58d22c13dc 100644 --- a/docs/guides/neo4j/reconfigure/reconfigure.md +++ b/docs/guides/neo4j/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ We will: - Review [Neo4j](/docs/guides/neo4j/concepts/neo4j.md), [OpsRequest](/docs/guides/neo4j/concepts/opsrequest.md), and [Reconfigure Overview](/docs/guides/neo4j/reconfigure/overview.md). ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Database @@ -59,7 +59,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: kubedb.com/v1alpha2 kind: Neo4j metadata: @@ -78,19 +78,24 @@ spec: storage: 2Gi deletionPolicy: WipeOut EOF +``` neo4j.kubedb.com/neo4j-test created -$ kubectl wait --for=condition=Ready neo4j/neo4j-test -n demo --timeout=600s -neo4j.kubedb.com/neo4j-test condition met +```bash +kubectl wait --for=condition=Ready neo4j/neo4j-test -n demo --timeout=600s ``` +neo4j.kubedb.com/neo4j-test condition met ## Check Current Settings (Before Reconfigure) Before applying the reconfigure request, connect with `cypher-shell` and check current values: ```bash -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -it -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -it -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" ``` These are the current values before running the reconfigure OpsRequest. @@ -173,7 +178,7 @@ stringData: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: v1 kind: Secret metadata: @@ -186,8 +191,8 @@ stringData: -XX:+UseG1GC -XX:-OmitStackTraceInFastThrow EOF -secret/custom-config created ``` +secret/custom-config created ## Reconfigure Request @@ -219,7 +224,7 @@ Here, - If the same key exists in both places, `applyConfig` takes precedence. ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -237,27 +242,32 @@ spec: timeout: 5m apply: IfReady EOF +``` neo4jopsrequest.ops.kubedb.com/reconfigure created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/reconfigure -n demo --timeout=600s -neo4jopsrequest.ops.kubedb.com/reconfigure condition met +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/reconfigure -n demo --timeout=600s ``` +neo4jopsrequest.ops.kubedb.com/reconfigure condition met ## Verify Reconfiguration Check OpsRequest status: ```bash -$ kubectl get neo4jopsrequest -n demo reconfigure +kubectl get neo4jopsrequest -n demo reconfigure +``` NAME TYPE STATUS AGE reconfigure Reconfigure Successful 2m5s -``` Now run the same three queries again and confirm updated values: ```bash -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -it -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` + +```bash +kubectl exec -it -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" ``` Check `db.query` settings: @@ -330,18 +340,26 @@ From the output: ## Cleaning up ```bash -$ kubectl delete neo4jopsrequest -n demo reconfigure +kubectl delete neo4jopsrequest -n demo reconfigure +``` neo4jopsrequest.ops.kubedb.com "reconfigure" deleted -$ kubectl delete secret -n demo custom-config +```bash +kubectl delete secret -n demo custom-config +``` secret "custom-config" deleted -$ kubectl patch -n demo neo4j/neo4j-test -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo neo4j/neo4j-test -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` neo4j.kubedb.com/neo4j-test patched -$ kubectl delete -n demo neo4j/neo4j-test +```bash +kubectl delete -n demo neo4j/neo4j-test +``` neo4j.kubedb.com "neo4j-test" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/neo4j/restart/restart.md b/docs/guides/neo4j/restart/restart.md index 1ba7932603..ede1e2d2b9 100644 --- a/docs/guides/neo4j/restart/restart.md +++ b/docs/guides/neo4j/restart/restart.md @@ -52,9 +52,11 @@ spec: Apply it and wait for the cluster to become ready: ```bash -$ kubectl apply -f neo4j.yaml +kubectl apply -f neo4j.yaml +``` -$ kubectl get neo4j -n demo neo4j-test -w +```bash +kubectl get neo4j -n demo neo4j-test -w ``` Wait until `STATUS` shows `Ready` before proceeding. @@ -83,7 +85,7 @@ spec: `apply: Always` tells KubeDB to execute the restart even if the database is not currently in the ready state. ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -96,20 +98,25 @@ spec: timeout: 5m apply: Always EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-restart created -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-restart -n demo --timeout=600s -neo4jopsrequest.ops.kubedb.com/neo4j-restart condition met +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful neo4jopsrequest/neo4j-restart -n demo --timeout=600s ``` +neo4jopsrequest.ops.kubedb.com/neo4j-restart condition met ## Verify ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-restart +kubectl get neo4jopsrequest -n demo neo4j-restart +``` NAME TYPE STATUS AGE neo4j-restart Restart Successful 1m -$ kubectl describe neo4jopsrequest -n demo neo4j-restart +```bash +kubectl describe neo4jopsrequest -n demo neo4j-restart +``` Name: neo4j-restart Namespace: demo Labels: @@ -125,7 +132,6 @@ Spec: Apply: Always Status: Phase: Successful -``` ## Cleaning up diff --git a/docs/guides/neo4j/rotate-auth/rotateauth.md b/docs/guides/neo4j/rotate-auth/rotateauth.md index b10255167a..5795ce46a1 100644 --- a/docs/guides/neo4j/rotate-auth/rotateauth.md +++ b/docs/guides/neo4j/rotate-auth/rotateauth.md @@ -120,9 +120,11 @@ spec: Apply it and wait for completion: ```bash -$ kubectl apply -f neo4j-rotate-auth.yaml +kubectl apply -f neo4j-rotate-auth.yaml +``` -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful \ +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful \ neo4jopsrequest/neo4j-rotate-auth \ -n demo --timeout=900s ``` @@ -136,13 +138,15 @@ neo4jopsrequest.ops.kubedb.com/neo4j-rotate-auth condition met ### Step 3 — Verify the Password Changed ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-rotate-auth - +kubectl get neo4jopsrequest -n demo neo4j-rotate-auth +``` AFTER_B64=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}') [ "$BEFORE_B64" != "$AFTER_B64" ] && echo "password_changed=true" || echo "password_changed=false" NEW_PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$NEW_PASS" "RETURN 'auth-ok' AS status" + +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$NEW_PASS" "RETURN 'auth-ok' AS status" ``` Expected output: @@ -168,7 +172,7 @@ In this mode, you supply a Kubernetes Secret containing your chosen password. Ku ### Step 1 — Create the Auth Secret ```bash -$ kubectl create secret generic external-neo4j-auth \ +kubectl create secret generic external-neo4j-auth \ -n demo \ --from-literal=username=neo4j \ --from-literal=password='Neo4j@12345' \ @@ -202,9 +206,11 @@ spec: Apply it and wait for completion: ```bash -$ kubectl apply -f neo4j-rotate-auth-user.yaml +kubectl apply -f neo4j-rotate-auth-user.yaml +``` -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful \ +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful \ neo4jopsrequest/neo4j-rotate-auth-user \ -n demo --timeout=900s ``` @@ -218,9 +224,11 @@ neo4jopsrequest.ops.kubedb.com/neo4j-rotate-auth-user condition met ### Step 3 — Verify Login with the New Password ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-rotate-auth-user +kubectl get neo4jopsrequest -n demo neo4j-rotate-auth-user +``` -$ kubectl exec -n demo neo4j-test-0 -- \ +```bash +kubectl exec -n demo neo4j-test-0 -- \ cypher-shell -u neo4j -p 'Neo4j@12345' "RETURN 'user-auth-ok' AS status" ``` @@ -253,10 +261,19 @@ status ## Cleanup ```bash -$ kubectl delete neo4jopsrequest -n demo neo4j-rotate-auth neo4j-rotate-auth-user -$ kubectl delete secret -n demo external-neo4j-auth -$ kubectl delete neo4j -n demo neo4j-test -$ kubectl delete ns demo +kubectl delete neo4jopsrequest -n demo neo4j-rotate-auth neo4j-rotate-auth-user +``` + +```bash +kubectl delete secret -n demo external-neo4j-auth +``` + +```bash +kubectl delete neo4j -n demo neo4j-test +``` + +```bash +kubectl delete ns demo ``` --- diff --git a/docs/guides/neo4j/scaling/horizontal-scaling/scale-horizontally/index.md b/docs/guides/neo4j/scaling/horizontal-scaling/scale-horizontally/index.md index 1218ee82eb..2ab124611a 100644 --- a/docs/guides/neo4j/scaling/horizontal-scaling/scale-horizontally/index.md +++ b/docs/guides/neo4j/scaling/horizontal-scaling/scale-horizontally/index.md @@ -56,7 +56,7 @@ You verify the result using two complementary Cypher views: ## Step 1 — Set Up the Namespace ```bash -$ kubectl create ns demo +kubectl create ns demo ``` --- @@ -66,9 +66,11 @@ $ kubectl create ns demo Apply the example manifest and wait for the cluster to become ready: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/neo4j/quickstart/neo4j.yaml +``` -$ kubectl get neo4j -n demo neo4j-test -w +```bash +kubectl get neo4j -n demo neo4j-test -w ``` Wait until `STATUS` shows `Ready` before proceeding. @@ -134,7 +136,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -150,28 +152,35 @@ spec: strategy: "incremental" batchSize: 1 EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-up created -$ kubectl wait \ +```bash +kubectl wait \ --for=jsonpath='{.status.phase}'=Successful \ neo4jopsrequest/neo4j-horizontal-scale-up \ -n demo --timeout=900s -neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-up condition met ``` +neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-up condition met ### Verify the Scale-Up Run these commands to confirm the cluster now has 5 members and that databases have been reallocated: ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-horizontal-scale-up +kubectl get neo4jopsrequest -n demo neo4j-horizontal-scale-up +``` NAME TYPE STATUS AGE neo4j-horizontal-scale-up HorizontalScaling Successful 16s -$ kubectl get neo4j -n demo neo4j-test -o jsonpath='{.spec.replicas}{"\n"}' +```bash +kubectl get neo4j -n demo neo4j-test -o jsonpath='{.spec.replicas}{"\n"}' +``` 5 -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` NAME READY STATUS RESTARTS AGE neo4j-test-0 1/1 Running 0 ... neo4j-test-1 1/1 Running 0 ... @@ -179,23 +188,28 @@ neo4j-test-2 1/1 Running 0 ... neo4j-test-3 1/1 Running 0 ... neo4j-test-4 1/1 Running 0 ... -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +```bash +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ "SHOW DATABASE appdb YIELD name, currentStatus, currentPrimariesCount, currentSecondariesCount RETURN name, currentStatus, currentPrimariesCount, currentSecondariesCount" +``` name, currentStatus, currentPrimariesCount, currentSecondariesCount "appdb", "online", 2, 0 "appdb", "online", 2, 0 -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ "SHOW SERVERS YIELD name, state, health, hosting RETURN name, state, health, hosting ORDER BY name" +``` name, state, health, hosting "neo4j-test-0", "Enabled", "Available", ["neo4j", "system"] "neo4j-test-1", "Enabled", "Available", ["neo4j", "system"] "neo4j-test-2", "Enabled", "Available", ["appdb", "system"] "neo4j-test-3", "Enabled", "Available", ["appdb", "system"] "neo4j-test-4", "Enabled", "Available", ["system"] -``` > **What to look for:** > - All 5 pods are `Running` @@ -225,7 +239,7 @@ spec: ``` ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: ops.kubedb.com/v1alpha1 kind: Neo4jOpsRequest metadata: @@ -240,53 +254,66 @@ spec: reallocate: strategy: "full" EOF +``` neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-down created -$ kubectl wait \ +```bash +kubectl wait \ --for=jsonpath='{.status.phase}'=Successful \ neo4jopsrequest/neo4j-horizontal-scale-down \ -n demo --timeout=900s -neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-down condition met ``` +neo4jopsrequest.ops.kubedb.com/neo4j-horizontal-scale-down condition met ### Verify the Scale-Down ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-horizontal-scale-down +kubectl get neo4jopsrequest -n demo neo4j-horizontal-scale-down +``` NAME TYPE STATUS AGE neo4j-horizontal-scale-down HorizontalScaling Successful 37s -$ kubectl get neo4j -n demo neo4j-test -o jsonpath='{.spec.replicas}{"\n"}' +```bash +kubectl get neo4j -n demo neo4j-test -o jsonpath='{.spec.replicas}{"\n"}' +``` 3 -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` NAME READY STATUS RESTARTS AGE neo4j-test-0 1/1 Running 0 ... neo4j-test-1 1/1 Running 0 ... neo4j-test-2 1/1 Running 0 ... -$ PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +```bash +PASS=$(kubectl get secret -n demo neo4j-test-auth -o jsonpath='{.data.password}' | base64 -d) +``` -$ kubectl exec -n demo neo4j-test-0 -- \ +```bash +kubectl exec -n demo neo4j-test-0 -- \ cypher-shell -d appdb -u neo4j -p "$PASS" \ "MATCH (u:User) RETURN count(u) AS totalUsers" +``` totalUsers 2000 -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ "SHOW DATABASE appdb YIELD name, currentStatus, currentPrimariesCount, currentSecondariesCount RETURN name, currentStatus, currentPrimariesCount, currentSecondariesCount" +``` name, currentStatus, currentPrimariesCount, currentSecondariesCount "appdb", "online", 2, 0 "appdb", "online", 2, 0 - -$ kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ +```bash +kubectl exec -n demo neo4j-test-0 -- cypher-shell -u neo4j -p "$PASS" \ "SHOW SERVERS YIELD name, state, health, hosting RETURN name, state, health, hosting ORDER BY name" +``` name, state, health, hosting "neo4j-test-0", "Enabled", "Available", ["neo4j", "system"] "neo4j-test-1", "Enabled", "Available", ["appdb", "neo4j", "system"] "neo4j-test-2", "Enabled", "Available", ["appdb", "system"] -``` > ✅ The `totalUsers: 2000` result confirms **no data was lost** during the scale-down. The database remained online and queryable throughout. @@ -325,15 +352,21 @@ If this OpsRequest does not finish, first inspect the affected pod and then chec Check the OpsRequest status, the pod events, and cluster allocation: ```bash -$ kubectl describe neo4jopsrequest -n demo -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test -$ kubectl describe pod -n demo neo4j-test-0 +kubectl describe neo4jopsrequest -n demo +``` + +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` + +```bash +kubectl describe pod -n demo neo4j-test-0 ``` If the node is full, the new server count may not be schedulable. Check node capacity: ```bash -$ kubectl describe node | grep -A 10 "Allocated resources" +kubectl describe node | grep -A 10 "Allocated resources" ``` **Database shows `offline` after scaling** @@ -341,8 +374,11 @@ $ kubectl describe node | grep -A 10 "Allocated resources" Neo4j may need time to reallocate. Wait a few seconds and re-run `SHOW DATABASE`. If it persists, check the `kubedb-ops-manager` logs and pod readiness: ```bash -$ kubectl logs -n -l app.kubernetes.io/name=kubedb-ops-manager --tail=50 -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +kubectl logs -n -l app.kubernetes.io/name=kubedb-ops-manager --tail=50 +``` + +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test ``` **OpsRequest moves to `Failed`** @@ -350,8 +386,11 @@ $ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test Read the failure condition and then inspect the `kubedb-ops-manager` logs: ```bash -$ kubectl get neo4jopsrequest -n demo -o jsonpath='{.status.conditions}' | jq . -$ kubectl logs -n -l app.kubernetes.io/name=kubedb-ops-manager --tail=50 +kubectl get neo4jopsrequest -n demo -o jsonpath='{.status.conditions}' | jq . +``` + +```bash +kubectl logs -n -l app.kubernetes.io/name=kubedb-ops-manager --tail=50 ``` --- @@ -361,11 +400,17 @@ $ kubectl logs -n -l app.kubernetes.io/name=kubedb-ops-manage Remove all resources created in this guide: ```bash -$ kubectl delete neo4jopsrequest -n demo \ +kubectl delete neo4jopsrequest -n demo \ neo4j-horizontal-scale-up \ neo4j-horizontal-scale-down -$ kubectl delete neo4j -n demo neo4j-test -$ kubectl delete ns demo +``` + +```bash +kubectl delete neo4j -n demo neo4j-test +``` + +```bash +kubectl delete ns demo ``` --- diff --git a/docs/guides/neo4j/scaling/vertical-scaling/scale-vertically/index.md b/docs/guides/neo4j/scaling/vertical-scaling/scale-vertically/index.md index 563bc03168..8423c1abb2 100644 --- a/docs/guides/neo4j/scaling/vertical-scaling/scale-vertically/index.md +++ b/docs/guides/neo4j/scaling/vertical-scaling/scale-vertically/index.md @@ -48,7 +48,7 @@ See also: [Neo4j](/docs/guides/neo4j/concepts/neo4j.md) · [Neo4jOpsRequest](/do ## Step 1 — Set Up the Namespace ```bash -$ kubectl create ns demo +kubectl create ns demo ``` --- @@ -90,9 +90,11 @@ spec: Apply it and wait for the cluster to become ready: ```bash -$ kubectl apply -f neo4j.yaml +kubectl apply -f neo4j.yaml +``` -$ kubectl get neo4j -n demo neo4j-test -w +```bash +kubectl get neo4j -n demo neo4j-test -w ``` Wait until `STATUS` shows `Ready` before proceeding. @@ -109,7 +111,7 @@ neo4j-test 2025.12.1 Ready 3m Before scaling, record the existing CPU and memory values so you can confirm the change later. ```bash -$ kubectl get pod -n demo neo4j-test-0 \ +kubectl get pod -n demo neo4j-test-0 \ -o jsonpath='{.spec.containers[0].resources}' | jq . ``` @@ -154,9 +156,11 @@ spec: Apply it and wait for completion: ```bash -$ kubectl apply -f neo4j-vertical-scale.yaml +kubectl apply -f neo4j-vertical-scale.yaml +``` -$ kubectl wait --for=jsonpath='{.status.phase}'=Successful \ +```bash +kubectl wait --for=jsonpath='{.status.phase}'=Successful \ neo4jopsrequest/neo4j-vertical-scale \ -n demo --timeout=600s ``` @@ -179,7 +183,7 @@ Once you apply the OpsRequest, KubeDB Ops-manager picks it up and begins the sca You can watch the live status with: ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-vertical-scale -w +kubectl get neo4jopsrequest -n demo neo4j-vertical-scale -w ``` --- @@ -187,9 +191,11 @@ $ kubectl get neo4jopsrequest -n demo neo4j-vertical-scale -w ## Step 5 — Verify the New Resources ```bash -$ kubectl get neo4jopsrequest -n demo neo4j-vertical-scale +kubectl get neo4jopsrequest -n demo neo4j-vertical-scale +``` -$ kubectl get pod -n demo neo4j-test-0 \ +```bash +kubectl get pod -n demo neo4j-test-0 \ -o jsonpath='{.spec.containers[0].resources}' | jq . ``` @@ -231,9 +237,15 @@ If this OpsRequest does not finish, first inspect the affected pod and then chec Check the pod that is being restarted and look for scheduling or resource issues: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test -$ kubectl describe pod -n demo neo4j-test-0 -$ kubectl describe node | grep -A 10 "Allocated resources" +kubectl get pods -n demo -l app.kubernetes.io/instance=neo4j-test +``` + +```bash +kubectl describe pod -n demo neo4j-test-0 +``` + +```bash +kubectl describe node | grep -A 10 "Allocated resources" ``` **OpsRequest moves to `Failed`** diff --git a/docs/guides/neo4j/tls/configure/index.md b/docs/guides/neo4j/tls/configure/index.md index 4ffc104ca0..d1522d2025 100644 --- a/docs/guides/neo4j/tls/configure/index.md +++ b/docs/guides/neo4j/tls/configure/index.md @@ -23,21 +23,25 @@ section_menu_id: guides - Install KubeDB following [the setup guide](/docs/setup/README.md). ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Create Issuer Create a CA secret and an `Issuer` that KubeDB will use to generate Neo4j certificates. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=neo4j/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/CN=neo4j/O=kubedb" +``` -$ kubectl create secret tls neo4j-ca --cert=ca.crt --key=ca.key -n demo +```bash +kubectl create secret tls neo4j-ca --cert=ca.crt --key=ca.key -n demo +``` secret/neo4j-ca created -$ cat <<'EOF' | kubectl apply -f - +```bash +cat <<'EOF' | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: Issuer metadata: @@ -47,8 +51,8 @@ spec: ca: secretName: neo4j-ca EOF -issuer.cert-manager.io/neo4j-ca-issuer created ``` +issuer.cert-manager.io/neo4j-ca-issuer created ## Deploy Neo4j with TLS @@ -92,7 +96,7 @@ Here, Apply the CR: ```bash -$ cat <<'EOF' | kubectl apply -f - +cat <<'EOF' | kubectl apply -f - apiVersion: kubedb.com/v1alpha2 kind: Neo4j metadata: @@ -120,56 +124,64 @@ spec: mode: mTLS deletionPolicy: WipeOut EOF -neo4j.kubedb.com/tls-neo4j created ``` +neo4j.kubedb.com/tls-neo4j created ## Verify TLS Check database readiness and generated TLS secret: ```bash -$ kubectl wait --for=condition=Ready neo4j/tls-neo4j -n demo --timeout=600s +kubectl wait --for=condition=Ready neo4j/tls-neo4j -n demo --timeout=600s +``` neo4j.kubedb.com/tls-neo4j condition met -$ kubectl get secret -n demo tls-neo4j-server-cert +```bash +kubectl get secret -n demo tls-neo4j-server-cert +``` NAME TYPE DATA AGE tls-neo4j-server-cert kubernetes.io/tls 3 2m -``` Get Neo4j credentials: ```bash -$ kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.username}' | base64 -d && echo +kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.username}' | base64 -d && echo +``` neo4j -$ kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.password}' | base64 -d && echo -8pyn3zno7QbX4iQn +```bash +kubectl get secret -n demo tls-neo4j-auth -o jsonpath='{.data.password}' | base64 -d && echo ``` +8pyn3zno7QbX4iQn Connect using `neo4j+s` and verify TLS session: ```bash -$ kubectl exec -it -n demo tls-neo4j-0 -- bash +kubectl exec -it -n demo tls-neo4j-0 -- bash +``` neo4j@tls-neo4j-0:~$ cypher-shell -a neo4j+s://tls-neo4j-0.demo.svc.cluster.local:7687 -u neo4j -p '8pyn3zno7QbX4iQn' Connected to Neo4j using Bolt protocol version 6.0 at neo4j+s://tls-neo4j-0.demo.svc.cluster.local:7687 as user neo4j. Type :help for a list of available commands or :exit to exit the shell. Note that Cypher queries must end with a semicolon. -``` The successful `neo4j+s` connection confirms the cluster is accepting encrypted, certificate-validated Bolt traffic. ## Cleaning up ```bash -$ kubectl patch -n demo neo4j/tls-neo4j -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo neo4j/tls-neo4j -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` neo4j.kubedb.com/tls-neo4j patched -$ kubectl delete -n demo neo4j/tls-neo4j +```bash +kubectl delete -n demo neo4j/tls-neo4j +``` neo4j.kubedb.com "tls-neo4j" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/oracle/concepts/oracle.md b/docs/guides/oracle/concepts/oracle.md index a97453c796..4428673012 100644 --- a/docs/guides/oracle/concepts/oracle.md +++ b/docs/guides/oracle/concepts/oracle.md @@ -89,11 +89,10 @@ spec: memory: 3Gi deletionPolicy: Delete ``` -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/quickstart/standalone.yaml -oracle.kubedb.com/oracle created - +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/quickstart/standalone.yaml ``` +oracle.kubedb.com/oracle created #### 2. DataGuard Mode Configuration ```yaml diff --git a/docs/guides/oracle/configuration/using-config-file.md b/docs/guides/oracle/configuration/using-config-file.md index 52651234fb..ee12eba493 100644 --- a/docs/guides/oracle/configuration/using-config-file.md +++ b/docs/guides/oracle/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Oracle. This tutorial will sh - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/configuration](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/configuration) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,9 +64,9 @@ stringData: Let's create the Secret, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/configuration/oracle-custom-config-secret.yaml -secret/oracle-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/configuration/oracle-custom-config-secret.yaml ``` +secret/oracle-custom-config created Now, create an `Oracle` CR that references this Secret through `spec.configuration.secretName`. The following is a **Standalone** example: @@ -105,9 +105,9 @@ Here, Create the database, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/configuration/standalone-cus-conf.yaml -oracle.kubedb.com/standalone-cus-conf created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/configuration/standalone-cus-conf.yaml ``` +oracle.kubedb.com/standalone-cus-conf created For a **DataGuard** cluster the configuration is supplied the same way — only `mode`, `replicas`, and the name change: @@ -219,19 +219,21 @@ Once the database is `Ready` (and the pod has printed the `DATABASE IS READY TO First, KubeDB projects the configuration file into the database pod at `/etc/config/oracle.cnf`, ```bash -$ kubectl exec -n demo standalone-cus-conf-0 -c oracle -- cat /etc/config/oracle.cnf -PROCESSES = 800 +kubectl exec -n demo standalone-cus-conf-0 -c oracle -- cat /etc/config/oracle.cnf ``` +PROCESSES = 800 Now, let's connect to the database and confirm that the `processes` parameter has actually been set to `800`, ```bash -$ kubectl get secret -n demo standalone-cus-conf-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo standalone-cus-conf-auth -o jsonpath='{.data.password}' | base64 -d +``` # (use the printed password below) -$ kubectl exec -n demo standalone-cus-conf-0 -c oracle -- bash -lc \ +```bash +kubectl exec -n demo standalone-cus-conf-0 -c oracle -- bash -lc \ "echo -e 'SHOW PARAMETER processes;\nexit;' | sqlplus -s sys/@localhost:1521/ORCL as sysdba" - +``` NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ aq_tm_processes integer 1 @@ -241,7 +243,6 @@ global_txn_processes integer 1 job_queue_processes integer 308 log_archive_max_processes integer 30 processes integer 800 -``` The `processes` parameter is now `800`, confirming that our custom configuration was applied successfully. diff --git a/docs/guides/oracle/failover/overview.md b/docs/guides/oracle/failover/overview.md index 3e8d9dffdd..a0834944c4 100644 --- a/docs/guides/oracle/failover/overview.md +++ b/docs/guides/oracle/failover/overview.md @@ -37,16 +37,15 @@ This guide demonstrates how to set up an `Oracle HA cluster` with `Data Guard` e Check StorageClasses: ```bash -$ kubectl get storageclasses +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 13d -``` - * We’ll use the `demo` namespace for isolation: ```bash -$ kubectl create ns demo +kubectl create ns demo ``` **Create an Oracle Container Registry token, if you haven't created one already, by following the instructions in the guide below:** @@ -173,23 +172,21 @@ Here, Apply the manifest: ```bash -$ kubectl apply -f oracle-dataguard.yaml +kubectl apply -f oracle-dataguard.yaml ``` -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/dataguard/dataguard.yaml -oracle.kubedb.com/oracle-sample created - +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/dataguard/dataguard.yaml ``` +oracle.kubedb.com/oracle-sample created Monitor status until all pods are ready: ```bash -$ watch kubectl get oracle -n demo +watch kubectl get oracle -n demo +``` NAME VERSION MODE STATUS AGE oracle-sample 21.3.0 DataGuard Ready 25m -``` - --- ### Step 2: Understanding Oracle Data Guard Failover @@ -238,13 +235,12 @@ consistent, and resilient against node or pod failures. You can check current roles: ```bash -$ kubectl get pods -n demo --show-labels | grep role +kubectl get pods -n demo --show-labels | grep role +``` oracle-sample-0 2/2 Running 0 49m app.kubernetes.io/component=database,app.kubernetes.io/instance=oracle-sample,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=oracles.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=oracle-sample-6d6fdb69ff,kubedb.com/role=primary,oracle.db/role=instance,statefulset.kubernetes.io/pod-name=oracle-sample-0 oracle-sample-1 2/2 Running 0 49m app.kubernetes.io/component=database,app.kubernetes.io/instance=oracle-sample,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=oracles.kubedb.com,apps.kubernetes.io/pod-index=1,controller-revision-hash=oracle-sample-6d6fdb69ff,kubedb.com/role=standby,oracle.db/role=instance,statefulset.kubernetes.io/pod-name=oracle-sample-1 oracle-sample-2 2/2 Running 0 48m app.kubernetes.io/component=database,app.kubernetes.io/instance=oracle-sample,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=oracles.kubedb.com,apps.kubernetes.io/pod-index=2,controller-revision-hash=oracle-sample-6d6fdb69ff,kubedb.com/role=standby,oracle.db/role=instance,statefulset.kubernetes.io/pod-name=oracle-sample-2 oracle-sample-observer-0 1/1 Running 0 49m app.kubernetes.io/component=database,app.kubernetes.io/instance=oracle-sample,app.kubernetes.io/managed-by=kubedb.com,app.kubernetes.io/name=oracles.kubedb.com,apps.kubernetes.io/pod-index=0,controller-revision-hash=oracle-sample-observer-68648c7957,oracle.db/role=observer,statefulset.kubernetes.io/pod-name=oracle-sample-observer-0 - -``` The pod having `kubedb.com/role=primary` is the primary, `kubedb.com/role=standby` are the standby's and `oracle-sample-observer-0` is the observer. @@ -346,8 +342,8 @@ SQL> SELECT * FROM kathak; ``` Typical output: -```shell -$ watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" +```bash +watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" ``` ```bash @@ -362,7 +358,7 @@ oracle-sample-observer-0 #### Case 1: Delete the Primary ```bash -$ kubectl delete pod -n demo oracle-sample-0 +kubectl delete pod -n demo oracle-sample-0 ``` Within few minutes (defined by `fastStartFailoverThreshold`), a standby is promoted: @@ -474,12 +470,11 @@ bash-4.2$ command terminated with exit code 137 #### Case 2: Delete Primary and One Standby ```bash -$ kubectl delete pod -n demo oracle-sample-0 oracle-sample-1 +kubectl delete pod -n demo oracle-sample-0 oracle-sample-1 +``` pod "oracle-sample-0" deleted pod "oracle-sample-1" deleted -``` - The remaining standby (`oracle-sample-2`) is promoted to primary. The deleted pods return and rejoin as standbys. ```shell @@ -493,7 +488,7 @@ oracle-sample-observer-0 #### Case 3: Delete All Standbys ```bash -$ kubectl delete pod -n demo oracle-sample-1 oracle-sample-2 +kubectl delete pod -n demo oracle-sample-1 oracle-sample-2 ``` The primary (`oracle-sample-0`) continues serving traffic. Once the standbys are recreated, they rejoin the Data Guard configuration and catch up from archived redo logs. @@ -509,11 +504,11 @@ oracle-sample-observer-0 #### Case 4: Delete All Pods ```bash -$ kubectl delete pod -n demo oracle-sample-0 oracle-sample-1 oracle-sample-2 +kubectl delete pod -n demo oracle-sample-0 oracle-sample-1 oracle-sample-2 +``` pod "oracle-sample-0" deleted pod "oracle-sample-1" deleted pod "oracle-sample-2" deleted -``` ```shell oracle-sample-0 oracle-sample-1 diff --git a/docs/guides/oracle/initialization/script_source.md b/docs/guides/oracle/initialization/script_source.md index b226bd5101..9a6acb9629 100644 --- a/docs/guides/oracle/initialization/script_source.md +++ b/docs/guides/oracle/initialization/script_source.md @@ -25,9 +25,9 @@ KubeDB supports initializing an Oracle database with a user provided SQL script. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/initialization](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/initialization) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,9 +60,9 @@ data: Let's create the `ConfigMap`, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/initialization/oracle-init-script-config-map.yaml -configmap/oracle-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/initialization/oracle-init-script-config-map.yaml ``` +configmap/oracle-init-script created > Note: the key inside the ConfigMap (the file name) must be `setup.sql`. @@ -107,9 +107,9 @@ Here, Let's create the `Oracle` CR, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/initialization/oracle-init-script.yaml -oracle.kubedb.com/init-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/initialization/oracle-init-script.yaml ``` +oracle.kubedb.com/init-config created Now, wait until `init-config` has status `Ready` and the pod prints the `DATABASE IS READY TO USE!!!` banner. The initialization script runs once during this first boot. @@ -120,16 +120,17 @@ Now, wait until `init-config` has status `Ready` and the pod prints the `DATABAS Once the database is ready, let's connect to it and confirm the `emp` table created by our script exists and contains the seeded row, ```bash -$ kubectl get secret -n demo init-config-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo init-config-auth -o jsonpath='{.data.password}' | base64 -d +``` # (use the printed password below) -$ kubectl exec -n demo init-config-0 -c oracle -- bash -lc \ +```bash +kubectl exec -n demo init-config-0 -c oracle -- bash -lc \ "echo -e 'SELECT * FROM emp;\nexit;' | sqlplus -s sys/@localhost:1521/ORCL as sysdba" - +``` ID NAME ---------- ---------- 1 John -``` The `emp` table and its row are present, confirming the initialization script ran successfully. diff --git a/docs/guides/oracle/monitoring/using-prometheus-operator.md b/docs/guides/oracle/monitoring/using-prometheus-operator.md index 26aad09786..de7fe4ff51 100644 --- a/docs/guides/oracle/monitoring/using-prometheus-operator.md +++ b/docs/guides/oracle/monitoring/using-prometheus-operator.md @@ -29,12 +29,14 @@ KubeDB collects Oracle metrics using the free, public **Oracle AI Database Metri - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the Prometheus operator. We are going to deploy the database in the `demo` namespace. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl create ns monitoring -namespace/monitoring created +```bash +kubectl create ns monitoring ``` +namespace/monitoring created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/monitoring](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/monitoring) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,17 +49,17 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` CR. Let's find out the available Prometheus servers and the labels they use to select ServiceMonitors, ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-operator-kube-p-prometheus v3.12.0-distroless 1 1 True True 18m -``` Inspect the Prometheus CR to see its `serviceMonitorSelector`, ```bash -$ kubectl get prometheus -n monitoring prometheus-operator-kube-p-prometheus -o jsonpath='{.spec.serviceMonitorSelector}' -{} +kubectl get prometheus -n monitoring prometheus-operator-kube-p-prometheus -o jsonpath='{.spec.serviceMonitorSelector}' ``` +{} In this tutorial the Prometheus server has an empty `serviceMonitorSelector` (`{}`), which means it discovers **all** `ServiceMonitor`s across the namespaces it watches. If, instead, your Prometheus selects ServiceMonitors by a specific label (e.g. `release: prometheus`), inspect `spec.serviceMonitorSelector.matchLabels` and use that label in the Oracle CR below. We set `release: prometheus` on our ServiceMonitor as an example. @@ -116,9 +118,9 @@ Here, Let's create the `Oracle` CR, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/monitoring/standalone-monitoring.yaml -oracle.kubedb.com/standalone-monitoring created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/monitoring/standalone-monitoring.yaml ``` +oracle.kubedb.com/standalone-monitoring created Wait until the database is `Ready` and the pod prints the `DATABASE IS READY TO USE!!!` banner. @@ -129,16 +131,18 @@ KubeDB creates a stats `Service` (named `-stats`) for the exporter and Let's check the stats service and the ServiceMonitor, ```bash -$ kubectl get service -n demo -l app.kubernetes.io/instance=standalone-monitoring +kubectl get service -n demo -l app.kubernetes.io/instance=standalone-monitoring +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE standalone-monitoring ClusterIP 10.43.50.21 1521/TCP 12m standalone-monitoring-pods ClusterIP None 1521/TCP 12m standalone-monitoring-stats ClusterIP 10.43.224.116 9161/TCP 12m -$ kubectl get servicemonitor -n demo +```bash +kubectl get servicemonitor -n demo +``` NAME AGE standalone-monitoring-stats 12m -``` The `standalone-monitoring-stats` service exposes the exporter on port `9161`, and the `standalone-monitoring-stats` ServiceMonitor tells Prometheus how to scrape it. Let's look at the ServiceMonitor spec, @@ -166,9 +170,12 @@ spec: Let's verify the exporter is actually serving Oracle metrics by scraping the `/metrics` endpoint of the stats service from inside the cluster, ```bash -$ kubectl run mon-curl -n demo --image=curlimages/curl:8.10.1 --restart=Never --command -- sleep 90 -$ kubectl exec -n demo mon-curl -- curl -s http://standalone-monitoring-stats.demo.svc:9161/metrics | grep '^oracledb' | head +kubectl run mon-curl -n demo --image=curlimages/curl:8.10.1 --restart=Never --command -- sleep 90 +``` +```bash +kubectl exec -n demo mon-curl -- curl -s http://standalone-monitoring-stats.demo.svc:9161/metrics | grep '^oracledb' | head +``` # HELP oracledb_activity_execute_count Generic counter metric from gv$sysstat view in Oracle. oracledb_activity_execute_count{database="default",inst_id="1"} 31038 # HELP oracledb_activity_parse_count_total Generic counter metric from gv$sysstat view in Oracle. @@ -178,7 +185,6 @@ oracledb_activity_user_rollbacks{database="default",inst_id="1"} 2 oracledb_ag_cluster_size_cluster_size{database="default"} 1 oracledb_batch_requests_batch_requests_total{database="default"} 31032 oracledb_buffer_cache_hit_ratio_cache_hit_ratio{database="default"} 0.9372 -``` These `oracledb_*` metrics are produced by the Oracle AI Database Metrics Exporter that KubeDB runs alongside the database. diff --git a/docs/guides/oracle/quickstart/index.md b/docs/guides/oracle/quickstart/index.md index f497ad54e2..559c2caaa0 100644 --- a/docs/guides/oracle/quickstart/index.md +++ b/docs/guides/oracle/quickstart/index.md @@ -32,26 +32,24 @@ This tutorial will show you how to use KubeDB to run an Oracle database. - check available StorageClass in your cluster: -```shell -$ kubectl get storageclasses +```bash +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 28d - -``` Use a separate namespace for isolation: -```shell -$ kubectl create ns demo -namespace/demo created +```bash +kubectl create ns demo ``` +namespace/demo created ## Find Available Oracle Versions KubeDB maintains an OracleVersion CRD with all supported Oracle versions: -```shell -$ kubectl get oracleversions +```bash +kubectl get oracleversions +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 21.3.0 21.3.0 container-registry.oracle.com/database/enterprise:21.3.0.0 28d - -``` ## Create Oracle image pull secret (important) To pull the Oracle image, create a secret with your Oracle credentials from : @@ -137,11 +135,10 @@ spec: storageType: Durable version: 21.3.0 ``` -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/quickstart/standalone.yaml -oracle.kubedb.com/oracle created - +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/quickstart/standalone.yaml ``` +oracle.kubedb.com/oracle created Here, - `spec.version`: Refers to the `OracleVersion CRD` specifying the docker image. @@ -164,9 +161,9 @@ KubeDB operator will create a new PetSet and a Service with the matching Oracle operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. If we describe the `Oracle` CRD we will get an overview of the steps that were followed. -```shell -$ kubectl describe oracle -n demo oracle - +```bash +kubectl describe oracle -n demo oracle +``` Name: oracle Namespace: demo Labels: @@ -277,8 +274,6 @@ Status: Phase: Ready Events: -``` - 🔹Status: (What the operator reports now) Conditions: @@ -293,8 +288,9 @@ Events: ## Check Resources Created by KubeDB operator: -```shell -$ kubectl get oracle,pods,pvc,services -n demo +```bash +kubectl get oracle,pods,pvc,services -n demo +``` NAME VERSION MODE STATUS AGE oracle.kubedb.com/oracle 21.3.0 Standalone Ready 109m @@ -308,11 +304,10 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/oracle ClusterIP 10.43.170.95 1521/TCP 109m service/oracle-pods ClusterIP None 1521/TCP 109m -``` - ## Connect to Oracle Database -```shell -$ kubectl exec -it -n demo oracle-0 -- bash +```bash +kubectl exec -it -n demo oracle-0 -- bash +``` Defaulted container "oracle" out of: oracle, oracle-init (init) bash-4.2$ sqlplus / as sysdba @@ -328,16 +323,20 @@ Version 21.3.0.0.0 SQL> exit Disconnected from Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production Version 21.3.0.0.0 - -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo oracle/oracle -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete oracle -n demo oracle -$ kubectl delete ns demo +kubectl patch -n demo oracle/oracle -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete oracle -n demo oracle +``` + +```bash +kubectl delete ns demo ``` > ## ⚠️ Legal Notice diff --git a/docs/guides/oracle/reconfigure/reconfigure.md b/docs/guides/oracle/reconfigure/reconfigure.md index 9663e5de84..44283f5183 100644 --- a/docs/guides/oracle/reconfigure/reconfigure.md +++ b/docs/guides/oracle/reconfigure/reconfigure.md @@ -25,9 +25,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/reconfigure](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/reconfigure) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -66,9 +66,9 @@ spec: Let's create the `Oracle` CR we have shown above and wait until it becomes `Ready`, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/standalone-minimal.yaml -oracle.kubedb.com/oracle-sa-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/standalone-minimal.yaml ``` +oracle.kubedb.com/oracle-sa-sample created ## Reconfigure using a config Secret @@ -89,9 +89,9 @@ stringData: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/oracle-custom-config-secret.yaml -secret/oracle-custom created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/oracle-custom-config-secret.yaml ``` +secret/oracle-custom created ### Create OracleOpsRequest @@ -121,24 +121,25 @@ Here, Let's create the `OracleOpsRequest`, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/standalone-reconfigure.yaml -oracleopsrequest.ops.kubedb.com/standalone-reconfigure created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/reconfigure/standalone-reconfigure.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-reconfigure created ### Verify the new configuration Let's wait for the `OracleOpsRequest` to become `Successful`, ```bash -$ kubectl get oracleopsrequest -n demo standalone-reconfigure +kubectl get oracleopsrequest -n demo standalone-reconfigure +``` NAME TYPE STATUS AGE standalone-reconfigure Reconfigure Successful 118s -``` We can see the full progress in the `kubectl describe` output, ```bash -$ kubectl describe oracleopsrequest -n demo standalone-reconfigure +kubectl describe oracleopsrequest -n demo standalone-reconfigure +``` Name: standalone-reconfigure Namespace: demo ... @@ -174,21 +175,21 @@ Status: Status: True Type: Successful Phase: Successful -``` Finally, let's connect to the database and confirm that `PROCESSES` is now `800`, ```bash -$ kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d +kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d +``` # (use the printed password below) -$ kubectl exec -n demo oracle-sa-sample-0 -c oracle -- bash -lc \ +```bash +kubectl exec -n demo oracle-sa-sample-0 -c oracle -- bash -lc \ "echo -e 'SHOW PARAMETER processes;\nexit;' | sqlplus -s sys/@localhost:1521/ORCL as sysdba" - +``` NAME TYPE VALUE ------------------------------------ ----------- ----- processes integer 800 -``` The `processes` parameter has been updated to `800`, confirming the reconfiguration was applied successfully. diff --git a/docs/guides/oracle/restart/restart.md b/docs/guides/oracle/restart/restart.md index d0eee47f6f..2a1ed653d1 100644 --- a/docs/guides/oracle/restart/restart.md +++ b/docs/guides/oracle/restart/restart.md @@ -25,9 +25,9 @@ KubeDB supports restarting the Oracle database via an `OracleOpsRequest`. Restar - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/restart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/restart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -66,17 +66,17 @@ spec: Let's create the `Oracle` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/standalone-minimal.yaml -oracle.kubedb.com/oracle-sa-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/standalone-minimal.yaml ``` +oracle.kubedb.com/oracle-sa-sample created Now, wait until `oracle-sa-sample` has status `Ready`. i.e, ```bash -$ kubectl get oracle -n demo +kubectl get oracle -n demo +``` NAME VERSION MODE STATUS AGE oracle-sa-sample 21.3.0 Standalone Ready 8m49s -``` ## Apply Restart opsRequest @@ -104,22 +104,23 @@ Here, Let's create the `OracleOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/standalone-restart.yaml -oracleopsrequest.ops.kubedb.com/standalone-restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/standalone-restart.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-restart created Now the Ops-manager operator will restart the pods one by one (in a reconciliation-safe rolling manner). Let's wait until the `OracleOpsRequest` becomes `Successful`, ```bash -$ kubectl get oracleopsrequest -n demo +kubectl get oracleopsrequest -n demo +``` NAME TYPE STATUS AGE standalone-restart Restart Successful 2m -``` We can see from the above output that the `OracleOpsRequest` has succeeded. Let's check the details with `kubectl describe`, ```bash -$ kubectl describe oracleopsrequest -n demo standalone-restart +kubectl describe oracleopsrequest -n demo standalone-restart +``` Name: standalone-restart Namespace: demo ... @@ -174,38 +175,41 @@ Events: Warning evict pod; ConditionStatus:True; PodName:oracle-sa-sample-0 55s KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:oracle-sa-sample-0 Warning running pod; ConditionStatus:False; PodName:oracle-sa-sample-0 51s KubeDB Ops-manager Operator running pod; ConditionStatus:False; PodName:oracle-sa-sample-0 Warning running pod; ConditionStatus:True; PodName:oracle-sa-sample-0 45s KubeDB Ops-manager Operator running pod; ConditionStatus:True; PodName:oracle-sa-sample-0 -``` After the ops request succeeds, the database pod is freshly recreated. Oracle then re-opens the existing database; while it is opening, the `Oracle` object may briefly report the `Critical` phase before settling back to `Ready`, ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=oracle-sa-sample +kubectl get pods -n demo -l app.kubernetes.io/instance=oracle-sa-sample +``` NAME READY STATUS RESTARTS AGE oracle-sa-sample-0 1/1 Running 0 24s -$ kubectl get oracle -n demo oracle-sa-sample +```bash +kubectl get oracle -n demo oracle-sa-sample +``` NAME VERSION MODE STATUS AGE oracle-sa-sample 21.3.0 Standalone Ready 12m -``` ## Restarting a DataGuard cluster The same `OracleOpsRequest` works for a DataGuard cluster — just point `spec.databaseRef.name` at the DataGuard database. A DataGuard cluster (`mode: DataGuard`, `replicas: 3`) consists of 3 database pods (each running an `oracle` and an `oracle-coordinator` container) plus a single observer pod: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=oracle-dg-sample -L kubedb.com/role +kubectl get pods -n demo -l app.kubernetes.io/instance=oracle-dg-sample -L kubedb.com/role +``` NAME READY STATUS RESTARTS AGE ROLE oracle-dg-sample-0 2/2 Running 0 18m primary oracle-dg-sample-1 2/2 Running 0 18m standby oracle-dg-sample-2 2/2 Running 0 18m standby oracle-dg-sample-observer-0 1/1 Running 0 18m -$ kubectl get svc -n demo -l app.kubernetes.io/instance=oracle-dg-sample +```bash +kubectl get svc -n demo -l app.kubernetes.io/instance=oracle-dg-sample +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE oracle-dg-sample ClusterIP 10.43.232.240 1521/TCP 18m oracle-dg-sample-pods ClusterIP None 1521/TCP 18m oracle-dg-sample-standby ClusterIP 10.43.50.35 1521/TCP 18m -``` Here, the `kubedb.com/role` label marks pod `oracle-dg-sample-0` as the `primary` and the other two as `standby`. The `oracle-dg-sample` service always routes to the live primary, while `oracle-dg-sample-standby` routes to the read-only standbys. @@ -227,18 +231,21 @@ spec: For a DataGuard cluster the operator restarts the pods one at a time (a reconciliation-safe rolling restart). The KubeDB coordinator keeps the `kubedb.com/role` label (`primary`/`standby`) in sync, and the observer drives Fast-Start Failover, so a standby is promoted if the primary pod is restarted — the primary service (`oracle-dg-sample`) always points at the live primary. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/dataguard-restart.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/restart/dataguard-restart.yaml +``` oracleopsrequest.ops.kubedb.com/dataguard-restart created -$ kubectl get oracleopsrequest -n demo dataguard-restart +```bash +kubectl get oracleopsrequest -n demo dataguard-restart +``` NAME TYPE STATUS AGE dataguard-restart Restart Successful 2m42s -``` The `kubectl describe` output shows the pods being evicted and restarted one at a time (the standby pods `oracle-dg-sample-1` and `oracle-dg-sample-2`, then the primary), each verified healthy before moving to the next, ```bash -$ kubectl describe oracleopsrequest -n demo dataguard-restart +kubectl describe oracleopsrequest -n demo dataguard-restart +``` ... Status: Conditions: @@ -266,7 +273,6 @@ Status: Status: True Type: Successful Phase: Successful -``` ## Cleaning up diff --git a/docs/guides/oracle/rotate-authentication/rotateauth.md b/docs/guides/oracle/rotate-authentication/rotateauth.md index a57d15c334..969a705500 100644 --- a/docs/guides/oracle/rotate-authentication/rotateauth.md +++ b/docs/guides/oracle/rotate-authentication/rotateauth.md @@ -25,9 +25,9 @@ KubeDB supports rotating the authentication credentials (the database password) - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/rotate-auth](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/rotate-auth) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,11 +70,14 @@ Let's create the `Oracle` CR we have shown above and wait until it is `Ready`. KubeDB stores the database credentials in a Secret named `-auth`. For our database that is `oracle-sa-sample-auth`, ```bash -$ kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.username}' | base64 -d +``` sys -$ kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d -LbK!aQQ3zkcOC3~u + +```bash +kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d ``` +LbK!aQQ3zkcOC3~u > **Note:** The privileged user for Oracle is `SYS`. Oracle does **not** allow renaming the `SYS` user, so rotate authentication changes the **password** only. @@ -108,22 +111,23 @@ Here, Let's create the `OracleOpsRequest`, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/rotate-auth/standalone-rotate-auth.yaml -oracleopsrequest.ops.kubedb.com/standalone-rotate-auth created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/rotate-auth/standalone-rotate-auth.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-rotate-auth created Let's wait until the `OracleOpsRequest` becomes `Successful`, ```bash -$ kubectl get oracleopsrequest -n demo standalone-rotate-auth +kubectl get oracleopsrequest -n demo standalone-rotate-auth +``` NAME TYPE STATUS AGE standalone-rotate-auth RotateAuth Successful 2m7s -``` The full progress is shown by `kubectl describe`, ```bash -$ kubectl describe oracleopsrequest -n demo standalone-rotate-auth +kubectl describe oracleopsrequest -n demo standalone-rotate-auth +``` Name: standalone-rotate-auth Namespace: demo ... @@ -159,21 +163,21 @@ Status: Status: True Type: Successful Phase: Successful -``` **Verify auth is rotated:** After the operation succeeds, the operator has generated a new password and stored it in the auth secret. The previous credential is kept under the `authData.prev` keys so applications have a grace window to migrate, ```bash -$ kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d -VYWX2Wu!Sx1JdqKl +kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password}' | base64 -d ``` +VYWX2Wu!Sx1JdqKl The auth secret now also holds the previous credentials under the `.prev` keys, ```bash -$ kubectl get secret -n demo oracle-sa-sample-auth -o json | jq '.data | keys' +kubectl get secret -n demo oracle-sa-sample-auth -o json | jq '.data | keys' +``` [ "password", "password.prev", @@ -181,32 +185,32 @@ $ kubectl get secret -n demo oracle-sa-sample-auth -o json | jq '.data | keys' "username.prev" ] -$ kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password\.prev}' | base64 -d -LbK!aQQ3zkcOC3~u +```bash +kubectl get secret -n demo oracle-sa-sample-auth -o jsonpath='{.data.password\.prev}' | base64 -d ``` +LbK!aQQ3zkcOC3~u Finally, let's confirm the new password works by connecting to the database, ```bash -$ kubectl exec -n demo oracle-sa-sample-0 -c oracle -- bash -lc \ +kubectl exec -n demo oracle-sa-sample-0 -c oracle -- bash -lc \ "echo -e 'SELECT USER FROM DUAL;\nexit;' | sqlplus -s sys/@localhost:1521/ORCL as sysdba" - +``` USER ------------------------------ SYS -``` #### 2. Using user created credentials If you want to set a specific password, first create a Secret of type `kubernetes.io/basic-auth` containing the `username` (`sys`) and your desired `password`: ```bash -$ kubectl create secret generic oracle-user-auth -n demo \ +kubectl create secret generic oracle-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=sys \ --from-literal=password='New-Strong-Pass-123' -secret/oracle-user-auth created ``` +secret/oracle-user-auth created > **Note:** The `username` must remain `sys`; only the password can change. @@ -230,9 +234,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/rotate-auth/standalone-rotate-auth-user.yaml -oracleopsrequest.ops.kubedb.com/standalone-rotate-auth-user created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/rotate-auth/standalone-rotate-auth-user.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-rotate-auth-user created Once the ops request succeeds, the database password is updated to the value from your `oracle-user-auth` secret, and the `Oracle` object's `spec.authSecret` is pointed at it. diff --git a/docs/guides/oracle/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/oracle/scaling/vertical-scaling/vertical-scaling.md index e6d398c1b0..756c0fe1c4 100644 --- a/docs/guides/oracle/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/oracle/scaling/vertical-scaling/vertical-scaling.md @@ -25,9 +25,9 @@ This guide will show you how to use the `KubeDB` Ops-manager operator to update - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/scaling) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,9 +70,9 @@ spec: Let's create the `Oracle` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/scaling/standalone-minimal.yaml -oracle.kubedb.com/oracle-sa-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/scaling/standalone-minimal.yaml ``` +oracle.kubedb.com/oracle-sa-sample created Now, wait until `oracle-sa-sample` has status `Ready` and the pod prints the `DATABASE IS READY TO USE!!!` banner. @@ -81,7 +81,8 @@ Now, wait until `oracle-sa-sample` has status `Ready` and the pod prints the `DA Let's check the Pod containers' resources of the database. Run the following command to get the resources of the `oracle-sa-sample-0` Pod, ```bash -$ kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | select(.name=="oracle") | .resources' +kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | select(.name=="oracle") | .resources' +``` { "limits": { "cpu": "4", @@ -92,7 +93,6 @@ $ kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | "memory": "7Gi" } } -``` These are the default resources KubeDB assigns to the main `oracle` container. Now, we are going to update these resources using vertical scaling. @@ -134,24 +134,25 @@ Here, Let's create the `OracleOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/scaling/standalone-vertical-scaling.yaml -oracleopsrequest.ops.kubedb.com/standalone-vertical-scaling created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/scaling/standalone-vertical-scaling.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-vertical-scaling created **Verify Oracle resources updated successfully:** If everything goes well, the `OracleOpsRequest` will reach the `Successful` phase. Let's wait for it, ```bash -$ kubectl get oracleopsrequest -n demo standalone-vertical-scaling +kubectl get oracleopsrequest -n demo standalone-vertical-scaling +``` NAME TYPE STATUS AGE standalone-vertical-scaling VerticalScaling Successful 43s -``` We can see from the following `kubectl describe` output that the scaling completed successfully, ```bash -$ kubectl describe oracleopsrequest -n demo standalone-vertical-scaling +kubectl describe oracleopsrequest -n demo standalone-vertical-scaling +``` Name: standalone-vertical-scaling Namespace: demo ... @@ -178,12 +179,12 @@ Status: Status: True Type: Successful Phase: Successful -``` Now, let's verify that the Pod resources have been updated to our desired values, ```bash -$ kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | select(.name=="oracle") | .resources' +kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | select(.name=="oracle") | .resources' +``` { "limits": { "cpu": "5", @@ -194,7 +195,6 @@ $ kubectl get pod -n demo oracle-sa-sample-0 -o json | jq '.spec.containers[] | "memory": "10Gi" } } -``` The resources of the Oracle database have been updated successfully. diff --git a/docs/guides/oracle/tls/configure/index.md b/docs/guides/oracle/tls/configure/index.md index a4e1580a55..3f817a1feb 100644 --- a/docs/guides/oracle/tls/configure/index.md +++ b/docs/guides/oracle/tls/configure/index.md @@ -25,15 +25,15 @@ section_menu_id: guides - Install [`cert-manager`](https://cert-manager.io/docs/installation/) in your cluster. KubeDB uses cert-manager to issue the Oracle certificates. ```bash -$ kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml +kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml ``` - To keep things isolated, this tutorial uses a separate namespace called `demo`. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/tls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,18 +44,20 @@ namespace/demo created KubeDB needs a cert-manager `Issuer` (or `ClusterIssuer`) to sign the Oracle certificates. First, generate a CA and create a TLS secret from it, ```bash -$ openssl req -x509 -nodes -days 3650 \ +openssl req -x509 -nodes -days 3650 \ -newkey rsa:2048 \ -keyout ca.key \ -out ca.crt \ -subj "/CN=oracle-ca" +``` -$ kubectl create secret tls oracle-ca \ +```bash +kubectl create secret tls oracle-ca \ --cert=ca.crt \ --key=ca.key \ -n demo -secret/oracle-ca created ``` +secret/oracle-ca created Now create an `Issuer` that uses this CA secret, @@ -71,13 +73,15 @@ spec: ``` ```bash -$ kubectl apply -f issuer.yaml +kubectl apply -f issuer.yaml +``` issuer.cert-manager.io/oracle-ca-issuer created -$ kubectl get issuer -n demo +```bash +kubectl get issuer -n demo +``` NAME READY AGE oracle-ca-issuer True 10s -``` > If the Issuer is not present (or not `Ready`), the Oracle database will stay in the `Provisioning` phase. @@ -129,9 +133,9 @@ For a **DataGuard** cluster, set `mode: DataGuard` and `replicas: 3` (see `datag Let's create the `Oracle` CR, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/tls/standalone-tls.yaml -oracle.kubedb.com/standalone-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/tls/standalone-tls.yaml ``` +oracle.kubedb.com/standalone-tls created Wait until the database is `Ready` and the pod prints the `DATABASE IS READY TO USE!!!` banner. @@ -140,31 +144,31 @@ Wait until the database is `Ready` and the pod prints the `DATABASE IS READY TO Once the database is ready, KubeDB has created the cert-manager `Certificate`s and the Oracle auto-login wallet. Let's check the generated certificate and wallet secrets, ```bash -$ kubectl get secret -n demo | grep standalone-tls +kubectl get secret -n demo | grep standalone-tls +``` standalone-tls-auth kubernetes.io/basic-auth 2 16m standalone-tls-client-cert kubernetes.io/tls 4 16m standalone-tls-metrics-exporter-cert kubernetes.io/tls 4 16m standalone-tls-server-cert kubernetes.io/tls 3 16m standalone-tls-tls-wallet Opaque 5 16m -``` Here, `standalone-tls-server-cert`, `standalone-tls-client-cert`, and `standalone-tls-metrics-exporter-cert` are the cert-manager issued certificates, and `standalone-tls-tls-wallet` is the Oracle auto-login wallet (built from those certificates) that clients use to connect over TCPS. The underlying cert-manager `Certificate` objects are all `Ready`, ```bash -$ kubectl get certificate -n demo | grep standalone-tls +kubectl get certificate -n demo | grep standalone-tls +``` standalone-tls-client-cert True standalone-tls-client-cert 16m standalone-tls-metrics-exporter-cert True standalone-tls-metrics-exporter-cert 16m standalone-tls-server-cert True standalone-tls-server-cert 16m -``` The TCPS listener is exposed on port `2484` of the database services (the plaintext listener remains on `1521`), ```bash -$ kubectl get svc -n demo -l app.kubernetes.io/instance=standalone-tls +kubectl get svc -n demo -l app.kubernetes.io/instance=standalone-tls +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE standalone-tls ClusterIP 10.43.67.172 1521/TCP,2484/TCP 16m standalone-tls-pods ClusterIP None 1521/TCP,2484/TCP 16m -``` ## Connect over TCPS @@ -200,7 +204,7 @@ spec: Exec into the pod, ```bash -$ kubectl exec -it -n demo oracle-client-pod -- bash +kubectl exec -it -n demo oracle-client-pod -- bash ``` Configure `sqlnet.ora` to point at the mounted wallet, @@ -251,24 +255,23 @@ sqlplus sys/''@ORCL as sysdba `tnsping ORCL` resolves the `TCPS` address and reaches the listener on port `2484`, ```bash -$ tnsping ORCL - +tnsping ORCL +``` TNS Ping Utility for Linux: Version 21.0.0.0.0 - Production ... Attempting to contact (DESCRIPTION = (ADDRESS = (PROTOCOL = TCPS)(HOST = standalone-tls.demo.svc.cluster.local)(PORT = 2484)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORCL))) OK (10 msec) -``` Finally, connect with `sqlplus` and confirm the session protocol is `tcps`, ```bash -$ sqlplus -s sys/''@ORCL as sysdba +sqlplus -s sys/''@ORCL as sysdba +``` SQL> SELECT SYS_CONTEXT('USERENV','NETWORK_PROTOCOL') AS PROTOCOL FROM DUAL; PROTOCOL -------------------------------------------------------------------------------- tcps -``` The session protocol reported as `tcps` confirms that the connection is TLS/SSL encrypted. diff --git a/docs/guides/oracle/volume-expansion/volume-expansion.md b/docs/guides/oracle/volume-expansion/volume-expansion.md index 708717a8b0..67a86c46a4 100644 --- a/docs/guides/oracle/volume-expansion/volume-expansion.md +++ b/docs/guides/oracle/volume-expansion/volume-expansion.md @@ -25,20 +25,20 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the - You must have a `StorageClass` that supports volume expansion (i.e. its provisioner sets `allowVolumeExpansion: true`). This tutorial uses `longhorn`. ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 12d longhorn driver.longhorn.io Delete Immediate true 12d -``` > **Note:** `local-path` has `ALLOWVOLUMEEXPANSION: false`, so it cannot be used for volume expansion. Use a storage class such as `longhorn` that supports it. - To keep things isolated, this tutorial uses a separate namespace called `demo`. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/oracle/volume-expansion](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/oracle/volume-expansion) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,10 +79,10 @@ Let's create the `Oracle` CR and wait until it is `Ready`. Once ready, let's check the size of the PersistentVolumeClaim used by the database, ```bash -$ kubectl get pvc -n demo -l app.kubernetes.io/instance=oracle-sa-sample +kubectl get pvc -n demo -l app.kubernetes.io/instance=oracle-sa-sample +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-oracle-sa-sample-0 Bound pvc-7c115ba3-ed65-4437-992c-aa8b789b0019 10Gi RWO longhorn 8m37s -``` ## Expand Volume @@ -117,22 +117,23 @@ Here, Let's create the `OracleOpsRequest`, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/volume-expansion/standalone-volume-expention.yaml -oracleopsrequest.ops.kubedb.com/standalone-volume-expention created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/oracle/volume-expansion/standalone-volume-expention.yaml ``` +oracleopsrequest.ops.kubedb.com/standalone-volume-expention created ### Verify the volume expanded Let's wait for the `OracleOpsRequest` to become `Successful`, ```bash -$ kubectl get oracleopsrequest -n demo standalone-volume-expention +kubectl get oracleopsrequest -n demo standalone-volume-expention +``` NAME TYPE STATUS AGE standalone-volume-expention VolumeExpansion Successful 61s -``` ```bash -$ kubectl describe oracleopsrequest -n demo standalone-volume-expention +kubectl describe oracleopsrequest -n demo standalone-volume-expention +``` Name: standalone-volume-expention Namespace: demo ... @@ -159,21 +160,20 @@ Status: Status: True Type: Successful Phase: Successful -``` The operator has updated the `Oracle` spec and the PetSet `volumeClaimTemplate` to `12Gi`, ```bash -$ kubectl get oracle -n demo oracle-sa-sample -o jsonpath='{.spec.storage.resources.requests.storage}' -12Gi +kubectl get oracle -n demo oracle-sa-sample -o jsonpath='{.spec.storage.resources.requests.storage}' ``` +12Gi The capacity reported by the `PersistentVolumeClaim` changes once the **storage provisioner** finishes resizing the underlying volume. While the resize is in progress, the PVC carries a `Resizing` condition and the requested size (`spec.resources.requests.storage`) updates ahead of the reported capacity (`status.capacity.storage`), ```bash -$ kubectl get pvc data-oracle-sa-sample-0 -n demo -o jsonpath='req={.spec.resources.requests.storage} cap={.status.capacity.storage} cond={.status.conditions[*].type}' -req=12Gi cap=10Gi cond=Resizing +kubectl get pvc data-oracle-sa-sample-0 -n demo -o jsonpath='req={.spec.resources.requests.storage} cap={.status.capacity.storage} cond={.status.conditions[*].type}' ``` +req=12Gi cap=10Gi cond=Resizing > **Note (test environment):** On the single-node longhorn dev cluster used to capture this guide, the `OracleOpsRequest` reached the `Successful` phase and both the `Oracle` spec and the PetSet `volumeClaimTemplate` were updated to `12Gi`, but the longhorn volume remained in the `Resizing` state and the PVC capacity had not yet been reflected as `12Gi` at the time of writing. Volume expansion depends on the CSI driver fully completing the resize; on a production-grade storage class the PVC capacity updates to the new size once resizing completes. Always confirm the final size with `kubectl get pvc -n demo data-oracle-sa-sample-0 -o jsonpath='{.status.capacity.storage}'`. diff --git a/docs/guides/percona-xtradb/autoscaler/compute/cluster/index.md b/docs/guides/percona-xtradb/autoscaler/compute/cluster/index.md index f4688d2bc0..1d18ed354a 100644 --- a/docs/guides/percona-xtradb/autoscaler/compute/cluster/index.md +++ b/docs/guides/percona-xtradb/autoscaler/compute/cluster/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Cluster Database Here, we are going to deploy a `PerconaXtraDB` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `PerconaXtraDBAutoscaler` to set up autoscaling. @@ -79,22 +79,23 @@ spec: Let's create the `PerconaXtraDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/compute/cluster/examples/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/compute/cluster/examples/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 14m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -105,11 +106,11 @@ $ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resource "memory": "300Mi" } } -``` Let's check the PerconaXtraDB resources, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "perconaxtradb") | .resources' +kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "perconaxtradb") | .resources' +``` { "limits": { "cpu": "200m", @@ -120,7 +121,6 @@ $ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.s "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the perconaxtradb. @@ -181,20 +181,23 @@ If a step doesn't finish within the specified timeout, the ops request will resu Let's create the `PerconaXtraDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/compute/cluster/examples/pxas-compute.yaml -perconaxtradbautoscaler.autoscaling.kubedb.com/pxas-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/compute/cluster/examples/pxas-compute.yaml ``` +perconaxtradbautoscaler.autoscaling.kubedb.com/pxas-compute created #### Verify Autoscaling is set up successfully Let's check that the `perconaxtradbautoscaler` resource is created successfully, ```bash -$ kubectl get perconaxtradbautoscaler -n demo +kubectl get perconaxtradbautoscaler -n demo +``` NAME AGE px-as-compute 5m56s -$ kubectl describe perconaxtradbautoscaler px-as-compute -n demo +```bash +kubectl describe perconaxtradbautoscaler px-as-compute -n demo +``` Name: px-as-compute Namespace: demo Labels: @@ -300,8 +303,6 @@ Status: Memory: 1Gi Vpa Name: sample-pxc Events: - -``` So, the `perconaxtradbautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -311,23 +312,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `perconaxtradbopsrequest` in the demo namespace to see if any `perconaxtradbopsrequest` object is created. After some time you'll see that a `perconaxtradbopsrequest` will be created based on the recommendation. ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` NAME TYPE STATUS AGE pxops-sample-pxc-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` NAME TYPE STATUS AGE pxops-vpa-sample-pxc-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe perconaxtradbopsrequest -n demo pxops-vpa-sample-pxc-z43wc8 +kubectl describe perconaxtradbopsrequest -n demo pxops-vpa-sample-pxc-z43wc8 +``` Name: pxops-sample-pxc-6xc1kc Namespace: demo Labels: @@ -445,12 +447,12 @@ Events: Normal Starting 5m8s KubeDB Enterprise Operator Resuming PerconaXtraDB database: demo/sample-pxc Normal Successful 5m8s KubeDB Enterprise Operator Successfully resumed PerconaXtraDB database: demo/sample-pxc Normal Successful 5m8s KubeDB Enterprise Operator Controller has Successfully scaled the PerconaXtraDB database: demo/sample-pxc -``` Now, we are going to verify from the Pod, and the PerconaXtraDB yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -462,7 +464,9 @@ $ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resource } } -$ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "perconaxtradb") | .resources' +```bash +kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "perconaxtradb") | .resources' +``` { "limits": { "cpu": "250m", @@ -473,7 +477,6 @@ $ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.podTemplate.s "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the PerconaXtraDB replicaset database. diff --git a/docs/guides/percona-xtradb/autoscaler/storage/cluster/index.md b/docs/guides/percona-xtradb/autoscaler/storage/cluster/index.md index 6ad5b43ee7..c3678ad3f2 100644 --- a/docs/guides/percona-xtradb/autoscaler/storage/cluster/index.md +++ b/docs/guides/percona-xtradb/autoscaler/storage/cluster/index.md @@ -37,20 +37,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Perco To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -85,30 +85,32 @@ spec: Let's create the `PerconaXtraDB` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/storage/cluster/examples/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/storage/cluster/examples/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-sample-pxc-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-sample-pxc-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-pxc-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -150,20 +152,23 @@ Here, Let's create the `PerconaXtraDBAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/storage/cluster/examples/pxas-storage.yaml -perconaxtradbautoscaler.autoscaling.kubedb.com/px-as-st created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/autoscaler/storage/cluster/examples/pxas-storage.yaml ``` +perconaxtradbautoscaler.autoscaling.kubedb.com/px-as-st created #### Storage Autoscaling is set up successfully Let's check that the `perconaxtradbautoscaler` resource is created successfully, ```bash -$ kubectl get perconaxtradbautoscaler -n demo +kubectl get perconaxtradbautoscaler -n demo +``` NAME AGE px-as-st 33s -$ kubectl describe perconaxtradbautoscaler px-as-st -n demo +```bash +kubectl describe perconaxtradbautoscaler px-as-st -n demo +``` Name: px-as-st Namespace: demo Labels: @@ -185,7 +190,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `perconaxtradbautoscaler` resource is created successfully. @@ -194,7 +198,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume(`var/lib/mysql`) using the following commands: ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` root@sample-pxc-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 357M 658M 36% /var/lib/mysql @@ -205,30 +210,30 @@ root@sample-pxc-0:/ dd if=/dev/zero of=/var/lib/mysql/file.img bs=500M count=1 root@sample-pxc-0:/ df -h /var/lib/mysql Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 857M 158M 85% /var/lib/mysql -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 20%. Let's watch the `perconaxtradbopsrequest` in the demo namespace to see if any `perconaxtradbopsrequest` object is created. After some time you'll see that a `perconaxtradbopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-pxc-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` NAME TYPE STATUS AGE mops-sample-pxc-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe perconaxtradbopsrequest -n demo mops-sample-pxc-xojkua +kubectl describe perconaxtradbopsrequest -n demo mops-sample-pxc-xojkua +``` Name: mops-sample-pxc-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -291,19 +296,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming PerconaXtraDB database: demo/sample-pxc Normal Successful 103s KubeDB Enterprise Operator Successfully resumed PerconaXtraDB database: demo/sample-pxc Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of PerconaXtraDB: demo/sample-pxc -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-sample-pxc-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-sample-pxc-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-sample-pxc-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the PerconaXtraDB replicaset database. diff --git a/docs/guides/percona-xtradb/clustering/galera-cluster/index.md b/docs/guides/percona-xtradb/clustering/galera-cluster/index.md index cd42b383d7..f11555b33f 100644 --- a/docs/guides/percona-xtradb/clustering/galera-cluster/index.md +++ b/docs/guides/percona-xtradb/clustering/galera-cluster/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/mysql](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/mysql) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,9 +60,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/clustering/galera-cluster/examples/demo-1.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/clustering/galera-cluster/examples/demo-1.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Here, @@ -72,7 +72,8 @@ Here, KubeDB operator watches for `PerconaXtraDB` objects using Kubernetes API. When a `PerconaXtraDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching PerconaXtraDB object name. KubeDB operator will also create a governing service for the PetSet with the name `-pods`. ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o yaml +kubectl get perconaxtradb -n demo sample-pxc -o yaml +``` apiVersion: kubedb.com/v1 kind: PerconaXtraDB metadata: @@ -162,7 +163,9 @@ status: observedGeneration: 4 phase: Ready -$ kubectl get sts,svc,secret,pvc,pv,pod -n demo +```bash +kubectl get sts,svc,secret,pvc,pv,pod -n demo +``` NAME READY AGE petset.apps/sample-pxc 3/3 7m5s @@ -192,15 +195,14 @@ pod/sample-pxc-0 2/2 Running 0 7m5s pod/sample-pxc-1 2/2 Running 0 7m5s pod/sample-pxc-2 2/2 Running 0 7m5s -``` - ## Connect with PerconaXtraDB database Once the database is in running state we can connect to each of three nodes. We will use login credentials `MYSQL_ROOT_USERNAME` and `MYSQL_ROOT_PASSWORD` saved as container's environment variable. -```bash # First Node -$ kubectl exec -it -n demo sample-pxc-0 -- bash +```bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -228,9 +230,10 @@ mysql> SELECT 1; mysql> quit; Bye - # Second Node -$ kubectl exec -it -n demo sample-pxc-1 -- bash +```bash +kubectl exec -it -n demo sample-pxc-1 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -258,9 +261,10 @@ mysql> SELECT 1; mysql> quit; Bye - # Third Node -$ kubectl exec -it -n demo sample-pxc-2 -- bash +```bash +kubectl exec -it -n demo sample-pxc-2 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -288,14 +292,13 @@ mysql> SELECT 1; mysql> quit; Bye -``` - ## Check the Cluster Status Now, we are ready to check newly created cluster status. Connect and run the following commands from any of the hosts and you will get the same result, that is the cluster size is three. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -323,8 +326,6 @@ mysql> show status like 'wsrep_cluster_size'; mysql> quit; Bye -``` - ## Data Availability In a PerconaXtraDB Galera Cluster, Each member can read and write. In this section, we will insert data from any nodes, and we will see whether we can get the data from every other members. @@ -332,7 +333,8 @@ In a PerconaXtraDB Galera Cluster, Each member can read and write. In this secti > Read the comment written for the following commands. They contain the instructions and explanations of the commands. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -371,7 +373,9 @@ Bye bash-4.4$ exit exit -$ kubectl exec -it -n demo sample-pxc-2 -- bash +```bash +kubectl exec -it -n demo sample-pxc-2 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -413,7 +417,9 @@ Bye bash-4.4$ exit exit -$ kubectl exec -it -n demo sample-pxc-2 -- bash +```bash +kubectl exec -it -n demo sample-pxc-2 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -447,7 +453,6 @@ mysql> quit; Bye bash-4.4$ exit exit -``` ## Automatic Failover @@ -456,7 +461,8 @@ To test automatic failover, we will force the one of three pods to restart and c > Read the comment written for the following commands. They contain the instructions and explanations of the commands. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -494,7 +500,9 @@ exit pod "sample-pxc-0" deleted # Wait for sample-pxc-0 to restart -$ kubectl exec -it -n demo sample-pxc-0 -- bash +```bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -532,15 +540,17 @@ mysql [(none)]> show status like 'wsrep_cluster_size'; mysql> quit Bye -``` ## Cleaning up Clean what we created in this tutorial. ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc +kubectl delete perconaxtradb -n demo sample-pxc +``` perconaxtradb.kubedb.com "sample-pxc" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/percona-xtradb/concepts/perconaxtradb/index.md b/docs/guides/percona-xtradb/concepts/perconaxtradb/index.md index 7b3281c4f4..ce52b3954d 100644 --- a/docs/guides/percona-xtradb/concepts/perconaxtradb/index.md +++ b/docs/guides/percona-xtradb/concepts/perconaxtradb/index.md @@ -126,7 +126,8 @@ type: Opaque In the given secrets below, `sample-pxc-monitor` and `sample-pxc-replication` are the system user secrets under `sample-pxc` PerconaXtraDB object. ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE default-token-r556j kubernetes.io/service-account-token 3 157m sample-pxc-auth kubernetes.io/basic-auth 2 157m @@ -134,8 +135,6 @@ sample-pxc-monitor kubernetes.io/basic-auth 2 157m sample-pxc-replication kubernetes.io/basic-auth 2 157m sample-pxc-token-p25ww kubernetes.io/service-account-token 3 141m -``` - ### spec.storageType `spec.storageType` is an optional field that specifies the type of storage to use for the database. It can be either `Durable` or `Ephemeral`. The default value of this field is `Durable`. If `Ephemeral` is used then KubeDB will create PerconaXtraDB database using [emptyDir](https://kubernetes.io/docs/concepts/storage/volumes/#emptydir) volume. In this case, you don't have to specify `spec.storage` field. diff --git a/docs/guides/percona-xtradb/configuration/using-config-file/index.md b/docs/guides/percona-xtradb/configuration/using-config-file/index.md index 149ee2e137..3a4d2f121b 100644 --- a/docs/guides/percona-xtradb/configuration/using-config-file/index.md +++ b/docs/guides/percona-xtradb/configuration/using-config-file/index.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for PerconaXtraDB. This tutorial - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - $ kubectl get ns demo + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-config-file/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -65,14 +67,15 @@ Here, `read_buffer_size` is set to 1MB in bytes. Now, create a Secret with this configuration file. ```bash -$ kubectl create secret generic -n demo px-configuration --from-file=./px-config.cnf -secret/px-configuration created +kubectl create secret generic -n demo px-configuration --from-file=./px-config.cnf ``` +secret/px-configuration created Verify the Secret has the configuration file. ```bash -$ kubectl get secret -n demo px-configuration -o yaml +kubectl get secret -n demo px-configuration -o yaml +``` apiVersion: v1 stringData: px-config.cnf: | @@ -84,14 +87,13 @@ metadata: name: px-configuration namespace: demo ... -``` Now, create PerconaXtraDB crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-config-file/examples/px-custom.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-config-file/examples/px-custom.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Below is the YAML for the PerconaXtraDB crd we just created. @@ -122,16 +124,18 @@ Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, serv Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE sample-pxc-0 2/2 Running 0 75m sample-pxc-1 2/2 Running 0 95m sample-pxc-2 2/2 Running 0 95m -$ kubectl get perconaxtradb -n demo +```bash +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 96m -``` We can see the database is in ready phase so it can accept connection. @@ -139,9 +143,10 @@ Now, we will check if the database has started with the custom configuration we > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # Connecting to the database -$ kubectl exec -it -n demo sample-pxc-0 -- bash +```bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -178,15 +183,17 @@ mysql> show variables like 'read_buffer_size'; mysql> exit Bye -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc +kubectl delete perconaxtradb -n demo sample-pxc +``` perconaxtradb.kubedb.com "sample-pxc" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/percona-xtradb/configuration/using-pod-template/index.md b/docs/guides/percona-xtradb/configuration/using-pod-template/index.md index a94afcec77..82f98dba52 100644 --- a/docs/guides/percona-xtradb/configuration/using-pod-template/index.md +++ b/docs/guides/percona-xtradb/configuration/using-pod-template/index.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for PerconaXtraDB via [PodTemplat - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/mysql](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-pod-template/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -95,36 +95,37 @@ spec: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-pod-template/examples/md-misc-config.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/configuration/using-pod-template/examples/md-misc-config.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `sample-pxc` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE sample-pxc-0 2/2 Running 0 3m30s sample-pxc-1 2/2 Running 0 3m30s sample-pxc-2 2/2 Running 0 3m30s -``` Check the perconaxtradb CRD status if the database is ready ```bash -$ kubectl get perconaxtradb --all-namespaces +kubectl get perconaxtradb --all-namespaces +``` NAMESPACE NAME VERSION STATUS AGE demo sample-pxc 8.4.3 Ready 4m8s -``` Once we see `Note] mysqld: ready for connections.` in the log, the database is ready. Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -172,15 +173,17 @@ mysql> show variables like 'char%'; mysql> quit; Bye -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc +kubectl delete perconaxtradb -n demo sample-pxc +``` perconaxtradb.kubedb.com "sample-pxc" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/index.md b/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/index.md index 6a84964b2f..6a51a773b7 100644 --- a/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/index.md +++ b/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/index.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,14 +46,15 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo px-custom-serviceaccount -serviceaccount/px-custom-serviceaccount created +kubectl create serviceaccount -n demo px-custom-serviceaccount ``` +serviceaccount/px-custom-serviceaccount created It should create a service account. ```bash -$ kubectl get serviceaccount -n demo px-custom-serviceaccount -o yaml +kubectl get serviceaccount -n demo px-custom-serviceaccount -o yaml +``` apiVersion: v1 kind: ServiceAccount metadata: @@ -65,14 +66,13 @@ metadata: uid: 788bd6c6-3eae-4797-b6ca-5722ef64c9dc secrets: - name: px-custom-serviceaccount-token-jnhvd -``` Now, we need to create a role that has necessary access permissions for the PerconaXtraDB instance named `sample-pxc`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-role.yaml -role.rbac.authorization.k8s.io/px-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-role.yaml ``` +role.rbac.authorization.k8s.io/px-custom-role created Below is the YAML for the Role we just created. @@ -98,16 +98,17 @@ This permission is required for PerconaXtraDB pods running on PSP enabled cluste Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding px-custom-rolebinding --role=px-custom-role --serviceaccount=demo:px-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/px-custom-rolebinding created +kubectl create rolebinding px-custom-rolebinding --role=px-custom-role --serviceaccount=demo:px-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/px-custom-rolebinding created It should bind `px-custom-role` and `px-custom-serviceaccount` successfully. SO, All required resources for RBAC are created. ```bash -$ kubectl get serviceaccount,role,rolebindings -n demo +kubectl get serviceaccount,role,rolebindings -n demo +``` NAME SECRETS AGE serviceaccount/default 1 38m serviceaccount/px-custom-serviceaccount 1 36m @@ -117,14 +118,13 @@ role.rbac.authorization.k8s.io/px-custom-role 2021-03-18T05:13:27Z NAME ROLE AGE rolebinding.rbac.authorization.k8s.io/px-custom-rolebinding Role/px-custom-role 79s -``` Now, create a PerconaXtraDB crd specifying `spec.podTemplate.spec.serviceAccountName` field to `px-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-db.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-db.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Below is the YAML for the PerconaXtraDB crd we just created. @@ -156,14 +156,13 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, PetSet, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE sample-pxc-0 2/2 Running 0 84m sample-pxc-1 2/2 Running 0 84m sample-pxc-2 2/2 Running 0 84m -``` - Check the PerconaXtraDB custom resource to see if the database cluster is ready: ```bash @@ -179,9 +178,9 @@ An existing service account can be reused in another PerconaXtraDB instance. No Now, create PerconaXtraDB crd `another-perconaxtradb` using the existing service account name `px-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-db-2.yaml -perconaxtradb.kubedb.com/another-perconaxtradb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/custom-rbac/using-custom-rbac/examples/px-custom-db-2.yaml ``` +perconaxtradb.kubedb.com/another-perconaxtradb created Below is the YAML for the PerconaXtraDB crd we just created. @@ -213,10 +212,10 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo another-perconaxtradb-0 +kubectl get pod -n demo another-perconaxtradb-0 +``` NAME READY STATUS RESTARTS AGE another-perconaxtradb-0 2/2 Running 0 37s -``` Check the PerconaXtraDB custom resource to see if the database cluster is ready: @@ -231,18 +230,33 @@ demo another-perconaxtradb 8.4.3 Ready 83m To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc +kubectl delete perconaxtradb -n demo sample-pxc +``` perconaxtradb.kubedb.com "sample-pxc" deleted -$ kubectl delete perconaxtradb -n demo another-perconaxtradb + +```bash +kubectl delete perconaxtradb -n demo another-perconaxtradb +``` perconaxtradb.kubedb.com "another-perconaxtradb" deleted -$ kubectl delete -n demo role px-custom-role + +```bash +kubectl delete -n demo role px-custom-role +``` role.rbac.authorization.k8s.io "px-custom-role" deleted -$ kubectl delete -n demo rolebinding px-custom-rolebinding + +```bash +kubectl delete -n demo rolebinding px-custom-rolebinding +``` rolebinding.rbac.authorization.k8s.io "px-custom-rolebinding" deleted -$ kubectl delete sa -n demo px-custom-serviceaccount + +```bash +kubectl delete sa -n demo px-custom-serviceaccount +``` serviceaccount "px-custom-serviceaccount" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/percona-xtradb/failover/overview.md b/docs/guides/percona-xtradb/failover/overview.md index f79faba845..f647a64856 100644 --- a/docs/guides/percona-xtradb/failover/overview.md +++ b/docs/guides/percona-xtradb/failover/overview.md @@ -39,17 +39,17 @@ This guide walks you through setting up a PerconaXtraDB HA cluster using KubeDB * A valid [StorageClass](https://kubernetes.io /concepts/storage/storage-classes/) is required. ```bash -$ kubectl get storageclasses +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h -``` * For isolation, we’ll use a separate namespace called `demo`. -```shell -$ kubectl create ns demo -namespace/demo created +```bash +kubectl create ns demo ``` +namespace/demo created ### Step 1: Deploy a PerconaXtraDB Cluster @@ -79,15 +79,15 @@ spec: Apply the manifest: -```shell -$ kubectl apply -f pxc-ha.yaml -perconaxtradb.kubedb.com/pxc-ha created +```bash +kubectl apply -f pxc-ha.yaml ``` +perconaxtradb.kubedb.com/pxc-ha created Watch resources until ready: -```shell -$ watch kubectl get perconaxtradb,petset,pods -n demo +```bash +watch kubectl get perconaxtradb,petset,pods -n demo ``` Sample ready output: @@ -108,16 +108,17 @@ pod/pxc-ha-2 2/2 Running 0 16h All nodes are part of the Galera cluster and can handle read/write traffic. Inspect the role/labels of all nodes (note: Galera is multi-primary — labels might show `Primary` for each): -```shell -$ kubectl get pods -n demo --show-labels | grep pxc-ha +```bash +kubectl get pods -n demo --show-labels | grep pxc-ha ``` ### Step 2: Verify Cluster Functionality Let’s connect to one node and create a database: -```shell -$ kubectl exec -it -n demo pxc-ha-0 -- bash +```bash +kubectl exec -it -n demo pxc-ha-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-5.1$ mysql -u root --password='kpbogmFdR!tXVcaG' @@ -156,12 +157,12 @@ Bye bash-5.1$ exit exit ⏎ -``` Check the database from another node: -```shell -$kubectl exec -it -n demo pxc-ha-1 -- bash +```bash +kubectl exec -it -n demo pxc-ha-1 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-5.1$ mysql -u root --password='kpbogmFdR!tXVcaG' mysql: [Warning] Using a password on the command line interface can be insecure. @@ -197,7 +198,6 @@ bash-5.1$ exit exit # odissi is present instantly (Galera synchronous replication) -``` ### Step 3: Simulate Node Failure @@ -210,18 +210,18 @@ Below are corrected, explicit steps and expected outputs for the failure scenari 1. **Observe current pod state** (open a separate terminal and run): ```bash -$ kubectl get pods -n demo --show-labels | grep pxc-ha +kubectl get pods -n demo --show-labels | grep pxc-ha +``` pxc-ha-0 Primary pxc-ha-1 Primary pxc-ha-2 Primary -``` 2. **Delete the node (pod)**: ```bash -$ kubectl delete pod -n demo pxc-ha-0 -pod "pxc-ha-0" deleted +kubectl delete pod -n demo pxc-ha-0 ``` +pod "pxc-ha-0" deleted we can see output similar to: ```shell @@ -231,7 +231,7 @@ we can see output similar to: 3. **Watch cluster state while the pod is terminated and recreated**: ```bash -$ watch -n 2 "kubectl get pods -n demo --show-labels | grep pxc-ha" +watch -n 2 "kubectl get pods -n demo --show-labels | grep pxc-ha" ``` You will see a sequence similar to: @@ -264,19 +264,19 @@ pxc-ha-2 Primary 4. **Verify Galera cluster membership and status while the node is down** (check from any remaining node, e.g., `pxc-ha-1`): ```bash -$ kubectl exec -it -n demo pxc-ha-1 -- mysql -uroot --password='kpbogmFdR!tXVcaG' -e "SHOW STATUS LIKE 'wsrep_cluster_size';" - +kubectl exec -it -n demo pxc-ha-1 -- mysql -uroot --password='kpbogmFdR!tXVcaG' -e "SHOW STATUS LIKE 'wsrep_cluster_size';" +``` +---------------------+-------+ | Variable_name | Value | +---------------------+-------+ | wsrep_cluster_size | 2 | +---------------------+-------+ -``` When `pxc-ha-0` is back: -```shell -$ kubectl exec -it -n demo pxc-ha-1 -- mysql -uroot --password='kpbogmFdR!tXVcaG' -e "SHOW STATUS LIKE 'wsrep_cluster_size';" +```bash +kubectl exec -it -n demo pxc-ha-1 -- mysql -uroot --password='kpbogmFdR!tXVcaG' -e "SHOW STATUS LIKE 'wsrep_cluster_size';" +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. +--------------------+-------+ @@ -285,32 +285,28 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | wsrep_cluster_size | 3 | +--------------------+-------+ -``` - #### Case 2: Delete two nodes (Kept and clarified from the original doc.) Example commands and expected behavior: ```bash -$ kubectl delete pod -n demo pxc-ha-0 pxc-ha-1 +kubectl delete pod -n demo pxc-ha-0 pxc-ha-1 +``` pod "pxc-ha-0" deleted pod "pxc-ha-1" deleted -``` - * Immediately after deletion you'll see two pods terminating; the remaining pod will keep serving traffic as long as it can (quorum depends on how your cluster is configured and how many nodes are healthy). * Monitor `wsrep_cluster_size` on the remaining node — it will show `1` while two nodes are down and return to `3` after the others rejoin. #### Case 3: Delete all nodes ```bash -$ kubectl delete pod -n demo pxc-ha-0 pxc-ha-1 pxc-ha-2 +kubectl delete pod -n demo pxc-ha-0 pxc-ha-1 pxc-ha-2 +``` pod "pxc-ha-0" deleted pod "pxc-ha-1" deleted pod "pxc-ha-2" deleted -``` - KubeDB will recreate all pods. After they are all `Running` and Galera finishes SST/IST, cluster size will return to `3` and data will be available. ### Cleanup @@ -318,8 +314,11 @@ KubeDB will recreate all pods. After they are all `Running` and Galera finishes To clean up resources created in this tutorial: ```bash -$ kubectl delete perconaxtradb -n demo pxc-ha -$ kubectl delete ns demo +kubectl delete perconaxtradb -n demo pxc-ha +``` + +```bash +kubectl delete ns demo ``` ### Next Steps diff --git a/docs/guides/percona-xtradb/initialization/script_source.md b/docs/guides/percona-xtradb/initialization/script_source.md index 0be5302f46..8ebb2abf32 100644 --- a/docs/guides/percona-xtradb/initialization/script_source.md +++ b/docs/guides/percona-xtradb/initialization/script_source.md @@ -25,13 +25,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/percona-xtradb](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/percona-xtradb) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ At first, we will create a ConfigMap from an `init.sql` file. Then, we will prov Let's create a ConfigMap with the initialization script: ```bash -$ kubectl create configmap -n demo pxc-init-script \ +kubectl create configmap -n demo pxc-init-script \ --from-literal=init.sql="$(curl -fsSL https://raw.githubusercontent.com/kubedb/percona-xtradb-init-scripts/master/init.sql)" -configmap/pxc-init-script created ``` +configmap/pxc-init-script created ## Create PerconaXtraDB with Script Source @@ -88,22 +90,23 @@ VolumeSource provided in `init.script` will be mounted in the Pod and will be ex Now, let's create the PerconaXtraDB CRD using the YAML shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/initialization/yamls/script-pxc.yaml -perconaxtradb.kubedb.com/script-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/initialization/yamls/script-pxc.yaml ``` +perconaxtradb.kubedb.com/script-pxc created Now, wait until PerconaXtraDB goes in `Ready` state. Verify that the cluster is in `Ready` state using the following command: ```bash -$ kubectl get perconaxtradb -n demo script-pxc +kubectl get perconaxtradb -n demo script-pxc +``` NAME VERSION STATUS AGE script-pxc 8.4.3 Ready 3m -``` You can use `kubectl dba describe` command to view which resources have been created by KubeDB for this PerconaXtraDB object: ```bash -$ kubectl dba describe perconaxtradb -n demo script-pxc +kubectl dba describe perconaxtradb -n demo script-pxc +``` Name: script-pxc Namespace: demo Labels: @@ -260,7 +263,6 @@ Events: Normal Successful 17m KubeDB Operator Successfully created PerconaXtraDB Normal Successful 17m KubeDB Operator Successfully created appbinding Normal PhaseChanged 15m KubeDB Operator Phase changed from Provisioning to Ready. -``` ## Verify Initialization @@ -276,21 +278,22 @@ Now let's connect to our PerconaXtraDB cluster to verify that the database has b - Username: Run the following command to get the *username*: ```bash - $ kubectl get secret -n demo script-pxc-auth -o jsonpath='{.data.username}' | base64 -d - root + kubectl get secret -n demo script-pxc-auth -o jsonpath='{.data.username}' | base64 -d ``` + root - Password: Run the following command to get the *password*: ```bash - $ kubectl get secret -n demo script-pxc-auth -o jsonpath='{.data.password}' | base64 -d - nsTqGdVwR!~DA(t + kubectl get secret -n demo script-pxc-auth -o jsonpath='{.data.password}' | base64 -d ``` + nsTqGdVwR!~DA(t Now, connect to the PerconaXtraDB cluster and run the following query to confirm initialization: ```bash -$ kubectl exec -it -n demo script-pxc-0 -- mysql -u root --password='nsTqGdVwR!~DA(ta' -e "SHOW TABLES FROM mysql;" +kubectl exec -it -n demo script-pxc-0 -- mysql -u root --password='nsTqGdVwR!~DA(ta' -e "SHOW TABLES FROM mysql;" +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. +------------------------------------------------------+ @@ -340,8 +343,6 @@ mysql: [Warning] Using a password on the command line interface can be insecure. | wsrep_streaming_log | +------------------------------------------------------+ -``` - We can see the TABLE `kubedb_table` in `mysql` database which was created through initialization. ## Cleaning up @@ -349,11 +350,19 @@ We can see the TABLE `kubedb_table` in `mysql` database which was created throug To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo pxc/script-pxc -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo pxc/script-pxc +kubectl patch -n demo pxc/script-pxc -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete -n demo configmap/pxc-init-script -$ kubectl delete ns demo +```bash +kubectl delete -n demo pxc/script-pxc +``` + +```bash +kubectl delete -n demo configmap/pxc-init-script +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/percona-xtradb/monitoring/builtin-prometheus/index.md b/docs/guides/percona-xtradb/monitoring/builtin-prometheus/index.md index 6e0583986a..4adf37f87b 100644 --- a/docs/guides/percona-xtradb/monitoring/builtin-prometheus/index.md +++ b/docs/guides/percona-xtradb/monitoring/builtin-prometheus/index.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor PerconaXtraDB database using builtin - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the PerconaXtraDB crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples/builtin-prom-px.yaml -perconaxtradb.kubedb.com/builtin-prom-px created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples/builtin-prom-px.yaml ``` +perconaxtradb.kubedb.com/builtin-prom-px created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get perconaxtradb -n demo builtin-prom-px +kubectl get perconaxtradb -n demo builtin-prom-px +``` NAME VERSION STATUS AGE builtin-prom-px 8.4.3 Ready 76s -``` KubeDB will create a separate stats service with name `{PerconaXtraDB crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-px" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-px" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-px ClusterIP 10.106.32.194 3306/TCP 2m3s builtin-prom-px-pods ClusterIP None 3306/TCP 2m3s builtin-prom-px-stats ClusterIP 10.109.106.92 56790/TCP 2m2s -``` Here, `builtin-prom-px-stats ` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-px-stats +kubectl describe svc -n demo builtin-prom-px-stats +``` Name: builtin-prom-px-stats Namespace: demo Labels: app.kubernetes.io/instance=builtin-prom-px @@ -113,7 +116,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.34:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -277,20 +279,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/builtin-prometheus/examples/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -301,9 +303,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -312,18 +314,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-5dff66b455-cz9td 1/1 Running 0 42s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-px-stats` service as one of the targets. diff --git a/docs/guides/percona-xtradb/monitoring/prometheus-operator/index.md b/docs/guides/percona-xtradb/monitoring/prometheus-operator/index.md index 7b11bc8635..666f795c67 100644 --- a/docs/guides/percona-xtradb/monitoring/prometheus-operator/index.md +++ b/docs/guides/percona-xtradb/monitoring/prometheus-operator/index.md @@ -25,9 +25,9 @@ section_menu_id: guides - To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -42,10 +42,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE default prometheus 1 2m19s -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -96,9 +96,9 @@ KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add l Let's add label `prometheus: prometheus` to `demo` namespace, ```bash -$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' -namespace/demo patched +kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' ``` +namespace/demo patched ## Deploy PerconaXtraDB with Monitoring Enabled @@ -140,34 +140,35 @@ Here, Let's create the PerconaXtraDB object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/prometheus-operator/examples/prom-operator-px.yaml -perconaxtradb.kubedb.com/coreos-prom-px created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/monitoring/prometheus-operator/examples/prom-operator-px.yaml ``` +perconaxtradb.kubedb.com/coreos-prom-px created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get perconaxtradb -n demo coreos-prom-px +kubectl get perconaxtradb -n demo coreos-prom-px +``` NAME VERSION STATUS AGE coreos-prom-px 8.4.3 Ready 59s -``` KubeDB will create a separate stats service with name `{PerconaXtraDB crd name}-stats` for monitoring purpose. ```bash -$ $ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-px" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-px" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-px ClusterIP 10.99.96.226 3306/TCP 107s coreos-prom-px-pods ClusterIP None 3306/TCP 107s coreos-prom-px-stats ClusterIP 10.101.190.67 56790/TCP 107s -``` Here, `coreos-prom-px-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo coreos-prom-px-stats +kubectl describe svc -n demo coreos-prom-px-stats +``` Name: coreos-prom-px-stats Namespace: demo Labels: app.kubernetes.io/instance=coreos-prom-px @@ -183,22 +184,22 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.31:56790 Session Affinity: None Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-px-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-px-stats 4m8s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of PerconaXtraDB crd. ```bash -$ kubectl get servicemonitor -n demo coreos-prom-px-stats -o yaml +kubectl get servicemonitor -n demo coreos-prom-px-stats -o yaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -241,7 +242,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: perconaxtradbs.kubedb.com kubedb.com/role: stats -``` Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in PerconaXtraDB crd. @@ -252,22 +252,22 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n default -l=app=prometheus +kubectl get pod -n default -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 16m prometheus-prometheus-1 3/3 Running 1 16m prometheus-prometheus-2 3/3 Running 1 16m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n default prometheus-prometheus-0 9090 +kubectl port-forward -n default prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-px-stats` service as one of the targets. diff --git a/docs/guides/percona-xtradb/private-registry/quickstart/index.md b/docs/guides/percona-xtradb/private-registry/quickstart/index.md index 6e59fd88ba..3a7e81aec0 100644 --- a/docs/guides/percona-xtradb/private-registry/quickstart/index.md +++ b/docs/guides/percona-xtradb/private-registry/quickstart/index.md @@ -27,11 +27,11 @@ KubeDB operator supports using private Docker registry. This tutorial will show - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/u/kubedb) into your private registry. For perconaxtradb, push `DB_IMAGE`, `EXPORTER_IMAGE`, `INITCONTAINER_IMAGE` of following PerconaXtraDBVersions, where `deprecated` is not true, to your private registry. ```bash -$ kubectl get perconaxtradbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +kubectl get perconaxtradbversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image,INITCONTAINER_IMAGE:.spec.initContainer.image,DEPRECATED:.spec.deprecated +``` NAME VERSION DB_IMAGE EXPORTER_IMAGE INITCONTAINER_IMAGE DEPRECATED 8.0.40 8.0.40 percona/percona-xtradb-cluster:8.0.40 prom/mysqld-exporter:v0.13.0 kubedb/percona-xtradb-init:0.2.0 8.0.28 8.0.28 percona/percona-xtradb-cluster:8.0.28 prom/mysqld-exporter:v0.13.0 kubedb/percona-xtradb-init:0.2.0 -``` Docker hub repositories: @@ -63,9 +63,9 @@ Docker hub repositories: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - ``` ## Create ImagePullSecret @@ -74,13 +74,13 @@ ImagePullSecrets is a type of a Kubernete Secret whose sole purpose is to pull p Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo pxregistrykey \ +kubectl create secret docker-registry -n demo pxregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/pxregistrykey created ``` +secret/pxregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -120,25 +120,28 @@ spec: Now run the command to deploy this `PerconaXtraDB` object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/private-registry/quickstart/examples/demo.yaml -perconaxtradb.kubedb.com/px-pvt-reg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/private-registry/quickstart/examples/demo.yaml ``` +perconaxtradb.kubedb.com/px-pvt-reg created To check if the images pulled successfully from the repository, see if the `PerconaXtraDB` is in running state: ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE px-pvt-reg-0 1/1 Running 0 56s -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo px-pvt-reg +kubectl delete perconaxtradb -n demo px-pvt-reg +``` perconaxtradb.kubedb.com "px-pvt-reg" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/percona-xtradb/quickstart/overview/index.md b/docs/guides/percona-xtradb/quickstart/overview/index.md index 522d3fff9d..f94ae7e64d 100644 --- a/docs/guides/percona-xtradb/quickstart/overview/index.md +++ b/docs/guides/percona-xtradb/quickstart/overview/index.md @@ -31,10 +31,10 @@ This tutorial will show you how to use KubeDB to run a PerconaXtraDB database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash -$ kubectl get storageclasses +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m -``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. @@ -48,11 +48,11 @@ namespace/demo created When you have installed KubeDB, it has created `PerconaXtraDBVersion` crd for all supported PerconaXtraDB versions. Check it by using the following command, ```bash -$ kubectl get perconaxtradbversions +kubectl get perconaxtradbversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 8.0.40 8.0.40 percona/percona-xtradb-cluster:8.0.40 6m1s 8.0.28 8.0.28 percona/percona-xtradb-cluster:8.0.28 6m1s -``` ## Create a PerconaXtraDB database @@ -80,9 +80,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -104,9 +104,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1alpha2.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1alpha2.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Here, @@ -120,7 +120,8 @@ Here, KubeDB operator watches for `PerconaXtraDB` objects using Kubernetes api. When a `PerconaXtraDB` object is created, KubeDB operator will create a new PetSet and a Service with the matching PerconaXtraDB object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. ```bash -$ kubectl describe -n demo perconaxtradb sample-pxc +kubectl describe -n demo perconaxtradb sample-pxc +``` Name: sample-pxc Namespace: demo Labels: @@ -220,33 +221,39 @@ Events: Normal Successful 6m32s KubeDB Operator Successfully created appbinding Normal PhaseChanged 51s KubeDB Operator Phase changed from NotReady to Provisioning. Normal PhaseChanged 32s KubeDB Operator Phase changed from Provisioning to Ready. - - -$ kubectl get petset -n demo + +```bash +kubectl get petset -n demo +``` NAME READY AGE sample-pxc 1/1 27m -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-sample-pxc-0 Bound pvc-10651900-d975-467f-80ff-9c4755bdf917 1Gi RWO standard 27m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-10651900-d975-467f-80ff-9c4755bdf917 1Gi RWO Delete Bound demo/data-sample-pxc-0 standard 27m -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-pxc ClusterIP 10.105.207.172 3306/TCP 28m sample-pxc-pods ClusterIP None 3306/TCP 28m -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see PerconaXtraDB object status: ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 9m32s -``` ## Connect with PerconaXtraDB database @@ -257,18 +264,20 @@ If you want to use an existing secret please specify that when creating the Perc Now, we need `username` and `password` to connect to this database from `kubeclt exec` command. In this example, `sample-pxc-auth` secret holds username and password. ```bash -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d -w*yOU$b53dTbjsjJ +```bash +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d ``` +w*yOU$b53dTbjsjJ We will exec into the pod `sample-pxc-0` and connet to the database using `username` and `password`. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- mysql -u root --password='w*yOU$b53dTbjsjJ' - +kubectl exec -it -n demo sample-pxc-0 -- mysql -u root --password='w*yOU$b53dTbjsjJ' +``` Server version: 8.4.3-3.1 Percona XtraDB Cluster (GPL), Release rel3, Revision cf742b4, WSREP version 26.1.4.3 Copyright (c) 2009-2021 Percona LLC and/or its affiliates @@ -292,8 +301,6 @@ mysql> show databases; +--------------------+ 5 rows in set (0.00 sec) -``` - ## Database DeletionPolicy This field is used to regulate the deletion process of the related resources when `PerconaXtraDB` object is deleted. User can set the value of this field according to their needs. The available options and their use case scenario is described below: @@ -303,9 +310,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. If you create a database with `deletionPolicy` `DoNotTerminate` and try to delete it, you will see this: ```bash -$ kubectl delete perconaxtradb sample-pxc -n demo -Error from server (BadRequest): admission webhook "perconaxtradb.validators.kubedb.com" denied the request: perconaxtradb "perconaxtradb-quickstart" can't be halted. To delete, change spec.deletionPolicy +kubectl delete perconaxtradb sample-pxc -n demo ``` +Error from server (BadRequest): admission webhook "perconaxtradb.validators.kubedb.com" denied the request: perconaxtradb "perconaxtradb-quickstart" can't be halted. To delete, change spec.deletionPolicy Now, run `kubectl edit perconaxtradb sample-pxc -n demo` to set `spec.deletionPolicy` to `Halt` (which deletes the perconaxtradb object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -319,21 +326,21 @@ When the `DeletionPolicy` is set to `Halt` and the PerconaXtraDB object is delet At first, run `kubectl edit perconaxtradb sample-pxc -n demo` to set `spec.deletionPolicy` to `Halt`. Then delete the perconaxtradb object, ```bash -$ kubectl delete perconaxtradb sample-pxc -n demo -perconaxtradb.kubedb.com "sample-pxc" deleted +kubectl delete perconaxtradb sample-pxc -n demo ``` +perconaxtradb.kubedb.com "sample-pxc" deleted Now, run the following command to get all perconaxtradb resources in `demo` namespaces, ```bash -$ kubectl get sts,svc,secret,pvc -n demo +kubectl get sts,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/default-token-w2pgw kubernetes.io/service-account-token 3 31m secret/sample-pxc-auth kubernetes.io/basic-auth 2 39s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-sample-pxc-0 Bound pvc-7502c222-2b02-4363-9027-91ab0e7b76dc 1Gi RWO standard 39s -``` From the above output, you can see that all perconaxtradb resources(`PetSet`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your perconaxtradb again using this resources. @@ -346,14 +353,15 @@ When the `DeletionPolicy` is set to `Delete` and the PerconaXtraDB object is del Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete perconaxtradb sample-pxc -n demo -perconaxtradb.kubedb.com "sample-pxc" deleted +kubectl delete perconaxtradb sample-pxc -n demo ``` +perconaxtradb.kubedb.com "sample-pxc" deleted Now, run the following command to get all perconaxtradb resources in `demo` namespaces, ```bash -$ kubectl get sts,svc,secret,pvc -n demo +kubectl get sts,svc,secret,pvc -n demo +``` NAME READY AGE petset.apps/sample-pxc 3/3 3m46s @@ -372,7 +380,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-sample-pxc-0 Bound pvc-11f7b634-689e-457e-ba41-157a51090475 1Gi RWO standard 3m46s persistentvolumeclaim/data-sample-pxc-1 Bound pvc-84dce4b5-35df-4a06-bfea-b0530d83ebb0 1Gi RWO standard 3m46s persistentvolumeclaim/data-sample-pxc-2 Bound pvc-85a35a7c-dfb8-4ca2-96a6-21c9e0b892db 1Gi RWO standard 3m46s -``` From the above output, you can see that all perconaxtradb resources(`PetSet`, `Service`, `PVCs` etc.) are deleted except `Secret`. @@ -392,9 +399,9 @@ perconaxtradb.kubedb.com "sample-pxc" deleted Now, run the following command to get all perconaxtradb resources in `demo` namespaces, ```bash -$ kubectl get sts,svc,secret,pvc -n demo -No resources found in demo namespace. +kubectl get sts,svc,secret,pvc -n demo ``` +No resources found in demo namespace. From the above output, you can see that all perconaxtradb resources are deleted. there is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. @@ -409,7 +416,8 @@ Suppose we have a database running `perconaxtradb-quickstart` in our cluster. No Run the following command to get PerconaXtraDB resources, ```bash -$ kubectl get perconaxtradb,sts,secret,svc,pvc -n demo +kubectl get perconaxtradb,sts,secret,svc,pvc -n demo +``` NAME VERSION STATUS AGE perconaxtradb.kubedb.com/sample-pxc 8.4.3 Halted 22m @@ -428,7 +436,6 @@ NAME STATUS VOLUME persistentvolumeclaim/data-sample-pxc-0 Bound pvc-11f7b634-689e-457e-ba41-157a51090475 1Gi RWO standard 3m46s persistentvolumeclaim/data-sample-pxc-1 Bound pvc-84dce4b5-35df-4a06-bfea-b0530d83ebb0 1Gi RWO standard 3m46s persistentvolumeclaim/data-sample-pxc-2 Bound pvc-85a35a7c-dfb8-4ca2-96a6-21c9e0b892db 1Gi RWO standard 3m46s -``` From the above output , you can see that `PerconaXtraDB` object, `PVCs`, `Secret` are still alive. Then you can recreate your `PerconaXtraDB` with same configuration. diff --git a/docs/guides/percona-xtradb/reconfigure-tls/cluster/index.md b/docs/guides/percona-xtradb/reconfigure-tls/cluster/index.md index e37b0e7a96..cf2f8dc5b1 100644 --- a/docs/guides/percona-xtradb/reconfigure-tls/cluster/index.md +++ b/docs/guides/percona-xtradb/reconfigure-tls/cluster/index.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Add TLS to a PerconaXtraDB Cluster @@ -63,26 +63,31 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 9m17s -``` ```bash -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d +``` U6(h_pYrekLZ2OOd -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +```bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the PerconaXtraDB monitor. Commands end with ; or \g. Your PerconaXtraDB connection id is 108 @@ -109,8 +114,6 @@ PerconaXtraDB [(none)]> show variables like '%ssl%'; +---------------------+-----------------------------+ 10 rows in set (0.001 sec) -``` - We can verify from the above output that TLS is disabled for this database. ### Create Issuer/ ClusterIssuer @@ -120,12 +123,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=perconaxtradb/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=perconaxtradb/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -199,19 +202,19 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-add-tls.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-add-tls.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CRO, ```bash -$ kubectl get perconaxtradbopsrequest --all-namespaces +kubectl get perconaxtradbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo pxops-add-tls ReconfigureTLS Successful 6m6s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. @@ -220,7 +223,8 @@ Now, we are going to connect to the database for verifying the `PerconaXtraDB` s Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ ls /etc/mysql/certs/client ca.crt tls.crt tls.key root@sample-pxc-0:/ ls /etc/mysql/certs/server @@ -261,7 +265,6 @@ PerconaXtraDB [(none)]> show variables like '%require_secure_transport%'; PerconaXtraDB [(none)]> quit; Bye -``` We can see from the above output that, `have_ssl` is set to `ture`. So, database TLS is enabled successfully to this database. @@ -272,12 +275,12 @@ We can see from the above output that, `have_ssl` is set to `ture`. So, 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 exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ apt update root@sample-pxc-0:/ apt install openssl root@sample-pxc-0:/ openssl x509 -in /etc/mysql/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Apr 13 05:18:43 2022 GMT -``` So, the certificate will expire on this time `Apr 13 05:18:43 2022 GMT`. @@ -308,29 +311,29 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-rotate-tls.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-rotate-tls.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-rotate-tls created #### Verify Certificate Rotated Successfully Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CRO, ```bash -$ kubectl get perconaxtradbopsrequest --all-namespaces +kubectl get perconaxtradbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo pxops-rotate-tls ReconfigureTLS Successful 3m -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ apt update root@sample-pxc-0:/ apt install openssl root@sample-pxc-0:/# openssl x509 -in /etc/mysql/certs/client/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Apr 13 06:04:50 2022 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -340,7 +343,8 @@ Now, we are going to update the server certificate. - Let's describe the server certificate `sample-pxc-server-cert` ```bash -$ kubectl describe certificate -n demo sample-pxc-server-cert +kubectl describe certificate -n demo sample-pxc-server-cert +``` Name: sample-pxc-server-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -409,7 +413,6 @@ Events: Normal Requested 19m cert-manager Created new CertificateRequest resource "sample-pxc-server-cert-p5287" Normal Reused 19m (x5 over 22m) cert-manager Reusing private key stored in existing Secret resource "sample-pxc-server-cert" Normal Issuing 19m (x6 over 65m) cert-manager The certificate has been successfully issued -``` We want to add `subject` and `emailAddresses` in the spec of server sertificate. @@ -448,34 +451,33 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-update-tls.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-update-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-update-tls.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-update-tls created #### Verify certificate is updated successfully Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CRO, ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` Every 2.0s: kubectl get perconaxtradbopsrequest -n demo NAME TYPE STATUS AGE pxops-update-tls ReconfigureTLS Successful 7m -``` - We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ apt update root@sample-pxc-0:/ apt install openssl root@sample-pxc-0:/ openssl x509 -in /etc/mysql/certs/server/tls.crt -inform PEM -subject -email -nameopt RFC2253 -noout subject=CN=sample-pxc.demo.svc,O=kubedb:server kubedb@appscode.com -``` We can see from the above output that, the subject name and email address match with the new ca certificate that we have created. So, the issuer is changed successfully. @@ -510,26 +512,27 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-remove-tls.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure-tls/cluster/examples/pxops-remove-tls.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-remove-tls created #### Verify TLS Removed Successfully Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CRO, ```bash -$ kubectl get perconaxtradbopsrequest --all-namespaces +kubectl get perconaxtradbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo pxops-remove-tls ReconfigureTLS Successful 6m27s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed. Now, Let's exec into the database and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} Welcome to the PerconaXtraDB monitor. Commands end with ; or \g. Your PerconaXtraDB connection id is 108 @@ -556,8 +559,6 @@ PerconaXtraDB [(none)]> show variables like '%ssl%'; +---------------------+-----------------------------+ 10 rows in set (0.001 sec) -``` - So, we can see from the above that, output that tls is disabled successfully. ## Cleaning up @@ -565,8 +566,17 @@ So, we can see from the above that, output that tls is disabled successfully. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo --all -$ kubectl delete issuer -n demo --all -$ kubectl delete perconaxtradbopsrequest -n demo --all -$ kubectl delete ns demo +kubectl delete perconaxtradb -n demo --all +``` + +```bash +kubectl delete issuer -n demo --all +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo --all +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/percona-xtradb/reconfigure/cluster/index.md b/docs/guides/percona-xtradb/reconfigure/cluster/index.md index 562459b3e3..63ec65a9bd 100644 --- a/docs/guides/percona-xtradb/reconfigure/cluster/index.md +++ b/docs/guides/percona-xtradb/reconfigure/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `PerconaXtraDB` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `PerconaXtraDBOpsRequest` to reconfigure its configuration. @@ -57,9 +57,9 @@ Here, `max_connections` is set to `200`, whereas the default value is `151`. Lik Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo px-configuration --from-file=./px-config.cnf -secret/px-configuration created +kubectl create secret generic -n demo px-configuration --from-file=./px-config.cnf ``` +secret/px-configuration created In this section, we are going to create a PerconaXtraDB object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `PerconaXtraDB` CR that we are going to create, @@ -88,34 +88,37 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/sample-pxc-config.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/sample-pxc-config.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 71s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a perconaxtradb instance, ```bash -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -153,7 +156,6 @@ mysql> show variables like 'read_buffer_size'; mysql> exit Bye -``` As we can see from the configuration of ready perconaxtradb, the value of `max_connections` has been set to `200` and `read_buffer_size` has been set to `1048576`. @@ -173,9 +175,9 @@ read_buffer_size = 122880 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-px-configuration --from-file=./new-px-config.cnf -secret/new-px-configuration created +kubectl create secret generic -n demo new-px-configuration --from-file=./new-px-config.cnf ``` +secret/new-px-configuration created #### Create PerconaXtraDBOpsRequest @@ -205,9 +207,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/reconfigure-using-secret.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/reconfigure-using-secret.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-config created #### Verify the new configuration is working @@ -216,15 +218,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest --all-namespaces +kubectl get perconaxtradbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo pxops-reconfigure-config Reconfigure Successful 3m8s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe perconaxtradbopsrequest -n demo pxops-reconfigure-config +kubectl describe perconaxtradbopsrequest -n demo pxops-reconfigure-config +``` Name: pxops-reconfigure-config Namespace: demo Labels: @@ -272,12 +275,11 @@ Status: Observed Generation: 3 Phase: Successful -``` - Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -315,7 +317,6 @@ mysql> show variables like 'read_buffer_size'; mysql> exit Bye -``` As we can see from the configuration has changed, the value of `max_connections` has been changed from `200` to `250` and and the `read_buffer_size` has been changed `1048576` to `122880`. So the reconfiguration of the database is successful. @@ -355,7 +356,8 @@ Here, Before applying this yaml we are going to check the existing value of our new field, ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -382,7 +384,6 @@ mysql> show variables like 'innodb_log_buffer_size'; PerconaXtraDB [(none)]> exit Bye -``` 16777216 @@ -391,9 +392,9 @@ Here, we can see the default value for `innodb_log_buffer_size` is `16777216`. Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/pxops-reconfigure-apply-config.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/pxops-reconfigure-apply-config.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-apply-config created #### Verify the new configuration is working @@ -403,15 +404,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest pxops-reconfigure-apply-config -n demo +kubectl get perconaxtradbopsrequest pxops-reconfigure-apply-config -n demo +``` NAME TYPE STATUS AGE pxops-reconfigure-apply-config Reconfigure Successful 4m59s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe perconaxtradbopsrequest -n demo pxops-reconfigure-apply-config +kubectl describe perconaxtradbopsrequest -n demo pxops-reconfigure-apply-config +``` Name: pxops-reconfigure-apply-config Namespace: demo Labels: @@ -470,12 +472,12 @@ Status: Type: Successful Observed Generation: 3 Phase: Successful -``` Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -522,7 +524,6 @@ mysql> show variables like 'innodb_log_buffer_size'; mysql> exit Bye -``` As we can see from above the configuration has been changed, the value of `max_connections` has been changed from `250` to `230` and the `read_buffer_size` has been changed `122880` to `1064960` also, `innodb_log_buffer_size` has been changed from `16777216` to `17408000`. So the reconfiguration of the `sample-pxc` database is successful. @@ -558,9 +559,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/reconfigure-remove.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/reconfigure/cluster/examples/reconfigure-remove.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-reconfigure-remove created #### Verify the new configuration is working @@ -569,15 +570,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest --all-namespaces +kubectl get perconaxtradbopsrequest --all-namespaces +``` NAMESPACE NAME TYPE STATUS AGE demo pxops-reconfigure-remove Reconfigure Successful 2m1s -``` Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -623,7 +625,6 @@ PerconaXtraDB [(none)]> show variables like 'innodb_log_buffer_size'; PerconaXtraDB [(none)]> exit Bye -``` As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `PerconaXtraDBOpsRequest` is successful. @@ -632,7 +633,13 @@ As we can see from the configuration has changed to its default value. So remova To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc -$ kubectl delete perconaxtradbopsrequest -n demo pxops-reconfigure-config pxops-reconfigure-apply-config pxops-reconfigure-remove -$ kubectl delete ns demo +kubectl delete perconaxtradb -n demo sample-pxc +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo pxops-reconfigure-config pxops-reconfigure-apply-config pxops-reconfigure-remove +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/percona-xtradb/restart/index.md b/docs/guides/percona-xtradb/restart/index.md index e1ac1d0fb1..963e7a75a0 100644 --- a/docs/guides/percona-xtradb/restart/index.md +++ b/docs/guides/percona-xtradb/restart/index.md @@ -61,9 +61,9 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/restart/yamls/pxc.yaml -perconaxtradb.kubedb.com/pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/restart/yamls/pxc.yaml ``` +perconaxtradb.kubedb.com/pxc created let's wait until all pods are in the `Running` state, ```shell @@ -76,11 +76,18 @@ pxc-2 2/2 Running 0 6m28s let's check database is ready to accept connections, ```bash -$ kubectl get secrets -n demo pxc-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo pxc-auth -o jsonpath='{.data.\username}' | base64 -d +``` root -$ kubectl get secrets -n demo pxc-auth -o jsonpath='{.data.\password}' | base64 -d + +```bash +kubectl get secrets -n demo pxc-auth -o jsonpath='{.data.\password}' | base64 -d +``` kP!VVJ2e~DUtcD*D -$ kubectl exec -it -n demo pxc-0 -- mysql -u root --password='kP!VVJ2e~DUtcD*D' + +```bash +kubectl exec -it -n demo pxc-0 -- mysql -u root --password='kP!VVJ2e~DUtcD*D' +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -113,7 +120,6 @@ Query OK, 1 row affected (0.02 sec) mysql> exit Bye -``` # Apply Restart opsRequest @@ -145,9 +151,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/restart/yamls/restart.yaml -PerconaXtraDBOpsRequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/restart/yamls/restart.yaml ``` +PerconaXtraDBOpsRequest.ops.kubedb.com/restart created In a PerconaXtraDB cluster, all pods act as primary nodes. When you apply a restart OpsRequest, the KubeDB operator will restart the pods sequentially, one by one, to maintain cluster availability. @@ -174,12 +180,15 @@ pxc-2 2/2 Terminating 0 56m ``` -```shell -$ kubectl get PerconaXtraDBopsrequest -n demo +```bash +kubectl get PerconaXtraDBopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 64m -$ kubectl get PerconaXtraDBopsrequest -n demo restart -oyaml +```bash +kubectl get PerconaXtraDBopsrequest -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: PerconaXtraDBOpsRequest metadata: @@ -251,14 +260,13 @@ status: type: Successful observedGeneration: 1 phase: Successful - -``` **Verify Data Persistence** After the restart, reconnect to the database and verify that the previously created database still exists: ```bash -$ kubectl exec -it -n demo pxc-0 -- mysql -u root --password='kP!VVJ2e~DUtcD*D' +kubectl exec -it -n demo pxc-0 -- mysql -u root --password='kP!VVJ2e~DUtcD*D' +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -289,7 +297,6 @@ mysql> show databases; mysql> exit Bye -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/percona-xtradb/rotateauth/rotateauth.md b/docs/guides/percona-xtradb/rotateauth/rotateauth.md index ebae4da44f..d1f4a876c1 100644 --- a/docs/guides/percona-xtradb/rotateauth/rotateauth.md +++ b/docs/guides/percona-xtradb/rotateauth/rotateauth.md @@ -26,10 +26,10 @@ section_menu_id: guides - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash -$ kubectl get storageclasses +kubectl get storageclasses +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m -``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. @@ -64,17 +64,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/quickstart/overview/examples/sample-pxc-v1.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until sample-pxc has status Ready. i.e, -```shell -$ kubectl get perconaxtradb -n demo +```bash + kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 43m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an example showing how to retrieve the credentials from the secret. @@ -92,13 +92,14 @@ Q!IsZ7.NXM.ZIxvT⏎ Here, we will connect to PerconaXtraDB server from local-machine through port-forwarding. We will connect to `sample-pxc-0` pod from local-machine using port-forwarding and it must be running in separate terminal. ```bash -$ kubectl port-forward -n demo sample-pxc-0 3306 +kubectl port-forward -n demo sample-pxc-0 3306 +``` Forwarding from 127.0.0.1:3306 -> 3306 Forwarding from [::1]:3306 -> 3306 -``` Now, you can exec into the pod `sample-pxc` and connect to database using `username` and `password` -```shell -$ kubectl exec -it -n demo sample-pxc-0 -- mysql -u root --password='Q!IsZ7.NXM.ZIxvT' +```bash +kubectl exec -it -n demo sample-pxc-0 -- mysql -u root --password='Q!IsZ7.NXM.ZIxvT' +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -130,8 +131,6 @@ Query OK, 1 row affected (0.03 sec) mysql> EXIT Bye - -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth PerconaXtraDBOpsRequest @@ -157,19 +156,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on PerconaXtraDB. Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/rotateauth/yamls/PerconaXtraDB-rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/rotateauth/yamls/PerconaXtraDB-rotate-auth-generated.yaml + ``` PerconaXtraDBopsrequest.ops.kubedb.com/pxops-rotate-auth-generated created -``` Let's wait for `PerconaXtraDBOpsrequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsrequest` CRO -```shell - $ kubectl get PerconaXtraDBopsrequest -n demo + ```bash + kubectl get PerconaXtraDBopsrequest -n demo + ``` NAME TYPE STATUS AGE pxops-rotate-auth-generated RotateAuth Successful 6m44s -``` If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe PerconaXtraDBopsrequest -n demo pxops-rotate-auth-generated +```bash +kubectl describe PerconaXtraDBopsrequest -n demo pxops-rotate-auth-generated +``` Name: pxops-rotate-auth-generated Namespace: demo Labels: @@ -253,37 +253,44 @@ Status: Phase: Successful Events: -``` - **Verify Auth is rotated** -```shell -$ kubectl get perconaxtradb -n demo sample-pxc -ojson | jq .spec.authSecret.name +```bash +kubectl get perconaxtradb -n demo sample-pxc -ojson | jq .spec.authSecret.name +``` "sample-pxc-auth" -$ kubectl get secret -n demo sample-pxc-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo sample-pxc-auth -o=jsonpath='{.data.username}' | base64 -d +``` root⏎ -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d -0o~37yrZq(363vDz⏎ + +```bash + kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d ``` +0o~37yrZq(363vDz⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The key is `authData.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo sample-pxc-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo sample-pxc-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo sample-pxc-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -Q!IsZ7.NXM.ZIxvT⏎ + +```bash +kubectl get secret -n demo sample-pxc-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +Q!IsZ7.NXM.ZIxvT⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > Note: The `username` must be fixed as `root`. -```shell -$ kubectl create secret generic quick-pcx-user-auth -n demo \ +```bash + kubectl create secret generic quick-pcx-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=root \ --from-literal=password=PerconaXtraDB2 -secret/quick-pcx-user-auth created ``` +secret/quick-pcx-user-auth created Now create a `PerconaXtraDBOpsRequest` with `RotateAuth` type. Below is the YAML of the `PerconaXtraDBOpsRequest` that we are going to create, ```shell @@ -311,22 +318,22 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/rotateauth/yamls/rotate-auth-user.yaml -PerconaXtraDBopsrequest.ops.kubedb.com/pxops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/rotateauth/yamls/rotate-auth-user.yaml ``` +PerconaXtraDBopsrequest.ops.kubedb.com/pxops-rotate-auth-user created Let’s wait for `PerconaXtraDBOpsRequest` to be Successful. Run the following command to watch `PerconaXtraDBOpsRequest` CRO: -```shell -$ kubectl get PerconaXtraDBopsrequest -n demo +```bash +kubectl get PerconaXtraDBopsrequest -n demo +``` NAME TYPE STATUS AGE pxops-rotate-auth-generated RotateAuth Successful 55m pxops-rotate-auth-user RotateAuth Successful 3m44s - -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe PerconaXtraDBopsrequest -n demo pxops-rotate-auth-user +```bash +kubectl describe PerconaXtraDBopsrequest -n demo pxops-rotate-auth-user +``` Name: pxops-rotate-auth-user Namespace: demo Labels: @@ -498,24 +505,31 @@ Events: Normal Starting 36m KubeDB Ops-manager Operator Resuming PerconaXtraDB database: demo/sample-pxc Normal Successful 36m KubeDB Ops-manager Operator Successfully resumed PerconaXtraDB database: demo/sample-pxc Normal Successful 36m KubeDB Ops-manager Operator Controller has successfully rotate PerconaXtraDB auth secret - -``` **Verify auth is rotate** -```shell -$ kubectl get perconaxtradb -n demo sample-pxc -ojson | jq .spec.authSecret.name +```bash +kubectl get perconaxtradb -n demo sample-pxc -ojson | jq .spec.authSecret.name +``` "quick-pcx-user-auth " -$ kubectl get secrets -n demo quick-pcx-user-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secrets -n demo quick-pcx-user-auth -o jsonpath='{.data.\username}' | base64 -d +``` root⏎ -$ kubectl get secrets -n demo quick-pcx-user-auth -o jsonpath='{.data.\password}' | base64 -d -PerconaXtraDB2⏎ + +```bash +kubectl get secrets -n demo quick-pcx-user-auth -o jsonpath='{.data.\password}' | base64 -d ``` +PerconaXtraDB2⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo quick-pcx-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo quick-pcx-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` root⏎ -$ kubectl get secret -n demo quick-pcx-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -0o~37yrZq(363vDz⏎ + +```bash +kubectl get secret -n demo quick-pcx-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +0o~37yrZq(363vDz⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -524,11 +538,17 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete PerconaXtraDBopsrequest pxops-rotate-auth-generated pxops-rotate-auth-user -n demo +```bash +kubectl delete PerconaXtraDBopsrequest pxops-rotate-auth-generated pxops-rotate-auth-user -n demo +``` PerconaXtraDBopsrequest.ops.kubedb.com "pxops-rotate-auth-generated" "pxops-rotate-auth-user" deleted -$ kubectl delete secret -n demo sample-pxc-auth + +```bash +kubectl delete secret -n demo sample-pxc-auth +``` secret "sample-pxc-auth" deleted -$ kubectl delete secret -n demo quick-pcx-user-auth -secret "quick-pcx-user-auth " deleted + +```bash +kubectl delete secret -n demo quick-pcx-user-auth ``` +secret "quick-pcx-user-auth " deleted diff --git a/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/index.md b/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/index.md index 8c798030c6..96077fb327 100644 --- a/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/index.md +++ b/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to scale the cl To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Horizontal Scaling on Cluster @@ -70,26 +70,29 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 2m36s -``` Let's check the number of replicas this database has from the PerconaXtraDB object, number of pods the petset have, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' -3 -$ kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' +kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' +``` 3 + +```bash +kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' ``` +3 We can see from both command that the database has 3 replicas in the cluster. @@ -97,17 +100,20 @@ Also, we can verify the replicas of the replicaset from an internal perconaxtrad First we need to get the username and password to connect to a perconaxtradb instance, ```bash -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d -nrKuxni0wDSMrgwy +```bash +kubectl get secrets -n demo sample-pxc-auth -o jsonpath='{.data.\password}' | base64 -d ``` +nrKuxni0wDSMrgwy Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash + kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | @@ -115,8 +121,6 @@ root@sample-pxc-0:/ mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'ws | wsrep_cluster_size | 3 | +--------------------+-------+ -``` - We can see from the above output that the cluster has 3 nodes. We are now ready to apply the `PerconaXtraDBOpsRequest` CR to scale this database. @@ -152,9 +156,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/pxops-upscale.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-scale-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/pxops-upscale.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-scale-horizontal-up created #### Verify Cluster replicas scaled up successfully @@ -163,32 +167,35 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ watch kubectl get perconaxtradbopsrequest -n demo +watch kubectl get perconaxtradbopsrequest -n demo +``` Every 2.0s: kubectl get perconaxtradbopsrequest -n demo NAME TYPE STATUS AGE pxops-scale-horizontal-up HorizontalScaling Successful 106s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the PerconaXtraDB object, number of pods the petset have, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' -5 -$ kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' +kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' +``` 5 + +```bash +kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' ``` +5 Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the number of replicas, ```bash -$ $ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 5 | +--------------------+-------+ -``` From all the above outputs we can see that the replicas of the cluster is `5`. That means we have successfully scaled up the replicas of the PerconaXtraDB replicaset. @@ -223,9 +230,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/pxops-downscale.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-scale-horizontal-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/horizontal-scaling/cluster/example/pxops-downscale.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-scale-horizontal-down created #### Verify Cluster replicas scaled down successfully @@ -234,31 +241,34 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ watch kubectl get perconaxtradbopsrequest -n demo +watch kubectl get perconaxtradbopsrequest -n demo +``` Every 2.0s: kubectl get perconaxtradbopsrequest -n demo NAME TYPE STATUS AGE pxops-scale-horizontal-down HorizontalScaling Successful 2m32s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the PerconaXtraDB object, number of pods the petset have, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' -3 -$ kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' +kubectl get perconaxtradb -n demo sample-pxc -o json | jq '.spec.replicas' +``` 3 + +```bash +kubectl get petset -n demo sample-pxc -o json | jq '.spec.replicas' ``` +3 Now let's connect to a perconaxtradb instance and run a perconaxtradb internal command to check the number of replicas, ```bash -$ $ kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +kubectl exec -it -n demo sample-pxc-0 -c perconaxtradb -- bash +``` root@sample-pxc-0:/ mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "show status like 'wsrep_cluster_size';" +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | wsrep_cluster_size | 3 | +--------------------+-------+ -``` From all the above outputs we can see that the replicas of the cluster is `3`. That means we have successfully scaled down the replicas of the PerconaXtraDB replicaset. @@ -267,6 +277,9 @@ From all the above outputs we can see that the replicas of the cluster is `3`. T To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc -$ kubectl delete perconaxtradbopsrequest -n demo pxops-scale-horizontal-up pxops-scale-horizontal-down +kubectl delete perconaxtradb -n demo sample-pxc +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo pxops-scale-horizontal-up pxops-scale-horizontal-down ``` \ No newline at end of file diff --git a/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/index.md b/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/index.md index d229d55e19..4125d47301 100644 --- a/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/index.md +++ b/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Vertical Scaling on Cluster @@ -71,22 +71,23 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/example/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/example/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 3m46s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -97,7 +98,6 @@ $ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resource "memory": "1Gi" } } -``` You can see the Pod has the default resources which is assigned by KubeDB operator. @@ -141,9 +141,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/example/pxops-vscale.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/scaling/vertical-scaling/cluster/example/pxops-vscale.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-vscale created #### Verify PerconaXtraDB Cluster resources updated successfully @@ -152,16 +152,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` Every 2.0s: kubectl get perconaxtradbopsrequest -n demo NAME TYPE STATUS AGE pxops-vscale VerticalScaling Successful 3m56s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -172,7 +173,6 @@ $ kubectl get pod -n demo sample-pxc-0 -o json | jq '.spec.containers[].resource "memory": "1288490188800m" } } -``` The above output verifies that we have successfully scaled up the resources of the PerconaXtraDB database. @@ -181,6 +181,9 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc -$ kubectl delete perconaxtradbopsrequest -n demo pxops-vscale +kubectl delete perconaxtradb -n demo sample-pxc +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo pxops-vscale ``` \ No newline at end of file diff --git a/docs/guides/percona-xtradb/tls/configure/index.md b/docs/guides/percona-xtradb/tls/configure/index.md index 23f4a812ad..7c5f76a8df 100644 --- a/docs/guides/percona-xtradb/tls/configure/index.md +++ b/docs/guides/percona-xtradb/tls/configure/index.md @@ -27,9 +27,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/percona-xtradb/tls/configure/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/percona-xtradb/tls/configure/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,12 +44,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=perconaxtradb/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=perconaxtradb/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -132,16 +132,17 @@ perconaxtradb.kubedb.com/sample-pxc created Now, wait for `PerconaXtraDB` going on `Running` state and also wait for `PetSet` and its pods to be created and going to `Running` state, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc +kubectl get perconaxtradb -n demo sample-pxc +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 3m23s - -$ kubectl get pod -n demo | grep sample-pxc +```bash +kubectl get pod -n demo | grep sample-pxc +``` sample-pxc-0 2/2 Running 0 3m32s sample-pxc-1 2/2 Running 0 3m32s sample-pxc-2 2/2 Running 0 3m32s -``` **Verify tls-secrets created successfully :** @@ -152,7 +153,8 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secrets -n demo | grep sample-pxc +kubectl get secrets -n demo | grep sample-pxc +``` sample-pxc-auth kubernetes.io/basic-auth 2 4m18s sample-pxc-client-cert kubernetes.io/tls 3 4m19s sample-pxc-metrics-exporter-cert kubernetes.io/tls 3 4m18s @@ -161,8 +163,6 @@ sample-pxc-replication kubernetes.io/basic-auth 2 sample-pxc-server-cert kubernetes.io/tls 3 4m18s sample-pxc-token-84hrj kubernetes.io/service-account-token 3 4m19s -``` - **Verify PerconaXtraDB Cluster configured with TLS/SSL:** Now, we are going to connect to the database for verifying the `PerconaXtraDB` server has configured with TLS/SSL encryption. @@ -170,7 +170,8 @@ Now, we are going to connect to the database for verifying the `PerconaXtraDB` s Let's exec into the first pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ ls /etc/mysql/certs/client ca.crt tls.crt tls.key @@ -234,12 +235,11 @@ mysql> show variables like '%require_secure_transport%'; mysql> quit; Bye -``` - Now let's check for the second database server, ```bash -$ kubectl exec -it -n demo sample-pxc-1 -- bash +kubectl exec -it -n demo sample-pxc-1 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ ls /etc/mysql/certs/client ca.crt tls.crt tls.key @@ -302,7 +302,6 @@ mysql> show variables like '%require_secure_transport%'; mysql> quit; Bye -``` The above output shows that the `PerconaXtraDB` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/etc/mysql/certs/client/` and `/etc/mysql/certs/server/` directory for client and server respectively. @@ -313,7 +312,8 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, ```bash -$ kubectl exec -it -n demo sample-pxc-0 -- bash +kubectl exec -it -n demo sample-pxc-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -u${MYSQL_ROOT_USERNAME} -p${MYSQL_ROOT_PASSWORD} mysql: [Warning] Using a password on the command line interface can be insecure. @@ -361,7 +361,6 @@ switching ssl off as it does not make connection via unix socket any more secure. mysql> exit Bye -``` From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/mysql/certs/client/` directory. @@ -370,8 +369,11 @@ From the above output, you can see that only using client certificate we can acc To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc +kubectl delete perconaxtradb -n demo sample-pxc +``` perconaxtradb.kubedb.com "sample-pxc" deleted -$ kubectl delete ns demo -namespace "demo" deleted -``` \ No newline at end of file + +```bash +kubectl delete ns demo +``` +namespace "demo" deleted \ No newline at end of file diff --git a/docs/guides/percona-xtradb/update-version/cluster/index.md b/docs/guides/percona-xtradb/update-version/cluster/index.md index 3655a5b003..68c09bb2a6 100644 --- a/docs/guides/percona-xtradb/update-version/cluster/index.md +++ b/docs/guides/percona-xtradb/update-version/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare PerconaXtraDB Cluster @@ -69,17 +69,17 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/update-version/cluster/examples/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/update-version/cluster/examples/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` created has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.0.40 Ready 3m15s -``` We are now ready to apply the `PerconaXtraDBOpsRequest` CR to update this database. @@ -114,9 +114,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/update-version/cluster/examples/pxops-update.yaml -perconaxtradbopsrequest.ops.kubedb.com/pxops-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/update-version/cluster/examples/pxops-update.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/pxops-update created #### Verify PerconaXtraDB version updated successfully @@ -125,26 +125,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` Every 2.0s: kubectl get perconaxtradbopsrequest -n demo NAME TYPE STATUS AGE pxops-update UpdateVersion Successful 84s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. Now, we are going to verify whether the `PerconaXtraDB` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get perconaxtradb -n demo sample-pxc -o=jsonpath='{.spec.version}{"\n"}' +kubectl get perconaxtradb -n demo sample-pxc -o=jsonpath='{.spec.version}{"\n"}' +``` 8.4.3 -$ kubectl get petset -n demo sample-pxc -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo sample-pxc -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/percona-xtradb-cluster:8.4.3 -$ kubectl get pods -n demo sample-pxc-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/percona-xtradb-cluster:8.4.3 +```bash +kubectl get pods -n demo sample-pxc-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/percona-xtradb-cluster:8.4.3 You can see from above, our `PerconaXtraDB` cluster database has been updated with the new version. So, the update process is successfully completed. @@ -153,6 +157,9 @@ You can see from above, our `PerconaXtraDB` cluster database has been updated wi To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc -$ kubectl delete perconaxtradbopsrequest -n demo pxops-update +kubectl delete perconaxtradb -n demo sample-pxc +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo pxops-update ``` \ No newline at end of file diff --git a/docs/guides/percona-xtradb/volume-expansion/volume-expansion/index.md b/docs/guides/percona-xtradb/volume-expansion/volume-expansion/index.md index db3f75640b..5c1d89e34e 100644 --- a/docs/guides/percona-xtradb/volume-expansion/volume-expansion/index.md +++ b/docs/guides/percona-xtradb/volume-expansion/volume-expansion/index.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to expand the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of PerconaXtraDB @@ -45,13 +45,12 @@ Here, we are going to deploy a `PerconaXtraDB` cluster using a supported versio At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 69s topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 37s -``` - We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. You can install topolvm from [here](https://github.com/topolvm/topolvm). Now, we are going to deploy a `PerconaXtraDB` database of 3 replicas with version `8.4.3`. @@ -84,30 +83,32 @@ spec: Let's create the `PerconaXtraDB` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/volume-expansion/volume-expansion/example/sample-pxc.yaml -perconaxtradb.kubedb.com/sample-pxc created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/volume-expansion/volume-expansion/example/sample-pxc.yaml ``` +perconaxtradb.kubedb.com/sample-pxc created Now, wait until `sample-pxc` has status `Ready`. i.e, ```bash -$ kubectl get perconaxtradb -n demo +kubectl get perconaxtradb -n demo +``` NAME VERSION STATUS AGE sample-pxc 8.4.3 Ready 5m4s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 1Gi RWO Delete Bound demo/data-sample-pxc-0 topolvm-provisioner 63s pvc-b90179f8-c40a-4273-ad77-74ca8470b782 1Gi RWO Delete Bound demo/data-sample-pxc-1 topolvm-provisioner 62s pvc-f72411a4-80d5-4d32-b713-cb30ec662180 1Gi RWO Delete Bound demo/data-sample-pxc-2 topolvm-provisioner 62s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -148,9 +149,9 @@ Here, Let's create the `PerconaXtraDBOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/volume-expansion/volume-expansion/example/online-volume-expansion.yaml -perconaxtradbopsrequest.ops.kubedb.com/px-online-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/percona-xtradb/volume-expansion/volume-expansion/example/online-volume-expansion.yaml ``` +perconaxtradbopsrequest.ops.kubedb.com/px-online-volume-expansion created #### Verify PerconaXtraDB volume expanded successfully @@ -159,15 +160,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the volume siz Let's wait for `PerconaXtraDBOpsRequest` to be `Successful`. Run the following command to watch `PerconaXtraDBOpsRequest` CR, ```bash -$ kubectl get perconaxtradbopsrequest -n demo +kubectl get perconaxtradbopsrequest -n demo +``` NAME TYPE STATUS AGE px-online-volume-expansion VolumeExpansion Successful 96s -``` We can see from the above output that the `PerconaXtraDBOpsRequest` has succeeded. If we describe the `PerconaXtraDBOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe perconaxtradbopsrequest -n demo px-online-volume-expansion +kubectl describe perconaxtradbopsrequest -n demo px-online-volume-expansion +``` Name: px-online-volume-expansion Namespace: demo Labels: @@ -216,21 +218,21 @@ Events: Normal Starting 41s KubeDB Enterprise Operator Resuming PerconaXtraDB database: demo/sample-pxc Normal Successful 41s KubeDB Enterprise Operator Successfully resumed PerconaXtraDB database: demo/sample-pxc Normal Successful 41s KubeDB Enterprise Operator Controller has Successfully expand the volume of PerconaXtraDB: demo/sample-pxc - -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo sample-pxc -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-331335d1-c8e0-4b73-9dab-dae57920e997 2Gi RWO Delete Bound demo/data-sample-pxc-0 topolvm-provisioner 12m pvc-b90179f8-c40a-4273-ad77-74ca8470b782 2Gi RWO Delete Bound demo/data-sample-pxc-1 topolvm-provisioner 12m pvc-f72411a4-80d5-4d32-b713-cb30ec662180 2Gi RWO Delete Bound demo/data-sample-pxc-2 topolvm-provisioner 12m -``` The above output verifies that we have successfully expanded the volume of the PerconaXtraDB database. @@ -239,6 +241,9 @@ The above output verifies that we have successfully expanded the volume of the P To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete perconaxtradb -n demo sample-pxc -$ kubectl delete perconaxtradbopsrequest -n demo px-online-volume-expansion +kubectl delete perconaxtradb -n demo sample-pxc +``` + +```bash +kubectl delete perconaxtradbopsrequest -n demo px-online-volume-expansion ``` diff --git a/docs/guides/pgbouncer/autoscaler/compute/compute-autoscale.md b/docs/guides/pgbouncer/autoscaler/compute/compute-autoscale.md index 60bcee69c8..68135d184a 100644 --- a/docs/guides/pgbouncer/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/pgbouncer/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -79,22 +79,23 @@ spec: Let's create the `PgBouncer` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/autoscaling/compute/pgbouncer-autoscale.yaml -pgbouncer.kubedb.com/pgbouncer-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/autoscaling/compute/pgbouncer-autoscale.yaml ``` +pgbouncer.kubedb.com/pgbouncer-autoscale created Now, wait until `pgbouncer-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME TYPE VERSION STATUS AGE pgbouncer-autoscale kubedb.com/v1 1.18.0 Ready 22s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "300Mi" @@ -104,11 +105,11 @@ $ kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[] "memory": "300Mi" } } -``` Let's check the PgBouncer resources, ```bash -$ kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "memory": "300Mi" @@ -118,7 +119,6 @@ $ kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTempl "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the pgbouncer. @@ -172,20 +172,23 @@ Here, Let's create the `PgBouncerAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/autoscaling/compute/pgbouncer-autoscaler.yaml -pgbouncerautoscaler.autoscaling.kubedb.com/pgbouncer-autoscaler-ops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/autoscaling/compute/pgbouncer-autoscaler.yaml ``` +pgbouncerautoscaler.autoscaling.kubedb.com/pgbouncer-autoscaler-ops created #### Verify Autoscaling is set up successfully Let's check that the `pgbouncerautoscaler` resource is created successfully, ```bash -$ kubectl get pgbouncerautoscaler -n demo +kubectl get pgbouncerautoscaler -n demo +``` NAME AGE pgbouncer-autoscale-ops 6m55s -$ kubectl describe pgbouncerautoscaler pgbouncer-autoscale-ops -n demo +```bash +kubectl describe pgbouncerautoscaler pgbouncer-autoscale-ops -n demo +``` Name: pgbouncer-autoscale-ops Namespace: demo Labels: @@ -268,7 +271,6 @@ Status: Memory: 1Gi Vpa Name: pgbouncer-autoscale Events: -``` So, the `pgbouncerautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our pgbouncer. Our autoscaler operator continuously watches the recommendation generated and creates an `pgbounceropsrequest` based on the recommendations, if the pgbouncer pods are needed to scaled up or down. @@ -276,25 +278,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `pgbounceropsrequest` in the demo namespace to see if any `pgbounceropsrequest` object is created. After some time you'll see that a `pgbounceropsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pbops-pgbouncer-autoscale-zzell6 VerticalScaling Progressing 1m48s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pbops-pgbouncer-autoscale-zzell6 VerticalScaling Successful 3m40s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to scale the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pbops-pgbouncer-autoscale-zzell6 +kubectl describe pgbounceropsrequest -n demo pbops-pgbouncer-autoscale-zzell6 +``` Name: pbops-pgbouncer-autoscale-zzell6 Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -393,12 +396,12 @@ Events: Normal RestartPods 7m31s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 7m31s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pgbouncer-autoscale Normal Successful 7m30s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pgbouncer-autoscale for PgBouncerOpsRequest: pbops-pgbouncer-autoscale-zzell6 -``` Now, we are going to verify from the Pod, and the PgBouncer yaml whether the resources of the pgbouncer has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "400Mi" @@ -409,7 +412,9 @@ $ kubectl get pod -n demo pgbouncer-autoscale-0 -o json | jq '.spec.containers[] } } -$ kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +```bash +kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "memory": "400Mi" @@ -419,7 +424,6 @@ $ kubectl get pgbouncer -n demo pgbouncer-autoscale -o json | jq '.spec.podTempl "memory": "400Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the PgBouncer. diff --git a/docs/guides/pgbouncer/cli/cli.md b/docs/guides/pgbouncer/cli/cli.md index 54de02cebc..9330f060ef 100644 --- a/docs/guides/pgbouncer/cli/cli.md +++ b/docs/guides/pgbouncer/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a pgbouncer CRD object in `default` namespace by default. Following command will create a PgBouncer object as specified in `pgbouncer.yaml`. ```bash -$ kubectl create -f pgbouncer-demo.yaml -pgbouncer "pgbouncer-demo" created +kubectl create -f pgbouncer-demo.yaml ``` +pgbouncer "pgbouncer-demo" created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f pgbouncer-demo.yaml --namespace=kube-system -pgbouncer "pgbouncer-demo" created +kubectl create -f pgbouncer-demo.yaml --namespace=kube-system ``` +pgbouncer "pgbouncer-demo" created `kubectl create` command also considers `stdin` as input. @@ -45,13 +45,13 @@ cat pgbouncer-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all PgBouncer objects in `default` namespace, run the following command: ```bash -$ kubectl get pgbouncer +kubectl get pgbouncer +``` NAME VERSION STATUS AGE pgbouncer-demo 1.17.0 Running 13m pgbouncer-dev 1.17.0 Running 11m pgbouncer-prod 1.17.0 Running 11m pgbouncer-qa 1.17.0 Running 10m -``` To get YAML of an object, use `--output=yaml` flag. @@ -110,7 +110,8 @@ kubectl get pgbouncer pgbouncer-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get all -n demo -o wide +kubectl get all -n demo -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/pgbouncer-demo-0 2/2 Running 0 5m53s 10.244.1.3 kind-worker @@ -125,8 +126,6 @@ petset.apps/pgbouncer-demo 1/1 5m53s pgbouncer,exporter ku NAME VERSION STATUS AGE pgbouncer.kubedb.com/pgbouncer-demo 1.17.0 Running 5m54s -``` - Flag `--output=wide` is used to print additional information. List command supports short names for each object types. You can use it like `kubectl get `. Below are the short name for KubeDB objects: @@ -139,32 +138,32 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Snapshots with their corresponding labels. ```bash -$ kubectl get pb -n demo --show-labels +kubectl get pb -n demo --show-labels +``` NAME DATABASE STATUS AGE LABELS pgbouncer-demo pb/pgbouncer-demo Succeeded 11m app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-demo pgbouncer-tmp pb/postgres-demo Succeeded 1h app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-tmp -``` You can also filter list using `--selector` flag. ```bash -$ kubectl get pb --selector='app.kubernetes.io/name=pgbouncers.kubedb.com' --show-labels +kubectl get pb --selector='app.kubernetes.io/name=pgbouncers.kubedb.com' --show-labels +``` NAME DATABASE STATUS AGE LABELS pgbouncer-demo pb/pgbouncer-demo Succeeded 11m app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-demo pgbouncer-dev pb/postgres-demo Succeeded 1h app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-dev -``` To print only object name, run the following command: ```bash -$ kubectl get all -n demo -o name +kubectl get all -n demo -o name +``` pod/pgbouncer-demo-0 service/kubedb service/pgbouncer-demo service/pgbouncer-demo-stats petset.apps/pgbouncer-demo pgbouncer.kubedb.com/pgbouncer-demo -``` ### How to Describe Objects @@ -264,8 +263,8 @@ To learn about various options of `describe` command, please visit [here](/docs/ Let's edit an existing running PgBouncer object to setup [Monitoring](/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md). The following command will open PgBouncer `pgbouncer-demo` in editor. ```bash -$ kubectl edit pb pgbouncer-demo - +kubectl edit pb pgbouncer-demo +``` # Add following to Spec to configure monitoring: monitor: agent: prometheus.io/operator @@ -275,7 +274,6 @@ $ kubectl edit pb pgbouncer-demo release: prometheus interval: 10s pgbouncer "pgbouncer-demo" edited -``` #### Edit restrictions @@ -291,16 +289,16 @@ Various fields of a KubeDb object can't be edited using `edit` command. The foll `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a PgBouncer `pgbouncer-dev` in default namespace ```bash -$ kubectl delete pgbouncer pgbouncer-dev -pgbouncer "pgbouncer-dev" deleted +kubectl delete pgbouncer pgbouncer-dev ``` +pgbouncer "pgbouncer-dev" deleted You can also use YAML files to delete objects. The following command will delete a PgBouncer using the type and name specified in `pgbouncer.yaml`. ```bash -$ kubectl delete -f pgbouncer.yaml -PgBouncer "pgbouncer-dev" deleted +kubectl delete -f pgbouncer.yaml ``` +PgBouncer "pgbouncer-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -318,16 +316,23 @@ kubectl delete pgbouncer -l pgbouncer.app.kubernetes.io/instance=pgbouncer-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # Create objects -$ kubectl create -f +```bash +kubectl create -f +``` # List objects -$ kubectl get pgbouncer -$ kubectl get pgbouncer.kubedb.com +```bash +kubectl get pgbouncer +``` + +```bash +kubectl get pgbouncer.kubedb.com +``` # Delete objects -$ kubectl delete pgbouncer +```bash +kubectl delete pgbouncer ``` ## Next Steps diff --git a/docs/guides/pgbouncer/initialization/gitsync.md b/docs/guides/pgbouncer/initialization/gitsync.md index 6da46c2a4e..459c2d8534 100644 --- a/docs/guides/pgbouncer/initialization/gitsync.md +++ b/docs/guides/pgbouncer/initialization/gitsync.md @@ -31,9 +31,9 @@ In this example, we will initialize PgBouncer using a `.sh` script from the GitH To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -94,16 +94,16 @@ The `git-sync` container has one required flags: Now, wait until `pb` has status `Ready`. i.e, ```bash -$ kubectl get PgBouncer -n demo +kubectl get PgBouncer -n demo +``` NAME VERSION STATUS AGE pb 1.24.0 Ready 49m -``` - Next, we will connect to the PgBouncer database and verify the data inserted from the `*.sql` script stored in the Git repository. ```bash -$ kubectl exec -it -n demo pb-0 -- sh +kubectl exec -it -n demo pb-0 -- sh +``` Defaulted container "pgbouncer" out of: pgbouncer, git-sync (init) / $ cd init-scripts/ @@ -119,8 +119,6 @@ postgres=# \dt public | kubedb_write_check_pgbouncer | table | postgres public | my_table | table | postgres (2 rows) - -``` `my_table` is created by the `init-script.sh` script stored in the Git repository. ## From Private Git Repository @@ -131,7 +129,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -146,7 +144,7 @@ This secret will be used by git-sync to authenticate with the Git repository. >Here, we are using the default SSH key file located at `$HOME/.ssh/id_rsa`. If your SSH key is stored in a different location, please update the command accordingly. Also you can use any name instead of `git-creds` to create the secret. ```bash -$ kubectl create secret generic -n demo \ +kubectl create secret generic -n demo \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -204,13 +202,13 @@ The `git-sync` container has two required flags: Once the database reaches the `Ready` state, you can verify the data using the method described above. ```bash -$ kubectl get PgBouncer -n demo +kubectl get PgBouncer -n demo +``` NAME VERSION STATUS AGE pb 1.24.0 Ready 8m - -``` ```bash -$ kubectl exec -it -n demo pb-0 -- sh +kubectl exec -it -n demo pb-0 -- sh +``` Defaulted container "pgbouncer" out of: pgbouncer, git-sync (init) / $ cd init-scripts/ @@ -226,8 +224,6 @@ postgres=# \dt public | kubedb_write_check_pgbouncer | table | postgres public | my_table | table | postgres (2 rows) - -``` `my_table` is created by the `init-script.sh` script stored in the Git repository. ### 2. Using Username and Personal Access Token(PAT) @@ -236,7 +232,7 @@ First, create a `Personal Access Token (PAT)` on your Git host server with the r Then create a Kubernetes secret using the `Personal Access Token (PAT)`: > Here, you can use any key name instead of `git-pat` to store the token in the secret. ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -289,13 +285,13 @@ Here, OOnce the database reaches the `Ready` state, you can verify the data using the method described above. ```bash -$ kubectl get PgBouncer -n demo +kubectl get PgBouncer -n demo +``` NAME VERSION STATUS AGE pb 1.24.0 Ready 19m - -``` ```bash -$ kubectl exec -it -n demo pb-0 -- sh +kubectl exec -it -n demo pb-0 -- sh +``` Defaulted container "pgbouncer" out of: pgbouncer, git-sync (init) / $ cd init-scripts/ @@ -311,8 +307,6 @@ postgres=# \dt public | kubedb_write_check_pgbouncer | table | postgres public | my_table | table | postgres (2 rows) - -``` `my_table` is created by the `init-script.sh` script stored in the Private Git repository. ## CleanUp @@ -320,7 +314,13 @@ postgres=# \dt To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete PgBouncer -n demo pb -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete PgBouncer -n demo pb +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/pgbouncer/initialization/script_source.md b/docs/guides/pgbouncer/initialization/script_source.md index d47c0c16fc..9fce791a70 100644 --- a/docs/guides/pgbouncer/initialization/script_source.md +++ b/docs/guides/pgbouncer/initialization/script_source.md @@ -25,13 +25,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +50,10 @@ We will use a ConfigMap as the script source. You can use any Kubernetes support Let's create a ConfigMap with the initialization script: ```bash -$ kubectl create configmap -n demo pb-init-script \ +kubectl create configmap -n demo pb-init-script \ --from-literal=init.sh="$(curl -fsSL https://raw.githubusercontent.com/kubedb/pgbouncer-pgpool-init-scripts/master/pgbouncer/init.sh)" -configmap/pb-init-script created ``` +configmap/pb-init-script created > **Note:** The initialization script above is provided only as an example. You can use your own initialization script as long as it performs the required setup for your environment. If your script connects to PostgreSQL, make sure to include the appropriate PostgreSQL credentials (such as the password) so the script can authenticate successfully. ## Create PgBouncer with Script Source @@ -92,17 +94,17 @@ VolumeSource provided in `init.script` will be mounted in the Pod and executed w Now, let's create the PgBouncer CRD using the YAML shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/initialization/script-pgbouncer.yaml -pgbouncer.kubedb.com/script-pgbouncer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/initialization/script-pgbouncer.yaml ``` +pgbouncer.kubedb.com/script-pgbouncer created Now, wait until PgBouncer goes in `Ready` state. Verify that it is in `Ready` state using the following command: ```bash -$ kubectl get pgbouncer -n demo script-pgbouncer +kubectl get pgbouncer -n demo script-pgbouncer +``` NAME VERSION STATUS AGE script-pgbouncer 1.24.0 Ready 2m -``` ## Verify Initialization @@ -118,22 +120,23 @@ Now let's connect to our PgBouncer instance to verify that it has been initializ - Username: Run the following command to get the *username*: ```bash - $ kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.username}' | base64 -d - postgres + kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.username}' | base64 -d ``` + postgres - Password: Run the following command to get the *password*: ```bash - $ kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d - S3cur3P@ssw0rd + kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + S3cur3P@ssw0rd Connect to PgBouncer and verify that it is successfully proxying connections to PostgreSQL: ```bash -$ kubectl exec -it -n demo script-pgbouncer-0 -- \ +kubectl exec -it -n demo script-pgbouncer-0 -- \ psql -h localhost -p 5432 -U postgres -d postgres +``` Password for user postgres: psql (16.14, server 17.5) WARNING: psql major version 16, server major version 17. @@ -147,7 +150,6 @@ postgres=# \dt public | kubedb_write_check_pgbouncer | table | postgres public | my_table | table | postgres (2 rows) -``` We can see that PgBouncer is running and proxying connections to the PostgreSQL backend through the initialized connection pool. @@ -156,11 +158,19 @@ We can see that PgBouncer is running and proxying connections to the PostgreSQL To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo pgbouncer/script-pgbouncer -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo pgbouncer/script-pgbouncer +kubectl patch -n demo pgbouncer/script-pgbouncer -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo pgbouncer/script-pgbouncer +``` + +```bash +kubectl delete -n demo configmap/pb-init-script +``` -$ kubectl delete -n demo configmap/pb-init-script -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md b/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md index e9319ae309..227a84195b 100644 --- a/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md +++ b/docs/guides/pgbouncer/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor PgBouncer database using builtin [Pro - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -74,32 +76,33 @@ Here, Let's create the PgBouncer crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/monitoring/builtin-prom-pb.yaml -pgbouncer.kubedb.com/builtin-prom-pb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/monitoring/builtin-prom-pb.yaml ``` +pgbouncer.kubedb.com/builtin-prom-pb created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pb -n demo builtin-prom-pb +kubectl get pb -n demo builtin-prom-pb +``` NAME TYPE VERSION STATUS AGE builtin-prom-pb kubedb.com/v1 1.18.0 Ready 65s -``` KubeDB will create a separate stats service with name `{PgBouncer cr name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-pb" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-pb" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-pb ClusterIP 10.96.210.2 5432/TCP 86s builtin-prom-pb-pods ClusterIP None 5432/TCP 86s builtin-prom-pb-stats ClusterIP 10.96.215.193 56790/TCP 74s -``` Here, `builtin-prom-pb-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-pb-stats +kubectl describe svc -n demo builtin-prom-pb-stats +``` Name: builtin-prom-pb-stats Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -122,7 +125,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.28:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -286,20 +288,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -310,9 +312,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -321,18 +323,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-d64b668fb-4khbg 1/1 Running 0 21s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-d64b668fb-4khbg` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-d64b668fb-4khbg 9090 +kubectl port-forward -n monitoring prometheus-d64b668fb-4khbg 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-pb-stats` service as one of the targets. diff --git a/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md b/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md index 9742949ae7..ffe7f1a351 100644 --- a/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md +++ b/docs/guides/pgbouncer/monitoring/using-prometheus-operator.md @@ -34,12 +34,14 @@ The following diagram shows how KubeDB Provisioner operator monitor `PgBouncer` - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -52,16 +54,16 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE monitoring prometheus-kube-prometheus-prometheus v2.39.0 1 13d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -216,34 +218,34 @@ Here, Let's create the PgBouncer object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/monitoring/coreos-prom-pb.yaml -pgbouncer.kubedb.com/coreos-prom-pb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/monitoring/coreos-prom-pb.yaml ``` +pgbouncer.kubedb.com/coreos-prom-pb created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pb -n demo coreos-prom-pb +kubectl get pb -n demo coreos-prom-pb +``` NAME TYPE VERSION STATUS AGE coreos-prom-pb kubedb.com/v1 1.18.0 Ready 65s -``` KubeDB will create a separate stats service with name `{PgBouncer crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-pb" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-pb" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-pb ClusterIP 10.96.201.180 9999/TCP,9595/TCP 4m3s coreos-prom-pb-pods ClusterIP None 9999/TCP 4m3s coreos-prom-pb-stats ClusterIP 10.96.73.22 9719/TCP 4m3s -``` Here, `coreos-prom-pb-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo coreos-prom-pb-stats +kubectl describe svc -n demo coreos-prom-pb-stats ``` ```yaml Name: coreos-prom-pb-stats @@ -271,15 +273,15 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this informatio KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-pb-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-pb-stats 2m40s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of PgBouncer crd. ```bash -$ kubectl get servicemonitor -n demo coreos-prom-pb-stats -o yaml +kubectl get servicemonitor -n demo coreos-prom-pb-stats -o yaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -330,20 +332,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 13d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `coreos-prom-pb-stats` service as one of the targets. diff --git a/docs/guides/pgbouncer/private-registry/using-private-registry.md b/docs/guides/pgbouncer/private-registry/using-private-registry.md index dded843a54..5654db0b24 100644 --- a/docs/guides/pgbouncer/private-registry/using-private-registry.md +++ b/docs/guides/pgbouncer/private-registry/using-private-registry.md @@ -23,9 +23,9 @@ At first, you need to have a Kubernetes cluster, and the kubectl command-line to To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -36,10 +36,10 @@ namespace/demo created - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For pgbouncer, push `SERVER_IMAGE`, `EXPORTER_IMAGE` of following PgBouncerVersions, where `deprecated` is not true, to your private registry. ```bash - $ kubectl get pgbouncerversions -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.pgBouncer.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + kubectl get pgbouncerversions -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.pgBouncer.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + ``` NAME VERSION SERVER_IMAGE EXPORTER_IMAGE DEPRECATED 1.17.0 1.17.0 kubedb/pgbouncer:1.17.0 kubedb/pgbouncer_exporter:v0.1.1 false - ``` Docker hub repositories: @@ -54,13 +54,13 @@ ImagePullSecrets is a type of a Kubernetes Secret whose sole purpose is to pull Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret generic -n demo docker-registry myregistrykey \ +kubectl create secret generic -n demo docker-registry myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -93,9 +93,9 @@ spec: Now, create the PgBouncerVersion crd, ```bash -$ kubectl apply -f pvt-pgbouncerversion.yaml -pgbouncerversion.kubedb.com/1.17.0 created +kubectl apply -f pvt-pgbouncerversion.yaml ``` +pgbouncerversion.kubedb.com/1.17.0 created ## Deploy PgBouncer from Private Registry @@ -129,17 +129,17 @@ spec: Now run the command to create this pgbouncer server: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/private-registry/pvt-reg-pgbouncer.yaml -pgbouncer.kubedb.com/pvt-reg-pgbouncer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/private-registry/pvt-reg-pgbouncer.yaml ``` +pgbouncer.kubedb.com/pvt-reg-pgbouncer created To check if the images pulled successfully from the repository, see if the PgBouncer is in Running state: ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-pgbouncer" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-pgbouncer" +``` NAME READY STATUS RESTARTS AGE pvt-reg-pgbouncer-0 1/1 Running 0 3m -``` ## Cleaning up diff --git a/docs/guides/pgbouncer/quickstart/quickstart.md b/docs/guides/pgbouncer/quickstart/quickstart.md index ca711bec9d..bf8bb44c71 100644 --- a/docs/guides/pgbouncer/quickstart/quickstart.md +++ b/docs/guides/pgbouncer/quickstart/quickstart.md @@ -29,9 +29,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,15 +42,13 @@ namespace/demo created When you have installed KubeDB, it has created `PgBouncerVersion` crd for all supported PgBouncer versions. Let's check available PgBouncerVersion by, ```bash -$ kubectl get pgbouncerversions - +kubectl get pgbouncerversions +``` NAME VERSION PGBOUNCER_IMAGE DEPRECATED AGE 1.17.0 1.17.0 ghcr.io/kubedb/pgbouncer:1.17.0 22h 1.18.0 1.18.0 ghcr.io/kubedb/pgbouncer:1.18.0 22h 1.23.1 1.23.1 ghcr.io/kubedb/pgbouncer:1.23.1 22h 1.24.0 1.24.0 ghcr.io/kubedb/pgbouncer:1.24.0 22h - -``` Notice the `DEPRECATED` column. Here, `true` means that this PgBouncerVersion is deprecated for current KubeDB version. KubeDB will not work for deprecated PgBouncerVersion. @@ -65,9 +63,9 @@ Luckily PostgreSQL is readily available in KubeDB as crd and can easily be deplo In this tutorial, we will use a Postgres named `quick-postgres` in the `demo` namespace. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/quick-postgres.yaml -postgres.kubedb.com/quick-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/quick-postgres.yaml ``` +postgres.kubedb.com/quick-postgres created KubeDB creates all the necessary resources including services, secrets, and appbindings to get this server up and running. A default database `postgres` is created in `quick-postgres`. Database secret `quick-postgres-auth` holds this user's username and password. Following is the yaml file for it. @@ -97,31 +95,36 @@ type: kubernetes.io/basic-auth For the purpose of this tutorial, we will need to extract the username and password from database secret `quick-postgres-auth`. ```bash -$ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +``` RoX*L8I;8R7v32ti⏎ -$ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\username}' | base64 -d -postgres⏎ +```bash +kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\username}' | base64 -d ``` +postgres⏎ Now, to test connection with this database using the credentials obtained above, we will expose the service port associated with `quick-postgres` to localhost. ```bash -$ kubectl port-forward -n demo svc/quick-postgres 5432 +kubectl port-forward -n demo svc/quick-postgres 5432 +``` Forwarding from 127.0.0.1:5432 -> 5432 Forwarding from [::1]:5432 -> 5432 -``` With that done , we should now be able to connect to `postgres` database using username `postgres`, and password `RoX*L8I;8R7v32ti`. ```bash -$ export PGPASSWORD='RoX*L8I;8R7v32ti' -$ psql --host=localhost --port=5432 --username=postgres postgres +export PGPASSWORD='RoX*L8I;8R7v32ti' +``` + +```bash +psql --host=localhost --port=5432 --username=postgres postgres +``` psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1), server 13.2) Type "help" for help. postgres=# -``` After establishing connection successfully, we will create a table in `postgres` database and populate it with data. @@ -183,9 +186,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server-v1.yaml -pgbouncer.kubedb.com/pgbouncer-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server-v1.yaml ``` +pgbouncer.kubedb.com/pgbouncer-server created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -210,9 +213,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server-v1.yaml -pgbouncer.kubedb.com/pgbouncer-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server-v1.yaml ``` +pgbouncer.kubedb.com/pgbouncer-server created Here, @@ -269,57 +272,56 @@ Now that we've been introduced to the pgBouncer crd, let's create it, > For more details visit [here](https://appscode.com/blog/post/deletion-policy/) ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server.yaml - -pgbouncer.kubedb.com/pgbouncer-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/quickstart/pgbouncer-server.yaml ``` +pgbouncer.kubedb.com/pgbouncer-server created ## Connect via PgBouncer To connect via pgBouncer we have to expose its service to localhost. ```bash -$ kubectl port-forward -n demo svc/pgbouncer-server 5432 - +kubectl port-forward -n demo svc/pgbouncer-server 5432 +``` Forwarding from 127.0.0.1:5432 -> 5432 Forwarding from [::1]:5432 -> 5432 -``` Now, let's connect to `postgres` database via PgBouncer using psql. -``` bash -$ env PGPASSWORD='RoX*L8I;8R7v32ti' psql --host=localhost --port=5432 --username=postgres postgres +```bash +env PGPASSWORD='RoX*L8I;8R7v32ti' psql --host=localhost --port=5432 --username=postgres postgres +``` psql (14.9 (Ubuntu 14.9-0ubuntu0.22.04.1), server 13.2) Type "help" for help. postgres=# \q -``` If everything goes well, we'll be connected to the `postgres` database and be able to execute commands. Let's confirm if the company data we inserted in the `postgres` database before are available via PgBouncer: ```bash -$ env PGPASSWORD='RoX*L8I;8R7v32ti' psql --host=localhost --port=5432 --username=postgres postgres --command='SELECT * FROM company ORDER BY name;' +env PGPASSWORD='RoX*L8I;8R7v32ti' psql --host=localhost --port=5432 --username=postgres postgres --command='SELECT * FROM company ORDER BY name;' +``` name | employee --------+---------- Apple | 10 Google | 15 (2 rows) -``` KubeDB operator watches for PgBouncer objects using Kubernetes api. When a PgBouncer object is created, KubeDB operator will create a new PetSet and a Service with the matching name. KubeDB operator will also create a governing service for PetSet with the name `kubedb`, if one is not already present. KubeDB operator sets the `status.phase` to `Running` once the connection-pooling mechanism is ready. ```bash -$ kubectl get pb -n demo pgbouncer-server -o wide +kubectl get pb -n demo pgbouncer-server -o wide +``` NAME VERSION STATUS AGE pgbouncer-server 1.18.0 Ready 2h -``` Let's describe PgBouncer object `pgbouncer-server` ```bash -$ kubectl dba describe pb -n demo pgbouncer-server +kubectl dba describe pb -n demo pgbouncer-server +``` Name: pgbouncer-server Namespace: demo Labels: @@ -476,16 +478,15 @@ Status: Observed Generation: 2 Phase: Ready Events: -``` KubeDB has created a service for the PgBouncer object. ```bash -$ kubectl get service -n demo --selector=app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-server +kubectl get service -n demo --selector=app.kubernetes.io/name=pgbouncers.kubedb.com,app.kubernetes.io/instance=pgbouncer-server +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE pgbouncer-server ClusterIP 10.96.36.35 5432/TCP 141m pgbouncer-server-pods ClusterIP None 5432/TCP 141m -``` Here, Service *`pgbouncer-server`* targets random pods to carry out connection-pooling. @@ -494,15 +495,19 @@ Here, Service *`pgbouncer-server`* targets random pods to carry out connection-p To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo pg/quick-postgres +kubectl delete -n demo pg/quick-postgres +``` postgres.kubedb.com "quick-postgres" deleted -$ kubectl delete -n demo pb/pgbouncer-server +```bash +kubectl delete -n demo pb/pgbouncer-server +``` pgbouncer.kubedb.com "pgbouncer-server" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md b/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md index 1e9eeeb81a..715294c448 100644 --- a/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/pgbouncer/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,18 +79,21 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/pb.yaml -pgbouncer.kubedb.com/pb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure-tls/pb.yaml ``` +pgbouncer.kubedb.com/pb created Now, wait until `pb` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME VERSION STATUS AGE pb 1.18.0 Ready 131m -$ kubectl dba describe pgbouncer pb -n demo +```bash +kubectl dba describe pgbouncer pb -n demo +``` Name: pb Namespace: demo Labels: @@ -186,7 +189,6 @@ Status: Observed Generation: 2 Phase: Ready Events: -``` Now, we can verify that the TLS is disabled. diff --git a/docs/guides/pgbouncer/reconfigure/reconfigure-pgbouncer.md b/docs/guides/pgbouncer/reconfigure/reconfigure-pgbouncer.md index 948fac1d2d..51fc0a98a6 100644 --- a/docs/guides/pgbouncer/reconfigure/reconfigure-pgbouncer.md +++ b/docs/guides/pgbouncer/reconfigure/reconfigure-pgbouncer.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -59,9 +59,9 @@ Here, `auth_type` is set to `scram-sha-256`, whereas the default value is `md5`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo pb-custom-config --from-file=./pgbouncer.ini -secret/pb-custom-config created +kubectl create secret generic -n demo pb-custom-config --from-file=./pgbouncer.ini ``` +secret/pb-custom-config created In this section, we are going to create a PgBouncer object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `PgBouncer` CR that we are going to create, @@ -95,24 +95,25 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pb-custom-config.yaml -pgbouncer.kubedb.com/pb-custom created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pb-custom-config.yaml ``` +pgbouncer.kubedb.com/pb-custom created Now, wait until `pb-custom` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME TYPE VERSION STATUS AGE pb-custom kubedb.com/v1 1.18.0 Ready 112s -``` Now, we will check if the pgbouncer has started with the custom configuration we have provided. Now, you can exec into the pgbouncer pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo pb-custom-0 -- /bin/sh +kubectl exec -it -n demo pb-custom-0 -- /bin/sh +``` pb-custom-0:/$ cat etc/config/pgbouncer.ini [databases] postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres @@ -137,7 +138,6 @@ max_user_connections = 2 stats_period = 60 pb-custom-0:/$ exit exit -``` As we can see from the configuration of running pgbouncer, the value of `auth_type` has been set to `scram-sha-256`. @@ -155,9 +155,9 @@ auth_type=md5 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./pgbouncer.ini -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./pgbouncer.ini ``` +secret/new-custom-config created #### Create PgBouncerOpsRequest @@ -191,9 +191,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pbops-reconfigure.yaml -pgbounceropsrequest.ops.kubedb.com/pbops-reconfigure created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pbops-reconfigure.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pbops-reconfigure created #### Verify the new configuration is working @@ -202,16 +202,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pbops-reconfigure Reconfigure Successful 63s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to reconfigure the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pbops-reconfigure +kubectl describe pgbounceropsrequest -n demo pbops-reconfigure +``` Name: pbops-reconfigure Namespace: demo Labels: @@ -315,12 +316,12 @@ Events: Normal Starting 12s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-custom Normal Successful 12s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-custom Normal Successful 12s KubeDB Ops-manager Operator Controller has Successfully Reconfigured PgBouncer databases: demo/pb-custom -``` Now let's exec into the pgbouncer pod and check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo pb-custom-0 -- /bin/sh +kubectl exec -it -n demo pb-custom-0 -- /bin/sh +``` pb-custom-0:/$ cat etc/config/pgbouncer.ini [databases] postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres @@ -345,7 +346,6 @@ reserve_pool_size = 5 reserve_pool_timeout = 5 pb-custom-0:/$ exit exit -``` As we can see from the configuration of running pgbouncer, the value of `auth_type` has been changed from `scram-sha-256` to `md5`. So the reconfiguration of the pgbouncer is successful. @@ -386,9 +386,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pbops-reconfigure-apply.yaml -pgbounceropsrequest.ops.kubedb.com/pbops-reconfigure-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/reconfigure/pbops-reconfigure-apply.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pbops-reconfigure-apply created #### Verify the new configuration is working @@ -397,17 +397,18 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pbops-reconfigure Reconfigure Successful 9m15s pbops-reconfigure-apply Reconfigure Successful 53s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to reconfigure the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pbops-reconfigure-apply +kubectl describe pgbounceropsrequest -n demo pbops-reconfigure-apply +``` Name: pbops-reconfigure-apply Namespace: demo Labels: @@ -508,12 +509,12 @@ Events: Normal Starting 41s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-custom Normal Successful 41s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-custom Normal Successful 41s KubeDB Ops-manager Operator Controller has Successfully Reconfigured PgBouncer databases: demo/pb-custom -``` Now let's exec into the pgbouncer pod and check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo pb-custom-0 -- /bin/sh +kubectl exec -it -n demo pb-custom-0 -- /bin/sh +``` pb-custom-0:/$ cat etc/config/pgbouncer.ini [databases] postgres= host=ha-postgres.demo.svc port=5432 dbname=postgres @@ -538,7 +539,6 @@ listen_port = 5432 reserve_pool_size = 5 pb-custom-0:/$ exit exit -``` As we can see from the configuration of running pgbouncer, the value of `auth_type` has been changed from `md5` to `scram-sha-256`. So the reconfiguration of the pgbouncer using the `applyConfig` field is successful. diff --git a/docs/guides/pgbouncer/restart/restart.md b/docs/guides/pgbouncer/restart/restart.md index ae3bec2348..401e68052d 100644 --- a/docs/guides/pgbouncer/restart/restart.md +++ b/docs/guides/pgbouncer/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the PgBouncer via a PgBouncerOpsRequest. Restarting i - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,9 +67,9 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/restart/pgbouncer.yaml -pgbouncer.kubedb.com/pgbouncer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/restart/pgbouncer.yaml ``` +pgbouncer.kubedb.com/pgbouncer created ## Apply Restart opsRequest @@ -94,18 +94,21 @@ spec: Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/restart/ops.yaml -pgbounceropsrequest.ops.kubedb.com/restart-pgbouncer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/restart/ops.yaml ``` +pgbounceropsrequest.ops.kubedb.com/restart-pgbouncer created Now the Ops-manager operator will restart the pods one by one. -```shell -$ kubectl get pbops -n demo +```bash +kubectl get pbops -n demo +``` NAME TYPE STATUS AGE restart-pgbouncer Restart Successful 79s -$ kubectl get pbops -n demo -oyaml restart-pgbouncer +```bash +kubectl get pbops -n demo -oyaml restart-pgbouncer +``` apiVersion: ops.kubedb.com/v1alpha1 kind: PgBouncerOpsRequest metadata: @@ -167,7 +170,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/pgbouncer/rotateauth/rotateauth.md b/docs/guides/pgbouncer/rotateauth/rotateauth.md index b949adf151..306e271f36 100644 --- a/docs/guides/pgbouncer/rotateauth/rotateauth.md +++ b/docs/guides/pgbouncer/rotateauth/rotateauth.md @@ -26,9 +26,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -54,23 +54,26 @@ I*7SQB7)6~Kni8*X⏎ Here, we will connect to PgBouncer server from local-machine through port-forwarding. We will connect to `pgbouncer-server` pod from local-machine using port-frowarding and it must be running in separate terminal. ```bash -$ kubectl port-forward svc/pgbouncer-server -n demo 9999:5432 +kubectl port-forward svc/pgbouncer-server -n demo 9999:5432 +``` Forwarding from 127.0.0.1:9999 -> 5432 Forwarding from [::1]:9999 -> 5432 - -``` Now, you can exec into the pod pgbouncer-server` and connect to database using `username` and `password` -```shell -$ kubectl exec -it -n demo pgbouncer-server-0 -- /bin/sh +```bash +kubectl exec -it -n demo pgbouncer-server-0 -- /bin/sh +``` / $ cat /var/run/pgbouncer/secret/userlist "pgbouncer" "md5f24d95a2a5c1ed1debe8c3e6f19ac7ec" "postgres" "md5095f5936c7d03fbc4998320d3bf993c4" / $ exit -``` First, you have to have `PostgreSQL` to run these commands. -```shell -$ export PGPASSWORD='I*7SQB7)6~Kni8*X' -$ psql --host=localhost --port=9999 --username=pgbouncer -d pgbouncer +```bash +export PGPASSWORD='I*7SQB7)6~Kni8*X' +``` + +```bash +psql --host=localhost --port=9999 --username=pgbouncer -d pgbouncer +``` psql (16.9 (Ubuntu 16.9-0ubuntu0.24.04.1), server 1.18.0/bouncer) WARNING: psql major version 16, server major version 1.18. Some psql features might not work. @@ -82,8 +85,6 @@ pgbouncer=# show databases; postgres | quick-postgres.demo.svc | 5432 | postgres | | 20 | 1 | 5 | | 1 | 1 | 0 | 0 (2 rows) -``` - If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth PgBouncerOpsRequest @@ -109,19 +110,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on PgBouncer. Let's create the `PgBouncerOpsRequest` CR we have shown above, -```shell - $kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/rotateauth/rotateauth.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/rotateauth/rotateauth.yaml + ``` pgbounceropsrequest.ops.kubedb.com/pbops-rotate-auth-generated created -``` Let's wait for `PgBouncerOpsrequest` to be `Successful`. Run the following command to watch `PgBouncerOpsrequest` CRO -```shell - $ kubectl get PgBouncerOpsRequest -n demo + ```bash + kubectl get PgBouncerOpsRequest -n demo + ``` NAME TYPE STATUS AGE pbops-rotate-auth-generated RotateAuth Successful 4m34s -``` If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe PgBounceropsrequest -n demo pbops-rotate-auth-generated +```bash + kubectl describe PgBounceropsrequest -n demo pbops-rotate-auth-generated +``` Name: pbops-rotate-auth-generated Namespace: demo Labels: @@ -218,37 +220,45 @@ Events: Warning check pod ready; ConditionStatus:True; PodName:pgbouncer-server-0 4m37s KubeDB Ops-manager Operator check pod ready; ConditionStatus:True; PodName:pgbouncer-server-0 Warning check pg bouncer running; ConditionStatus:True; PodName:pgbouncer-server-0 4m37s KubeDB Ops-manager Operator check pg bouncer running; ConditionStatus:True; PodName:pgbouncer-server-0 Normal Successful 4m32s KubeDB Ops-manager Operator Restart performed successfully in PgBouncer: demo/pgbouncer-server for PgBouncerOpsRequest: pbops-rotate-auth-generated -``` **Verify Auth is rotated** -```shell -$ kubectl get PgBouncer -n demo pgbouncer-server -ojson | jq .spec.authsecret.name +```bash +kubectl get PgBouncer -n demo pgbouncer-server -ojson | jq .spec.authsecret.name +``` "pgbouncer-server-auth" -$ kubectl get secret -n demo pgbouncer-server-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo pgbouncer-server-auth -o=jsonpath='{.data.username}' | base64 -d +``` pgbouncer⏎ -$ kubectl get secrets -n demo pgbouncer-server-auth -o jsonpath='{.data.\password}' | base64 -d -Hc5nXhC403rvDGPf⏎ + +```bash +kubectl get secrets -n demo pgbouncer-server-auth -o jsonpath='{.data.\password}' | base64 -d ``` +Hc5nXhC403rvDGPf⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The key is `authData.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo pgbouncer-server-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo pgbouncer-server-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` pgbouncer⏎ -$ kubectl get secret -n demo pgbouncer-server-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -I*7SQB7)6~Kni8*X⏎ + +```bash +kubectl get secret -n demo pgbouncer-server-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +I*7SQB7)6~Kni8*X⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, -```shell -$ kubectl create secret generic quick-pb-user-auth -n demo \ +```bash + kubectl create secret generic quick-pb-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=user \ --from-literal=password=PgBouncer2 -secret/quick-pb-user-auth created ``` +secret/quick-pb-user-auth created Now create a `PgBouncerOpsRequest` with `RotateAuth` type. Below is the YAML of the `PgBouncerOpsRequest` that we are going to create, ```shell @@ -276,21 +286,22 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/rotateauth/rotateauthuser.yaml -pgbounceropsrequest.ops.kubedb.com/pbops-rotate-auth-user created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/rotateauth/rotateauthuser.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pbops-rotate-auth-user created Let’s wait for `PgBouncerOpsRequest` to be Successful. Run the following command to watch `PgBouncerOpsRequest` CRO: -```shell -$ kubectl get PgBouncerOpsRequest -n demo +```bash +kubectl get PgBouncerOpsRequest -n demo +``` NAME TYPE STATUS AGE pbops-rotate-auth-generated RotateAuth Successful 20m pbops-rotate-auth-user RotateAuth Successful 6m16s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe PgBounceropsrequest -n demo pbops-rotate-auth-user +```bash + kubectl describe PgBounceropsrequest -n demo pbops-rotate-auth-user +``` Name: pbops-rotate-auth-user Namespace: demo Labels: @@ -388,24 +399,31 @@ Events: Warning check pod ready; ConditionStatus:True; PodName:pgbouncer-server-0 6m23s KubeDB Ops-manager Operator check pod ready; ConditionStatus:True; PodName:pgbouncer-server-0 Warning check pg bouncer running; ConditionStatus:True; PodName:pgbouncer-server-0 6m23s KubeDB Ops-manager Operator check pg bouncer running; ConditionStatus:True; PodName:pgbouncer-server-0 Normal Successful 6m18s KubeDB Ops-manager Operator Restart performed successfully in PgBouncer: demo/pgbouncer-server for PgBouncerOpsRequest: pbops-rotate-auth-user - -``` **Verify auth is rotate** -```shell -$ kubectl get PgBouncer -n demo pgbouncer-server -ojson | jq .spec.authsecret.name +```bash + kubectl get PgBouncer -n demo pgbouncer-server -ojson | jq .spec.authsecret.name +``` "quick-pb-user-auth" -$ kubectl get secrets -n demo quick-pb-user-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secrets -n demo quick-pb-user-auth -o jsonpath='{.data.\username}' | base64 -d +``` user⏎ -$ kubectl get secrets -n demo quick-pb-user-auth -o jsonpath='{.data.\password}' | base64 -d -PgBouncer2⏎ + +```bash +kubectl get secrets -n demo quick-pb-user-auth -o jsonpath='{.data.\password}' | base64 -d ``` +PgBouncer2⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo quick-pb-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash + kubectl get secret -n demo quick-pb-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` pgbouncer⏎ -$ kubectl get secret -n demo quick-pb-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -Hc5nXhC403rvDGPf⏎ + +```bash +kubectl get secret -n demo quick-pb-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +Hc5nXhC403rvDGPf⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -414,14 +432,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete PgBounceropsrequest pbops-rotate-auth-generated pbops-rotate-auth-user -n demo +```bash +kubectl delete PgBounceropsrequest pbops-rotate-auth-generated pbops-rotate-auth-user -n demo +``` PgBounceropsrequest.ops.kubedb.com "pbops-rotate-auth-generated" "pbops-rotate-auth-user" deleted -$ kubectl delete secret -n demoquick-pb-user-auth + +```bash +kubectl delete secret -n demoquick-pb-user-auth +``` secret "quick-pb-user-auth" deleted -$ kubectl delete secret -n demo pgbouncer-server-auth -secret "pgbouncer-server-auth " deleted + +```bash +kubectl delete secret -n demo pgbouncer-server-auth ``` +secret "pgbouncer-server-auth " deleted ## Next Steps diff --git a/docs/guides/pgbouncer/scaling/horizontal-scaling/horizontal-ops.md b/docs/guides/pgbouncer/scaling/horizontal-scaling/horizontal-ops.md index 7845eaa6c3..3c344cf3a7 100644 --- a/docs/guides/pgbouncer/scaling/horizontal-scaling/horizontal-ops.md +++ b/docs/guides/pgbouncer/scaling/horizontal-scaling/horizontal-ops.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -79,27 +79,29 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-horizontal.yaml -pgbouncer.kubedb.com/pb-horizontal created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-horizontal.yaml ``` +pgbouncer.kubedb.com/pb-horizontal created Now, wait until `pb-horizontal ` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME VERSION STATUS AGE pb-horizontal 1.18.0 Ready 2m19s -``` Let's check the number of replicas this pgbouncer has from the PgBouncer object, number of pods the petset have, ```bash -$ kubectl get pgbouncer -n demo pb-horizontal -o json | jq '.spec.replicas' +kubectl get pgbouncer -n demo pb-horizontal -o json | jq '.spec.replicas' +``` 1 -$ kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' ``` +1 We can see from both command that the pgbouncer has 1 replicas. @@ -136,9 +138,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/horizontal-scaling-ops.yaml -pgbounceropsrequest.ops.kubedb.com/pgbouncer-horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/horizontal-scaling-ops.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pgbouncer-horizontal-scale-up created #### Verify replicas scaled up successfully @@ -147,16 +149,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pgbouncer-horizontal-scale-up HorizontalScaling Successful 2m49s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to scale the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pgbouncer-horizontal-scale-up +kubectl describe pgbounceropsrequest -n demo pgbouncer-horizontal-scale-up +``` Name: pgbouncer-horizontal-scale-up Namespace: demo Labels: @@ -238,17 +241,18 @@ Events: Normal Starting 95s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-horizontal Normal Successful 95s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-horizontal Normal Successful 95s KubeDB Ops-manager Operator Controller has Successfully scaled the PgBouncer database: demo/pb-horizontal -``` Now, we are going to verify the number of replicas this pgbouncer has from the PgBouncer object, number of pods the petset have, ```bash -$ kubectl get pb -n demo pb-horizontal -o json | jq '.spec.replicas' +kubectl get pb -n demo pb-horizontal -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the pgbouncer is `3`. That means we have successfully scaled up the replicas of the PgBouncer. @@ -283,9 +287,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/horizontal-scaling-down-ops.yaml -pgbounceropsrequest.ops.kubedb.com/pgbouncer-horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/horizontal-scaling-down-ops.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pgbouncer-horizontal-scale-down created #### Verify replicas scaled down successfully @@ -294,16 +298,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pgbouncer-horizontal-scale-down HorizontalScaling Successful 75s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to scale the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pgbouncer-horizontal-scale-down +kubectl describe pgbounceropsrequest -n demo pgbouncer-horizontal-scale-down +``` Name: pgbouncer-horizontal-scale-down Namespace: demo Labels: @@ -373,17 +378,18 @@ Events: Normal Starting 2m10s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-horizontal Normal Successful 2m10s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-horizontal Normal Successful 2m10s KubeDB Ops-manager Operator Controller has Successfully scaled the PgBouncer database: demo/pb-horizontal -``` Now, we are going to verify the number of replicas this pgbouncer has from the PgBouncer object, number of pods the petset have, ```bash -$ kubectl get pb -n demo pb-horizontal -o json | jq '.spec.replicas' +kubectl get pb -n demo pb-horizontal -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo pb-horizontal -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the pgbouncer is `2`. That means we have successfully scaled down the replicas of the PgBouncer. ## Cleaning Up diff --git a/docs/guides/pgbouncer/scaling/vertical-scaling/vertical-ops.md b/docs/guides/pgbouncer/scaling/vertical-scaling/vertical-ops.md index 40b451439d..1c4b8044f1 100644 --- a/docs/guides/pgbouncer/scaling/vertical-scaling/vertical-ops.md +++ b/docs/guides/pgbouncer/scaling/vertical-scaling/vertical-ops.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,22 +80,23 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-vertical.yaml -pgbouncer.kubedb.com/pb-vertical created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-vertical.yaml ``` +pgbouncer.kubedb.com/pb-vertical created Now, wait until `pb-vertical` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME TYPE VERSION STATUS AGE pb-vertical kubedb.com/v1 1.18.0 Ready 17s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -105,7 +106,6 @@ $ kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resourc "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -152,9 +152,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-vertical-ops.yaml -pgbounceropsrequest.ops.kubedb.com/pgbouncer-scale-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/scaling/pb-vertical-ops.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pgbouncer-scale-vertical created #### Verify PgBouncer resources updated successfully @@ -163,16 +163,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ kubectl get pgbounceropsrequest -n demo +kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pgbouncer-scale-vertical VerticalScaling Successful 3m42s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to scale the pgbouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pgbouncer-scale-vertical +kubectl describe pgbounceropsrequest -n demo pgbouncer-scale-vertical +``` Name: pgbouncer-scale-vertical Namespace: demo Labels: @@ -274,12 +275,12 @@ Events: Normal Starting 30s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-vertical Normal Successful 30s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-vertical Normal Successful 30s KubeDB Ops-manager Operator Controller has Successfully scaled the PgBouncer database: demo/pb-vertical -``` Now, we are going to verify from the Pod yaml whether the resources of the pgbouncer has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -290,7 +291,6 @@ $ kubectl get pod -n demo pb-vertical-0 -o json | jq '.spec.containers[].resourc "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the PgBouncer. diff --git a/docs/guides/pgbouncer/sync-users/sync-users-pgbouncer.md b/docs/guides/pgbouncer/sync-users/sync-users-pgbouncer.md index 09fb103e34..3b2769558d 100644 --- a/docs/guides/pgbouncer/sync-users/sync-users-pgbouncer.md +++ b/docs/guides/pgbouncer/sync-users/sync-users-pgbouncer.md @@ -25,9 +25,9 @@ KubeDB supports providing a way to add/update users to PgBouncer in runtime simp - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -92,17 +92,17 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/sync-users/pgbouncer-sync.yaml -pgbouncer.kubedb.com/pgbouncer-sync created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/sync-users/pgbouncer-sync.yaml ``` +pgbouncer.kubedb.com/pgbouncer-sync created Now, wait until `pgbouncer-sync` has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME TYPE VERSION STATUS AGE pgbouncer-sync kubedb.com/v1 1.18.0 Ready 41s -``` ### Sync Users @@ -125,54 +125,60 @@ stringData: Now, create the secret by applying the yaml above. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/sync-users/secret.yaml -secret/sync-secret created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/sync-users/secret.yaml ``` +secret/sync-secret created Now, after `20 seconds` you can exec into the pgbouncer pod and find if the new user is there, ```bash -$ kubectl exec -it -n demo pgbouncer-sync-0 -- /bin/sh +kubectl exec -it -n demo pgbouncer-sync-0 -- /bin/sh +``` /$ cat /var/run/pgbouncer/secret/userlist "postgres" "md5AESOmAkfj+zX8zXLm92d6Vup6a5yASiiGScoHNDTIgBwH8=" "john" "md5AEScbLKDSMb+KVrILhh7XEmyQ==" "pgbouncer" "md5AESOmAkfj+zX8zXLm92d6Vup6a5yASiiGScoHNDTIgBwH8=" /$ exit exit -``` We can see that the user is there in PgBouncer. So, now let's create this user and try to use this user through PgBouncer. Now, you can connect to this pgbouncer through [psql](https://www.postgresql.org/docs/current/app-psql.html). Before that we need to port-forward to the primary service of pgbouncer. ```bash -$ kubectl port-forward svc/pgbouncer-sync -n demo 9999:5432 +kubectl port-forward svc/pgbouncer-sync -n demo 9999:5432 +``` Forwarding from 127.0.0.1:9999 -> 5432 Forwarding from [::1]:9999 -> 5432 -``` We will use the root Postgres user to create the user, so let's get the password for the root user, so that we can use it. ```bash -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d -qEeuU6cu5aH!O9CI⏎ +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d ``` +qEeuU6cu5aH!O9CI⏎ We can use this password now, ```bash -$ export PGPASSWORD='qEeuU6cu5aH!O9CI' -$ psql --host=localhost --port=9999 --username=postgres postgres +export PGPASSWORD='qEeuU6cu5aH!O9CI' +``` + +```bash +psql --host=localhost --port=9999 --username=postgres postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=# CREATE USER john WITH PASSWORD '12345'; CREATE ROLE postgres=# exit -``` Now, let's use this john user. ```bash -$ export PGPASSWORD='12345' -$ psql --host=localhost --port=9999 --username=john postgres +export PGPASSWORD='12345' +``` + +```bash +psql --host=localhost --port=9999 --username=john postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=> exit -``` So, we can successfully verify that the user is registered in PgBouncer and also we can use it. ## Cleaning up diff --git a/docs/guides/pgbouncer/tls/configure_ssl.md b/docs/guides/pgbouncer/tls/configure_ssl.md index 653dea9553..b431ea94b4 100644 --- a/docs/guides/pgbouncer/tls/configure_ssl.md +++ b/docs/guides/pgbouncer/tls/configure_ssl.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `connectionPool - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgbouncer](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgbouncer) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -106,9 +106,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/issuer.yaml -issuer.cert-manager.io/pgbouncer-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/issuer.yaml ``` +issuer.cert-manager.io/pgbouncer-ca-issuer created ## Prepare Postgres Prepare a KubeDB Postgres cluster using this [tutorial](/docs/guides/postgres/clustering/streaming_replication.md), or you can use any externally managed postgres but in that case you need to create an [appbinding](/docs/guides/pgbouncer/concepts/appbinding.md) yourself. In this tutorial we will use 3 node Postgres cluster named `ha-postgres`. @@ -161,25 +161,26 @@ spec: ### Deploy PgBouncer ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml -pgbouncer.kubedb.com/pb-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/tls/pgbouncer-ssl.yaml ``` +pgbouncer.kubedb.com/pb-tls created Now, wait until `pb-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get pb -n demo +watch kubectl get pb -n demo +``` Every 2.0s: kubectl get pgbouncer -n demo NAME VERSION STATUS AGE pb-tls 1.18.0 Ready 108s -``` ### Verify TLS/SSL in PgBouncer Now, connect to this database through [psql](https://www.postgresql.org/docs/current/app-psql.html) and verify if `SSLMode` has been set up as intended (i.e, `require`). ```bash -$ kubectl describe secret -n demo pb-tls-client-cert +kubectl describe secret -n demo pb-tls-client-cert +``` Name: pb-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -203,13 +204,16 @@ Data ca.crt: 1159 bytes tls.crt: 1135 bytes tls.key: 1679 bytes -``` Now, Lets save the client cert and key to two different files: ```bash -$ kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt -$ cat client.crt +kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt +``` + +```bash +cat client.crt +``` -----BEGIN CERTIFICATE----- MIIDGTCCAgGgAwIBAgIQFzXjq6IExD5sjF7FW44NzTANBgkqhkiG9w0BAQsFADAl MRIwEAYDVQQDDAlwZ2JvdW5jZXIxDzANBgNVBAoMBmt1YmVkYjAeFw0yNTAxMjMx @@ -229,8 +233,14 @@ coSL5sY28QU1iS0bO3wHoFx6t8gzwluP/H040ImS60CE5t/b3njIgfWDHzhDOkKV Rl66yC3j2YD8+Dvdl63Dp8r5KtWDvGAkiM8SVysASHnKAM/ipEqUoqyWBUT7gG/L JbiZCRCTnewRU9/mzcn9FxxmAPt7yq9IEND1cMQ= -----END CERTIFICATE----- -$ kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key -$ cat client.key + +```bash +kubectl get secrets -n demo pb-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +``` + +```bash +cat client.key +``` -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA22vbbMwzwDSTu2w+9cgKk1ZQB9bXGoOsS/l2wc/Tg93xjCKg I/qWsNJqFXyOQWEjiOssLLhFhiELyfN/dAtORgg9MR099hpL2NN80+AYcwPyFIoV @@ -257,25 +267,24 @@ yqS9bNW+KpngP4tQtyQLizW8JbWRVVdrsvRWFeouifswF0hvRNSIA9XAD9DrjbiQ HJ+zYQKBgQCKfewbwVLuexdW6yLrxwXuMAZljtHUQWe7Txx3k+bw+kAF46NEBlN2 bZc0zaz8cEn8d7GWVGGGulZA7XxZM+Tr3uD1t/8AkiS/GwRKcXBOjzQZS08bnTVJ BwIhO4g2OiLojS6dQxrXtj/miB3pTZbVed7QhYOBUGEFs3lUV+KEVQ== -``` Now, if you see the common name of the client.crt you can see, ```bash -$ openssl x509 -in client.crt -inform PEM -subject -nameopt RFC2253 -noout -subject=CN=pgbouncer +openssl x509 -in client.crt -inform PEM -subject -nameopt RFC2253 -noout ``` +subject=CN=pgbouncer Here common name of the client certificate is important if you want to connect with the client certificate, the `username must match the common name of the certificate`. Here, we can see the common name(CN) is, `pgbouncer`. So, we will use pgbouncer user to connect with PgBouncer. Now, we can connect using `subject=CN=pgbouncer` to connect to the psql, ```bash -$ psql "sslmode=require port=9999 host=localhost dbname=pgbouncer user=pgbouncer sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" +psql "sslmode=require port=9999 host=localhost dbname=pgbouncer user=pgbouncer sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. pgbouncer=# -``` We are connected to the pgbouncer database. Let's run some command to verify the sslMode and the user, @@ -299,9 +308,9 @@ User can update `sslMode` & `connectionPool.authType` if needed. Some changes ma The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the PgBouncer object.** i.e., ```bash -$ kubectl patch -n demo pb/pb-tls -p '{"spec":{"sslMode": "disabled"}}' --type="merge" -The PgBouncer "pb-tls" is invalid: spec.sslMode: Unsupported value: "disabled": supported values: "disable", "allow", "prefer", "require", "verify-ca", "verify-full" +kubectl patch -n demo pb/pb-tls -p '{"spec":{"sslMode": "disabled"}}' --type="merge" ``` +The PgBouncer "pb-tls" is invalid: spec.sslMode: Unsupported value: "disabled": supported values: "disable", "allow", "prefer", "require", "verify-ca", "verify-full" > Note: There is no official support from kubedb for PgBouncer to connect wit cert mode`. diff --git a/docs/guides/pgbouncer/update-version/update_version.md b/docs/guides/pgbouncer/update-version/update_version.md index cfe4e85605..45ebd6072f 100644 --- a/docs/guides/pgbouncer/update-version/update_version.md +++ b/docs/guides/pgbouncer/update-version/update_version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgbouncer](/docs/examples/pgbouncer) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -76,17 +76,17 @@ spec: Let's create the `PgBouncer` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/update-version/pb-update.yaml -pgbouncer.kubedb.com/pb-update created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/update-version/pb-update.yaml ``` +pgbouncer.kubedb.com/pb-update created Now, wait until `pb-update` created has status `Ready`. i.e, ```bash -$ kubectl get pb -n demo +kubectl get pb -n demo +``` NAME TYPE VERSION STATUS AGE pb-update kubedb.com/v1 1.18.0 Ready 26s -``` We are now ready to apply the `PgBouncerOpsRequest` CR to update this PgBouncer. @@ -122,9 +122,9 @@ Here, Let's create the `PgBouncerOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/update-version/pbops-update.yaml -pgbounceropsrequest.ops.kubedb.com/pgbouncer-version-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/update-version/pbops-update.yaml ``` +pgbounceropsrequest.ops.kubedb.com/pgbouncer-version-update created #### Verify PgBouncer version updated successfully : @@ -133,16 +133,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `PgBouncerOpsRequest` to be `Successful`. Run the following command to watch `PgBouncerOpsRequest` CR, ```bash -$ watch kubectl get pgbounceropsrequest -n demo +watch kubectl get pgbounceropsrequest -n demo +``` Every 2.0s: kubectl get pgbounceropsrequest -n demo NAME TYPE STATUS AGE pgbouncer-version-update UpdateVersion Successful 93s -``` We can see from the above output that the `PgBouncerOpsRequest` has succeeded. If we describe the `PgBouncerOpsRequest` we will get an overview of the steps that were followed to update the PgBouncer. ```bash -$ kubectl describe pgbounceropsrequest -n demo pgbouncer-version-update +kubectl describe pgbounceropsrequest -n demo pgbouncer-version-update +``` Name: pgbouncer-version-update Namespace: demo Labels: @@ -248,20 +249,23 @@ Events: Normal Starting 53s KubeDB Ops-manager Operator Resuming PgBouncer database: demo/pb-update Normal Successful 53s KubeDB Ops-manager Operator Successfully resumed PgBouncer database: demo/pb-update Normal Successful 53s KubeDB Ops-manager Operator Controller has Successfully updated the version of PgBouncer database: demo/pb-update -``` Now, we are going to verify whether the `PgBouncer` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get pb -n demo pb-update -o=jsonpath='{.spec.version}{"\n"}' +kubectl get pb -n demo pb-update -o=jsonpath='{.spec.version}{"\n"}' +``` 1.23.1 -$ kubectl get petset -n demo pb-update -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo pb-update -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/kubedb/pgbouncer:1.23.1@sha256:9829a24c60938ab709fe9e039fecd9f0019354edf4e74bfd9e62bb2203e945ee -$ kubectl get pods -n demo pb-update-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/kubedb/pgbouncer:1.23.1@sha256:9829a24c60938ab709fe9e039fecd9f0019354edf4e74bfd9e62bb2203e945ee +```bash +kubectl get pods -n demo pb-update-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/kubedb/pgbouncer:1.23.1@sha256:9829a24c60938ab709fe9e039fecd9f0019354edf4e74bfd9e62bb2203e945ee You can see from above, our `PgBouncer` has been updated with the new version. So, the update process is successfully completed. diff --git a/docs/guides/pgbouncer/virtual_secret/guide.md b/docs/guides/pgbouncer/virtual_secret/guide.md index 2171fa9725..93f42b25c5 100644 --- a/docs/guides/pgbouncer/virtual_secret/guide.md +++ b/docs/guides/pgbouncer/virtual_secret/guide.md @@ -44,19 +44,28 @@ Before you begin, ensure you have the following prerequisites in place: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## How to use Virtual Secrets ### Install Virtual Secrets Server First, install the virtual-secret-server which is a custom api server for the `secrets.virtual-secrets.dev` resource. ```bash -$ helm repo add appscode https://charts.appscode.com/stable/ -$ helm repo update -$ helm search repo appscode/virtual-secrets-server --version=v2025.3.14 -$ helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ +helm repo add appscode https://charts.appscode.com/stable/ +``` + +```bash +helm repo update +``` + +```bash +helm search repo appscode/virtual-secrets-server --version=v2025.3.14 +``` + +```bash +helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ --version=v2025.3.14 -n kubevault --create-namespace ``` @@ -67,28 +76,30 @@ read, list, delete and delete in a kv secret engine named `virtual-secrets.dev` Now let’s configure the vault server with following commands: -```shell # enable kv secret engine in the path virtual-secrets.dev -$ vault secrets enable -path=virtual-secrets.dev -version=2 kv +```bash +vault secrets enable -path=virtual-secrets.dev -version=2 kv +``` Success! Enabled the kv secrets engine at: virtual-secrets.dev/ - # creates a policy with the permission to create, update, read, list and delete -$ vault policy write virtual-secrets-policy - <}}/docs/examples/vault/secretstore.yaml -secretstore.config.virtual-secrets.dev/vault configured +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretstore.yaml ``` +secretstore.config.virtual-secrets.dev/vault configured Here, - `spec.vault` - section describes the connection information for vault. @@ -135,9 +146,9 @@ Here, - Other than that, everything else is similar to a core Kubernetes Secret. Let’s go ahead and apply the Secret, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/pgb_vs.yaml -secret.virtual-secrets.dev/virtual-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/pgb_vs.yaml ``` +secret.virtual-secrets.dev/virtual-secret created Let's list the Secrets to see if it is created or not, @@ -149,8 +160,9 @@ virtual-secret Opaque 2 2d19h We can also get the whole definition of the `Secret`, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +```bash +kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +``` apiVersion: virtual-secrets.dev/v1alpha1 data: password: dmlydHVhbC1zZWNyZXQ= @@ -168,7 +180,6 @@ metadata: uid: fb756118-3dbf-46b6-ac24-fa5cded478bc secretStoreName: vault type: Opaque -``` We can see that this `Secret`actually behaves identical of the core `Secret`. But the data is not stored in the `etcd` and it is way more secure than using the native `k8s Secret`. @@ -177,15 +188,22 @@ We can see that this `Secret`actually behaves identical of the core `Secret`. Bu We will connect to the Vault by using Vault CLI. Therefore, we need to export the necessary environment variables and port-forward the service. In one terminal port-forward the vault server service, -```shell -$ kubectl port-forward -n vault-demo service/vault 8200 +```bash +kubectl port-forward -n vault-demo service/vault 8200 +``` Forwarding from 127.0.0.1:8200 -> 8200 Forwarding from [::1]:8200 -> 8200 +```bash +export VAULT_ADDR=http://127.0.0.1:8200 +``` + +```bash +export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) +``` + +```bash +vault kv get virtual-secrets.dev/demo/virtual-secret ``` -```shell -$ export VAULT_ADDR=http://127.0.0.1:8200 -$ export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) -$ vault kv get virtual-secrets.dev/demo/virtual-secret ================ Secret Path ================ virtual-secrets.dev/data/demo/virtual-secret @@ -203,7 +221,6 @@ Key Value --- ----- password virtual-secret username default -``` We can see that the secret data is stored in the `virtual-secrets.dev/demo/virtual-secret` path where, - `virtual-secret.dev` is the secret engine name. @@ -218,22 +235,30 @@ data from virtual secrets and uses the `Secrets Store CSI Driver` to mount those Let’s go ahead and install `Secrets Store CSI Driver` and `secrets-store-csi-driver-provider-virtual-secrets` into our cluster, -```shell -$ helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts -$ helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +```bash +helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts +``` + +```bash +helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +``` + +```bash +helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 +``` -$ helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 -$ helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 +```bash +helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 ``` If both of them are deployed we should see two new pods in the `kube-system` namespace. -```shell -$ kubectl get pods -n kube-system +```bash +kubectl get pods -n kube-system +``` NAME READY STATUS RESTARTS AGE csi-secrets-store-secrets-store-csi-driver-qzq8z 3/3 Running 3 (36h ago) 2d secrets-store-csi-driver-provider-virtual-secrets-mdw84 1/1 Running 1 (36h ago) 47h -``` The `Secrets Store CSI Driver` uses a custom resource named `SecretProviderClass` to mount the secret. Let’s go ahead and create that, ```yaml @@ -256,10 +281,10 @@ Here, > **Note:** We can also call the mount subresource of the virtual secret to create the SecretProviderClass for us. The namespace and the name of SecretProviderClass should be same as the Virtual Secret it is being used for. Let’s create the SecretProviderClass, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml -secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml ``` +secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created ## Get PostgreSQL Server ready using virtual secret @@ -270,9 +295,9 @@ Luckily PostgreSQL is readily available in KubeDB as crd and can easily be deplo In this tutorial, we will use a Postgres named `quick-postgres` in the `demo` namespace. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/virtual_secret/postgres.yaml -postgres.kubedb.com/pg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/virtual_secret/postgres.yaml ``` +postgres.kubedb.com/pg created KubeDB creates all the necessary resources including services, secrets, and appbindings to get this server up and running. A default database `postgres` is created in `quick-postgres`. Database secret `quick-postgres-auth` holds this user's username and password. Following is the yaml file for it. @@ -313,28 +338,28 @@ Here, We can now apply the Pgbouncer custom resource, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/vs.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgbouncer/vs.yaml +``` Pgbouncer.kubedb.com/pgb-vs created -``` Now, wait until `pgb-vs` has status `Ready`. i.e. , -```shell -$ kubectl get pb -n demo +```bash +kubectl get pb -n demo +``` NAME VERSION STATUS AGE pgb-vs 1.18.0 Ready 22h -``` Now, lets go ahead and check what secret it is using, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo +```bash +kubectl get secrets.virtual-secrets.dev -n demo +``` NAME TYPE DATA AGE virtual-secret Opaque 2 1d -``` We can see that the Pgbouncer user password is stored in the vault server as named ```virtual-secret``` . Now let’s go ahead and connect to the database using the password to check whether it is working or not. ```bash -$ kubectl exec -it -n demo pgb-vs-0 -- sh - +kubectl exec -it -n demo pgb-vs-0 -- sh +``` / $ psql -U pgbouncer -d pgbouncer -h localhost -p 5432 psql (17.6, server 1.18.0/bouncer) WARNING: psql major version 17, server major version 1.18. @@ -360,22 +385,35 @@ pgbouncer=# SHOW CLIENTS; ------+-----------+-----------+--------+------+-------+------------+------------+-------------------------+-------------------------+------+---------+--------------+----------------+------+------------+-----+------------------ C | pgbouncer | pgbouncer | active | ::1 | 54834 | ::1 | 5432 | 2026-02-27 05:42:36 UTC | 2026-02-27 05:56:50 UTC | 27 | 168287 | 0 | 0x76c98b8147d0 | | 0 | | psql (1 row) - -``` We can see that we are able to connect to the database and create a database and a table successfully. ## Cleanup To clean up the resources created in this guide, run the following commands: ```bash -$ kubectl delete pb -n demo pgb-vs +kubectl delete pb -n demo pgb-vs +``` pgpool.kubedb.com "pgb-vs" deleted -$ kubectl delete secretproviderclass -n demo virtual-secret -$ kubectl delete ns demo -$ helm uninstall virtual-secrets-server -n kubevault -$ helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system -$ helm uninstall csi-secrets-store -n kube-system + +```bash +kubectl delete secretproviderclass -n demo virtual-secret +``` + +```bash +kubectl delete ns demo +``` + +```bash +helm uninstall virtual-secrets-server -n kubevault +``` + +```bash +helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system +``` + +```bash +helm uninstall csi-secrets-store -n kube-system ``` If you want to uninstall the `KubeVault`, run: ```bash -$ helm uninstall kubevault --namespace kubevault +helm uninstall kubevault --namespace kubevault ``` diff --git a/docs/guides/pgpool/autoscaler/compute/compute-autoscale.md b/docs/guides/pgpool/autoscaler/compute/compute-autoscale.md index e069369f93..2d8cfd42ba 100644 --- a/docs/guides/pgpool/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/pgpool/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -79,22 +79,23 @@ spec: Let's create the `Pgpool` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/autoscaling/compute/pgpool-autoscale.yaml -pgpool.kubedb.com/pgpool-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/autoscaling/compute/pgpool-autoscale.yaml ``` +pgpool.kubedb.com/pgpool-autoscale created Now, wait until `pgpool-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pgpool-autoscale kubedb.com/v1alpha2 4.5.0 Ready 22s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -105,11 +106,11 @@ $ kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].re "memory": "300Mi" } } -``` Let's check the Pgpool resources, ```bash -$ kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "200m", @@ -120,7 +121,6 @@ $ kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.sp "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the pgpool. @@ -174,20 +174,23 @@ Here, Let's create the `PgpoolAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/autoscaling/compute/pgpool-autoscaler.yaml -pgpoolautoscaler.autoscaling.kubedb.com/pgpool-autoscaler-ops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/autoscaling/compute/pgpool-autoscaler.yaml ``` +pgpoolautoscaler.autoscaling.kubedb.com/pgpool-autoscaler-ops created #### Verify Autoscaling is set up successfully Let's check that the `pgpoolautoscaler` resource is created successfully, ```bash -$ kubectl get pgpoolautoscaler -n demo +kubectl get pgpoolautoscaler -n demo +``` NAME AGE pgpool-autoscale-ops 6m55s -$ kubectl describe pgpoolautoscaler pgpool-autoscale-ops -n demo +```bash +kubectl describe pgpoolautoscaler pgpool-autoscale-ops -n demo +``` Name: pgpool-autoscale-ops Namespace: demo Labels: @@ -270,7 +273,6 @@ Status: Memory: 1Gi Vpa Name: pgpool-autoscale Events: -``` So, the `pgpoolautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our pgpool. Our autoscaler operator continuously watches the recommendation generated and creates an `pgpoolopsrequest` based on the recommendations, if the pgpool pods are needed to scaled up or down. @@ -278,25 +280,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `pgpoolopsrequest` in the demo namespace to see if any `pgpoolopsrequest` object is created. After some time you'll see that a `pgpoolopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-pgpool-autoscale-zzell6 VerticalScaling Progressing 1m48s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-pgpool-autoscale-zzell6 VerticalScaling Successful 3m40s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to scale the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-pgpool-autoscale-zzell6 +kubectl describe pgpoolopsrequest -n demo ppops-pgpool-autoscale-zzell6 +``` Name: ppops-pgpool-autoscale-zzell6 Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -395,12 +398,12 @@ Events: Normal RestartPods 7m31s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 7m31s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pgpool-autoscale Normal Successful 7m30s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pgpool-autoscale for PgpoolOpsRequest: ppops-pgpool-autoscale-zzell6 -``` Now, we are going to verify from the Pod, and the Pgpool yaml whether the resources of the pgpool has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -412,7 +415,9 @@ $ kubectl get pod -n demo pgpool-autoscale-0 -o json | jq '.spec.containers[].re } } -$ kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +```bash +kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "400m", @@ -423,7 +428,6 @@ $ kubectl get pgpool -n demo pgpool-autoscale -o json | jq '.spec.podTemplate.sp "memory": "400Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the Pgpool. diff --git a/docs/guides/pgpool/concepts/pgpool.md b/docs/guides/pgpool/concepts/pgpool.md index f07789f459..1d44755f93 100644 --- a/docs/guides/pgpool/concepts/pgpool.md +++ b/docs/guides/pgpool/concepts/pgpool.md @@ -151,11 +151,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic pgpool-auth -n demo \ +kubectl create secret generic pgpool-auth -n demo \ --from-literal=username=jhon \ --from-literal=password=O9xE1mZZDAdBTbrV -secret "pgpool-auth" created ``` +secret "pgpool-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/pgpool/configuration/using-config-file.md b/docs/guides/pgpool/configuration/using-config-file.md index 6eaf918869..59edbec5fa 100644 --- a/docs/guides/pgpool/configuration/using-config-file.md +++ b/docs/guides/pgpool/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Pgpool. This tutorial will sh - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -50,23 +50,24 @@ For a Pgpool surely we will need a Postgres server so, prepare a KubeDB Postgres At first, create `pgpool.conf` file containing required configuration settings. ```bash -$ cat pgpool.conf +cat pgpool.conf +``` num_init_children = 6 max_pool = 65 child_life_time = 400 -``` Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo pp-configuration --from-file=./pgpool.conf -secret/pp-configuration created +kubectl create secret generic -n demo pp-configuration --from-file=./pgpool.conf ``` +secret/pp-configuration created Verify the secret has the configuration file. ```bash -$ kubectl get secret -n demo pp-configuration -o yaml + kubectl get secret -n demo pp-configuration -o yaml +``` apiVersion: v1 data: pgpool.conf: bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== @@ -79,11 +80,12 @@ metadata: uid: 80f5324a-9a65-4801-b136-21d2fa001b12 type: Opaque -$ echo bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== | base64 -d +```bash +echo bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== | base64 -d +``` num_init_children = 6 max_pool = 65 child_life_time = 400 -``` Now, create Pgpool crd specifying `spec.configuration.secretName` field. @@ -105,26 +107,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-config-file.yaml -pgpool.kubedb.com/pp-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-config-file.yaml ``` +pgpool.kubedb.com/pp-custom-config 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 `pp-custom-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo pp-custom-config-0 +kubectl get pod -n demo pp-custom-config-0 +``` NAME READY STATUS RESTARTS AGE pp-custom-config-0 1/1 Running 0 35s -``` Now, we will check if the pgpool has started with the custom configuration we have provided. Now, you can exec into the pgpool pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo pp-custom-config-0 -- bash +kubectl exec -it -n demo pp-custom-config-0 -- bash +``` pp-custom-config-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -163,7 +166,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pp-custom-config-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `num_init_children`, `max_pool` and `child_life_time` has been set to our desired value successfully. diff --git a/docs/guides/pgpool/configuration/using-init-config.md b/docs/guides/pgpool/configuration/using-init-config.md index c25d91ff68..3e094a3b15 100644 --- a/docs/guides/pgpool/configuration/using-init-config.md +++ b/docs/guides/pgpool/configuration/using-init-config.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Pgpool while initializing the - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,22 +70,23 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-init-config.yaml -pgpool.kubedb.com/pp-init-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-init-config.yaml ``` +pgpool.kubedb.com/pp-init-config 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 `pp-init-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo pp-init-config-0 +kubectl get pod -n demo pp-init-config-0 +``` NAME READY STATUS RESTARTS AGE pp-init-config-0 1/1 Running 0 2m31s -``` Now check the config secret KubeDB operator has created and check out `pgpool.conf`. ```bash -$ kubectl get secret -n demo pp-init-config-config -o yaml + kubectl get secret -n demo pp-init-config-config -o yaml +``` apiVersion: v1 data: pgpool.conf: YmFja2VuZF9ob3N0bmFtZTAgPSAnaGEtcG9zdGdyZXMuZGVtby5zdmMnCmJhY2tlbmRfcG9ydDAgPSA1NDMyCmJhY2tlbmRfd2VpZ2h0MCA9IDEKYmFja2VuZF9mbGFnMCA9ICdBTFdBWVNfUFJJTUFSWXxESVNBTExPV19UT19GQUlMT1ZFUicKYmFja2VuZF9ob3N0bmFtZTEgPSAnaGEtcG9zdGdyZXMtc3RhbmRieS5kZW1vLnN2YycKYmFja2VuZF9wb3J0MSA9IDU0MzIKYmFja2VuZF93ZWlnaHQxID0gMQpiYWNrZW5kX2ZsYWcxID0gJ0RJU0FMTE9XX1RPX0ZBSUxPVkVSJwpudW1faW5pdF9jaGlsZHJlbiA9IDYKbWF4X3Bvb2wgPSA2NQpjaGlsZF9saWZlX3RpbWUgPSA0MDAKZW5hYmxlX3Bvb2xfaGJhID0gb24KbGlzdGVuX2FkZHJlc3NlcyA9ICoKcG9ydCA9IDk5OTkKc29ja2V0X2RpciA9ICcvdmFyL3J1bi9wZ3Bvb2wnCnBjcF9saXN0ZW5fYWRkcmVzc2VzID0gKgpwY3BfcG9ydCA9IDk1OTUKcGNwX3NvY2tldF9kaXIgPSAnL3Zhci9ydW4vcGdwb29sJwpsb2dfcGVyX25vZGVfc3RhdGVtZW50ID0gb24Kc3JfY2hlY2tfcGVyaW9kID0gMApoZWFsdGhfY2hlY2tfcGVyaW9kID0gMApiYWNrZW5kX2NsdXN0ZXJpbmdfbW9kZSA9ICdzdHJlYW1pbmdfcmVwbGljYXRpb24nCmNoaWxkX21heF9jb25uZWN0aW9ucyA9IDAKY29ubmVjdGlvbl9saWZlX3RpbWUgPSAwCmNsaWVudF9pZGxlX2xpbWl0ID0gMApjb25uZWN0aW9uX2NhY2hlID0gb24KbG9hZF9iYWxhbmNlX21vZGUgPSBvbgpzc2wgPSAnb2ZmJwpmYWlsb3Zlcl9vbl9iYWNrZW5kX2Vycm9yID0gJ29mZicKbG9nX21pbl9tZXNzYWdlcyA9ICd3YXJuaW5nJwpzdGF0ZW1lbnRfbGV2ZWxfbG9hZF9iYWxhbmNlID0gJ29mZicKbWVtb3J5X2NhY2hlX2VuYWJsZWQgPSAnb2ZmJwptZW1xY2FjaGVfb2lkZGlyID0gJy90bXAvb2lkZGlyLycKYWxsb3dfY2xlYXJfdGV4dF9mcm9udGVuZF9hdXRoID0gJ2ZhbHNlJwo= @@ -111,7 +112,9 @@ metadata: uid: d27154e6-b843-4c1d-b2af-79a80af38ca0 type: Opaque -$ echo YmFja2VuZF9ob3N0bmFtZTAgPSAnaGEtcG9zdGdyZXMuZGVtby5zdmMnCmJhY2tlbmRfcG9ydDAgPSA1NDMyCmJhY2tlbmRfd2VpZ2h0MCA9IDEKYmFja2VuZF9mbGFnMCA9ICdBTFdBWVNfUFJJTUFSWXxESVNBTExPV19UT19GQUlMT1ZFUicKYmFja2VuZF9ob3N0bmFtZTEgPSAnaGEtcG9zdGdyZXMtc3RhbmRieS5kZW1vLnN2YycKYmFja2VuZF9wb3J0MSA9IDU0MzIKYmFja2VuZF93ZWlnaHQxID0gMQpiYWNrZW5kX2ZsYWcxID0gJ0RJU0FMTE9XX1RPX0ZBSUxPVkVSJwpudW1faW5pdF9jaGlsZHJlbiA9IDYKbWF4X3Bvb2wgPSA2NQpjaGlsZF9saWZlX3RpbWUgPSA0MDAKZW5hYmxlX3Bvb2xfaGJhID0gb24KbGlzdGVuX2FkZHJlc3NlcyA9ICoKcG9ydCA9IDk5OTkKc29ja2V0X2RpciA9ICcvdmFyL3J1bi9wZ3Bvb2wnCnBjcF9saXN0ZW5fYWRkcmVzc2VzID0gKgpwY3BfcG9ydCA9IDk1OTUKcGNwX3NvY2tldF9kaXIgPSAnL3Zhci9ydW4vcGdwb29sJwpsb2dfcGVyX25vZGVfc3RhdGVtZW50ID0gb24Kc3JfY2hlY2tfcGVyaW9kID0gMApoZWFsdGhfY2hlY2tfcGVyaW9kID0gMApiYWNrZW5kX2NsdXN0ZXJpbmdfbW9kZSA9ICdzdHJlYW1pbmdfcmVwbGljYXRpb24nCmNoaWxkX21heF9jb25uZWN0aW9ucyA9IDAKY29ubmVjdGlvbl9saWZlX3RpbWUgPSAwCmNsaWVudF9pZGxlX2xpbWl0ID0gMApjb25uZWN0aW9uX2NhY2hlID0gb24KbG9hZF9iYWxhbmNlX21vZGUgPSBvbgpzc2wgPSAnb2ZmJwpmYWlsb3Zlcl9vbl9iYWNrZW5kX2Vycm9yID0gJ29mZicKbG9nX21pbl9tZXNzYWdlcyA9ICd3YXJuaW5nJwpzdGF0ZW1lbnRfbGV2ZWxfbG9hZF9iYWxhbmNlID0gJ29mZicKbWVtb3J5X2NhY2hlX2VuYWJsZWQgPSAnb2ZmJwptZW1xY2FjaGVfb2lkZGlyID0gJy90bXAvb2lkZGlyLycKYWxsb3dfY2xlYXJfdGV4dF9mcm9udGVuZF9hdXRoID0gJ2ZhbHNlJwo= | base64 -d +```bash +echo YmFja2VuZF9ob3N0bmFtZTAgPSAnaGEtcG9zdGdyZXMuZGVtby5zdmMnCmJhY2tlbmRfcG9ydDAgPSA1NDMyCmJhY2tlbmRfd2VpZ2h0MCA9IDEKYmFja2VuZF9mbGFnMCA9ICdBTFdBWVNfUFJJTUFSWXxESVNBTExPV19UT19GQUlMT1ZFUicKYmFja2VuZF9ob3N0bmFtZTEgPSAnaGEtcG9zdGdyZXMtc3RhbmRieS5kZW1vLnN2YycKYmFja2VuZF9wb3J0MSA9IDU0MzIKYmFja2VuZF93ZWlnaHQxID0gMQpiYWNrZW5kX2ZsYWcxID0gJ0RJU0FMTE9XX1RPX0ZBSUxPVkVSJwpudW1faW5pdF9jaGlsZHJlbiA9IDYKbWF4X3Bvb2wgPSA2NQpjaGlsZF9saWZlX3RpbWUgPSA0MDAKZW5hYmxlX3Bvb2xfaGJhID0gb24KbGlzdGVuX2FkZHJlc3NlcyA9ICoKcG9ydCA9IDk5OTkKc29ja2V0X2RpciA9ICcvdmFyL3J1bi9wZ3Bvb2wnCnBjcF9saXN0ZW5fYWRkcmVzc2VzID0gKgpwY3BfcG9ydCA9IDk1OTUKcGNwX3NvY2tldF9kaXIgPSAnL3Zhci9ydW4vcGdwb29sJwpsb2dfcGVyX25vZGVfc3RhdGVtZW50ID0gb24Kc3JfY2hlY2tfcGVyaW9kID0gMApoZWFsdGhfY2hlY2tfcGVyaW9kID0gMApiYWNrZW5kX2NsdXN0ZXJpbmdfbW9kZSA9ICdzdHJlYW1pbmdfcmVwbGljYXRpb24nCmNoaWxkX21heF9jb25uZWN0aW9ucyA9IDAKY29ubmVjdGlvbl9saWZlX3RpbWUgPSAwCmNsaWVudF9pZGxlX2xpbWl0ID0gMApjb25uZWN0aW9uX2NhY2hlID0gb24KbG9hZF9iYWxhbmNlX21vZGUgPSBvbgpzc2wgPSAnb2ZmJwpmYWlsb3Zlcl9vbl9iYWNrZW5kX2Vycm9yID0gJ29mZicKbG9nX21pbl9tZXNzYWdlcyA9ICd3YXJuaW5nJwpzdGF0ZW1lbnRfbGV2ZWxfbG9hZF9iYWxhbmNlID0gJ29mZicKbWVtb3J5X2NhY2hlX2VuYWJsZWQgPSAnb2ZmJwptZW1xY2FjaGVfb2lkZGlyID0gJy90bXAvb2lkZGlyLycKYWxsb3dfY2xlYXJfdGV4dF9mcm9udGVuZF9hdXRoID0gJ2ZhbHNlJwo= | base64 -d +``` backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 backend_weight0 = 1 @@ -146,13 +149,13 @@ statement_level_load_balance = 'off' memory_cache_enabled = 'off' memqcache_oiddir = '/tmp/oiddir/' allow_clear_text_frontend_auth = 'false' -``` Now, we will check if the pgpool has started with the init configuration we have provided. Now, you can exec into the pgpool pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo pp-init-config-0 -- bash +kubectl exec -it -n demo pp-init-config-0 -- bash +``` pp-init-config-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -191,7 +194,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pp-init-config-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `num_init_children`, `max_pool` and `child_life_time` has been set to our desired value successfully. diff --git a/docs/guides/pgpool/configuration/using-podtemplate.md b/docs/guides/pgpool/configuration/using-podtemplate.md index f60708100d..0c6df09d1c 100644 --- a/docs/guides/pgpool/configuration/using-podtemplate.md +++ b/docs/guides/pgpool/configuration/using-podtemplate.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Pgpool via [PodTemplate](/doc - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -97,24 +97,25 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pp-misc-config.yaml -pgpool.kubedb.com/pp-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pp-misc-config.yaml ``` +pgpool.kubedb.com/pp-misc-config 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 `pp-misc-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE pp-misc-config-0 1/1 Running 0 68s -``` Now, check if the pgpool has started with the custom configuration we have provided. We will exec in the pod and see the `pool_passwd` file if the user exists of not. We will also see if the environment variable is set or not. ```bash -$ kubectl exec -it -n demo pp-misc-config-0 -- bash +kubectl exec -it -n demo pp-misc-config-0 -- bash +``` pp-misc-config-0:/$ echo $BOB_USERNAME bob pp-misc-config-0:/$ echo $BOB_PASSWORD @@ -129,23 +130,23 @@ bob:AESBw7fOtf4SCfFiI7vbAYpKg== alice:AESgda2WBFwHQfKluCkXwo+MA== pp-misc-config-0:/$ exit exit -``` So, we can see that the additional two users Alice and Bob is successfully registered. Now we can use them. So, first let create the users through the root user postgres. Now, you can connect to this pgpool through [psql](https://www.postgresql.org/docs/current/app-psql.html). Before that we need to port-forward to the primary service of pgpool. ```bash -$ kubectl port-forward -n demo svc/pp-misc-config 9999 -Forwarding from 127.0.0.1:9999 -> 9999 +kubectl port-forward -n demo svc/pp-misc-config 9999 ``` +Forwarding from 127.0.0.1:9999 -> 9999 Now, let's get the password for the root user. ```bash -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d -qEeuU6cu5aH!O9CI⏎ +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d ``` +qEeuU6cu5aH!O9CI⏎ We can use this password now, ```bash -$ psql --host=localhost --port=9999 --username=postgres postgres +psql --host=localhost --port=9999 --username=postgres postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. @@ -154,23 +155,31 @@ CREATE ROLE postgres=# CREATE USER bob WITH PASSWORD '456'; CREATE ROLE postgres=# exit -``` Now, let's verify if we can to the database through pgpool with the new users, ```bash -$ export PGPASSWORD='123' -$ psql --host=localhost --port=9999 --username=alice postgres +export PGPASSWORD='123' +``` + +```bash +psql --host=localhost --port=9999 --username=alice postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=> exit -$ export PGPASSWORD='456' -$ psql --host=localhost --port=9999 --username=bob postgres + +```bash +export PGPASSWORD='456' +``` + +```bash +psql --host=localhost --port=9999 --username=bob postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=> exit -``` You can see we can use these new users to connect to the database. @@ -197,8 +206,11 @@ 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 +docker build -t repository_name/custom_filebeat:latest . +``` + +```bash +docker push repository_name/custom_filebeat:latest ``` Now we will deploy our pgpool with custom sidecar container and will also use the `spec.configuration.inline` to configure the logs related settings. Here is the yaml of our pgpool: ```yaml @@ -244,24 +256,23 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-config-sidecar.yaml -pgpool.kubedb.com/pgpool-custom-sidecar created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-config-sidecar.yaml ``` +pgpool.kubedb.com/pgpool-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 `pgpool-custom-sidecar-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE pgpool-custom-sidecar-0 2/2 Running 0 33s -``` - Now, Let’s fetch the logs shipped to filebeat console output. The outputs will be generated in json format. ```bash -$ kubectl logs -f -n demo pgpool-custom-sidecar-0 -c filebeat +kubectl logs -f -n demo pgpool-custom-sidecar-0 -c filebeat ``` We will find the query logs in filebeat console output. Sample output: ```json @@ -305,31 +316,32 @@ So, we have successfully extracted logs from pgpool to our sidecar filebeat cont Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our pgpool 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -345,7 +357,6 @@ Labels: beta.kubernetes.io/arch=amd64 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 pgpool with this new label as nodeSelector. Below is the yaml we are going to apply: @@ -368,24 +379,24 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-node-selector.yaml -pgpool.kubedb.com/pgpool-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-node-selector.yaml ``` +pgpool.kubedb.com/pgpool-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 `pgpool-node-selector-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE pgpool-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 pgpool-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo pgpool-node-selector-0 -o wide +kubectl get pods -n demo pgpool-node-selector-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pgpool-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 @@ -393,28 +404,33 @@ We can successfully verify that our pod was scheduled to our desired node. 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +```bash +kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +``` node/lke212553-307295-5541798e0000 tainted -$ kubectl taint nodes lke212553-307295-5b53c5520000 key1=node3:NoSchedule -node/lke212553-307295-5b53c5520000 tainted +```bash +kubectl taint nodes lke212553-307295-5b53c5520000 key1=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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -439,7 +455,6 @@ lke212553-307295-5b53c5520000 "value": "node3" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a pgpool without proper tolerations. Here is the yaml of pgpool we are going to createc ```yaml apiVersion: kubedb.com/v1alpha2 @@ -456,20 +471,21 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-without-tolerations.yaml -pgpool.kubedb.com/pgpool-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-without-tolerations.yaml ``` +pgpool.kubedb.com/pgpool-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 `pgpool-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE pgpool-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 pgpool-without-tolerations-0 +kubectl describe pods -n demo pgpool-without-tolerations-0 +``` Name: pgpool-without-tolerations-0 Namespace: demo Priority: 0 @@ -535,7 +551,6 @@ Events: 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 pgpool. Here is the yaml we are going to apply, @@ -562,24 +577,24 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-with-tolerations.yaml -pgpool.kubedb.com/pgpool-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/configuration/pgpool-with-tolerations.yaml ``` +pgpool.kubedb.com/pgpool-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 `pgpool-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE pgpool-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 pgpool-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo pgpool-with-tolerations-0 -o wide +kubectl get pods -n demo pgpool-with-tolerations-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pgpool-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 diff --git a/docs/guides/pgpool/custom-rbac/using-custom-rbac.md b/docs/guides/pgpool/custom-rbac/using-custom-rbac.md index 0547552dc8..625157d150 100644 --- a/docs/guides/pgpool/custom-rbac/using-custom-rbac.md +++ b/docs/guides/pgpool/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,9 +44,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -65,9 +65,9 @@ metadata: Now, we need to create a role that has necessary access permissions for the Pgpool instance named `pgpool`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/mg-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/mg-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -93,10 +93,9 @@ This permission is required for Pgpool pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -123,9 +122,9 @@ subjects: Now, create a Pgpool crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/pp-custom.yaml -pgpool.kubedb.com/pgpool created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/pp-custom.yaml ``` +pgpool.kubedb.com/pgpool created Below is the YAML for the Pgpool crd we just created. @@ -152,15 +151,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary petset, servi Check that the petset's pod is running ```bash -$ kubectl get pod -n demo pgpool-0 +kubectl get pod -n demo pgpool-0 +``` NAME READY STATUS RESTARTS AGE pgpool-0 1/1 Running 0 50s -``` Check the pod's log to see if the pgpool is ready ```bash -$ kubectl logs -f -n demo pgpool-0 +kubectl logs -f -n demo pgpool-0 +``` Configuring Pgpool-II... Custom pgpool.conf file detected. Use custom configuration files. Generating pool_passwd... @@ -192,13 +192,13 @@ Starting Pgpool-II... 2024-08-01 05:03:30.152: health_check pid 70: LOG: process started 2024-08-01 05:03:30.152: health_check pid 71: LOG: process started 2024-08-01 05:03:30.153: main pid 61: LOG: pgpool-II successfully started. version 4.5.0 (hotooriboshi) -``` Once we see `pgpool-II successfully started` in the log, the pgpool is ready. Also, if we want to verify that the pod is actually using our custom service account we can just describe the pod and see the `Service Accouunt Name`, ```bash -$ kubectl describe pp -n demo pgpool +kubectl describe pp -n demo pgpool +``` Name: pgpool Namespace: demo Labels: @@ -288,7 +288,6 @@ Status: Type: Provisioned Phase: Ready Events: -``` ## Reusing Service Account @@ -297,9 +296,9 @@ An existing service account can be reused in another Pgpool instance. No new acc Now, create Pgpool crd `pgpool-new` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/pgpool-new.yaml -pgpool.kubedb.com/pgpool-new created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/custom-rbac/pgpool-new.yaml ``` +pgpool.kubedb.com/pgpool-new created Below is the YAML for the Pgpool crd we just created. @@ -326,15 +325,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary petset, servi Check that the petset's pod is running ```bash -$ kubectl get pod -n demo pgpool-new-0 +kubectl get pod -n demo pgpool-new-0 +``` NAME READY STATUS RESTARTS AGE pgpool-new-0 1/1 Running 0 55s -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo pgpool-new-0 +kubectl logs -f -n demo pgpool-new-0 +``` Configuring Pgpool-II... Custom pgpool.conf file detected. Use custom configuration files. Generating pool_passwd... @@ -366,12 +366,12 @@ Starting Pgpool-II... 2024-08-01 05:05:34.570: health_check pid 70: LOG: process started 2024-08-01 05:05:34.570: pcp_main pid 67: LOG: PCP process: 67 started 2024-08-01 05:05:34.570: main pid 60: LOG: pgpool-II successfully started. version 4.5.0 (hotooriboshi) -``` `pgpool-II successfully started` in the log signifies that the pgpool is running successfully. Also, if we want to verify that the pod is actually using our custom service account we can just describe the pod and see the `Service Accouunt Name`, ```bash -$ kubectl describe pp -n demo pgpool-new +kubectl describe pp -n demo pgpool-new +``` Name: pgpool-new Namespace: demo Labels: @@ -461,7 +461,6 @@ Status: Type: Provisioned Phase: Ready Events: -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/pgpool/initializing/git-sync.md b/docs/guides/pgpool/initializing/git-sync.md index 35fe8c046a..5a814c2223 100644 --- a/docs/guides/pgpool/initializing/git-sync.md +++ b/docs/guides/pgpool/initializing/git-sync.md @@ -32,9 +32,9 @@ In this example, we will initialize Pgpool using a `.sh` script from the GitHub To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -96,15 +96,16 @@ Here, Now, wait until `pgpool` has status `Ready`. i.e, ```bash -$ kubectl get Pgpool -n demo +kubectl get Pgpool -n demo +``` NAME TYPE VERSION STATUS AGE pgpool kubedb.com/v1alpha2 4.4.5 Ready 4m -``` Next, we will connect to the Pgpool database and verify the data inserted from the `*.sql` script stored in the Git repository. ```bash -$kubectl exec -it -n demo pgpool-0 -- sh +kubectl exec -it -n demo pgpool-0 -- sh +``` Defaulted container "pgpool" out of: pgpool, git-sync (init) / $ export PGPASSWORD="qrDy;GnX4QsKQ0UL" / $ psql -U postgres -d postgres -h localhost -p @@ -118,8 +119,6 @@ postgres=# \dt public | kubedb_write_check_pgpool | table | postgres public | my_table | table | postgres (2 rows) - -``` `my_table` is created by the `init-script.sh` script stored in the Git repository. ## From Private Git Repository @@ -130,7 +129,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -145,7 +144,7 @@ This secret will be used by git-sync to authenticate with the Git repository. >Here, we are using the default SSH key file located at `$HOME/.ssh/id_rsa`. If your SSH key is stored in a different location, please update the command accordingly. Also you can use any name instead of `git-creds` to create the secret. ```bash -$ kubectl create secret generic -n demo \ +kubectl create secret generic -n demo \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -206,13 +205,13 @@ The `git-sync` container has two required flags: Once the database reaches the `Ready` state, you can verify the data using the method described above. ```bash -$ kubectl get Pgpool -n demo +kubectl get Pgpool -n demo +``` NAME TYPE VERSION STATUS AGE pgpool kubedb.com/v1alpha2 4.4.5 Ready 5m23s - -``` ```bash -$ kubectl exec -it -n demo pgpool-0 -- sh +kubectl exec -it -n demo pgpool-0 -- sh +``` Defaulted container "pgpool" out of: pgpool, git-sync (init) / $ export PGPASSWORD="qrDy;GnX4QsKQ0UL" / $ psql -U postgres -d postgres -h localhost -p @@ -226,8 +225,6 @@ postgres=# \dt public | kubedb_write_check_pgpool | table | postgres public | my_table | table | postgres (2 rows) - -``` `my_table` is created by the `init-script.sh` script stored in the Git repository. ### 2. Using Username and Personal Access Token(PAT) @@ -236,7 +233,7 @@ First, create a `Personal Access Token (PAT)` on your Git host server with the r Then create a Kubernetes secret using the `Personal Access Token (PAT)`: > Here, you can use any key name instead of `git-pat` to store the token in the secret. ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -291,13 +288,13 @@ Here, Once the database reaches the `Ready` state, you can verify the data using the method described above. ```bash -$ kubectl get Pgpool -n demo +kubectl get Pgpool -n demo +``` NAME TYPE VERSION STATUS AGE pgpool kubedb.com/v1alpha2 4.4.5 Ready 3m32s - -``` ```bash -$ kubectl exec -it -n demo pgpool-0 -- sh +kubectl exec -it -n demo pgpool-0 -- sh +``` Defaulted container "pgpool" out of: pgpool, git-sync (init) / $ export PGPASSWORD="qrDy;GnX4QsKQ0UL" / $ psql -U postgres -d postgres -h localhost -p 9999 @@ -311,7 +308,6 @@ postgres=# \dt public | kubedb_write_check_pgpool | table | postgres public | my_table | table | postgres (2 rows) -``` `my_table` is created by the `init-script.sh` script stored in the Private Git repository. ## CleanUp @@ -319,7 +315,13 @@ postgres=# \dt To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete Pgpool -n demo pgpool -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete Pgpool -n demo pgpool +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/pgpool/monitoring/using-builtin-prometheus.md b/docs/guides/pgpool/monitoring/using-builtin-prometheus.md index 6e6bcb1e6f..08474c51f0 100644 --- a/docs/guides/pgpool/monitoring/using-builtin-prometheus.md +++ b/docs/guides/pgpool/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Pgpool database using builtin [Promet - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -68,32 +70,33 @@ Here, Let's create the Pgpool crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/monitoring/builtin-prom-pp.yaml -pgpool.kubedb.com/builtin-prom-pp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/monitoring/builtin-prom-pp.yaml ``` +pgpool.kubedb.com/builtin-prom-pp created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pp -n demo builtin-prom-pp +kubectl get pp -n demo builtin-prom-pp +``` NAME TYPE VERSION STATUS AGE builtin-prom-pp kubedb.com/v1alpha2 4.5.0 Ready 65s -``` KubeDB will create a separate stats service with name `{Pgpool crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-pp" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-pp" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-pp ClusterIP 10.96.124.220 9999/TCP,9595/TCP 2m20s builtin-prom-pp-pods ClusterIP None 9999/TCP 2m20s builtin-prom-pp-stats ClusterIP 10.96.132.175 9719/TCP 2m20s -``` Here, `builtin-prom-pp-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-pp-stats +kubectl describe svc -n demo builtin-prom-pp-stats +``` Name: builtin-prom-pp-stats Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -115,7 +118,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.27:9719 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -279,20 +281,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -303,9 +305,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -314,18 +316,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-d64b668fb-4khbg 1/1 Running 0 21s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-d64b668fb-4khbg` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-d64b668fb-4khbg 9090 +kubectl port-forward -n monitoring prometheus-d64b668fb-4khbg 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-pp-stats` service as one of the targets. diff --git a/docs/guides/pgpool/monitoring/using-prometheus-operator.md b/docs/guides/pgpool/monitoring/using-prometheus-operator.md index e1761982e3..262544b4cd 100644 --- a/docs/guides/pgpool/monitoring/using-prometheus-operator.md +++ b/docs/guides/pgpool/monitoring/using-prometheus-operator.md @@ -34,12 +34,14 @@ The following diagram shows how KubeDB Provisioner operator monitor `Pgpool` usi - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -52,16 +54,16 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE monitoring prometheus-kube-prometheus-prometheus v2.39.0 1 13d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -o yaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -209,34 +211,34 @@ Here, Let's create the Pgpool object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/monitoring/coreos-prom-pp.yaml -pgpool.kubedb.com/coreos-prom-pp created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/monitoring/coreos-prom-pp.yaml ``` +pgpool.kubedb.com/coreos-prom-pp created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pp -n demo coreos-prom-pp +kubectl get pp -n demo coreos-prom-pp +``` NAME TYPE VERSION STATUS AGE coreos-prom-pp kubedb.com/v1alpha2 4.5.0 Ready 65s -``` KubeDB will create a separate stats service with name `{Pgpool crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-pp" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-pp" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-pp ClusterIP 10.96.201.180 9999/TCP,9595/TCP 4m3s coreos-prom-pp-pods ClusterIP None 9999/TCP 4m3s coreos-prom-pp-stats ClusterIP 10.96.73.22 9719/TCP 4m3s -``` Here, `coreos-prom-pp-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo coreos-prom-pp-stats +kubectl describe svc -n demo coreos-prom-pp-stats ``` ```yaml Name: coreos-prom-pp-stats @@ -264,15 +266,15 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this informatio KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `coreos-prom-pp-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE coreos-prom-pp-stats 2m40s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Pgpool crd. ```bash -$ kubectl get servicemonitor -n demo coreos-prom-pp-stats -o yaml +kubectl get servicemonitor -n demo coreos-prom-pp-stats -o yaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -323,20 +325,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 13d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `coreos-prom-pp-stats` service as one of the targets. diff --git a/docs/guides/pgpool/quickstart/quickstart.md b/docs/guides/pgpool/quickstart/quickstart.md index d346a3a64d..9c5a8f4c60 100644 --- a/docs/guides/pgpool/quickstart/quickstart.md +++ b/docs/guides/pgpool/quickstart/quickstart.md @@ -29,14 +29,14 @@ This tutorial will show you how to use KubeDB to run Pgpool. - To keep things isolated, this tutorial uses two separate namespaces called `demo` for deploying PostgreSQL and `pool` for Pgpool, throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ```bash -$ kubectl create ns pool -namespace/pool created +kubectl create ns pool ``` +namespace/pool created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,12 +47,11 @@ namespace/pool created When you have installed KubeDB, it has created `PgpoolVersion` CRD for all supported Pgpool versions. Let's check available PgpoolVersion by, ```bash -$ kubectl get pgpoolversions - +kubectl get pgpoolversions +``` NAME VERSION PGPOOL_IMAGE DEPRECATED AGE 4.4.5 4.4.5 ghcr.io/appscode-images/pgpool2:4.4.5 2d17h 4.5.0 4.5.0 ghcr.io/appscode-images/pgpool2:4.5.0 2d17h -``` Notice the `DEPRECATED` column. Here, `true` means that this PgpoolVersion is deprecated for current KubeDB version. KubeDB will not work for deprecated PgpoolVersion. @@ -71,7 +70,7 @@ In this tutorial, we will use a PostgreSQL named `quick-postgres` in the `demo` KubeDB creates all the necessary resources including services, secrets, and appbindings to get this server up and running. A default database `postgres` is created in `quick-postgres`. Database secret `quick-postgres-auth` holds this user's username and password. Following is the yaml file for it. ```bash -$ kubectl get secrets -n demo quick-postgres-auth -o yaml +kubectl get secrets -n demo quick-postgres-auth -o yaml ``` ```yaml apiVersion: v1 @@ -96,31 +95,36 @@ type: kubernetes.io/basic-auth For the purpose of this tutorial, we will need to extract the username and password from database secret `quick-postgres-auth`. ```bash -$ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +``` 3mn~ap3ImNjMQ25j⏎ -$ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\username}' | base64 -d -postgres⏎ +```bash +kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.\username}' | base64 -d ``` +postgres⏎ Now, to test connection with this database using the credentials obtained above, we will expose the service port associated with `quick-postgres` to localhost. ```bash -$ kubectl port-forward -n demo svc/quick-postgres 5432 +kubectl port-forward -n demo svc/quick-postgres 5432 +``` Forwarding from 127.0.0.1:5432 -> 5432 Forwarding from [::1]:5432 -> 5432 -``` With that done, we should now be able to connect to `postgres` database using username `postgres`, and password `3mn~ap3ImNjMQ25j`. ```bash -$ export PGPASSWORD='3mn~ap3ImNjMQ25j' -$ psql --host=localhost --port=5432 --username=postgres postgres +export PGPASSWORD='3mn~ap3ImNjMQ25j' +``` + +```bash +psql --host=localhost --port=5432 --username=postgres postgres +``` psql (16.2 (Ubuntu 16.2-1.pgdg22.04+1), server 13.13) Type "help" for help. postgres=# -``` After establishing connection successfully, we will create a table in `postgres` database and populate it with data. @@ -188,56 +192,59 @@ Here, Now that we've been introduced to the pgpool CRD, let's create it, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/quickstart/quick-pgpool.yaml -pgpool.kubedb.com/quick-pgpool created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/quickstart/quick-pgpool.yaml ``` +pgpool.kubedb.com/quick-pgpool created ## Connect via Pgpool To connect via pgpool we have to expose its service to localhost. ```bash -$ kubectl port-forward -n pool svc/quick-pgpool 9999 -Forwarding from 127.0.0.1:9999 -> 9999 +kubectl port-forward -n pool svc/quick-pgpool 9999 ``` +Forwarding from 127.0.0.1:9999 -> 9999 Now, let's connect to `postgres` database via Pgpool using psql. -``` bash -$ export PGPASSWORD='3mn~ap3ImNjMQ25j' -$ psql --host=localhost --port=9999 --username=postgres postgres +```bash +export PGPASSWORD='3mn~ap3ImNjMQ25j' +``` + +```bash +psql --host=localhost --port=9999 --username=postgres postgres +``` psql (16.2 (Ubuntu 16.2-1.pgdg22.04+1), server 13.13) Type "help" for help. postgres=# -``` If everything goes well, we'll be connected to the `postgres` database and be able to execute commands. Let's confirm if the company data we inserted in the `postgres` database before are available via Pgpool: ```bash -$ psql --host=localhost --port=9999 --username=postgres postgres --command='SELECT * FROM company ORDER BY name;' +psql --host=localhost --port=9999 --username=postgres postgres --command='SELECT * FROM company ORDER BY name;' +``` name | employee --------+---------- Apple | 10 Google | 15 (2 rows) -``` KubeDB operator watches for Pgpool objects using Kubernetes api. When a Pgpool object is created, KubeDB operator will create a new PetSet and a Service with the matching name. KubeDB operator will also create a governing service for PetSet, if one is not already present. There are also two secrets created by KubeDB operator, one is auth secret for Pgpool `PCP` user and another one is the configuration secret, which will be created based on default and user given declarative configuration. KubeDB operator sets the `status.phase` to `Ready` once Pgpool is ready after all checks. ```bash -$ kubectl get pp -n pool quick-pgpool -o wide +kubectl get pp -n pool quick-pgpool -o wide +``` NAME TYPE VERSION STATUS AGE quick-pgpool kubedb.com/v1alpha2 4.5.0 Ready 63m -``` - Let's describe Pgpool object `quick-pgpool` ```bash -$ kubectl dba describe pp -n pool quick-pgpool +kubectl dba describe pp -n pool quick-pgpool +``` Name: quick-pgpool Namespace: pool Labels: @@ -380,31 +387,28 @@ Status: Phase: Ready Events: -``` - KubeDB has created services for the Pgpool object. ```bash -$ `kubectl get service -n pool --selector=app.kubernetes.io/name=pgpools.kubedb.com,app.kubernetes.io/instance=quick-pgpool` +`kubectl get service -n pool --selector=app.kubernetes.io/name=pgpools.kubedb.com,app.kubernetes.io/instance=quick-pgpool` +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE quick-pgpool ClusterIP 10.96.33.221 9999/TCP 67m quick-pgpool-pods ClusterIP None 9999/TCP 67m -``` Here, Service *`quick-pgpool`* targets random pods to carry out any operation that are made through this service. KubeDB has created secrets for the Pgpool object. Let's see the secrets KubeDB operator created for us. ```bash -$ kubectl get secrets -n pool +kubectl get secrets -n pool +``` NAME TYPE DATA AGE quick-pgpool-auth kubernetes.io/basic-auth 2 67m quick-pgpool-config Opaque 2 67m -``` - Now lets get the auth secret first with yaml format. ```bash -$ kubectl get secrets -n pool quick-pgpool-auth -oyaml +kubectl get secrets -n pool quick-pgpool-auth -oyaml ``` ```yaml apiVersion: v1 @@ -435,7 +439,8 @@ Here, this username and password specified in the secret can be used for `PCP` u Now let's apply this command, ```bash -$ kubectl view-secret -n pool quick-pgpool-config --all +kubectl view-secret -n pool quick-pgpool-config --all +``` pgpool.conf='backend_hostname0 = 'quick-postgres.demo.svc' backend_port0 = 5432 backend_weight0 = 1 @@ -484,7 +489,6 @@ host all all 0.0.0.0/0 md5 host postgres postgres 0.0.0.0/0 md5 host all all ::/0 md5 host postgres postgres ::/0 md5' -``` Here, we can see the default configuration KubeDB operator has set for us. You can also use declarative configuration to configure the server as you want. ## Cleaning up @@ -497,50 +501,70 @@ If you want to delete the existing pgpool, but want to keep the secrets intact t When the DeletionPolicy is set to Delete and the pgpool object is deleted, the KubeDB operator will delete the PetSet and its pods along with the services but leaves the secrets intact. ```bash -$ kubectl patch -n pool pp/quick-pgpool -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +kubectl patch -n pool pp/quick-pgpool -p '{"spec":{"deletionPolicy":"Delete"}}' --type="merge" +``` pgpool.kubedb.com/quick-pgpool patched -$ kubectl delete -n pool pp/quick-pgpool +```bash +kubectl delete -n pool pp/quick-pgpool +``` pgpool.kubedb.com "quick-pgpool" deleted -$ kubectl get pp,petset,svc,secret -n pool +```bash +kubectl get pp,petset,svc,secret -n pool +``` NAME TYPE DATA AGE secret/quick-pgpool-auth kubernetes.io/basic-auth 2 3h22m secret/quick-pgpool-config Opaque 2 3h22m -$ kubectl delete ns pool +```bash +kubectl delete ns pool +``` namespace "pool" deleted -$ kubectl delete -n demo pg/quick-postgres +```bash +kubectl delete -n demo pg/quick-postgres +``` pgpool.kubedb.com "quick-postgres" deleted -$ kubectl get pp,petset,svc,secret -n pool +```bash +kubectl get pp,petset,svc,secret -n pool +``` NAME TYPE DATA AGE secret/quick-pgpool-auth kubernetes.io/basic-auth 2 3h22m secret/quick-pgpool-config Opaque 2 3h22m -``` ### WipeOut But if you want to cleanup each of the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n pool pp/quick-pgpool -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n pool pp/quick-pgpool -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete -n pool pp/quick-pgpool +```bash +kubectl delete -n pool pp/quick-pgpool +``` pgpool.kubedb.com "quick-pgpool" deleted -$ kubectl get pp,petset,svc,secret -n pool +```bash +kubectl get pp,petset,svc,secret -n pool +``` No resources found in pool namespace. -$ kubectl delete ns pool +```bash +kubectl delete ns pool +``` namespace "pool" deleted -$ kubectl delete -n demo pg/quick-postgres +```bash +kubectl delete -n demo pg/quick-postgres +``` pgpool.kubedb.com "quick-postgres" deleted -$ kubectl get pp,petset,svc,secret -n pool -No resources found in pool namespace. +```bash +kubectl get pp,petset,svc,secret -n pool ``` +No resources found in pool namespace. ## Next Steps diff --git a/docs/guides/pgpool/reconfigure-tls/reconfigure-tls.md b/docs/guides/pgpool/reconfigure-tls/reconfigure-tls.md index 65956532f2..a7a6786d9f 100644 --- a/docs/guides/pgpool/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/pgpool/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,18 +62,21 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/pgpool.yaml -pgpool.kubedb.com/pgpool created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/pgpool.yaml ``` +pgpool.kubedb.com/pgpool created Now, wait until `pgpool` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pgpool kubedb.com/v1alpha2 4.5.0 Ready 21s -$ kubectl dba describe pgpool pgpool -n demo +```bash +kubectl dba describe pgpool pgpool -n demo +``` Name: pgpool Namespace: demo Labels: @@ -211,13 +214,13 @@ Status: Type: Provisioned Phase: Ready Events: -``` Now, we let exec into a pgpool pod and verify that the TLS is disabled. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash +kubectl exec -it -n demo pgpool-0 -- bash +``` pgpool-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -256,7 +259,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pgpool-0:/$ exit exit -``` We can see from the above output that `ssl='off'` so we can verify that TLS is disabled for this pgpool. ### Create Issuer/ ClusterIssuer @@ -266,23 +268,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 pgpool-ca \ +kubectl create secret tls pgpool-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/pgpool-ca created ``` +secret/pgpool-ca created Now, Let's create an `Issuer` using the `pgpool-ca` secret that we have just created. The `YAML` file looks like this: @@ -300,9 +302,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/pgpool-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/pgpool-issuer created ### Create PgpoolOpsRequest @@ -349,25 +351,26 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-add-tls.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-add-tls.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CRO, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-add-tls ReconfigureTLS Successful 107s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-add-tls +kubectl describe pgpoolopsrequest -n demo ppops-add-tls +``` Name: ppops-add-tls Namespace: demo Labels: @@ -509,12 +512,12 @@ Events: Normal RestartPods 66s KubeDB Ops-manager Operator Successfully Restarted Pgpool pods Normal Starting 57s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pgpool Normal Successful 57s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pgpool for PgpoolOpsRequest: ppops-add-tls -``` Now, we let exec into a pgpool pod and verify that the TLS is enabled. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash +kubectl exec -it -n demo pgpool-0 -- bash +``` pgpool-0:/$ cat opt/pgpool-II/etc/pgpool.conf pgpool-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' @@ -558,19 +561,21 @@ ssl_cert = '/opt/pgpool-II/tls/tls.crt' failover_on_backend_error = 'off' pgpool-0:/$ exit exit -``` We can see from the above output that `ssl='on'` so we can verify that TLS is enabled for this pgpool. Now, let's connect with just client certificate using psql. For that first save the `tls.crt` and `tls.key` from the secret named `pgpool-client-cert`. ```bash -$ kubectl get secrets -n demo pgpool-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt master ⬆ ⬇ ✱ ◼ -$ kubectl get secrets -n demo pgpool-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +kubectl get secrets -n demo pgpool-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt master ⬆ ⬇ ✱ ◼ +``` + +```bash +kubectl get secrets -n demo pgpool-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key ``` Now let's port forward to the main service of the pgpool: ```bash -$ kubectl port-forward -n demo svc/pgpool 9999 pgpool ✱ ◼ -Forwarding from 127.0.0.1:9999 -> 9999 +kubectl port-forward -n demo svc/pgpool 9999 pgpool ✱ ◼ ``` +Forwarding from 127.0.0.1:9999 -> 9999 Now connect with `psql`: ```bash psql "sslmode=require port=9999 host=localhost dbname=postgres user=postgres sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" master ⬆ ⬇ ✱ ◼ @@ -586,10 +591,10 @@ So, here we have connected using the client certificate and now password was nee Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash master ⬆ ⬇ ✱ ◼ +kubectl exec -it -n demo pgpool-0 -- bash master ⬆ ⬇ ✱ ◼ +``` pgpool-0:/$ openssl x509 -in /opt/pgpool-II/tls/ca.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Oct 27 06:47:28 2024 GMT -``` So, the certificate will expire on this time `27 06:47:28 2024 GMT`. @@ -620,25 +625,26 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-rotate.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-rotate.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CRO, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-rotate ReconfigureTLS Successful 113s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-rotate +kubectl describe pgpoolopsrequest -n demo ppops-rotate +``` Name: ppops-rotate Namespace: demo Labels: @@ -773,15 +779,14 @@ Events: Normal RestartPods 66s KubeDB Ops-manager Operator Successfully Restarted Pgpool pods Normal Starting 66s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pgpool Normal Successful 66s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pgpool for PgpoolOpsRequest: ppops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash master ⬆ ⬇ ✱ ◼ +kubectl exec -it -n demo pgpool-0 -- bash master ⬆ ⬇ ✱ ◼ +``` pgpool-0:/$ openssl x509 -in /opt/pgpool-II/tls/ca.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Oct 27 07:10:20 2024 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -792,23 +797,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 pgpool-new-ca \ +kubectl create secret tls pgpool-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/pgpool-new-ca created ``` +secret/pgpool-new-ca created Now, Let's create a new `Issuer` using the `pgpool-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -826,9 +831,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/pp-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/pp-new-issuer created ### Create PgpoolOpsRequest @@ -860,25 +865,26 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-change-issuer.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-change-issuer.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-change-issuer created #### Verify Issuer is changed successfully Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CRO, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-change-issuer ReconfigureTLS Successful 87s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-change-issuer +kubectl describe pgpoolopsrequest -n demo ppops-change-issuer +``` Name: ppops-change-issuer Namespace: demo Labels: @@ -1010,15 +1016,14 @@ Events: Normal RestartPods 2m33s KubeDB Ops-manager Operator Successfully Restarted Pgpool pods Normal Starting 2m32s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pgpool Normal Successful 2m32s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pgpool for PgpoolOpsRequest: ppops-change-issuer -``` Now, Let's exec pgpool and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash +kubectl exec -it -n demo pgpool-0 -- bash +``` pgpool-0:/$ openssl x509 -in /opt/pgpool-II/tls/ca.pem -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -1053,25 +1058,26 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-remove.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfigure-tls/ppops-remove.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-remove created #### Verify TLS Removed Successfully Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CRO, ```bash -$ wacth kubectl get pgpoolopsrequest -n demo +wacth kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-remove ReconfigureTLS Successful 65s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-remove +kubectl describe pgpoolopsrequest -n demo ppops-remove +``` Name: ppops-remove Namespace: demo Labels: @@ -1159,12 +1165,12 @@ Events: Normal RestartPods 29s KubeDB Ops-manager Operator Successfully Restarted Pgpool pods Normal Starting 29s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pgpool Normal Successful 28s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pgpool for PgpoolOpsRequest: ppops-remove -``` Now, Let's exec into pgpool and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo pgpool-0 -- bash +kubectl exec -it -n demo pgpool-0 -- bash +``` pgpool-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -1201,7 +1207,6 @@ memory_cache_enabled = 'off' memqcache_oiddir = '/tmp/oiddir/' allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' -``` We can see from the above output that `ssl='off'` so we can verify that TLS is disabled successfully for this pgpool. diff --git a/docs/guides/pgpool/reconfigure/reconfigure-pgpool.md b/docs/guides/pgpool/reconfigure/reconfigure-pgpool.md index cd17ad4ac6..e60f8b4fc6 100644 --- a/docs/guides/pgpool/reconfigure/reconfigure-pgpool.md +++ b/docs/guides/pgpool/reconfigure/reconfigure-pgpool.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -59,9 +59,9 @@ Here, `max_pool` is set to `60`, whereas the default value is `numberof replicas Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo pp-custom-config --from-file=./pgpool.conf -secret/pp-custom-config created +kubectl create secret generic -n demo pp-custom-config --from-file=./pgpool.conf ``` +secret/pp-custom-config created In this section, we are going to create a Pgpool object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Pgpool` CR that we are going to create, @@ -85,24 +85,25 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/pp-custom-config.yaml -pgpool.kubedb.com/pp-custom created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/pp-custom-config.yaml ``` +pgpool.kubedb.com/pp-custom created Now, wait until `pp-custom` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pp-custom kubedb.com/v1alpha2 4.5.0 Ready 112s -``` Now, we will check if the pgpool has started with the custom configuration we have provided. Now, you can exec into the pgpool pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo pp-custom-0 -- bash +kubectl exec -it -n demo pp-custom-0 -- bash +``` pp-custom-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -141,7 +142,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pp-custom-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `max_pool` has been set to `60`. @@ -159,9 +159,9 @@ max_pool=50 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./pgpool.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./pgpool.conf ``` +secret/new-custom-config created #### Create PgpoolOpsRequest @@ -194,9 +194,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure created #### Verify the new configuration is working @@ -205,16 +205,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-reconfigure Reconfigure Successful 63s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to reconfigure the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-reconfigure +kubectl describe pgpoolopsrequest -n demo ppops-reconfigure +``` Name: ppops-reconfigure Namespace: demo Labels: @@ -306,12 +307,12 @@ Events: Normal RestartPods 51s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 51s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-custom Normal Successful 51s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-custom for PgpoolOpsRequest: ppops-reconfigure -``` Now let's exec into the pgpool pod and check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo pp-custom-0 -- bash +kubectl exec -it -n demo pp-custom-0 -- bash +``` pp-custom-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -350,7 +351,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pp-custom-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `max_pool` has been changed from `60` to `50`. So the reconfiguration of the pgpool is successful. @@ -390,9 +390,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure-apply.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure-apply.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure-apply created #### Verify the new configuration is working @@ -401,17 +401,18 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-reconfigure Reconfigure Successful 9m15s ppops-reconfigure-apply Reconfigure Successful 53s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to reconfigure the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-reconfigure-apply +kubectl describe pgpoolopsrequest -n demo ppops-reconfigure-apply +``` Name: ppops-reconfigure-apply Namespace: demo Labels: @@ -503,12 +504,12 @@ Events: Normal RestartPods 28s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 28s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-custom Normal Successful 28s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-custom for PgpoolOpsRequest: ppops-reconfigure-apply -``` Now let's exec into the pgpool pod and check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo pp-custom-0 -- bash +kubectl exec -it -n demo pp-custom-0 -- bash +``` pp-custom-0:/$ cat opt/pgpool-II/etc/pgpool.conf memory_cache_enabled = 'off' num_init_children = 5 @@ -547,7 +548,6 @@ client_idle_limit = 0 failover_on_backend_error = 'off' pp-custom-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `max_pool` has been changed from `50` to `75`. So the reconfiguration of the pgpool using the `applyConfig` field is successful. @@ -585,9 +585,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure-remove.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/reconfiguration/ppops-reconfigure-remove.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-reconfigure-remove created #### Verify if the configuration is removed @@ -596,19 +596,20 @@ If everything goes well, `KubeDB` Ops-manager operator will remove the custom co Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE ppops-reconfigure Reconfigure Successful 71m ppops-reconfigure-apply Reconfigure Successful 63m ppops-reconfigure-remove Reconfigure Successful 57s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to reconfigure the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo ppops-reconfigure-remove +kubectl describe pgpoolopsrequest -n demo ppops-reconfigure-remove +``` Name: ppops-reconfigure-remove Namespace: demo Labels: @@ -699,12 +700,12 @@ Events: Normal RestartPods 25s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 25s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-custom Normal Successful 25s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-custom for PgpoolOpsRequest: ppops-reconfigure-remove -``` Now let's exec into the pgpool pod and check the configuration. ```bash -$ kubectl exec -it -n demo pp-custom-0 -- bash +kubectl exec -it -n demo pp-custom-0 -- bash +``` pp-custom-0:/$ cat opt/pgpool-II/etc/pgpool.conf backend_hostname0 = 'ha-postgres.demo.svc' backend_port0 = 5432 @@ -743,7 +744,6 @@ allow_clear_text_frontend_auth = 'false' failover_on_backend_error = 'off' pp-custom-0:/$ exit exit -``` As we can see from the configuration of running pgpool, the value of `max_pool` has been changed from `75` to `15` which is the default configuration `number of repicas * 15`. So the reconfiguration of the pgpool using the `removeCustomConfig` field is successful. diff --git a/docs/guides/pgpool/restart/restart.md b/docs/guides/pgpool/restart/restart.md index 1c202a40ca..24fc6b2b2d 100644 --- a/docs/guides/pgpool/restart/restart.md +++ b/docs/guides/pgpool/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Pgpool via a PgpoolOpsRequest. Restarting is usef - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -56,9 +56,9 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/restart/pgpool.yaml -pgpool.kubedb.com/pgpool created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/restart/pgpool.yaml ``` +pgpool.kubedb.com/pgpool created ## Apply Restart opsRequest @@ -83,18 +83,21 @@ spec: Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/restart/ops.yaml -pgpoolopsrequest.ops.kubedb.com/restart-pgpool created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/restart/ops.yaml ``` +pgpoolopsrequest.ops.kubedb.com/restart-pgpool created Now the Ops-manager operator will restart the pods one by one. -```shell -$ kubectl get ppops -n demo +```bash +kubectl get ppops -n demo +``` NAME TYPE STATUS AGE restart-pgpool Restart Successful 79s -$ kubectl get ppops -n demo -oyaml restart-pgpool +```bash +kubectl get ppops -n demo -oyaml restart-pgpool +``` apiVersion: ops.kubedb.com/v1alpha1 kind: PgpoolOpsRequest metadata: @@ -156,7 +159,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/pgpool/rotateauth/rotateauth.md b/docs/guides/pgpool/rotateauth/rotateauth.md index 342d03082d..a3e7c61ef6 100644 --- a/docs/guides/pgpool/rotateauth/rotateauth.md +++ b/docs/guides/pgpool/rotateauth/rotateauth.md @@ -56,19 +56,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Pgpool. Let's create the `PgpoolOpsRequest` CR we have shown above, -```shell - $kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/rotateauth/rotateauth.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/rotateauth/rotateauth.yaml + ``` pgpoolopsrequest.ops.kubedb.com/pgpops-rotate-auth-generated created -``` Let's wait for `PgpoolOpsrequest` to be `Successful`. Run the following command to watch `PgpoolOpsrequest` CR -```shell - $ kubectl get PgpoolOpsRequest -n pool + ```bash + kubectl get PgpoolOpsRequest -n pool + ``` NAME TYPE STATUS AGE pgpops-rotate-auth-generated RotateAuth Successful 52s -``` If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe pgpoolopsrequest -n pool pgpops-rotate-auth-generated +```bash +kubectl describe pgpoolopsrequest -n pool pgpops-rotate-auth-generated +``` Name: pgpops-rotate-auth-generated Namespace: pool Labels: @@ -156,37 +157,45 @@ Events: Normal RestartPods 2m32s KubeDB Ops-manager Operator Successfully Restarted Pods With New User Normal Starting 2m32s KubeDB Ops-manager Operator Resuming Pgpool database: pool/quick-pgpool Normal Successful 2m32s KubeDB Ops-manager Operator Successfully resumed Pgpool database: pool/quick-pgpool for PgpoolOpsRequest: pgpops-rotate-auth-generated -``` **Verify Auth is rotated** -```shell -$ kubectl get Pgpool -n pool quick-pgpool -ojson | jq .spec.authSecret.name +```bash + kubectl get Pgpool -n pool quick-pgpool -ojson | jq .spec.authSecret.name +``` "quick-pgpool-auth" -$ kubectl get secrets -n pool quick-pgpool-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secrets -n pool quick-pgpool-auth -o jsonpath='{.data.\username}' | base64 -d +``` pcp⏎ -$ kubectl get secrets -n pool quick-pgpool-auth -o jsonpath='{.data.\password}' | base64 -d -h1yPX0CjgGXNjpKY⏎ + +```bash +kubectl get secrets -n pool quick-pgpool-auth -o jsonpath='{.data.\password}' | base64 -d ``` +h1yPX0CjgGXNjpKY⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The key is `authData.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n pool quick-pgpool-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n pool quick-pgpool-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` pcp⏎ -$ kubectl get secret -n pool quick-pgpool-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -gZoAOjr0iUkH07ku⏎ + +```bash +kubectl get secret -n pool quick-pgpool-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +gZoAOjr0iUkH07ku⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, -```shell -$ kubectl create secret generic quick-pp-user-auth -n pool \ +```bash +kubectl create secret generic quick-pp-user-auth -n pool \ --type=kubernetes.io/basic-auth \ --from-literal=username=user \ --from-literal=password=Pgpool2 -secret/quick-pp-user-auth created ``` +secret/quick-pp-user-auth created Now create a `PgpoolOpsRequest` with `RotateAuth` type. Below is the YAML of the `PgpoolOpsRequest` that we are going to create, ```shell @@ -214,21 +223,22 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/rotateauth/rotateauthuser.yaml -pgpoolopsrequest.ops.kubedb.com/ppops-rotate-auth-user created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/rotateauth/rotateauthuser.yaml ``` +pgpoolopsrequest.ops.kubedb.com/ppops-rotate-auth-user created Let’s wait for `PgpoolOpsRequest` to be Successful. Run the following command to watch `PgpoolOpsRequest` CR: -```shell -$ kubectl get PgpoolOpsRequest -n pool +```bash +kubectl get PgpoolOpsRequest -n pool +``` NAME TYPE STATUS AGE pgpops-rotate-auth-generated RotateAuth Successful 56m ppops-rotate-auth-user RotateAuth Successful 44m -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Pgpoolopsrequest -n pool ppops-rotate-auth-user +```bash + kubectl describe Pgpoolopsrequest -n pool ppops-rotate-auth-user +``` Name: ppops-rotate-auth-user Namespace: pool Labels: @@ -319,24 +329,31 @@ Events: Normal RestartPods 4m16s KubeDB Ops-manager Operator Successfully Restarted Pods With New User Normal Starting 4m16s KubeDB Ops-manager Operator Resuming Pgpool database: pool/quick-pgpool Normal Successful 4m16s KubeDB Ops-manager Operator Successfully resumed Pgpool database: pool/quick-pgpool for PgpoolOpsRequest: ppops-rotate-auth-user - -``` **Verify auth is rotate** -```shell -$ kubectl get pgpool -n pool quick-pgpool -ojson | jq .spec.authSecret.name +```bash +kubectl get pgpool -n pool quick-pgpool -ojson | jq .spec.authSecret.name +``` "quick-pp-user-auth" -$ kubectl get secrets -n pool quick-pp-user-auth -o jsonpath='{.data.\username}' | base64 -d + +```bash +kubectl get secrets -n pool quick-pp-user-auth -o jsonpath='{.data.\username}' | base64 -d +``` user⏎ -$ kubectl get secrets -n pool quick-pp-user-auth -o jsonpath='{.data.\password}' | base64 -d -Pgpool2⏎ + +```bash +kubectl get secrets -n pool quick-pp-user-auth -o jsonpath='{.data.\password}' | base64 -d ``` +Pgpool2⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n pool quick-pp-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash + kubectl get secret -n pool quick-pp-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` pcp⏎ -$ kubectl get secret -n pool quick-pp-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -gZoAOjr0iUkH07ku⏎ + +```bash +kubectl get secret -n pool quick-pp-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +gZoAOjr0iUkH07ku⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -345,14 +362,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Pgpoolopsrequest pgpops-rotate-auth-generated ppops-rotate-auth-user -n pool +```bash +kubectl delete Pgpoolopsrequest pgpops-rotate-auth-generated ppops-rotate-auth-user -n pool +``` Pgpoolopsrequest.ops.kubedb.com "pgpops-rotate-auth-generated" "ppops-rotate-auth-user" deleted -$ kubectl delete secret -n pool quick-pp-user-auth + +```bash +kubectl delete secret -n pool quick-pp-user-auth +``` secret "quick-pp-user-auth" deleted -$ kubectl delete secret -n pool quick-pgpool-auth -secret "quick-pgpool-auth " deleted + +```bash +kubectl delete secret -n pool quick-pgpool-auth ``` +secret "quick-pgpool-auth " deleted ## Next Steps diff --git a/docs/guides/pgpool/scaling/horizontal-scaling/horizontal-ops.md b/docs/guides/pgpool/scaling/horizontal-scaling/horizontal-ops.md index 9c391988ca..25ef66e45e 100644 --- a/docs/guides/pgpool/scaling/horizontal-scaling/horizontal-ops.md +++ b/docs/guides/pgpool/scaling/horizontal-scaling/horizontal-ops.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -72,27 +72,29 @@ spec: Here we are creating the pgpool with `max_pool=60`, it is necessary because we will up scale the pgpool replicas so for that we need larger `max_pool`. Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-horizontal.yaml -pgpool.kubedb.com/pp-horizontal created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-horizontal.yaml ``` +pgpool.kubedb.com/pp-horizontal created Now, wait until `pp-horizontal ` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pp-horizontal kubedb.com/v1alpha2 4.5.0 Ready 2m -``` Let's check the number of replicas this pgpool has from the Pgpool object, number of pods the petset have, ```bash -$ kubectl get pgpool -n demo pp-horizontal -o json | jq '.spec.replicas' +kubectl get pgpool -n demo pp-horizontal -o json | jq '.spec.replicas' +``` 1 -$ kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' ``` +1 We can see from both command that the pgpool has 1 replica. @@ -129,9 +131,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/ppops-hscale-up-ops.yaml -pgpoolopsrequest.ops.kubedb.com/pgpool-horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/ppops-hscale-up-ops.yaml ``` +pgpoolopsrequest.ops.kubedb.com/pgpool-horizontal-scale-up created #### Verify replicas scaled up successfully @@ -140,16 +142,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE pgpool-horizontal-scale-up HorizontalScaling Successful 2m49s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to scale the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo pgpool-horizontal-scale-up +kubectl describe pgpoolopsrequest -n demo pgpool-horizontal-scale-up +``` Name: pgpool-horizontal-scale-up Namespace: demo Labels: @@ -264,17 +267,18 @@ Events: Normal UpdateDatabase 3m37s KubeDB Ops-manager Operator Successfully updated Pgpool Normal Starting 3m37s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-horizontal Normal Successful 3m37s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-horizontal for PgpoolOpsRequest: pgpool-horizontal-scale-up -``` Now, we are going to verify the number of replicas this pgpool has from the Pgpool object, number of pods the petset have, ```bash -$ kubectl get pp -n demo pp-horizontal -o json | jq '.spec.replicas' +kubectl get pp -n demo pp-horizontal -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the pgpool is `3`. That means we have successfully scaled up the replicas of the Pgpool. @@ -309,9 +313,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/ppops-hscale-down-ops.yaml -pgpoolopsrequest.ops.kubedb.com/pgpool-horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/ppops-hscale-down-ops.yaml ``` +pgpoolopsrequest.ops.kubedb.com/pgpool-horizontal-scale-down created #### Verify replicas scaled down successfully @@ -320,16 +324,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE pgpool-horizontal-scale-down HorizontalScaling Successful 75s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to scale the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo pgpool-horizontal-scale-down +kubectl describe pgpoolopsrequest -n demo pgpool-horizontal-scale-down +``` Name: pgpool-horizontal-scale-down Namespace: demo Labels: @@ -416,17 +421,18 @@ Events: Normal UpdateDatabase 48s KubeDB Ops-manager Operator Successfully updated Pgpool Normal Starting 48s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-horizontal Normal Successful 48s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-horizontal for PgpoolOpsRequest: pgpool-horizontal-scale-down -``` Now, we are going to verify the number of replicas this pgpool has from the Pgpool object, number of pods the petset have, ```bash -$ kubectl get pp -n demo pp-horizontal -o json | jq '.spec.replicas' +kubectl get pp -n demo pp-horizontal -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo pp-horizontal -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the pgpool is `2`. That means we have successfully scaled up the replicas of the Pgpool. ## Cleaning Up diff --git a/docs/guides/pgpool/scaling/vertical-scaling/vertical-ops.md b/docs/guides/pgpool/scaling/vertical-scaling/vertical-ops.md index 0f5f3a8409..fb3417ef29 100644 --- a/docs/guides/pgpool/scaling/vertical-scaling/vertical-ops.md +++ b/docs/guides/pgpool/scaling/vertical-scaling/vertical-ops.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -69,22 +69,23 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-vertical.yaml -pgpool.kubedb.com/pp-vertical created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-vertical.yaml ``` +pgpool.kubedb.com/pp-vertical created Now, wait until `pp-vertical` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pp-vertical kubedb.com/v1alpha2 4.5.0 Ready 17s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -95,7 +96,6 @@ $ kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resourc "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -142,9 +142,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-vertical-ops.yaml -pgpoolopsrequest.ops.kubedb.com/pgpool-scale-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/scaling/pp-vertical-ops.yaml ``` +pgpoolopsrequest.ops.kubedb.com/pgpool-scale-vertical created #### Verify Pgpool resources updated successfully @@ -153,16 +153,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ kubectl get pgpoolopsrequest -n demo +kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE pgpool-scale-vertical VerticalScaling Successful 3m42s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to scale the pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo pgpool-scale-vertical +kubectl describe pgpoolopsrequest -n demo pgpool-scale-vertical +``` Name: pgpool-scale-vertical Namespace: demo Labels: @@ -252,12 +253,12 @@ Events: Normal RestartPods 3m28s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 3m28s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-vertical Normal Successful 3m28s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-vertical for PgpoolOpsRequest: pgpool-scale-vertical -``` Now, we are going to verify from the Pod yaml whether the resources of the pgpool has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -268,7 +269,6 @@ $ kubectl get pod -n demo pp-vertical-0 -o json | jq '.spec.containers[].resourc "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the Pgpool. diff --git a/docs/guides/pgpool/sync-users/sync-users-pgpool.md b/docs/guides/pgpool/sync-users/sync-users-pgpool.md index 5348630b07..827b14f7fd 100644 --- a/docs/guides/pgpool/sync-users/sync-users-pgpool.md +++ b/docs/guides/pgpool/sync-users/sync-users-pgpool.md @@ -25,9 +25,9 @@ KubeDB supports providing a way to add/update users to Pgpool in runtime simply - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -90,17 +90,17 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/sync-users/pgpool-sync.yaml -pgpool.kubedb.com/pgpool-sync created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/sync-users/pgpool-sync.yaml ``` +pgpool.kubedb.com/pgpool-sync created Now, wait until `pgpool-sync` has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pgpool-sync kubedb.com/v1alpha2 4.5.0 Ready 41s -``` ### Sync Users @@ -123,52 +123,58 @@ stringData: Now, create the secret by applying the yaml above. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/sync-users/secret.yaml -secret/sync-secret created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/sync-users/secret.yaml ``` +secret/sync-secret created Now, after `10 seconds` you can exec into the pgpool pod and find if the new user is there, ```bash -$ kubectl exec -it -n demo pgpool-sync-0 -- bash +kubectl exec -it -n demo pgpool-sync-0 -- bash +``` pgpool-sync-0:/$ cat opt/pgpool-II/etc/pool_passwd postgres:AESOmAkfj+zX8zXLm92d6Vup6a5yASiiGScoHNDTIgBwH8= john:AEScbLKDSMb+KVrILhh7XEmyQ== pgpool-sync-0:/$ exit exit -``` We can see that the user is there in Pgpool. So, now let's create this user and try to use this user through Pgpool. Now, you can connect to this pgpool through [psql](https://www.postgresql.org/docs/current/app-psql.html). Before that we need to port-forward to the primary service of pgpool. ```bash -$ kubectl port-forward -n demo svc/pgpool-sync 9999 -Forwarding from 127.0.0.1:9999 -> 9999 +kubectl port-forward -n demo svc/pgpool-sync 9999 ``` +Forwarding from 127.0.0.1:9999 -> 9999 We will use the root Postgres user to create the user, so let's get the password for the root user, so that we can use it. ```bash -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d -qEeuU6cu5aH!O9CI⏎ +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d ``` +qEeuU6cu5aH!O9CI⏎ We can use this password now, ```bash -$ export PGPASSWORD='qEeuU6cu5aH!O9CI' -$ psql --host=localhost --port=9999 --username=postgres postgres +export PGPASSWORD='qEeuU6cu5aH!O9CI' +``` + +```bash +psql --host=localhost --port=9999 --username=postgres postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=# CREATE USER john WITH PASSWORD '12345'; CREATE ROLE postgres=# exit -``` Now, let's use this john user. ```bash -$ export PGPASSWORD='12345' -$ psql --host=localhost --port=9999 --username=john postgres +export PGPASSWORD='12345' +``` + +```bash +psql --host=localhost --port=9999 --username=john postgres +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) Type "help" for help. postgres=> exit -``` So, we can successfully verify that the user is registered in Pgpool and also we can use it. ## Cleaning up diff --git a/docs/guides/pgpool/tls/configure_ssl.md b/docs/guides/pgpool/tls/configure_ssl.md index b99174147a..00ae140e19 100644 --- a/docs/guides/pgpool/tls/configure_ssl.md +++ b/docs/guides/pgpool/tls/configure_ssl.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `sslMode` and `clientAuthMode - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/pgpool](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/pgpool) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -104,9 +104,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/tls/issuer.yaml -issuer.cert-manager.io/pgpool-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/tls/issuer.yaml ``` +issuer.cert-manager.io/pgpool-ca-issuer created ## Prepare Postgres Prepare a KubeDB Postgres cluster using this [tutorial](/docs/guides/postgres/clustering/streaming_replication.md), or you can use any externally managed postgres but in that case you need to create an [appbinding](/docs/guides/pgpool/concepts/appbinding.md) yourself. In this tutorial we will use 3 node Postgres cluster named `ha-postgres`. @@ -150,25 +150,26 @@ spec: ### Deploy Pgpool ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/tls/pgpool-ssl.yaml -pgpool.kubedb.com/pp-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/tls/pgpool-ssl.yaml ``` +pgpool.kubedb.com/pp-tls created Now, wait until `pp-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get pp -n demo +watch kubectl get pp -n demo +``` Every 2.0s: kubectl get pgpool -n demo NAME TYPE VERSION STATUS AGE pp-tls kubedb.com/v1alpha2 4.5.0 Ready 60s -``` ### Verify TLS/SSL in Pgpool Now, connect to this database through [psql](https://www.postgresql.org/docs/current/app-psql.html) and verify if `SSLMode` has been set up as intended (i.e, `require`). ```bash -$ kubectl describe secret -n demo pp-tls-client-cert +kubectl describe secret -n demo pp-tls-client-cert +``` Name: pp-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -192,13 +193,16 @@ Data tls.key: 1675 bytes ca.crt: 1151 bytes tls.crt: 1131 bytes -``` Now, Lets save the client cert and key to two different files: ```bash -$ kubectl get secrets -n demo pp-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt -$ cat client.crt +kubectl get secrets -n demo pp-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt +``` + +```bash +cat client.crt +``` -----BEGIN CERTIFICATE----- MIIDFjCCAf6gAwIBAgIRAO9tAQn/9lqHN4Pfi+UCe2IwDQYJKoZIhvcNAQELBQAw IjEPMA0GA1UEAwwGcGdwb29sMQ8wDQYDVQQKDAZrdWJlZGIwHhcNMjQwNzE2MTAz @@ -218,8 +222,14 @@ rMQCOKGt8R0JJUXR0fcuDEGKv+jpz5P+n5dBtPQ40CrE34mhpa3m00Y64X4PVDI6 RusaLKyNGkaU+15WErg44/zM3LayvMImRnnoIttO7NkOe/9ige8C3hgEjZoivZKM 0Jc7koXlrnszBH2K/MOst9kHRTPk0VVmxBo= -----END CERTIFICATE----- -$ kubectl get secrets -n demo pp-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key -$ cat client.key + +```bash +kubectl get secrets -n demo pp-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +``` + +```bash +cat client.key +``` -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAyjtaKShzxcwBiiss7eVEltx5uI77yKNwj3pRnRIzN/t53IFs 7W9WuWsF5qf22gJxbxZ/jej5D6NGe9knPNWd9XYLuAt5psKjUj+DQlSYd1PGcg4u @@ -247,25 +257,24 @@ kg89+QKBgAQDWZkq2mPZMmb+ltW1TZO2HqmEXBP9plgYGfrSjpofTjsBzykoaHnA J/ocHs2cNkW8arrhiZQzDyokZRc1j5+PIYLfXZ1gSK7WfOe6HO/667eCNuoEcfDv w8MtuCJgbYP8J0BXun982+EnLkuyDAoyX9GvEqyGQagme1ENiwFm -----END RSA PRIVATE KEY----- -``` Now, if you see the common name of the client.crt you can see, ```bash -$ openssl x509 -in client.crt -inform PEM -subject -nameopt RFC2253 -noout -subject=CN=postgres +openssl x509 -in client.crt -inform PEM -subject -nameopt RFC2253 -noout ``` +subject=CN=postgres Here common name of the client certificate is important if you want to connect with the client certificate, the `username must match the common name of the certificate`. Here, we can see the common name(CN) is, `postgres`. So, we will use postgres user to connect with Pgpool. Now, we can connect using `subject=CN=postgres` to connect to the psql, ```bash -$ psql "sslmode=require port=9999 host=localhost dbname=postgres user=postgres sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" +psql "sslmode=require port=9999 host=localhost dbname=postgres user=postgres sslrootcert=ca.crt sslcert=client.crt sslkey=client.key" +``` psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 16.1) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. postgres=# -``` We are connected to the postgres database. Let's run some command to verify the sslMode and the user, @@ -299,9 +308,9 @@ User can update `sslMode` & `clientAuthMode` if needed. Some changes may be inva The good thing is, **KubeDB operator will throw error for invalid SSL specs while creating/updating the Pgpool object.** i.e., ```bash -$ kubectl patch -n demo pp/pp-tls -p '{"spec":{"sslMode": "disabled","clientAuthMode": "cert"}}' --type="merge" -The Pgpool "pp-tls" is invalid: spec.sslMode: Unsupported value: "disabled": supported values: "disable", "allow", "prefer", "require", "verify-ca", "verify-full" +kubectl patch -n demo pp/pp-tls -p '{"spec":{"sslMode": "disabled","clientAuthMode": "cert"}}' --type="merge" ``` +The Pgpool "pp-tls" is invalid: spec.sslMode: Unsupported value: "disabled": supported values: "disable", "allow", "prefer", "require", "verify-ca", "verify-full" > Note: There is no official support for Pgpool with the Postgres cluster having `clientAuthMode` as `cert`. Check [here](https://www.pgpool.net/docs/42/en/html/auth-methods.html#:~:text=Note%3A%20The%20certificate%20authentication%20works%20between%20only%20client%20and%20Pgpool%2DII.%20The%20certificate%20authentication%20does%20not%20work%20between%20Pgpool%2DII%20and%20PostgreSQL.%20For%20backend%20authentication%20you%20can%20use%20any%20other%20authentication%20method.). diff --git a/docs/guides/pgpool/update-version/update_version.md b/docs/guides/pgpool/update-version/update_version.md index 08dd3b8403..f2116f70a3 100644 --- a/docs/guides/pgpool/update-version/update_version.md +++ b/docs/guides/pgpool/update-version/update_version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/pgpool](/docs/examples/pgpool) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -65,17 +65,17 @@ spec: Let's create the `Pgpool` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/update-version/pp-update.yaml -pgpool.kubedb.com/pp-update created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/update-version/pp-update.yaml ``` +pgpool.kubedb.com/pp-update created Now, wait until `pp-update` created has status `Ready`. i.e, ```bash -$ kubectl get pp -n demo +kubectl get pp -n demo +``` NAME TYPE VERSION STATUS AGE pp-update kubedb.com/v1alpha2 4.4.5 Ready 26s -``` We are now ready to apply the `PgpoolOpsRequest` CR to update this Pgpool. @@ -111,9 +111,9 @@ Here, Let's create the `PgpoolOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/update-version/ppops-update.yaml -pgpoolopsrequest.ops.kubedb.com/pgpool-version-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/update-version/ppops-update.yaml ``` +pgpoolopsrequest.ops.kubedb.com/pgpool-version-update created #### Verify Pgpool version updated successfully : @@ -122,16 +122,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `PgpoolOpsRequest` to be `Successful`. Run the following command to watch `PgpoolOpsRequest` CR, ```bash -$ watch kubectl get pgpoolopsrequest -n demo +watch kubectl get pgpoolopsrequest -n demo +``` Every 2.0s: kubectl get pgpoolopsrequest -n demo NAME TYPE STATUS AGE pgpool-version-update UpdateVersion Successful 93s -``` We can see from the above output that the `PgpoolOpsRequest` has succeeded. If we describe the `PgpoolOpsRequest` we will get an overview of the steps that were followed to update the Pgpool. ```bash -$ kubectl describe pgpoolopsrequest -n demo pgpool-version-update +kubectl describe pgpoolopsrequest -n demo pgpool-version-update +``` Name: pgpool-version-update Namespace: demo Labels: @@ -219,20 +220,23 @@ Events: Normal RestartPods 2m1s KubeDB Ops-manager Operator Successfully Restarted Pgpool pods Normal Starting 2m1s KubeDB Ops-manager Operator Resuming Pgpool database: demo/pp-update Normal Successful 2m1s KubeDB Ops-manager Operator Successfully resumed Pgpool database: demo/pp-update for PgpoolOpsRequest: pgpool-version-update -``` Now, we are going to verify whether the `Pgpool` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get pp -n demo pp-update -o=jsonpath='{.spec.version}{"\n"}' +kubectl get pp -n demo pp-update -o=jsonpath='{.spec.version}{"\n"}' +``` 4.5.0 -$ kubectl get petset -n demo pp-update -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo pp-update -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/pgpool2:4.5.0 -$ kubectl get pods -n demo pp-update-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/pgpool2:4.5.0@sha256:2697fcad9e11bdc704f6ae0fba85c4451c6b0243140aaaa33e719c3af548bda1 +```bash +kubectl get pods -n demo pp-update-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/pgpool2:4.5.0@sha256:2697fcad9e11bdc704f6ae0fba85c4451c6b0243140aaaa33e719c3af548bda1 You can see from above, our `Pgpool` has been updated with the new version. So, the update process is successfully completed. diff --git a/docs/guides/pgpool/virtual_secret/guide.md b/docs/guides/pgpool/virtual_secret/guide.md index 02682ffedd..f25a95349d 100644 --- a/docs/guides/pgpool/virtual_secret/guide.md +++ b/docs/guides/pgpool/virtual_secret/guide.md @@ -43,19 +43,28 @@ Before you begin, ensure you have the following prerequisites in place: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## How to use Virtual Secrets ### Install Virtual Secrets Server First, install the virtual-secret-server which is a custom api server for the `secrets.virtual-secrets.dev` resource. ```bash -$ helm repo add appscode https://charts.appscode.com/stable/ -$ helm repo update -$ helm search repo appscode/virtual-secrets-server --version=v2025.3.14 -$ helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ +helm repo add appscode https://charts.appscode.com/stable/ +``` + +```bash +helm repo update +``` + +```bash +helm search repo appscode/virtual-secrets-server --version=v2025.3.14 +``` + +```bash +helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ --version=v2025.3.14 -n kubevault --create-namespace ``` @@ -66,28 +75,30 @@ read, list, delete and delete in a kv secret engine named `virtual-secrets.dev` Now let’s configure the vault server with following commands: -```shell # enable kv secret engine in the path virtual-secrets.dev -$ vault secrets enable -path=virtual-secrets.dev -version=2 kv +```bash +vault secrets enable -path=virtual-secrets.dev -version=2 kv +``` Success! Enabled the kv secrets engine at: virtual-secrets.dev/ - # creates a policy with the permission to create, update, read, list and delete -$ vault policy write virtual-secrets-policy - <}}/docs/examples/vault/secretstore.yaml -secretstore.config.virtual-secrets.dev/vault configured +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretstore.yaml ``` +secretstore.config.virtual-secrets.dev/vault configured Here, @@ -135,9 +146,9 @@ Here, - Other than that, everything else is similar to a core Kubernetes Secret. Let’s go ahead and apply the Secret, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/pp_vs.yaml -secret.virtual-secrets.dev/virtual-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/pp_vs.yaml ``` +secret.virtual-secrets.dev/virtual-secret created Let's list the Secrets to see if it is created or not, @@ -149,8 +160,9 @@ virtual-secret Opaque 2 2d19h We can also get the whole definition of the `Secret`, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +```bash + kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +``` apiVersion: virtual-secrets.dev/v1alpha1 data: password: dmlydHVhbC1zZWNyZXQ= @@ -168,7 +180,6 @@ metadata: uid: fb756118-3dbf-46b6-ac24-fa5cded478bc secretStoreName: vault type: Opaque -``` We can see that this `Secret`actually behaves identical of the core `Secret`. But the data is not stored in the `etcd` and it is way more secure than using the native `k8s Secret`. @@ -177,15 +188,22 @@ We can see that this `Secret`actually behaves identical of the core `Secret`. Bu We will connect to the Vault by using Vault CLI. Therefore, we need to export the necessary environment variables and port-forward the service. In one terminal port-forward the vault server service, -```shell -$ kubectl port-forward -n demo service/vault 8200 +```bash +kubectl port-forward -n demo service/vault 8200 +``` Forwarding from 127.0.0.1:8200 -> 8200 Forwarding from [::1]:8200 -> 8200 +```bash +export VAULT_ADDR=http://127.0.0.1:8200 +``` + +```bash +export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) +``` + +```bash +vault kv get virtual-secrets.dev/demo/virtual-secret ``` -```shell -$ export VAULT_ADDR=http://127.0.0.1:8200 -$ export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) -$ vault kv get virtual-secrets.dev/demo/virtual-secret ================ Secret Path ================ virtual-secrets.dev/data/demo/virtual-secret @@ -203,7 +221,6 @@ Key Value --- ----- password virtual-secret username default -``` We can see that the secret data is stored in the `virtual-secrets.dev/demo/virtual-secret` path where, - `virtual-secret.dev` is the secret engine name. @@ -218,21 +235,30 @@ data from virtual secrets and uses the `Secrets Store CSI Driver` to mount those Let’s go ahead and install `Secrets Store CSI Driver` and `secrets-store-csi-driver-provider-virtual-secrets` into our cluster, -```shell -$ helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts -$ helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system -$ helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 -$ helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 +```bash +helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts +``` + +```bash +helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +``` + +```bash +helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 +``` + +```bash +helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 ``` If both of them are deployed we should see two new pods in the `kube-system` namespace. -```shell -$ kubectl get pods -n kube-system +```bash +kubectl get pods -n kube-system +``` NAME READY STATUS RESTARTS AGE coredns-695cbbfcb9-r6v7j 1/1 Running 1 (36h ago) 2d18h secrets-store-csi-driver-provider-virtual-secrets-mdw84 1/1 Running 1 (36h ago) 47h -``` The `Secrets Store CSI Driver` uses a custom resource named `SecretProviderClass` to mount the secret. Let’s go ahead and create that, ```yaml @@ -257,10 +283,10 @@ The namespace and the name of SecretProviderClass should be same as the Virtual Let’s create the SecretProviderClass, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml -secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml ``` +secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created ## Get PostgreSQL Server ready @@ -309,28 +335,32 @@ Here, We can now apply the pgpool custom resource, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/pp_vs.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/pgpool/pp_vs.yaml +``` pgpool.kubedb.com/pp-vs created -``` Now, wait until `pp-vs` has status `Ready`. i.e. , -```shell -$ kubectl get pp -n demo +```bash +kubectl get pp -n demo +``` NAME VERSION STATUS AGE pp-vs 4.5.0 Ready 41m -``` Now, lets go ahead and check what secret it is using, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo +```bash +kubectl get secrets.virtual-secrets.dev -n demo +``` NAME TYPE DATA AGE virtual-secret Opaque 2 1d -``` We can see that the pgpool user password is stored in the vault server as named ```virtual-secret``` . Now let’s go ahead and connect to the database using the password to check whether it is working or not. ```bash -$ export PGPASSWORD='virtual-secret' -$ psql --host=localhost --port=9999 --username=postgres postgres +export PGPASSWORD='virtual-secret' +``` + +```bash +psql --host=localhost --port=9999 --username=postgres postgres +``` psql (16.11 (Ubuntu 16.11-0ubuntu0.24.04.1), server 18.2) WARNING: psql major version 16, server major version 18. Some psql features might not work. @@ -343,22 +373,35 @@ postgres=# SELECT datname FROM pg_database; template1 template0 (3 rows) - -``` We can see that we are able to connect to the database and create a database and a table successfully. ## Cleanup To clean up the resources created in this guide, run the following commands: ```bash -$ kubectl delete pp -n demo pp-vs +kubectl delete pp -n demo pp-vs +``` pgpool.kubedb.com "pp-vs" deleted -$ kubectl delete secretproviderclass -n demo virtual-secret -$ kubectl delete ns demo -$ helm uninstall virtual-secrets-server -n kubevault -$ helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system -$ helm uninstall csi-secrets-store -n kube-system + +```bash +kubectl delete secretproviderclass -n demo virtual-secret +``` + +```bash +kubectl delete ns demo +``` + +```bash +helm uninstall virtual-secrets-server -n kubevault +``` + +```bash +helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system +``` + +```bash +helm uninstall csi-secrets-store -n kube-system ``` If you want to uninstall the `KubeVault`, run: ```bash -$ helm uninstall kubevault --namespace kubevault +helm uninstall kubevault --namespace kubevault ``` diff --git a/docs/guides/postgres/autoscaler/compute/cluster.md b/docs/guides/postgres/autoscaler/compute/cluster.md index 0edbb32668..a930b23eec 100644 --- a/docs/guides/postgres/autoscaler/compute/cluster.md +++ b/docs/guides/postgres/autoscaler/compute/cluster.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` to auto-scale compute resources i.e To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Cluster Database Here, we are going to deploy a `Postgres` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `PostgresAutoscaler` to set up autoscaling. @@ -78,22 +78,23 @@ spec: Let's create the `Postgres` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/compute/ha-postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/compute/ha-postgres.yaml ``` +postgres.kubedb.com/ha-postgres created Now, wait until `ha-postgres` has status `Ready`. i.e, ```bash -$ kubectl get postgres -n demo +kubectl get postgres -n demo +``` NAME VERSION STATUS AGE ha-postgres 18.3 Ready 14m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -104,11 +105,11 @@ $ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resourc "memory": "512Mi" } } -``` Let's check the Postgres resources, ```bash -$ kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec.resources' +kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec.resources' +``` { "limits": { "cpu": "200m", @@ -119,7 +120,6 @@ $ kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec. "memory": "512Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the postgres. @@ -180,20 +180,23 @@ Here, Let's create the `PostgresAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/compute/pgas-compute.yaml -postgresautoscaler.autoscaling.kubedb.com/pg-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/compute/pgas-compute.yaml ``` +postgresautoscaler.autoscaling.kubedb.com/pg-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `postgresautoscaler` resource is created successfully, ```bash -$ kubectl get postgresautoscaler -n demo +kubectl get postgresautoscaler -n demo +``` NAME AGE pg-as-compute 5m56s -$ kubectl describe postgresautoscaler pg-as-compute -n demo +```bash +kubectl describe postgresautoscaler pg-as-compute -n demo +``` Name: pg-as-compute Namespace: demo Labels: @@ -346,8 +349,6 @@ Status: Memory: 1Gi Vpa Name: ha-postgres Events: - -``` So, the `postgresautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -357,23 +358,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `postgresopsrequest` in the demo namespace to see if any `postgresopsrequest` object is created. After some time you'll see that a `postgresopsrequest` will be created based on the recommendation. ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-ha-postgres-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-vpa-ha-postgres-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe postgresopsrequest -n demo pgops-vpa-ha-postgres-z43wc8 +kubectl describe postgresopsrequest -n demo pgops-vpa-ha-postgres-z43wc8 +``` Name: pgops-ha-postgres-6xc1kc Namespace: demo Labels: @@ -491,12 +493,12 @@ Events: Normal Starting 5m8s KubeDB Enterprise Operator Resuming Postgres database: demo/ha-postgres Normal Successful 5m8s KubeDB Enterprise Operator Successfully resumed Postgres database: demo/ha-postgres Normal Successful 5m8s KubeDB Enterprise Operator Controller has Successfully scaled the Postgres database: demo/ha-postgres -``` Now, we are going to verify from the Pod, and the Postgres yaml whether the resources of the cluster database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -508,7 +510,9 @@ $ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[].resourc } } -$ kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec.resources' +```bash +kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec.resources' +``` { "limits": { "cpu": "250m", @@ -519,7 +523,6 @@ $ kubectl get postgres -n demo ha-postgres -o json | jq '.spec.podTemplate.spec. "memory": "1Gi" } } -``` The above output verifies that we have successfully autoscaled the resources of the Postgres cluster database. diff --git a/docs/guides/postgres/autoscaler/storage/cluster.md b/docs/guides/postgres/autoscaler/storage/cluster.md index 1b997efa48..f00dfbd4ff 100644 --- a/docs/guides/postgres/autoscaler/storage/cluster.md +++ b/docs/guides/postgres/autoscaler/storage/cluster.md @@ -36,20 +36,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Postg To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -84,30 +84,32 @@ spec: Let's create the `Postgres` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/storage/ha-postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/storage/ha-postgres.yaml ``` +postgres.kubedb.com/ha-postgres created Now, wait until `ha-postgres` has status `Ready`. i.e, ```bash -$ kubectl get postgres -n demo +kubectl get postgres -n demo +``` NAME VERSION STATUS AGE ha-postgres 18.3 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get sts -n demo ha-postgres -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo ha-postgres -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-ha-postgres-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-ha-postgres-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-ha-postgres-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -149,20 +151,23 @@ Here, Let's create the `PostgresAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/storage/pgas-storage.yaml -postgresautoscaler.autoscaling.kubedb.com/pg-as-st created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/autoscaler/storage/pgas-storage.yaml ``` +postgresautoscaler.autoscaling.kubedb.com/pg-as-st created #### Storage Autoscaling is set up successfully Let's check that the `postgresautoscaler` resource is created successfully, ```bash -$ kubectl get postgresautoscaler -n demo +kubectl get postgresautoscaler -n demo +``` NAME AGE pg-as-st 33s -$ kubectl describe postgresautoscaler pg-as-st -n demo +```bash +kubectl describe postgresautoscaler pg-as-st -n demo +``` Name: pg-as-st Namespace: demo Labels: @@ -184,7 +189,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `postgresautoscaler` resource is created successfully. @@ -193,7 +197,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume(`/var/pv/data`) using the following commands: ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` root@ha-postgres-0:/ df -h /var/pv/data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 357M 658M 36% /var/pv/data @@ -204,30 +209,30 @@ root@ha-postgres-0:/ dd if=/dev/zero of=/var/pv/data/file.img bs=500M count=1 root@ha-postgres-0:/ df -h /var/pv/data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/57cd4330-784f-42c1-bf8e-e743241df164 1014M 857M 158M 85% /var/pv/data -``` So, from the above output we can see that the storage usage is 83%, which exceeded the `usageThreshold` 20%. Let's watch the `postgresopsrequest` in the demo namespace to see if any `postgresopsrequest` object is created. After some time you'll see that a `postgresopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-ha-postgres-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-ha-postgres-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe postgresopsrequest -n demo pgops-ha-postgres-xojkua +kubectl describe postgresopsrequest -n demo pgops-ha-postgres-xojkua +``` Name: pgops-ha-postgres-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -290,19 +295,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming Postgres database: demo/ha-postgres Normal Successful 103s KubeDB Enterprise Operator Successfully resumed Postgres database: demo/ha-postgres Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of Postgres: demo/ha-postgres -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the cluster database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get sts -n demo ha-postgres -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get sts -n demo ha-postgres -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-ha-postgres-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-ha-postgres-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-ha-postgres-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the Postgres cluster database. diff --git a/docs/guides/postgres/backup/kubestash/application-level/index.md b/docs/guides/postgres/backup/kubestash/application-level/index.md index 50be0f3c06..1b5a71839b 100644 --- a/docs/guides/postgres/backup/kubestash/application-level/index.md +++ b/docs/guides/postgres/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/backup/kubestash/application-level/examples](/docs/guides/postgres/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -82,33 +82,35 @@ spec: Create the above `PostgreSQL` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/sample-postgres.yaml -postgres.kubedb.com/sample-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/sample-postgres.yaml ``` +postgres.kubedb.com/sample-postgres created KubeDB will deploy a `PostgreSQL` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get pg -n demo sample-postgres +kubectl get pg -n demo sample-postgres +``` NAME VERSION STATUS AGE sample-postgres 18.3 Ready 5m1s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-postgres-auth kubernetes.io/basic-auth 2 5m20s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-postgres +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-postgres +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-postgres ClusterIP 10.96.23.177 5432/TCP,2379/TCP 5m55s sample-postgres-pods ClusterIP None 5432/TCP,2380/TCP,2379/TCP 5m55s sample-postgres-standby ClusterIP 10.96.26.118 5432/TCP 5m55s -``` Here, we have to use service `sample-postgres` and secret `sample-postgres-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/postgres/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -118,15 +120,15 @@ Here, we have to use service `sample-postgres` and secret `sample-postgres-auth` Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-postgres kubedb.com/postgres 18.3 9m30s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-postgres -o yaml +kubectl get appbindings -n demo sample-postgres -o yaml ``` ```yaml @@ -195,18 +197,18 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-postgres" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-postgres" +``` NAME READY STATUS RESTARTS AGE sample-postgres-0 2/2 Running 0 16m sample-postgres-1 2/2 Running 0 13m sample-postgres-2 2/2 Running 0 13m -``` Now, let’s exec into the pod and create a table, ```bash -$ kubectl exec -it -n demo sample-postgres-0 -- sh - +kubectl exec -it -n demo sample-postgres-0 -- sh +``` # login as "postgres" superuser. / $ psql -U postgres psql (18.3) @@ -277,7 +279,6 @@ demo=# \q # exit from the pod / $ exit -``` Now, we are ready to backup the database. @@ -290,13 +291,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -325,9 +332,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -358,9 +365,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -373,11 +380,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create BackupConfiguration:** @@ -430,27 +440,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-postgres-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-postgres-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-postgres-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-postgres-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/postgres` directory. @@ -461,20 +471,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-postgres-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-postgres-backup-frequent-backup-1725449400 BackupConfiguration sample-postgres-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -483,18 +493,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-postgres-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-postgres-repo +kubectl get repository -n demo gcs-postgres-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-postgres-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 gcs-postgres-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -508,7 +518,7 @@ gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 gcs-postgr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -614,9 +624,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -657,18 +667,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-postgres created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE restore-sample-postgres gcs-postgres-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -678,10 +688,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `PostgreSQL` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get postgres -n dev +kubectl get postgres -n dev +``` NAME VERSION STATUS AGE sample-postgres 18.3 Ready 9m46s -``` The output confirms that the `PostgreSQL` database has been successfully created with the same configuration as it had at the time of backup. @@ -693,26 +703,27 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get postgres -n dev sample-postgres +kubectl get postgres -n dev sample-postgres +``` NAME VERSION STATUS AGE sample-postgres 18.3 Ready 9m46s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-postgres" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-postgres" +``` NAME READY STATUS RESTARTS AGE sample-postgres-0 2/2 Running 0 12m sample-postgres-1 2/2 Running 0 12m sample-postgres-2 2/2 Running 0 12m -``` Now, lets exec one of the Pod and verify restored data. ```bash -$ kubectl exec -it -n dev sample-postgres-0 -- /bin/sh +kubectl exec -it -n dev sample-postgres-0 -- /bin/sh +``` # login as "postgres" superuser. / # psql -U postgres psql (11.11) @@ -749,7 +760,6 @@ demo=# \q # exit from the pod / # exit -``` So, from the above output, we can see the `demo` database we had created in the original database `sample-postgres` has been restored successfully. diff --git a/docs/guides/postgres/backup/kubestash/auto-backup/index.md b/docs/guides/postgres/backup/kubestash/auto-backup/index.md index ccd015d2f4..c885b7dac0 100644 --- a/docs/guides/postgres/backup/kubestash/auto-backup/index.md +++ b/docs/guides/postgres/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/backup/kubestash/auto-backup/examples](/docs/guides/postgres/backup/kubestash/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -54,13 +54,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -89,9 +95,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -122,9 +128,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -133,11 +139,14 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created ## Auto-backup with default configurations @@ -199,9 +208,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/postgres-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/postgres-default-backup-blueprint created Now, we are ready to backup our `PostgreSQL` databases using few annotations. @@ -243,24 +252,24 @@ Here, Let's create the `PostgreSQL` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/sample-postgres.yaml -postgres.kubedb.com/sample-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/sample-postgres.yaml ``` +postgres.kubedb.com/sample-postgres created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our PostgreSQL in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-postgres Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-postgres -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-postgres -o yaml ``` ```yaml @@ -367,10 +376,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-postgres-frequent-backup-1725533628 BackupConfiguration appbinding-sample-postgres Succeeded 23s 6m40s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -379,18 +388,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 1.559 KiB Ready 80s 7m32s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-samgres-frequent-backup-1725533628 default-blueprint frequent-backup 2024-09-05T10:53:59Z Delete Succeeded 7m48s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -404,7 +413,7 @@ default-blueprint-appbinding-samgres-frequent-backup-1725533628 default-bluepr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-samgres-frequent-backup-1725533628 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-samgres-frequent-backup-1725533628 -oyaml ``` ```yaml @@ -552,9 +561,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/postgres-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/postgres-customize-backup-blueprint created Now, we are ready to backup our `PostgreSQL` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -599,24 +608,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `PostgreSQL` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/sample-postgres-2.yaml -postgres.kubedb.com/sample-postgres-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/auto-backup/examples/sample-postgres-2.yaml ``` +postgres.kubedb.com/sample-postgres-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our PostgreSQL in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-postgres-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-postgres-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-postgres-2 -o yaml ``` ```yaml @@ -726,10 +735,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-postgres-frequent-backup-1725597000 BackupConfiguration appbinding-sample-postgres Succeeded 58s 112s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -739,18 +748,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-ses-2-frequent-backup-1725597000 customize-blueprint frequent-backup 2024-09-06T04:30:00Z Delete Succeeded 6m19s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -764,7 +773,7 @@ customize-blueprint-appbinding-ses-2-frequent-backup-1725597000 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml ``` ```yaml diff --git a/docs/guides/postgres/backup/kubestash/customization/index.md b/docs/guides/postgres/backup/kubestash/customization/index.md index e3f260206a..f72c1cfbe3 100644 --- a/docs/guides/postgres/backup/kubestash/customization/index.md +++ b/docs/guides/postgres/backup/kubestash/customization/index.md @@ -285,13 +285,13 @@ spec: You can also restore a specific snapshot. At first, list the available snapshot as bellow, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725257849 gcs-postgres-repo frequent-backup 2024-09-02T06:18:01Z Delete Succeeded 15m gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725258000 gcs-postgres-repo frequent-backup 2024-09-02T06:20:00Z Delete Succeeded 13m gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725258300 gcs-postgres-repo frequent-backup 2024-09-02T06:25:00Z Delete Succeeded 8m34s gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725258600 gcs-postgres-repo frequent-backup 2024-09-02T06:30:00Z Delete Succeeded 3m34s -``` The below example shows how you can pass a specific snapshot name in `.spec.dataSource` section. diff --git a/docs/guides/postgres/backup/kubestash/logical/index.md b/docs/guides/postgres/backup/kubestash/logical/index.md index 1087f812f8..9b49c8ed4e 100644 --- a/docs/guides/postgres/backup/kubestash/logical/index.md +++ b/docs/guides/postgres/backup/kubestash/logical/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/backup/kubestash/logical/examples](/docs/guides/postgres/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -85,33 +85,35 @@ spec: Create the above `PostgreSQL` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/sample-postgres.yaml -postgres.kubedb.com/sample-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/sample-postgres.yaml ``` +postgres.kubedb.com/sample-postgres created KubeDB will deploy a `PostgreSQL` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get pg -n demo sample-postgres +kubectl get pg -n demo sample-postgres +``` NAME VERSION STATUS AGE sample-postgres 18.3 Ready 5m1s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-postgres-auth kubernetes.io/basic-auth 2 5m20s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-postgres +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-postgres +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-postgres ClusterIP 10.96.23.177 5432/TCP,2379/TCP 5m55s sample-postgres-pods ClusterIP None 5432/TCP,2380/TCP,2379/TCP 5m55s sample-postgres-standby ClusterIP 10.96.26.118 5432/TCP 5m55s -``` Here, we have to use service `sample-postgres` and secret `sample-postgres-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/postgres/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -121,15 +123,15 @@ Here, we have to use service `sample-postgres` and secret `sample-postgres-auth` Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-postgres kubedb.com/postgres 18.3 9m30s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-postgres -o yaml +kubectl get appbindings -n demo sample-postgres -o yaml ``` ```yaml @@ -199,18 +201,18 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-postgres" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-postgres" +``` NAME READY STATUS RESTARTS AGE sample-postgres-0 2/2 Running 0 16m sample-postgres-1 2/2 Running 0 13m sample-postgres-2 2/2 Running 0 13m -``` Now, let’s exec into the pod and create a table, ```bash -$ kubectl exec -it -n demo sample-postgres-0 -- sh - +kubectl exec -it -n demo sample-postgres-0 -- sh +``` # login as "postgres" superuser. / $ psql -U postgres psql (18.3) @@ -281,7 +283,6 @@ demo=# \q # exit from the pod / $ exit -``` Now, we are ready to backup the database. @@ -294,13 +295,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -329,9 +336,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -362,9 +369,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -377,11 +384,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created Below is the YAML for `BackupConfiguration` CR to backup the `sample-postgres` database that we have deployed earlier, @@ -430,27 +440,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-postgres-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-postgres-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-postgres-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-postgres-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/postgres` directory. @@ -461,20 +471,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-postgres-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-postgres-backup-frequent-backup-1725449400 BackupConfiguration sample-postgres-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -483,18 +493,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-postgres-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-postgres-repo +kubectl get repository -n demo gcs-postgres-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-postgres-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-postgres-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 gcs-postgres-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -508,7 +518,7 @@ gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 gcs-postgr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-postgres-repo-sample-postgres-backup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -626,17 +636,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/restored-postgres.yaml -postgres.kubedb.com/restore-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/restored-postgres.yaml ``` +postgres.kubedb.com/restore-postgres created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get postgres -n demo restored-postgres +kubectl get postgres -n demo restored-postgres +``` NAME VERSION STATUS AGE restored-postgres 8.2.0 Provisioning 61s -``` #### Create RestoreSession: @@ -677,18 +687,18 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f **https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-postgres-restore created +kubectl apply -f **https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-postgres-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-postgres-restore gcs-postgres-repo Succeeded 7s 116s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -699,25 +709,26 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get postgres -n demo restored-postgres +kubectl get postgres -n demo restored-postgres +``` NAME VERSION STATUS AGE restored-postgres 18.3 Ready 6m31s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-postgres" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-postgres" +``` NAME READY STATUS RESTARTS AGE restored-postgres-0 2/2 Running 0 6m7s restored-postgres-1 2/2 Running 0 6m1s restored-postgres-2 2/2 Running 0 5m55s -``` Now, lets exec one of the `Pod` and verify restored data. ```bash -$ kubectl exec -it -n demo restored-postgres-0 -- /bin/sh +kubectl exec -it -n demo restored-postgres-0 -- /bin/sh +``` # login as "postgres" superuser. / # psql -U postgres psql (11.11) @@ -763,7 +774,6 @@ demo=# \q # exit from the pod / # exit -``` So, from the above output, we can see the `demo` database we had created in the original database `sample-postgres` has been restored in the `restored-postgres` database. diff --git a/docs/guides/postgres/backup/stash/standalone/index.md b/docs/guides/postgres/backup/stash/standalone/index.md index 1fa3150c7c..ea98e751a1 100644 --- a/docs/guides/postgres/backup/stash/standalone/index.md +++ b/docs/guides/postgres/backup/stash/standalone/index.md @@ -35,9 +35,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create the `demo` namespace if you haven't created it already. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup PostgreSQL @@ -73,9 +73,9 @@ spec: Create the above `Postgres` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/postgres.yaml -postgres.kubedb.com/sample-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/postgres.yaml ``` +postgres.kubedb.com/sample-postgres created KubeDB will deploy a PostgreSQL database according to the above specification. It will also create the necessary secrets and services to access the database. @@ -244,15 +244,24 @@ We are going to store our backed-up data into a GCS bucket. At first, we need to Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -275,9 +284,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database to our desired backend. @@ -320,19 +329,19 @@ Here, Let's create the `BackupConfiguration` object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-postgres-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-postgres-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-postgres-backup postgres-backup-11.9 */5 * * * * Ready 11s -``` **Verify CronJob:** @@ -443,9 +452,9 @@ Notice the `init` section. Here, we have specified `waitForInitialRestore: true` Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/restored-postgres.yaml -postgres.kubedb.com/restored-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/restored-postgres.yaml ``` +postgres.kubedb.com/restored-postgres created This time, the database will get stuck in the `Provisioning` state because we haven't restored the data yet. @@ -512,9 +521,9 @@ Here, Let's create the `RestoreSession` crd we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-postgres-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/backup/stash/standalone/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-postgres-restore created Once, you have created the `RestoreSession` object, Stash will create a job to restore the database. We can watch the `RestoreSession` phase to check whether the restore process has succeeded or not. diff --git a/docs/guides/postgres/cli/cli.md b/docs/guides/postgres/cli/cli.md index ecb1825057..71c575378b 100644 --- a/docs/guides/postgres/cli/cli.md +++ b/docs/guides/postgres/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a Postgres object as specified in `postgres.yaml`. ```bash -$ kubectl create -f postgres-demo.yaml -postgres "postgres-demo" created +kubectl create -f postgres-demo.yaml ``` +postgres "postgres-demo" created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f postgres-demo.yaml --namespace=kube-system -postgres "postgres-demo" created +kubectl create -f postgres-demo.yaml --namespace=kube-system ``` +postgres "postgres-demo" created `kubectl create` command also considers `stdin` as input. @@ -45,13 +45,13 @@ cat postgres-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all Postgres objects in `default` namespace, run the following command: ```bash -$ kubectl get postgres +kubectl get postgres +``` NAME VERSION STATUS AGE postgres-demo 10.2-v5 Running 13m postgres-dev 10.2-v5 Running 11m postgres-prod 10.2-v5 Running 11m postgres-qa 10.2-v5 Running 10m -``` To get YAML of an object, use `--output=yaml` flag. @@ -80,8 +80,8 @@ kubectl get postgres postgres-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get all -o wide - +kubectl get all -o wide +``` NAME VERSION STATUS AGE es/elasticsearch-demo 2.3.1 Running 17m @@ -95,7 +95,6 @@ NAME DATABASE BUCKET snap/postgres-demo-20170605-073557 pg/postgres-demo gs:bucket-name Succeeded 9m snap/snapshot-20171212-114700 pg/postgres-demo gs:bucket-name Succeeded 1h snap/snapshot-xyz es/elasticsearch-demo local:/directory Succeeded 5m -``` Flag `--output=wide` is used to print additional information. @@ -108,26 +107,27 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Snapshots with their corresponding labels. ```bash -$ kubectl get snap --show-labels +kubectl get snap --show-labels +``` NAME DATABASE STATUS AGE LABELS postgres-demo-20170605-073557 pg/postgres-demo Succeeded 11m app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=postgres-demo snapshot-20171212-114700 pg/postgres-demo Succeeded 1h app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=postgres-demo snapshot-xyz es/elasticsearch-demo Succeeded 6m app.kubernetes.io/name=elasticsearches.kubedb.com,app.kubernetes.io/instance=elasticsearch-demo -``` You can also filter list using `--selector` flag. ```bash -$ kubectl get snap --selector='app.kubernetes.io/name=postgreses.kubedb.com' --show-labels +kubectl get snap --selector='app.kubernetes.io/name=postgreses.kubedb.com' --show-labels +``` NAME DATABASE STATUS AGE LABELS postgres-demo-20171212-073557 pg/postgres-demo Succeeded 14m app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=postgres-demo snapshot-20171212-114700 pg/postgres-demo Succeeded 2h app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=postgres-demo -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` postgres/postgres-demo postgres/postgres-dev postgres/postgres-prod @@ -135,14 +135,14 @@ postgres/postgres-qa snapshot/postgres-demo-20170605-073557 snapshot/snapshot-20170505-114700 snapshot/snapshot-xyz -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe PostgreSQL database `postgres-demo` with relevant information. ```bash -$ kubectl dba describe pg postgres-demo +kubectl dba describe pg postgres-demo +``` Name: postgres-demo Namespace: default StartTimestamp: Tue, 12 Dec 2017 11:46:16 +0600 @@ -191,7 +191,6 @@ Events: 5s 5s Postgres operator Normal SuccessfulCreate Successfully created Postgres 55s 55s Postgres operator Normal SuccessfulValidate Successfully validate Postgres 55s 55s Postgres operator Normal Creating Creating Kubernetes objects -``` `kubectl dba describe` command provides following basic information about a database. @@ -258,16 +257,16 @@ For DormantDatabase, _spec.origin_ can't be edited using `kubectl edit` `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a Postgres `postgres-dev` in default namespace ```bash -$ kubectl delete postgres postgres-dev -postgres "postgres-dev" deleted +kubectl delete postgres postgres-dev ``` +postgres "postgres-dev" deleted You can also use YAML files to delete objects. The following command will delete a postgres using the type and name specified in `postgres.yaml`. ```bash -$ kubectl delete -f postgres.yaml -postgres "postgres-dev" deleted +kubectl delete -f postgres.yaml ``` +postgres "postgres-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -285,16 +284,23 @@ kubectl delete postgres -l postgres.app.kubernetes.io/instance=postgres-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # Create objects -$ kubectl create -f +```bash +kubectl create -f +``` # List objects -$ kubectl get postgres -$ kubectl get postgres.kubedb.com +```bash +kubectl get postgres +``` + +```bash +kubectl get postgres.kubedb.com +``` # Delete objects -$ kubectl delete postgres +```bash +kubectl delete postgres ``` ## Next Steps diff --git a/docs/guides/postgres/clustering/arbiter.md b/docs/guides/postgres/clustering/arbiter.md index 4b0b6147bc..0d765a47cd 100644 --- a/docs/guides/postgres/clustering/arbiter.md +++ b/docs/guides/postgres/clustering/arbiter.md @@ -36,9 +36,9 @@ So storage space of 2Gi is more than enough for most of the clusters. To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Let's apply the following yaml. diff --git a/docs/guides/postgres/clustering/streaming_replication.md b/docs/guides/postgres/clustering/streaming_replication.md index 436becb0d7..b7efc49a28 100644 --- a/docs/guides/postgres/clustering/streaming_replication.md +++ b/docs/guides/postgres/clustering/streaming_replication.md @@ -26,9 +26,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -98,19 +98,19 @@ Here, Now create this Postgres object with Streaming Replication support ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/clustering/ha-postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/clustering/ha-postgres.yaml ``` +postgres.kubedb.com/ha-postgres created KubeDB operator creates three Pod as PostgreSQL server. ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=ha-postgres" --show-labels +kubectl get pods -n demo --selector="app.kubernetes.io/instance=ha-postgres" --show-labels +``` NAME READY STATUS RESTARTS AGE LABELS ha-postgres-0 1/1 Running 0 20s controller-revision-hash=ha-postgres-6b7998ccfd,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=primary,petset.kubernetes.io/pod-name=ha-postgres-0 ha-postgres-1 1/1 Running 0 16s controller-revision-hash=ha-postgres-6b7998ccfd,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=ha-postgres-1 ha-postgres-2 1/1 Running 0 10s controller-revision-hash=ha-postgres-6b7998ccfd,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=ha-postgres-2 -``` Here, @@ -120,20 +120,20 @@ Here, Services for Postgres `ha-postgres` are created. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=ha-postgres" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=ha-postgres" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ha-postgres ClusterIP 10.102.19.49 5432/TCP,2379/TCP 4m ha-postgres-pods ClusterIP None 5432/TCP,2380/TCP,2379/TCP,2384/TCP 4m ha-postgres-standby ClusterIP 10.97.36.117 5432/TCP 4m -``` ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=ha-postgres" -o=custom-columns=NAME:.metadata.name,SELECTOR:.spec.selector +kubectl get svc -n demo --selector="app.kubernetes.io/instance=ha-postgres" -o=custom-columns=NAME:.metadata.name,SELECTOR:.spec.selector +``` NAME SELECTOR ha-postgres map[app.kubernetes.io/name:postgreses.kubedb.com app.kubernetes.io/instance:ha-postgres kubedb.com/role:primary] ha-postgres-pods map[app.kubernetes.io/name:postgreses.kubedb.com app.kubernetes.io/instance:ha-postgres] ha-postgres-standby map[app.kubernetes.io/name:postgreses.kubedb.com app.kubernetes.io/instance:ha-postgres kubedb.com/role:standby] -``` Here, @@ -155,16 +155,16 @@ Now connect to this *primary* server Pod `ha-postgres-0` using pgAdmin installed - Username: Run following command to get *username*, ```bash - $ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.username}' | base64 -d - postgres + kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.username}' | base64 -d ``` + postgres - Password: Run the following command to get *password*, ```bash - $ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.password}' | base64 -d - MHRrOcuyddfh3YpU + kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + MHRrOcuyddfh3YpU You can check `pg_stat_replication` information to know who is currently streaming from *primary*. @@ -245,12 +245,12 @@ kubectl delete pod -n demo ha-postgres-0 ``` ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=ha-postgres" --show-labels +kubectl get pods -n demo --selector="app.kubernetes.io/instance=ha-postgres" --show-labels +``` NAME READY STATUS RESTARTS AGE LABELS ha-postgres-0 1/1 Running 0 10s controller-revision-hash=ha-postgres-b8b4b5fc4,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=ha-postgres-0 ha-postgres-1 1/1 Running 0 52m controller-revision-hash=ha-postgres-b8b4b5fc4,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=primary,petset.kubernetes.io/pod-name=ha-postgres-1 ha-postgres-2 1/1 Running 0 51m controller-revision-hash=ha-postgres-b8b4b5fc4,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=ha-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=ha-postgres-2 -``` Here, @@ -322,19 +322,19 @@ Here, Now create this Postgres object ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/clustering/hot-postgres.yaml -postgres "hot-postgres" created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/clustering/hot-postgres.yaml ``` +postgres "hot-postgres" created KubeDB operator creates three Pod as PostgreSQL server. ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=hot-postgres" --show-labels +kubectl get pods -n demo --selector="app.kubernetes.io/instance=hot-postgres" --show-labels +``` NAME READY STATUS RESTARTS AGE LABELS hot-postgres-0 1/1 Running 0 1m controller-revision-hash=hot-postgres-6c48cfb5bb,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=hot-postgres,kubedb.com/role=primary,petset.kubernetes.io/pod-name=hot-postgres-0 hot-postgres-1 1/1 Running 0 1m controller-revision-hash=hot-postgres-6c48cfb5bb,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=hot-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=hot-postgres-1 hot-postgres-2 1/1 Running 0 48s controller-revision-hash=hot-postgres-6c48cfb5bb,app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=hot-postgres,kubedb.com/role=standby,petset.kubernetes.io/pod-name=hot-postgres-2 -``` Here, @@ -357,16 +357,16 @@ Now connect to one of our *hot standby* servers Pod `hot-postgres-2` using pgAdm - Username: Run following command to get *username*, ```bash - $ kubectl get secrets -n demo hot-postgres-auth -o jsonpath='{.data.username}' | base64 -d - postgres + kubectl get secrets -n demo hot-postgres-auth -o jsonpath='{.data.username}' | base64 -d ``` + postgres - Password: Run the following command to get *password*, ```bash - $ kubectl get secrets -n demo hot-postgres-auth -o jsonpath='{.data.password}' | base64 -d - ZZgjjQMUdKJYy1W9 + kubectl get secrets -n demo hot-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + ZZgjjQMUdKJYy1W9 Try to create a database (write operation) @@ -391,10 +391,15 @@ So, you can see here that you can connect to *hot standby* and it only accepts r To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo pg/ha-postgres pg/hot-postgres -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo pg/ha-postgres pg/hot-postgres +kubectl patch -n demo pg/ha-postgres pg/hot-postgres -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete ns demo +```bash +kubectl delete -n demo pg/ha-postgres pg/hot-postgres +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/postgres/concepts/postgres-gitops.md b/docs/guides/postgres/concepts/postgres-gitops.md index 2f4bccf4b3..181c54dee9 100644 --- a/docs/guides/postgres/concepts/postgres-gitops.md +++ b/docs/guides/postgres/concepts/postgres-gitops.md @@ -214,14 +214,15 @@ If you want to use an existing or custom secret, please specify that when creati Example: ```bash -$ kubectl create secret generic p1-auth -n demo \ +kubectl create secret generic p1-auth -n demo \ --from-literal=POSTGRES_USER=not@user \ --from-literal=POSTGRES_PASSWORD=not@secret -secret "p1-auth" created ``` +secret "p1-auth" created ```bash -$ kubectl get secret -n demo p1-auth -o yaml +kubectl get secret -n demo p1-auth -o yaml +``` apiVersion: v1 data: POSTGRES_PASSWORD: bm90QHNlY3JldA== @@ -235,7 +236,6 @@ metadata: selfLink: /api/v1/namespaces/demo/secrets/p1-auth uid: 15b3e8a1-af6c-11e8-996d-0800270d7bae type: Opaque -``` > Updating this field create a `RotateAuth` OpsRequest by GitOps operator. diff --git a/docs/guides/postgres/concepts/postgres.md b/docs/guides/postgres/concepts/postgres.md index 0559fd5446..6ee62b5add 100644 --- a/docs/guides/postgres/concepts/postgres.md +++ b/docs/guides/postgres/concepts/postgres.md @@ -116,7 +116,8 @@ spec: `spec.version` is a required field that specifies the name of the [PostgresVersion](/docs/guides/postgres/concepts/catalog.md) crd where the docker images are specified. Currently, when you install KubeDB, it creates the following `PostgresVersion` resources, ```bash -$ kubectl get pgversion +kubectl get pgversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 10.2 10.2 kubedb/postgres:10.2 true 44m 10.2-v1 10.2 kubedb/postgres:10.2-v2 true 44m @@ -146,7 +147,6 @@ NAME VERSION DB_IMAGE DEPRECATED AGE 9.6.7-v3 9.6.7 kubedb/postgres:9.6.7-v4 44m 9.6.7-v4 9.6.7 kubedb/postgres:9.6.7-v5 44m 9.6.7-v5 9.6.7 kubedb/postgres:9.6.7-v6 44m -``` ### spec.replicas `spec.replicas` specifies the total number of primary and standby nodes in Postgres database cluster configuration. One pod is selected as Primary and others act as standby replicas. KubeDB uses `PodDisruptionBudget` to ensure that majority of the replicas are available during [voluntary disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#voluntary-and-involuntary-disruptions). @@ -180,14 +180,15 @@ If you want to use an existing or custom secret, please specify that when creati Example: ```bash -$ kubectl create secret generic p1-auth -n demo \ +kubectl create secret generic p1-auth -n demo \ --from-literal=POSTGRES_USER=not@user \ --from-literal=POSTGRES_PASSWORD=not@secret -secret "p1-auth" created ``` +secret "p1-auth" created ```bash -$ kubectl get secret -n demo p1-auth -o yaml +kubectl get secret -n demo p1-auth -o yaml +``` apiVersion: v1 data: POSTGRES_PASSWORD: bm90QHNlY3JldA== @@ -201,7 +202,6 @@ metadata: selfLink: /api/v1/namespaces/demo/secrets/p1-auth uid: 15b3e8a1-af6c-11e8-996d-0800270d7bae type: Opaque -``` ### spec.storageType diff --git a/docs/guides/postgres/configuration/pgtune.md b/docs/guides/postgres/configuration/pgtune.md index 96ec48714e..deee4e1e0d 100644 --- a/docs/guides/postgres/configuration/pgtune.md +++ b/docs/guides/postgres/configuration/pgtune.md @@ -27,9 +27,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -116,38 +116,41 @@ spec: Let's create it: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/configuration/pg-tuning.yaml -postgres.kubedb.com/pg-ha-tuning created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/configuration/pg-tuning.yaml ``` +postgres.kubedb.com/pg-ha-tuning created Now wait for the database to become `Ready`: ```bash -$ kubectl get pg -n demo pg-ha-tuning +kubectl get pg -n demo pg-ha-tuning +``` NAME VERSION STATUS AGE pg-ha-tuning 18.3 Ready 69s -$ kubectl get pods -n demo -l app.kubernetes.io/instance=pg-ha-tuning +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=pg-ha-tuning +``` NAME READY STATUS RESTARTS AGE pg-ha-tuning-0 2/2 Running 0 63s pg-ha-tuning-1 2/2 Running 0 57s pg-ha-tuning-2 2/2 Running 0 51s -``` ## See the Generated Configuration KubeDB stores the generated configuration in a Secret owned by the database. The secret name has a random suffix, so it will be different in your cluster. You can find it by listing the secrets for this database: ```bash -$ kubectl get secret -n demo | grep pg-ha-tuning +kubectl get secret -n demo | grep pg-ha-tuning +``` pg-ha-tuning-auth kubernetes.io/basic-auth 2 52s pg-ha-tuning-eba1da Opaque 1 52s -``` The `Opaque` secret (`pg-ha-tuning-eba1da` here) holds the tuned configuration under the `pgtune.conf` key. Let's print it: ```bash -$ kubectl get secret -n demo pg-ha-tuning-eba1da -o jsonpath='{.data.pgtune\.conf}' | base64 -d +kubectl get secret -n demo pg-ha-tuning-eba1da -o jsonpath='{.data.pgtune\.conf}' | base64 -d +``` # Tuned by KubeDB # https://kubedb.com @@ -172,7 +175,6 @@ work_mem = 2520kB huge_pages = off min_wal_size = 1GB max_wal_size = 4GB -``` The comment block at the top shows exactly what inputs KubeDB used (database type, total memory, CPUs, connections and storage), and the values below are calculated from them. @@ -181,7 +183,8 @@ The comment block at the top shows exactly what inputs KubeDB used (database typ Finally, let's confirm the running database actually uses these values. We'll `exec` into a pod and use the [SHOW](https://www.postgresql.org/docs/current/sql-show.html) command: ```bash -$ kubectl exec -it -n demo pg-ha-tuning-0 -c postgres -- psql -U postgres -c "SHOW shared_buffers; SHOW max_connections;" +kubectl exec -it -n demo pg-ha-tuning-0 -c postgres -- psql -U postgres -c "SHOW shared_buffers; SHOW max_connections;" +``` shared_buffers ---------------- 512MB @@ -191,7 +194,6 @@ $ kubectl exec -it -n demo pg-ha-tuning-0 -c postgres -- psql -U postgres -c "SH ----------------- 200 (1 row) -``` The values match what KubeDB generated. 🎉 diff --git a/docs/guides/postgres/configuration/using-config-file.md b/docs/guides/postgres/configuration/using-config-file.md index bd900061cd..4ce2d68903 100644 --- a/docs/guides/postgres/configuration/using-config-file.md +++ b/docs/guides/postgres/configuration/using-config-file.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -54,9 +54,9 @@ shared_buffers=256MB Now, create a Secret with this configuration file. ```bash -$ kubectl create secret generic -n demo pg-configuration --from-literal=user.conf="$(curl -fsSL https://raw.githubusercontent.com/kubedb/docs/{{< param "info.version" >}}/docs/examples/postgres/custom-config/user.conf)" -secret/pg-configuration created +kubectl create secret generic -n demo pg-configuration --from-literal=user.conf="$(curl -fsSL https://raw.githubusercontent.com/kubedb/docs/{{< param "info.version" >}}/docs/examples/postgres/custom-config/user.conf)" ``` +secret/pg-configuration created Verify the Secret has the configuration file. @@ -80,9 +80,9 @@ metadata: Now, create Postgres crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-config/pg-custom-config.yaml -postgres.kubedb.com/custom-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-config/pg-custom-config.yaml ``` +postgres.kubedb.com/custom-postgres created Below is the YAML for the Postgres crd we just created. @@ -110,15 +110,16 @@ Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, serv Check that the petset's pod is running ```bash -$ kubectl get pod -n demo custom-postgres-0 +kubectl get pod -n demo custom-postgres-0 +``` NAME READY STATUS RESTARTS AGE custom-postgres-0 1/1 Running 0 14m -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo custom-postgres-0 +kubectl logs -f -n demo custom-postgres-0 +``` I0705 12:05:51.697190 1 logs.go:19] FLAG: --alsologtostderr="false" I0705 12:05:51.717485 1 logs.go:19] FLAG: --enable-analytics="true" I0705 12:05:51.717543 1 logs.go:19] FLAG: --help="false" @@ -145,14 +146,14 @@ LOG: database system was shut down at 2018-07-05 12:07:51 UTC LOG: MultiXact member wraparound protections are now enabled LOG: database system is ready to accept connections LOG: autovacuum launcher started -``` Once we see `LOG: database system is ready to accept connections` in the log, the database is ready. Now, we will check if the database has started with the custom configuration we have provided. We will `exec` into the pod and use [SHOW](https://www.postgresql.org/docs/9.6/static/sql-show.html) query to check the run-time parameters. -```bash - $ kubectl exec -it -n demo custom-postgres-0 sh + ```bash + kubectl exec -it -n demo custom-postgres-0 sh + ``` / # ## login as user "postgres". no authentication required from inside the pod because it is using trust authentication local connection. / # psql -U postgres @@ -177,8 +178,6 @@ postgres=# SHOW shared_buffers; postgres=# \q / # -``` - You can also connect to this database from pgAdmin and use following SQL query to check these configuration. ```sql diff --git a/docs/guides/postgres/custom-rbac/using-custom-rbac.md b/docs/guides/postgres/custom-rbac/using-custom-rbac.md index b12a5d384d..70d271cbfc 100644 --- a/docs/guides/postgres/custom-rbac/using-custom-rbac.md +++ b/docs/guides/postgres/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,9 +46,9 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Account` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. @@ -70,9 +70,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the PostgreSQl Database named `quick-postgres`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -128,10 +128,9 @@ Please note that resourceNames `quick-postgres` and `quick-postgres-leader-lock` Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. @@ -160,9 +159,9 @@ subjects: Now, create a Postgres CRD specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-db.yaml -postgres.kubedb.com/quick-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-db.yaml ``` +postgres.kubedb.com/quick-postgres created Below is the YAML for the Postgres crd we just created. @@ -196,15 +195,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo quick-postgres-0 +kubectl get pod -n demo quick-postgres-0 +``` NAME READY STATUS RESTARTS AGE quick-postgres-0 1/1 Running 0 14m -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo quick-postgres-0 +kubectl logs -f -n demo quick-postgres-0 +``` I0705 12:05:51.697190 1 logs.go:19] FLAG: --alsologtostderr="false" I0705 12:05:51.717485 1 logs.go:19] FLAG: --enable-analytics="true" I0705 12:05:51.717543 1 logs.go:19] FLAG: --help="false" @@ -231,7 +231,6 @@ LOG: database system was shut down at 2018-07-05 12:07:51 UTC LOG: MultiXact member wraparound protections are now enabled LOG: database system is ready to accept connections LOG: autovacuum launcher started -``` Once we see `LOG: database system is ready to accept connections` in the log, the database is ready. @@ -242,9 +241,9 @@ An existing service account can be reused in another Postgres Database. However, For example, to reuse `my-custom-serviceaccount` in a new Database `minute-postgres`, create a role that has all the necessary access permissions for this PostgreSQl Database. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-role-two.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-role-two.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -277,17 +276,16 @@ rules: Now create a `RoleBinding` to bind `my-custom-role-two` with the already created `my-custom-serviceaccount`. ```bash -$ kubectl create rolebinding my-custom-rolebinding-two --role=my-custom-role-two --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding-two created - +kubectl create rolebinding my-custom-rolebinding-two --role=my-custom-role-two --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding-two created Now, create Postgres CRD `minute-postgres` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-db-two.yaml -postgres.kubedb.com/quick-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/custom-rbac/pg-custom-db-two.yaml ``` +postgres.kubedb.com/quick-postgres created Below is the YAML for the Postgres crd we just created. @@ -321,15 +319,16 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo minute-postgres-0 +kubectl get pod -n demo minute-postgres-0 +``` NAME READY STATUS RESTARTS AGE minute-postgres-0 1/1 Running 0 14m -``` Check the pod's log to see if the database is ready ```bash -$ kubectl logs -f -n demo minute-postgres-0 +kubectl logs -f -n demo minute-postgres-0 +``` I0705 12:05:51.697190 1 logs.go:19] FLAG: --alsologtostderr="false" I0705 12:05:51.717485 1 logs.go:19] FLAG: --enable-analytics="true" I0705 12:05:51.717543 1 logs.go:19] FLAG: --help="false" @@ -356,7 +355,6 @@ LOG: database system was shut down at 2018-07-05 12:07:51 UTC LOG: MultiXact member wraparound protections are now enabled LOG: database system is ready to accept connections LOG: autovacuum launcher started -``` `LOG: database system is ready to accept connections` in the log signifies that the database is running successfully. diff --git a/docs/guides/postgres/distributed/overview/index.md b/docs/guides/postgres/distributed/overview/index.md index 7ee47d1e06..3f83bc524f 100644 --- a/docs/guides/postgres/distributed/overview/index.md +++ b/docs/guides/postgres/distributed/overview/index.md @@ -51,7 +51,7 @@ Follow these steps to deploy a distributed Postgres cluster across multiple Kube Ensure your `KUBECONFIG` is set up to switch between clusters. This guide uses two clusters: `demo-controller` (hub and spoke) and `demo-worker` (spoke). ```bash -$ kubectl config get-contexts +kubectl config get-contexts ``` **Output:** @@ -67,8 +67,11 @@ CURRENT NAME CLUSTER AUTHINFO NAMESPACE On the `demo-controller` cluster, initialize the OCM hub: ```bash -$ kubectl config use-context demo-controller -$ clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true +kubectl config use-context demo-controller +``` + +```bash +clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true ``` #### 3. Verify Hub Deployment @@ -76,7 +79,7 @@ $ clusteradm init --wait --feature-gates=ManifestWorkReplicaSet=true Check the pods in the `open-cluster-management-hub` namespace to ensure all components are running: ```bash -$ kubectl get pods -n open-cluster-management-hub +kubectl get pods -n open-cluster-management-hub ``` **Output:** @@ -98,7 +101,7 @@ All pods should be in the `Running` state with `1/1` readiness and no restarts, Obtain the join token from the hub cluster: ```bash -$ clusteradm get token +clusteradm get token ``` **Output:** @@ -112,8 +115,11 @@ clusteradm join --hub-token --hub-apiserver https:/ On the `demo-worker` cluster, join it to the hub. Include the `RawFeedbackJsonString` feature gate for resource feedback: ```bash -$ kubectl config use-context demo-worker -$ clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-worker --feature-gates=RawFeedbackJsonString=true +kubectl config use-context demo-worker +``` + +```bash +clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-worker --feature-gates=RawFeedbackJsonString=true ``` #### 5. Accept Spoke Cluster @@ -121,8 +127,11 @@ $ clusteradm join --hub-token --hub-apiserver https On the `demo-controller` cluster, accept the `demo-worker` cluster: ```bash -$ kubectl config use-context demo-controller -$ clusteradm accept --clusters demo-worker +kubectl config use-context demo-controller +``` + +```bash +clusteradm accept --clusters demo-worker ``` > **Note:** It may take a few attempts (e.g., retry every 10 seconds) if the cluster is not immediately available. @@ -141,7 +150,7 @@ $ clusteradm accept --clusters demo-worker Confirm that a namespace for `demo-worker` was created on the hub cluster: ```bash -$ kubectl get ns +kubectl get ns ``` **Output:** @@ -162,15 +171,21 @@ open-cluster-management-hub Active 5m32s Repeat the join and accept process for `demo-controller` so it can also act as a spoke cluster: ```bash -$ kubectl config use-context demo-controller -$ clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-controller --feature-gates=RawFeedbackJsonString=true -$ clusteradm accept --clusters demo-controller +kubectl config use-context demo-controller +``` + +```bash +clusteradm join --hub-token --hub-apiserver https://:6443 --cluster-name demo-controller --feature-gates=RawFeedbackJsonString=true +``` + +```bash +clusteradm accept --clusters demo-controller ``` Verify the namespace for `demo-controller`: ```bash -$ kubectl get ns +kubectl get ns ``` **Output:** @@ -193,18 +208,24 @@ open-cluster-management-hub Active 10m After registration, use these commands to confirm which cluster is the hub and which are spokes: -```bash # Hub: lists all registered spoke clusters -$ kubectl get managedclusters +```bash +kubectl get managedclusters +``` # Spoke: shows this cluster's registered name -$ kubectl get klusterlet klusterlet -o jsonpath='{.spec.clusterName}' +```bash +kubectl get klusterlet klusterlet -o jsonpath='{.spec.clusterName}' +``` # Hub components run only on the hub cluster -$ kubectl get pods -n open-cluster-management-hub +```bash +kubectl get pods -n open-cluster-management-hub +``` # Spoke agent runs on every spoke cluster -$ kubectl get pods -n open-cluster-management-agent +```bash +kubectl get pods -n open-cluster-management-agent ``` ### Step 2: Configure OCM WorkConfiguration @@ -216,7 +237,8 @@ Run this on **every spoke cluster** (`demo-controller` and `demo-worker`). This > **Why this matters:** KubeDB uses OCM's ManifestWork feedback mechanism to watch the status of Postgres pods on remote spoke clusters. Without `RawFeedbackJsonString`, the KubeDB provisioner on the hub never receives pod status updates from spokes and the distributed Postgres CR will stay in a non-Ready state indefinitely. The rate limits prevent the klusterlet agent from being API-throttled during initial cluster formation. ```bash -$ kubectl patch klusterlet klusterlet --type=merge -p '{ +kubectl patch klusterlet klusterlet --type=merge -p '{ +``` "spec": { "workConfiguration": { "featureGates": [{"feature": "RawFeedbackJsonString", "mode": "Enable"}], @@ -227,12 +249,11 @@ $ kubectl patch klusterlet klusterlet --type=merge -p '{ } } }' -``` Verify the configuration: ```bash -$ kubectl get klusterlet klusterlet -oyaml +kubectl get klusterlet klusterlet -oyaml ``` **Sample Output (abridged):** @@ -263,7 +284,7 @@ KubeSlice enables pod-to-pod communication across clusters. Install the KubeSlic On `demo-controller`, get the hub API server address first: ```bash -$ kubectl cluster-info | grep 'Kubernetes control plane' +kubectl cluster-info | grep 'Kubernetes control plane' ``` Use the IP and port from that output as the `endpoint` value. Create a `controller.yaml` file: @@ -280,7 +301,7 @@ kubeslice: Deploy the controller using Helm: ```bash -$ helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-controller \ +helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-controller \ --version v2026.1.15 \ -f controller.yaml \ --namespace kubeslice-controller \ @@ -292,7 +313,7 @@ $ helm upgrade -i kubeslice-controller oci://ghcr.io/appscode-charts/kubeslice-c Verify the installation: ```bash -$ kubectl get pods -n kubeslice-controller +kubectl get pods -n kubeslice-controller ``` **Output:** @@ -321,13 +342,13 @@ spec: Apply the project: ```bash -$ kubectl apply -f project.yaml +kubectl apply -f project.yaml ``` Verify: ```bash -$ kubectl get project -n kubeslice-controller +kubectl get project -n kubeslice-controller ``` **Output:** @@ -340,7 +361,7 @@ demo-distributed-postgres 31s Check service accounts: ```bash -$ kubectl get sa -n kubeslice-demo-distributed-postgres +kubectl get sa -n kubeslice-demo-distributed-postgres ``` **Output:** @@ -358,16 +379,25 @@ Assign the `kubeslice.io/node-type=gateway` label to the node where the worker o On `demo-controller`: ```bash -$ kubectl get nodes -$ kubectl label node kubeslice.io/node-type=gateway +kubectl get nodes +``` + +```bash +kubectl label node kubeslice.io/node-type=gateway ``` On `demo-worker`: ```bash -$ kubectl config use-context demo-worker -$ kubectl get nodes -$ kubectl label node kubeslice.io/node-type=gateway +kubectl config use-context demo-worker +``` + +```bash +kubectl get nodes +``` + +```bash +kubectl label node kubeslice.io/node-type=gateway ``` #### 4. Register Clusters with KubeSlice @@ -375,7 +405,7 @@ $ kubectl label node kubeslice.io/node-type=gateway Identify the network interface for each cluster by running the following command **on the gateway node of each cluster**: ```bash -$ ip route get 8.8.8.8 | awk '{ print $5 }' +ip route get 8.8.8.8 | awk '{ print $5 }' ``` **Output (example):** @@ -443,13 +473,13 @@ spec: Apply on `demo-controller`: ```bash -$ kubectl apply -f registration.yaml +kubectl apply -f registration.yaml ``` Verify OCM is deploying the KubeSlice worker manifests to each cluster: ```bash -$ kubectl get managedclusteraddon -A +kubectl get managedclusteraddon -A ``` **Output:** @@ -462,9 +492,9 @@ demo-worker kubeslice Unknown True `PROGRESSING: True` means OCM is actively deploying. Wait until `kubeslice-operator` shows `2/2 Running` on both clusters before proceeding: -```bash # Run on each spoke cluster -$ kubectl get pods -n kubeslice-system --watch +```bash +kubectl get pods -n kubeslice-system --watch ``` **Expected output (after KubeSlice worker is fully deployed):** @@ -531,7 +561,7 @@ spec: Apply the `SliceConfig`: ```bash -$ kubectl apply -f sliceconfig.yaml +kubectl apply -f sliceconfig.yaml ``` After the SliceConfig is applied, a `vl3-slice-router` pod will appear in `kubeslice-system` on each cluster, indicating the slice VPN tunnel is being established. @@ -553,7 +583,7 @@ Update CoreDNS to forward `*.slice.local` traffic to the KubeSlice DNS service. Get the KubeSlice DNS service IP address on each cluster: ```bash -$ kubectl get svc -n kubeslice-system -owide -l 'app=kubeslice-dns' +kubectl get svc -n kubeslice-system -owide -l 'app=kubeslice-dns' ``` **Output:** @@ -576,7 +606,7 @@ slice.local:53 { Example of the full CoreDNS ConfigMap after editing: ```bash -$ kubectl get cm -n kube-system coredns -oyaml +kubectl get cm -n kube-system coredns -oyaml ``` **Output:** @@ -623,7 +653,7 @@ metadata: After editing the ConfigMap, restart CoreDNS to apply the change: ```bash -$ kubectl rollout restart deploy/coredns -n kube-system +kubectl rollout restart deploy/coredns -n kube-system ``` Repeat the DNS configuration steps on every cluster in the slice. @@ -636,18 +666,20 @@ Repeat the DNS configuration steps on every cluster in the slice. The KubeDB license is tied to the `kube-system` namespace UID of the hub cluster and has an expiry date. Get your cluster UID and verify the license before installing: -```bash # Get your cluster UID (required when requesting the license) -$ kubectl get ns kube-system -o jsonpath='{.metadata.uid}' +```bash +kubectl get ns kube-system -o jsonpath='{.metadata.uid}' +``` # Verify the license is not expired -$ openssl x509 -noout -enddate -in $HOME/Downloads/kubedb-license-.txt +```bash +openssl x509 -noout -enddate -in $HOME/Downloads/kubedb-license-.txt ``` If expired or not yet obtained, download a FREE license from the [AppsCode License Server](https://appscode.com/issue-license?p=kubedb) using the cluster UID above. ```bash -$ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ --version v2026.2.26 \ --namespace kubedb --create-namespace \ --set-file global.license=$HOME/Downloads/kubedb-license-.txt \ @@ -662,7 +694,7 @@ For additional details, refer to the [KubeDB Installation Guide](/docs/setup/REA Verify that the pods are running: ```bash -$ kubectl get pods -n kubedb +kubectl get pods -n kubedb ``` **Output:** @@ -721,7 +753,7 @@ This policy schedules: Apply the policy on `demo-controller`: ```bash -$ kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubeconfig $HOME/.kube/config +kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubeconfig $HOME/.kube/config ``` ### Step 6: Create a Distributed Postgres Instance @@ -729,7 +761,7 @@ $ kubectl apply -f pod-placement-policy.yaml --context demo-controller --kubecon Create the `demo` namespace first: ```bash -$ kubectl create namespace demo +kubectl create namespace demo ``` Define a Postgres custom resource with `spec.distributed` set to `true` and reference the `PlacementPolicy`. Create a `postgres.yaml` file: @@ -761,7 +793,7 @@ spec: Apply the resource on `demo-controller`: ```bash -$ kubectl apply -f postgres.yaml --context demo-controller --kubeconfig $HOME/.kube/config +kubectl apply -f postgres.yaml --context demo-controller --kubeconfig $HOME/.kube/config ``` ### Step 7: Verify the Deployment @@ -769,7 +801,7 @@ $ kubectl apply -f postgres.yaml --context demo-controller --kubeconfig $HOME/.k #### 1. Check Postgres Resource and Pods on `demo-controller` ```bash -$ kubectl get pg,pods,secret -n demo --context demo-controller --kubeconfig $HOME/.kube/config +kubectl get pg,pods,secret -n demo --context demo-controller --kubeconfig $HOME/.kube/config ``` **Output:** @@ -789,7 +821,7 @@ secret/postgres-auth kubernetes.io/basic-auth 2 95s #### 2. Check Pods and Secrets on `demo-worker` ```bash -$ kubectl get pods,secrets -n demo --context demo-worker --kubeconfig $HOME/.kube/config +kubectl get pods,secrets -n demo --context demo-worker --kubeconfig $HOME/.kube/config ``` **Output:** @@ -807,10 +839,10 @@ secret/postgres-auth kubernetes.io/basic-auth 2 95s Connect to the primary Postgres pod and check the replication status: ```bash -$ kubectl exec -it -n demo pod/postgres-0 --context demo-controller -- bash +kubectl exec -it -n demo pod/postgres-0 --context demo-controller -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) postgres-0:/$ psql -U postgres -``` Run the following query: diff --git a/docs/guides/postgres/gitops/gitops.md b/docs/guides/postgres/gitops/gitops.md index 64e28ec94e..5586c0df34 100644 --- a/docs/guides/postgres/gitops/gitops.md +++ b/docs/guides/postgres/gitops/gitops.md @@ -25,12 +25,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create postgres - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -100,11 +102,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── postgres.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `Postgres` CR is created in your cluster. @@ -112,18 +114,19 @@ Our `gitops` operator will create an actual `Postgres` database CR in the cluste ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 2m11s NAME VERSION STATUS AGE postgres.kubedb.com/ha-postgres 18.3 Ready 2m11s -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` Postgres. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=ha-postgres' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=ha-postgres' +``` NAME AGE petset.apps.k8s.appscode.com/ha-postgres 3m26s @@ -142,7 +145,6 @@ service/ha-postgres-standby ClusterIP 10.43.106.75 5432/TCP NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/ha-postgres kubedb.com/postgres 18.3 3m26s -``` ## Update Postgres Database using GitOps @@ -184,7 +186,8 @@ Resource Requests and Limits are updated to `700m` CPU and `2Gi` Memory. Commit Now, `gitops` operator will detect the resource changes and create a `PostgresOpsRequest` to update the `Postgres` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 13m @@ -193,11 +196,11 @@ postgres.kubedb.com/ha-postgres 18.3 Ready 13m NAME TYPE STATUS AGE postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Progressing 2s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the one of the pod, ```bash -$ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "2Gi" @@ -207,7 +210,6 @@ $ kubectl get pod -n demo ha-postgres-0 -o json | jq '.spec.containers[0].resour "memory": "2Gi" } } -``` ### Scale Postgres Replicas Update the `postgres.yaml` with the following, @@ -245,7 +247,8 @@ Update the `replicas` to `5`. Commit the changes and push to your Git repository Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` PostgresOpsRequest to update the `Postgres` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 21m @@ -255,18 +258,17 @@ postgres.kubedb.com/ha-postgres 18.3 Ready 21m NAME TYPE STATUS AGE postgresopsrequest.ops.kubedb.com/ha-postgres-horizontalscaling-wvxu5x HorizontalScaling Progressing 6s postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 7m54s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=ha-postgres' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=ha-postgres' +``` NAME READY STATUS RESTARTS AGE ha-postgres-0 2/2 Running 0 9m4s ha-postgres-1 2/2 Running 0 10m ha-postgres-2 2/2 Running 0 9m44s ha-postgres-3 2/2 Running 0 2m58s ha-postgres-4 2/2 Running 0 2m23s -``` We can also scale down the replicas by updating the `replicas` fields. @@ -308,7 +310,8 @@ Update the `storage.resources.requests.storage` to `10Gi`. Commit the changes an Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` PostgresOpsRequest to update the `Postgres` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 27m @@ -319,18 +322,17 @@ NAME TYPE postgresopsrequest.ops.kubedb.com/ha-postgres-horizontalscaling-wvxu5x HorizontalScaling Successful 6m postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 13m postgresopsrequest.ops.kubedb.com/ha-postgres-volumeexpansion-2j5x5g VolumeExpansion Progressing 2s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=ha-postgres' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=ha-postgres' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-ha-postgres-0 Bound pvc-061f3622-234f-4f91-b4d1-b81aa8739503 10Gi RWO longhorn 30m data-ha-postgres-1 Bound pvc-045fc563-fb4e-416c-a9c2-b20c96532978 10Gi RWO longhorn 30m data-ha-postgres-2 Bound pvc-a0f1d8fd-a677-4407-80b1-104b9f7b4cd1 10Gi RWO longhorn 30m data-ha-postgres-3 Bound pvc-060b6fab-0c2d-4935-b31b-2866be68dd6f 10Gi RWO longhorn 8m58s data-ha-postgres-4 Bound pvc-8149b579-a40f-4cd8-ac37-6a2401fd7807 10Gi RWO longhorn 8m23s -``` ## Reconfigure Postgres @@ -352,12 +354,12 @@ type: Opaque Now, we will add this file to `kubedb/pg-configuration.yaml`. ```bash -$ tree . +tree . +``` ├── kubedb │ ├── pg-configuration.yaml │ └── postgres.yaml 1 directories, 2 files -``` Update the `postgres.yaml` with the following, ```yaml @@ -397,7 +399,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` PostgresOpsRequest to update the `Postgres` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 36m @@ -408,12 +411,12 @@ NAME TYPE postgresopsrequest.ops.kubedb.com/ha-postgres-horizontalscaling-wvxu5x HorizontalScaling Successful 15m postgresopsrequest.ops.kubedb.com/ha-postgres-reconfigure-i4r23j Reconfigure Progressing 1s postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 23m -``` After Ops Request becomes `Succesful`, lets check these parameters, ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql psql (18.3) @@ -430,7 +433,6 @@ postgres=# show shared_buffers; ---------------- 256MB (1 row) -``` You can check the other pods same way. So we have configured custom parameters. @@ -456,13 +458,13 @@ type: kubernetes.io/basic-auth File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── pg-auth.yaml │ ├── pg-configuration.yaml │ └── postgres.yaml 1 directories, 3 files -``` Update the `postgres.yaml` with the following, ```yaml @@ -505,7 +507,8 @@ Change the `authSecret` field to `pg-rotate-auth`. Commit the changes and push t Now, `gitops` operator will detect the auth changes and create a `RotateAuth` PostgresOpsRequest to update the `Postgres` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 44m @@ -517,19 +520,17 @@ postgresopsrequest.ops.kubedb.com/ha-postgres-horizontalscaling-wvxu5x Horizon postgresopsrequest.ops.kubedb.com/ha-postgres-reconfigure-i4r23j Reconfigure Successful 7m25s postgresopsrequest.ops.kubedb.com/ha-postgres-rotate-auth-zot83x RotateAuth Progressing 2s postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 30m -``` After Ops Request becomes `Successful`, We can validate the changes connecting postgres with new credentials. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql -U postgres -W Password: psql (18.3) Type "help" for help. -``` - ### TLS configuration We can add, rotate or remove TLS configuration using `gitops`. @@ -539,23 +540,23 @@ To add tls, we are going to create an example `Issuer` that will be used to enab - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 postgres-ca \ +kubectl create secret tls postgres-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/postgres-ca created ``` +secret/postgres-ca created Now, Let's create an `Issuer` using the `postgres-ca` secret that we have just created. The `YAML` file looks like this: @@ -572,14 +573,14 @@ spec: Let's add that to our `kubedb/pg-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── pg-auth.yaml │ ├── pg-configuration.yaml │ ├── pg-issuer.yaml │ └── postgres.yaml 1 directories, 4 files -``` Update the `postgres.yaml` with the following, ```yaml @@ -637,7 +638,8 @@ Add `sslMode` and `tls` fields in the spec. Commit the changes and push to your Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` PostgresOpsRequest to update the `Postgres` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 3h17m @@ -650,17 +652,16 @@ postgresopsrequest.ops.kubedb.com/ha-postgres-reconfigure-i4r23j Reconfi postgresopsrequest.ops.kubedb.com/ha-postgres-reconfiguretls-91fseg ReconfigureTLS Progressing 4s postgresopsrequest.ops.kubedb.com/ha-postgres-rotate-auth-zot83x RotateAuth Successful 153m postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 3h4m -``` After Ops Request becomes `Successful`, We can validate the changes connecting postgres with new credentials. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql -h ha-postgres.demo.svc -U postgres -d "sslmode=verify-full sslrootcert=/tls/certs/client/ca.crt sslcert=/tls/certs/client/client.crt sslkey=/tls/certs/client/client.key" psql (18.3) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) Type "help" for help. -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for postgres. @@ -726,7 +727,8 @@ Update the `version` field to `18.3`. Commit the changes and push to your Git re Now, `gitops` operator will detect the version changes and create a `VersionUpdate` PostgresOpsRequest to update the `Postgres` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 3h25m @@ -740,21 +742,24 @@ postgresopsrequest.ops.kubedb.com/ha-postgres-reconfiguretls-91fseg Reconfi postgresopsrequest.ops.kubedb.com/ha-postgres-rotate-auth-zot83x RotateAuth Successful 161m postgresopsrequest.ops.kubedb.com/ha-postgres-versionupdate-1wxgt9 UpdateVersion Progressing 4s postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 3h11m -``` Now, we are going to verify whether the `Postgres`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get postgres -n demo ha-postgres -o=jsonpath='{.spec.version}{"\n"}' +kubectl get postgres -n demo ha-postgres -o=jsonpath='{.spec.version}{"\n"}' +``` 18.3 -$ kubectl get petset -n demo ha-postgres -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo ha-postgres -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/postgres:18.3-alpine -$ kubectl get pod -n demo ha-postgres-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/postgres:18.3-alpine +```bash +kubectl get pod -n demo ha-postgres-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/postgres:18.3-alpine ### Enable Monitoring @@ -822,7 +827,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` PostgresOpsRequest to add the `Postgres` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +kubectl get postgreses.gitops.kubedb.com,postgreses.kubedb.com,postgresopsrequest -n demo +``` NAME AGE postgres.gitops.kubedb.com/ha-postgres 3h34m @@ -837,7 +843,6 @@ postgresopsrequest.ops.kubedb.com/ha-postgres-restart-nhjk9u Restart postgresopsrequest.ops.kubedb.com/ha-postgres-rotate-auth-zot83x RotateAuth Successful 170m postgresopsrequest.ops.kubedb.com/ha-postgres-versionupdate-1wxgt9 UpdateVersion Successful 9m30s postgresopsrequest.ops.kubedb.com/ha-postgres-verticalscaling-i0kr1l VerticalScaling Successful 3h21m -``` Verify the monitoring is enabled by checking the prometheus targets. diff --git a/docs/guides/postgres/initialization/script_source.md b/docs/guides/postgres/initialization/script_source.md index 92ae554533..83cf97f92e 100644 --- a/docs/guides/postgres/initialization/script_source.md +++ b/docs/guides/postgres/initialization/script_source.md @@ -25,13 +25,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ At first, we will create a ConfigMap from `data.sql` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo pg-init-script \ +kubectl create configmap -n demo pg-init-script \ --from-literal=data.sql="$(curl -fsSL https://raw.githubusercontent.com/kubedb/postgres-init-scripts/master/data.sql)" -configmap/pg-init-script created ``` +configmap/pg-init-script created ## Create PostgreSQL with script source @@ -85,22 +87,23 @@ VolumeSource provided in `init.script` will be mounted in Pod and will be execut Now, let's create the Postgres crd which YAML we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/initialization/script-postgres.yaml -postgres.kubedb.com/script-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/initialization/script-postgres.yaml ``` +postgres.kubedb.com/script-postgres created Now, wait until Postgres goes in `Running` state. Verify that the database is in `Running` state using following command, -```bash - $ kubectl get pg -n demo script-postgres + ```bash + kubectl get pg -n demo script-postgres + ``` NAME VERSION STATUS AGE script-postgres 10.2-v5 Running 39s -``` You can use `kubectl dba describe` command to view which resources has been created by KubeDB for this Postgres object. ```bash -$ kubectl dba describe pg -n demo script-postgres +kubectl dba describe pg -n demo script-postgres +``` Name: script-postgres Namespace: demo CreationTimestamp: Fri, 21 Sep 2018 15:53:27 +0600 @@ -182,7 +185,6 @@ Events: Normal Successful 57s Postgres operator Successfully patched Postgres Normal Successful 57s Postgres operator Successfully patched PetSet Normal Successful 57s Postgres operator Successfully patched Postgres -``` ## Verify Initialization @@ -199,16 +201,16 @@ Now let's connect to our Postgres `script-postgres` using pgAdmin we have insta - Username: Run following command to get *username*, ```bash - $ kubectl get secrets -n demo script-postgres-auth -o jsonpath='{.data.username}' | base64 -d - postgres + kubectl get secrets -n demo script-postgres-auth -o jsonpath='{.data.username}' | base64 -d ``` + postgres - Password: Run the following command to get *password*, ```bash - $ kubectl get secrets -n demo script-postgres-auth -o jsonpath='{.data.password}' | base64 -d - NC1fEq0q5XqHazB8 + kubectl get secrets -n demo script-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + NC1fEq0q5XqHazB8 In PostgreSQL, run following query to check `pg_catalog.pg_tables` to confirm initialization. @@ -227,11 +229,19 @@ We can see TABLE `dashboard` in `data` Schema which is created through initializ To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo pg/script-postgres -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo pg/script-postgres +kubectl patch -n demo pg/script-postgres -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo pg/script-postgres +``` + +```bash +kubectl delete -n demo configmap/pg-init-script +``` -$ kubectl delete -n demo configmap/pg-init-script -$ kubectl delete ns demo +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/postgres/migration/databaseMigration.md b/docs/guides/postgres/migration/databaseMigration.md index 5c7254a6f3..c281f84ae1 100644 --- a/docs/guides/postgres/migration/databaseMigration.md +++ b/docs/guides/postgres/migration/databaseMigration.md @@ -43,9 +43,9 @@ A brief downtime occurs only during the final cutover when application endpoints To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Source Database @@ -85,7 +85,7 @@ Add `wal_level: logical` under `postgresql` parameters in the `Cluster` spec. ### Verify prerequisites ```bash -$ psql -h .rds.amazonaws.com -U postgres -p 5432 +psql -h .rds.amazonaws.com -U postgres -p 5432 ``` ```sql @@ -158,7 +158,7 @@ SELECT * FROM orders; First, create an authentication secret using the `migrator` user credentials: ```bash -$ kubectl create secret generic source-postgres-auth -n demo \ +kubectl create secret generic source-postgres-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=migrator \ --from-literal=password= @@ -221,9 +221,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/target-postgres.yaml -postgres.kubedb.com/target-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/target-postgres.yaml ``` +postgres.kubedb.com/target-postgres created > Note: Adjust the `resources.requests.storage` based on the source database size. @@ -268,9 +268,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/postgres-migrate.yaml -migration.courier.kubedb.com/postgres-migrate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/postgres-migrate.yaml ``` +migration.courier.kubedb.com/postgres-migrate created Here we connect to and migrate the `shop` database. Schema is extracted via `pg_dump` (`pgDump.schemaOnly: true`) and data is replicated using PostgreSQL logical replication with publication `pub` on the source and subscription `sub` on the target. For a full description of every field, see the [Migration CRD reference](/docs/guides/postgres/concepts/migrator.md). @@ -290,7 +290,7 @@ postgres-migrate Running postgres Streaming 0B 100% 4h36m Once the migration reaches the `Streaming` stage, exec into the KubeDB target pod and confirm all seed rows were copied over: ```bash -$ kubectl exec -it -n demo target-postgres-0 -- psql -U postgres -d shop +kubectl exec -it -n demo target-postgres-0 -- psql -U postgres -d shop ``` ```sql @@ -308,7 +308,7 @@ SELECT * FROM orders; With the migration still running, connect to the **source RDS** instance and run some DML: ```bash -$ psql -h .rds.amazonaws.com -U migrator -d shop -p 5432 +psql -h .rds.amazonaws.com -U migrator -d shop -p 5432 ``` ```sql @@ -344,8 +344,8 @@ Once the `LAG` drops to near zero, stop all writes to the source database. Wait Now delete the `Migration` CR to stop the migration process: ```bash -$ kubectl delete migration -n demo postgres-migrate -migration.courier.kubedb.com "postgres-migrate" deleted +kubectl delete migration -n demo postgres-migrate ``` +migration.courier.kubedb.com "postgres-migrate" deleted Finally, update your application's connection string to point to the target KubeDB-managed `PostgreSQL` database. The migration is complete. diff --git a/docs/guides/postgres/migration/storageMigration.md b/docs/guides/postgres/migration/storageMigration.md index 3756923265..83e022a96a 100644 --- a/docs/guides/postgres/migration/storageMigration.md +++ b/docs/guides/postgres/migration/storageMigration.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` Ops Manager to migrate `StorageCla To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare PostgreSQL Database @@ -73,13 +73,14 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/sample-postgres.yaml -postgres.kubedb.com/sample-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/sample-postgres.yaml ``` +postgres.kubedb.com/sample-postgres created Now, wait until sample-postgres has status `Ready` and check the `StorageClass`, ```bash -$ kubectl get postgres,pvc -n demo +kubectl get postgres,pvc -n demo +``` NAME VERSION STATUS AGE sample-postgres 18.3 Ready 101s @@ -87,17 +88,19 @@ NAME STATUS VOLUME persistentvolumeclaim/data-sample-postgres-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 3Gi RWO local-path 96s persistentvolumeclaim/data-sample-postgres-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 3Gi RWO local-path 90s persistentvolumeclaim/data-sample-postgres-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 3Gi RWO local-path 85s -``` The database is `Ready` and all the `PersistentVolumeClaim` uses `local-path` StorageClass, Let's create a table in the primary. -```bash # find the primary pod -$ kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +```bash +kubectl get pods -n demo --show-labels | grep primary | awk '{ print $1 }' +``` sample-postgres-0 # exec into the primary and generate some data -$ kubectl exec -it -n demo sample-postgres-0 -- bash +```bash +kubectl exec -it -n demo sample-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) sample-postgres-0:/$ psql psql (18.3) @@ -113,8 +116,6 @@ postgres=# select count(*) from hello; 111111 (1 row) -``` - ## Apply StorageMigration Ops-Request To migrate `StorageClass` we have to create a `PostgresOpsRequest` CR with our desired `StorageClass`. Below is the YAML of the `PostgresOpsRequest` CR that we are going to create, @@ -144,39 +145,39 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, -``` bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/storage-migration.yaml -postgresopsrequest.ops.kubedb.com/storage-migration created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/migration/storage-migration.yaml ``` +postgresopsrequest.ops.kubedb.com/storage-migration created ## Verify the StorageClass Migrated Successfully If everything goes well, `KubeDB` operator will migrate the `StorageClass` along with the data. Let’s wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch PostgresOpsRequest CR, -``` bash -$ watch kubectl get postgresopsrequest -n demo - +```bash +watch kubectl get postgresopsrequest -n demo +``` Every 2.0s: kubectl get postgresopsrequest -n demo NAME TYPE STATUS AGE storage-migration StorageMigration Successful 13m -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. Let's verify the StorageClass. -``` bash -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-sample-postgres-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 3Gi RWO standard-custom 21m data-sample-postgres-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 3Gi RWO standard-custom 21m data-sample-postgres-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 3Gi RWO standard-custom 21m -``` The `PersistentVolumeClaim` StorageClass has changed to `standard-custom`. Now, we will verify that the data remains intact after the `StorageMigration` operation. Let's exec into one of the `Postgres` pod and perform read query. ```bash -$ kubectl exec -it -n demo sample-postgres-0 -- bash +kubectl exec -it -n demo sample-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) sample-postgres-0:/$ psql psql (18.3) @@ -187,7 +188,6 @@ postgres=# select count(*) from hello; -------- 111111 (1 row) -``` From the above output we can verify that data remains intact after the `StorageMigration` operation. @@ -196,7 +196,13 @@ From the above output we can verify that data remains intact after the `StorageM To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete postgresopsrequest -n demo storage-migration -$ kubectl delete postgres -n demo sample-postgres -$ kubectl delete ns demo +kubectl delete postgresopsrequest -n demo storage-migration +``` + +```bash +kubectl delete postgres -n demo sample-postgres +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/postgres/monitoring/using-builtin-prometheus.md b/docs/guides/postgres/monitoring/using-builtin-prometheus.md index a759c1bd95..50cb2653a7 100644 --- a/docs/guides/postgres/monitoring/using-builtin-prometheus.md +++ b/docs/guides/postgres/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor PostgreSQL database using builtin [Pr - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the PostgreSQL crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/monitoring/builtin-prom-postgres.yaml -postgres.kubedb.com/builtin-prom-postgres created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/monitoring/builtin-prom-postgres.yaml ``` +postgres.kubedb.com/builtin-prom-postgres created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pg -n demo builtin-prom-postgres +kubectl get pg -n demo builtin-prom-postgres +``` NAME VERSION STATUS AGE builtin-prom-postgres 10.2-v5 Running 1m -``` KubeDB will create a separate stats service with name `{PostgreSQL crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-postgres" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-postgres" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-postgres ClusterIP 10.102.7.190 5432/TCP 87s builtin-prom-postgres-replicas ClusterIP 10.100.103.146 5432/TCP 87s builtin-prom-postgres-stats ClusterIP 10.102.128.153 56790/TCP 56s -``` Here, `builtin-prom-postgres-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-postgres-stats +kubectl describe svc -n demo builtin-prom-postgres-stats +``` Name: builtin-prom-postgres-stats Namespace: demo Labels: app.kubernetes.io/name=postgreses.kubedb.com @@ -111,7 +114,6 @@ TargetPort: prom-http/TCP Endpoints: 172.17.0.14:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -275,20 +277,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -299,9 +301,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -310,18 +312,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-postgres-stats` service as one of the targets. @@ -338,16 +340,31 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo pg/builtin-prom-postgres +kubectl delete -n demo pg/builtin-prom-postgres +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/postgres/monitoring/using-prometheus-operator.md b/docs/guides/postgres/monitoring/using-prometheus-operator.md index 54cb271852..27d0b8fc45 100644 --- a/docs/guides/postgres/monitoring/using-prometheus-operator.md +++ b/docs/guides/postgres/monitoring/using-prometheus-operator.md @@ -25,12 +25,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME AGE monitoring prometheus 18m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -125,27 +127,27 @@ Here, Let's create the PostgreSQL object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/monitoring/coreos-prom-postgres.yaml -postgresql.kubedb.com/coreos-prom-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/monitoring/coreos-prom-postgres.yaml ``` +postgresql.kubedb.com/coreos-prom-postgres created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get pg -n demo coreos-prom-postgres +kubectl get pg -n demo coreos-prom-postgres +``` NAME VERSION STATUS AGE coreos-prom-postgres 10.2-v5 Running 38s -``` KubeDB will create a separate stats service with name `{PostgreSQL crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-postgres" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-postgres" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-postgres ClusterIP 10.107.102.123 5432/TCP 58s coreos-prom-postgres-replicas ClusterIP 10.109.11.171 5432/TCP 58s coreos-prom-postgres-stats ClusterIP 10.110.218.172 56790/TCP 51s -``` Here, `coreos-prom-postgres-stats` service has been created for monitoring purpose. @@ -173,10 +175,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `coreos-prom-postgres-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n monitoring +kubectl get servicemonitor -n monitoring +``` NAME AGE kubedb-demo-coreos-prom-postgres 1m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of PostgreSQL crd. @@ -219,20 +221,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 63m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-postgres-stats` service as one of the targets. diff --git a/docs/guides/postgres/pitr/archiver.md b/docs/guides/postgres/pitr/archiver.md index 15822ee1bd..696e75dfe7 100644 --- a/docs/guides/postgres/pitr/archiver.md +++ b/docs/guides/postgres/pitr/archiver.md @@ -31,9 +31,9 @@ To install `External-snapshotter` in your cluster following the steps [here](ht To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/postgres/remote-replica/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## continuous archiving @@ -64,10 +64,10 @@ spec: deletionPolicy: WipeOut ``` -```bash - $ kubectl apply -f backupstorage.yaml + ```bash + kubectl apply -f backupstorage.yaml + ``` backupstorage.storage.kubestash.com/linode-storage created -``` ### secrets for backup-storage ```yaml @@ -83,10 +83,10 @@ stringData: AWS_ENDPOINT: https://ap-south-1.linodeobjects.com ``` -```bash - $ kubectl apply -f storage-secret.yaml + ```bash + kubectl apply -f storage-secret.yaml + ``` secret/storage created -``` ### Retention policy RetentionPolicy is a CR provided by KubeStash that allows you to set how long you'd like to retain the backup data. @@ -105,9 +105,9 @@ spec: last: 2 ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/retentionPolicy.yaml -retentionpolicy.storage.kubestash.com/postgres-retention-policy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/retentionPolicy.yaml ``` +retentionpolicy.storage.kubestash.com/postgres-retention-policy created ### PostgreSQLArchiver PostgreSQLArchiver is a CR provided by KubeDB for managing the archiving of MongoDB oplog files and performing volume-level backups @@ -171,20 +171,22 @@ stringData: RESTIC_PASSWORD: "changeit" ``` -```bash - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/postgresarchiver.yaml + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/postgresarchiver.yaml + ``` postgresarchiver.archiver.kubedb.com/postgresarchiver-sample created - $ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/encryptionSecret.yaml -``` + + ```bash + kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/pitr/yamls/encryptionSecret.yaml + ``` ## Ensure volumeSnapshotClass ```bash -$ kubectl get volumesnapshotclasses +kubectl get volumesnapshotclasses +``` NAME DRIVER DELETIONPOLICY AGE longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h - -``` If not any, try using `longhorn` or any other [volumeSnapshotClass](https://kubernetes.io/docs/concepts/storage/volume-snapshot-classes/). ```yaml kind: VolumeSnapshotClass @@ -199,11 +201,13 @@ parameters: ``` ```bash -$ helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace +``` -$ kubectl apply -f volumesnapshotclass.yaml - volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged +```bash +kubectl apply -f volumesnapshotclass.yaml ``` + volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc unchanged # Deploy PostgreSQL So far we are ready with setup for continuously archive PostgreSQL, We deploy a postgresql referring the PostgreSQL archiver object @@ -238,7 +242,8 @@ spec: ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE demo-pg-0 2/2 Running 0 8m52s demo-pg-1 2/2 Running 0 8m22s @@ -246,7 +251,6 @@ demo-pg-2 2/2 Running 0 demo-pg-backup-config-full-backup-1702388088-z4qbz 0/1 Completed 0 37s demo-pg-backup-config-manifest-1702388088-hpx6m 0/1 Completed 0 37s demo-pg-sidekick 1/1 Running 0 7m31s -``` `demo-pg-sidekick` is responsible for uploading wal-files @@ -257,13 +261,14 @@ demo-pg-sidekick 1/1 Running 0 ### validate BackupConfiguration and VolumeSnapshots ```bash - -$ kubectl get backupconfigurations -n demo - +kubectl get backupconfigurations -n demo +``` NAME PHASE PAUSED AGE demo-pg-backup-config Ready 2m43s -$ kubectl get backupsession -n demo +```bash +kubectl get backupsession -n demo +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE demo-pg-backup-config-full-backup-1702388088 BackupConfiguration demo-pg-backup-config Succeeded 74s demo-pg-backup-config-manifest-1702388088 BackupConfiguration demo-pg-backup-config Succeeded 74s @@ -271,14 +276,13 @@ demo-pg-backup-config-manifest-1702388088 BackupConfiguration demo-pg-bac kubectl get volumesnapshots -n demo NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE demo-pg-1702388096 true data-demo-pg-1 1Gi longhorn-snapshot-vsc snapcontent-735e97ad-1dfa-4b70-b416-33f7270d792c 2m5s 2m5s -``` ## data insert and switch wal After each and every wal switch the wal files will be uploaded to backup storage ```bash -$ kubectl exec -it -n demo demo-pg-0 -- bash - +kubectl exec -it -n demo demo-pg-0 -- bash +``` bash-5.1$ psql postgres=# create database hi; @@ -308,7 +312,6 @@ hi=# select pg_switch_wal(); hi=# select count(*) from tab_1 ; 200 -``` > At this point We have 200 rows in our newly created table `tab_1` on database `hi` @@ -317,7 +320,8 @@ Point-In-Time Recovery allows you to restore a PostgreSQL database to a specific Let's say accidentally our dba drops the table tab_1 and we want to restore. ```bash -$ kubectl exec -it -n demo demo-pg-0 -- bash +kubectl exec -it -n demo demo-pg-0 -- bash +``` bash-5.1$ psql postgres=# \c hi @@ -326,7 +330,6 @@ DROP TABLE hi=# select count(*) from tab_1 ; ERROR: relation "tab_1" does not exist LINE 1: select count(*) from tab_1 ; -``` We can't restore from a full backup since at this point no full backup was perform. so we can choose a specific time in which time we want to restore.We can get the specfice time from the wal that archived in the backup storage . Go to the binlog file and find where to store. You can parse wal-files using `pg-waldump`. @@ -381,40 +384,40 @@ spec: ``` ```bash -$ kubectl apply -f restore.yaml -postgres.kubedb.com/restore-pg created +kubectl apply -f restore.yaml ``` +postgres.kubedb.com/restore-pg created **check for Restored PostgreSQL** ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE restore-pg-0 2/2 Running 0 46s restore-pg-1 2/2 Running 0 41s restore-pg-2 2/2 Running 0 22s restore-pg-restorer-4d4dg 0/1 Completed 0 104s restore-pg-restoresession-2tsbv 0/1 Completed 0 115s -``` ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE demo-pg 18.3 Ready 44m restore-pg 18.3 Ready 2m36s -``` **Validating data on Restored PostgreSQL** ```bash -$ kubectl exec -it -n demo restore-pg-0 -- bash +kubectl exec -it -n demo restore-pg-0 -- bash +``` bash-5.1$ psql postgres=# \c hi hi=# select count(*) from tab_1 ; 100 -``` **so we are able to successfully recover from a disaster** @@ -423,11 +426,23 @@ hi=# select count(*) from tab_1 ; To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete -n demo pg/demo-pg -$ kubectl delete -n demo pg/restore-pg -$ kubectl delete -n demo backupstorage -$ kubectl delete -n demo postgresqlarchiver -$ kubectl delete ns demo +kubectl delete -n demo pg/demo-pg +``` + +```bash +kubectl delete -n demo pg/restore-pg +``` + +```bash +kubectl delete -n demo backupstorage +``` + +```bash +kubectl delete -n demo postgresqlarchiver +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/postgres/private-registry/using-private-registry.md b/docs/guides/postgres/private-registry/using-private-registry.md index 23ee66c9d3..b2dc0d7e7b 100644 --- a/docs/guides/postgres/private-registry/using-private-registry.md +++ b/docs/guides/postgres/private-registry/using-private-registry.md @@ -23,9 +23,9 @@ At first, you need to have a Kubernetes cluster, and the kubectl command-line to To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -36,7 +36,8 @@ namespace/demo created - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For postgres, push `DB_IMAGE`, `TOOLS_IMAGE`, `EXPORTER_IMAGE` of following PostgresVersions, where `deprecated` is not true, to your private registry. ```bash - $ kubectl get postgresversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,TOOLS_IMAGE:.spec.tools.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + kubectl get postgresversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,DB_IMAGE:.spec.db.image,TOOLS_IMAGE:.spec.tools.image,EXPORTER_IMAGE:.spec.exporter.image,DEPRECATED:.spec.deprecated + ``` NAME VERSION DB_IMAGE TOOLS_IMAGE EXPORTER_IMAGE DEPRECATED 10.2 10.2 kubedb/postgres:10.2 kubedb/postgres-tools:10.2 kubedb/operator:0.8.0 true 10.2-v1 10.2 kubedb/postgres:10.2-v2 kubedb/postgres-tools:10.2-v2 kubedb/postgres_exporter:v0.4.6 true @@ -66,7 +67,6 @@ namespace/demo created 9.6.7-v3 9.6.7 kubedb/postgres:9.6.7-v4 kubedb/postgres-tools:9.6.7-v3 kubedb/postgres_exporter:v0.4.7 9.6.7-v4 9.6.7 kubedb/postgres:9.6.7-v5 kubedb/postgres-tools:9.6.7-v3 kubedb/postgres_exporter:v0.4.7 9.6.7-v5 9.6.7 kubedb/postgres:9.6.7-v6 kubedb/postgres-tools:9.6.7-v3 kubedb/postgres_exporter:v0.4.7 - ``` Docker hub repositories: @@ -85,13 +85,13 @@ ImagePullSecrets is a type of a Kubernetes Secret whose sole purpose is to pull Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret generic -n demo docker-registry myregistrykey \ +kubectl create secret generic -n demo docker-registry myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -137,9 +137,9 @@ spec: Now, create the PostgresVersion crd, ```bash -$ kubectl apply -f pvt-postgresversion.yaml -postgresversion.kubedb.com/pvt-10.2 created +kubectl apply -f pvt-postgresversion.yaml ``` +postgresversion.kubedb.com/pvt-10.2 created ## Deploy PostgreSQL database from Private Registry @@ -171,17 +171,17 @@ spec: Now run the command to create this Postgres object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/private-registry/pvt-reg-postgres.yaml -postgres.kubedb.com/pvt-reg-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/private-registry/pvt-reg-postgres.yaml ``` +postgres.kubedb.com/pvt-reg-postgres created To check if the images pulled successfully from the repository, see if the PostgreSQL is in Running state: ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-postgres" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=pvt-reg-postgres" +``` NAME READY STATUS RESTARTS AGE pvt-reg-postgres-0 1/1 Running 0 3m -``` ## Snapshot diff --git a/docs/guides/postgres/quickstart/quickstart.md b/docs/guides/postgres/quickstart/quickstart.md index ee2f9b020c..9643d4fb93 100644 --- a/docs/guides/postgres/quickstart/quickstart.md +++ b/docs/guides/postgres/quickstart/quickstart.md @@ -29,9 +29,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,25 +44,27 @@ This tutorial will also use a pgAdmin to connect and test PostgreSQL database, o Run the following command to install pgAdmin, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/pgadmin.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/pgadmin.yaml +``` deployment.apps/pgadmin created service/pgadmin created -$ kubectl get pods -n demo --watch +```bash +kubectl get pods -n demo --watch +``` NAME READY STATUS RESTARTS AGE pgadmin-5b4b96779-lfpfh 0/1 ContainerCreating 0 1m pgadmin-5b4b96779-lfpfh 1/1 Running 0 2m ^C⏎ -``` Now, you can open pgAdmin on your browser using following address `http://:`. If you are using minikube then open pgAdmin in your browser by running `minikube service pgadmin -n demo`. Or you can get the URL of Service `pgadmin` by running following command ```bash -$ minikube service pgadmin -n demo --url -http://192.168.99.100:31983 +minikube service pgadmin -n demo --url ``` +http://192.168.99.100:31983 To log into the pgAdmin, use username __`admin`__ and password __`admin`__. @@ -71,12 +73,11 @@ To log into the pgAdmin, use username __`admin`__ and password __`admin`__. We will have to provide `StorageClass` in Postgres crd specification. Check available `StorageClass` in your cluster using following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 10d -``` - Here, we have `standard` StorageClass in our cluster. ## Find Available PostgresVersion @@ -84,7 +85,8 @@ Here, we have `standard` StorageClass in our cluster. When you have installed KubeDB, it has created `PostgresVersion` crd for all supported PostgreSQL versions. Let's check available PostgresVersions by, ```bash -$ kubectl get postgresversion +kubectl get postgresversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 10.23 10.23 Official ghcr.io/appscode-images/postgres:10.23-alpine 8d 10.23-bullseye 10.23 Official ghcr.io/appscode-images/postgres:10.23-bullseye 8d @@ -174,8 +176,6 @@ timescaledb-2.14.2-pg14 14.11 TimescaleDB docker.io/timescale/timescale timescaledb-2.14.2-pg15 15.6 Official docker.io/timescale/timescaledb:2.14.2-pg15-oss 8d timescaledb-2.14.2-pg16 16.2 Official docker.io/timescale/timescaledb:2.14.2-pg16-oss 8d -``` - Notice the `DEPRECATED` column. Here, `true` means that this PostgresVersion is deprecated for current KubeDB version. KubeDB will not work for deprecated PostgresVersion. In this tutorial, we will use `18.3` PostgresVersion crd to create PostgreSQL database. To know more about what is `PostgresVersion` crd and why there is `18.3` and `18.3-debian` variation, please visit [here](/docs/guides/postgres/concepts/catalog.md). You can also see supported PostgresVersion [here](/docs/guides/postgres/README.md#supported-postgresversion-crd). @@ -208,9 +208,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml -postgres.kubedb.com/quick-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml ``` +postgres.kubedb.com/quick-postgres created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -232,9 +232,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1alpha2.yaml -postgres.kubedb.com/quick-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1alpha2.yaml ``` +postgres.kubedb.com/quick-postgres created Here, @@ -252,15 +252,16 @@ If you are using RBAC enabled cluster, PostgreSQL specific RBAC permission is re KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. ```bash -$ kubectl get pg -n demo quick-postgres -o wide + kubectl get pg -n demo quick-postgres -o wide +``` NAME VERSION STATUS AGE quick-postgres 18.3 Creating 13s -``` Let's describe Postgres object `quick-postgres` ```bash -$ kubectl describe -n demo postgres quick-postgres +kubectl describe -n demo postgres quick-postgres +``` Name: quick-postgres Namespace: demo Labels: @@ -414,19 +415,16 @@ Events: Normal Successful 106s Postgres operator Successfully created governing service Normal Successful 106s Postgres operator Successfully created Service Normal Successful 105s Postgres operator Successfully created appbinding -``` KubeDB has created two services for the Postgres object. ```bash -$ kubectl get service -n demo --selector=app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=quick-postgres +kubectl get service -n demo --selector=app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=quick-postgres +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE quick-postgres ClusterIP 10.96.52.28 5432/TCP,2379/TCP 3m19s quick-postgres-pods ClusterIP None 5432/TCP,2380/TCP,2379/TCP 3m19s - -``` - Here, - Service *`quick-postgres`* targets only one Pod which is acting as *primary* server @@ -479,16 +477,16 @@ Now, you can connect to this database from the pgAdmin dashboard using `quick-po - Username: Run following command to get *username*, ```bash - $ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.username}' | base64 -d - postgres + kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.username}' | base64 -d ``` + postgres - Password: Run the following command to get *password*, ```bash - $ kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d - DD8i56UBIcs63PVO + kubectl get secrets -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + DD8i56UBIcs63PVO Now, go to pgAdmin dashboard and connect to the database using the connection information as shown below, @@ -505,37 +503,37 @@ KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or lat To halt the database, we have to set `spec.deletionPolicy:` to `Halt` by updating it, ```bash -$ kubectl edit pg -n demo quick-postgres +kubectl edit pg -n demo quick-postgres +``` spec: deletionPolicy: Halt -``` Now, if you delete the Postgres object, the KubeDB operator will delete every resource created for this Postgres CR, but leaves the auth secrets, and PVCs. Let's delete the Postgres object, ```bash -$ kubectl delete pg -n demo quick-postgres -postgres.kubedb.com "quick-postgres" deleted +kubectl delete pg -n demo quick-postgres ``` +postgres.kubedb.com "quick-postgres" deleted Check resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=quick-postgres' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=quick-postgres' +``` NAME TYPE DATA AGE secret/quick-postgres-auth kubernetes.io/basic-auth 2 27m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-quick-postgres-0 Bound pvc-b30e3255-a7ea-4f61-8637-f60e283236b2 1Gi RWO standard 27m -``` ## Resume Postgres Say, the Postgres CR was deleted with `spec.deletionPolicy` to `Halt` and you want to re-create the Postgres using the existing auth secrets and the PVCs. You can do it by simpily re-deploying the original Postgres object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml -postgres.kubedb.com/quick-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml ``` +postgres.kubedb.com/quick-postgres created ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/postgres/quickstart/rbac.md b/docs/guides/postgres/quickstart/rbac.md index 4175f2373b..2704ef8931 100644 --- a/docs/guides/postgres/quickstart/rbac.md +++ b/docs/guides/postgres/quickstart/rbac.md @@ -35,9 +35,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -67,9 +67,9 @@ spec: Create above Postgres object with following command ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml -postgres.kubedb.com/quick-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml ``` +postgres.kubedb.com/quick-postgres created When this Postgres object is created, KubeDB operator creates Role, ServiceAccount and RoleBinding with the matching PostgreSQL name and uses that ServiceAccount name in the corresponding PetSet. diff --git a/docs/guides/postgres/reconfigure-tls/reconfigure-tls.md b/docs/guides/postgres/reconfigure-tls/reconfigure-tls.md index e555550f5c..93963135a7 100644 --- a/docs/guides/postgres/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/postgres/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,18 +64,21 @@ spec: Let's create the `Postgres` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/ha-postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/ha-postgres.yaml ``` +postgres.kubedb.com/ha-postgres created Now, wait until `ha-postgres` has status `Ready`. i.e, ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE ha-postgres 18.3 Ready 87s -$ kubectl dba describe postgres ha-postgres -n demo +```bash +kubectl dba describe postgres ha-postgres -n demo +``` Name: ha-postgres Namespace: demo CreationTimestamp: Mon, 19 Aug 2024 13:38:28 +0600 @@ -206,19 +209,23 @@ Events: Normal Successful 2m KubeDB Operator Successfully created Service Normal Successful 2m KubeDB Operator Successfully created Postgres Normal Successful 49s KubeDB Operator Successfully patched Postgres -``` Now, we can connect to this database through `psql` and verify that the TLS is disabled. ```bash -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\username}' | base64 -d +``` postgres -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +```bash +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d +``` U6(h_pYrekLZ2OOd -$ kubectl exec -it -n demo ha-postgres-0 -- bash +```bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql -h ha-postgres.demo.svc -U postgres Password for user postgres: @@ -232,9 +239,6 @@ postgres=# SELECT name, setting FROM pg_settings WHERE name IN ('ssl'); ssl | off (1 row) - -``` - We can verify from the above output that TLS is disabled for this database. ### Create Issuer/ ClusterIssuer @@ -244,23 +248,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 postgres-ca \ +kubectl create secret tls postgres-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/postgres-ca created ``` +secret/postgres-ca created Now, Let's create an `Issuer` using the `postgres-ca` secret that we have just created. The `YAML` file looks like this: @@ -278,15 +282,15 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/pg-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/pg-issuer created ```bash -$ kubectl get issuer -n demo +kubectl get issuer -n demo +``` NAME READY AGE pg-issuer True 11s -``` Issuer is ready(true). ### Create PostgresOpsRequest @@ -329,25 +333,26 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/add-tls.yaml -postgresopsrequest.ops.kubedb.com/add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/add-tls.yaml ``` +postgresopsrequest.ops.kubedb.com/add-tls created #### Verify TLS Enabled Successfully Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CRO, ```bash -$ kubectl get pgops -n demo add-tls +kubectl get pgops -n demo add-tls +``` NAME TYPE STATUS AGE add-tls ReconfigureTLS Successful 5m23s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. Now, Let's exec into a database primary pods to see if certificates are added there. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ ls -R /tls tls: @@ -364,11 +369,10 @@ ca.crt tls.crt tls.key tls/certs/server: ca.crt server.crt server.key - -``` All the certs are added. Now lets connect with the postgres using client certs ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql -h ha-postgres.demo.svc -U postgres -d "sslmode=verify-full sslrootcert=/tls/certs/client/ca.crt sslcert=/tls/certs/client/client.crt sslkey=/tls/certs/client/client.key" psql (18.3) @@ -376,7 +380,6 @@ SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, co Type "help" for help. postgres=# -``` We can see our connection is now `SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)` Lets check whether ssl is on. @@ -443,32 +446,32 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/rotate-tls.yaml -postgresopsrequest.ops.kubedb.com/rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/rotate-tls.yaml ``` +postgresopsrequest.ops.kubedb.com/rotate-tls created #### Verify Certificate Rotated Successfully Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CRO, ```bash -$ kubectl get pgops -n demo +kubectl get pgops -n demo +``` NAME TYPE STATUS AGE rotate-tls ReconfigureTLS Successful 3m10s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. And we can check that the tls.crt has been updated. ```bash -$ kubectl get secrets -n demo ha-postgres-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates - + kubectl get secrets -n demo ha-postgres-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` notBefore=Aug 21 05:40:49 2024 GMT notAfter=Nov 19 05:40:49 2024 GMT -$ kubectl get secrets -n demo ha-postgres-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates - +```bash +kubectl get secrets -n demo ha-postgres-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates +``` notBefore=Aug 21 05:40:49 2024 GMT notAfter=Nov 19 05:40:49 2024 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -480,23 +483,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 postgres-new-ca \ +kubectl create secret tls postgres-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/postgres-new-ca created ``` +secret/postgres-new-ca created Now, Let's create a new `Issuer` using the `postgres-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -514,9 +517,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/pg-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/pg-new-issuer created ### Create PostgresOpsRequest @@ -548,35 +551,38 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/change-issuer.yaml -postgresopsrequest.ops.kubedb.com/change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/change-issuer.yaml ``` +postgresopsrequest.ops.kubedb.com/change-issuer created #### Verify Issuer is changed successfully Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CRO, ```bash -$ kubectl get pgops -n demo change-issuer +kubectl get pgops -n demo change-issuer +``` NAME TYPE STATUS AGE change-issuer ReconfigureTLS Successful 3m54s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl get secrets -n demo ha-postgres-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject - +kubectl get secrets -n demo ha-postgres-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject +``` subject=CN = ca-updated, O = kubedb-updated -$ kubectl get secrets -n demo ha-postgres-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject - +```bash +kubectl get secrets -n demo ha-postgres-server-cert -o jsonpath='{.data.ca\.crt}' | base64 -d | openssl x509 -noout -subject +``` subject=CN = ca-updated, O = kubedb-updated # other way to check this is -$ kubectl exec -it -n demo ha-postgres-0 -- bash +```bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ cat /tls/certs/server/ca.crt -----BEGIN CERTIFICATE----- @@ -599,7 +605,6 @@ sOhjQoxh3hMrHh1IDDsa5S+r1jyWSr6lkCkf5dAeIx/CVZgJUnnou68sVkNL5P3g 5sXwCzQQnRA+lw6nQFC3mbbNWP+klOqf27eFz6ve1VmPAKyMAGazQhKMqQS8gIzA aLcixLL6zhgM40K56RE7b14= -----END CERTIFICATE----- -``` Now you can check any certificate decoding website. 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. @@ -642,30 +647,31 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/remove-tls.yaml -postgresopsrequest.ops.kubedb.com/remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure-tls/remove-tls.yaml ``` +postgresopsrequest.ops.kubedb.com/remove-tls created #### Verify TLS Removed Successfully Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CRO, ```bash -$ kubectl get pgops -n demo remove-tls +kubectl get pgops -n demo remove-tls +``` NAME TYPE STATUS AGE remove-tls ReconfigureTLS Successful 4m -``` - Now first verify if we can connect without using certs. ```bash -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\username}' | base64 -d +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\username}' | base64 -d +``` postgres -$ kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d -U6(h_pYrekLZ2OOd +```bash +kubectl get secrets -n demo ha-postgres-auth -o jsonpath='{.data.\password}' | base64 -d ``` +U6(h_pYrekLZ2OOd ```bash kubectl exec -it -n demo ha-postgres-0 -- bash diff --git a/docs/guides/postgres/reconfigure/cluster.md b/docs/guides/postgres/reconfigure/cluster.md index 3cb0240113..600dc3287c 100644 --- a/docs/guides/postgres/reconfigure/cluster.md +++ b/docs/guides/postgres/reconfigure/cluster.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `Postgres` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `PostgresOpsRequest` to reconfigure its configuration. @@ -54,9 +54,9 @@ shared_buffers=256MB Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo pg-configuration --from-file=./user.conf -secret/pg-configuration created +kubectl create secret generic -n demo pg-configuration --from-file=./user.conf ``` +secret/pg-configuration created In this section, we are going to create a Postgres object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Postgres` CR that we are going to create, @@ -85,14 +85,15 @@ spec: Let's create the `Postgres` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/ha-postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/ha-postgres.yaml ``` +postgres.kubedb.com/ha-postgres created Now, wait until `ha-postgres` has status `Ready`. i.e, ```bash -$ kubectl get pods,pg -n demo +kubectl get pods,pg -n demo +``` NAME READY STATUS RESTARTS AGE pod/ha-postgres-0 2/2 Running 0 2m28s pod/ha-postgres-1 2/2 Running 0 59s @@ -101,11 +102,10 @@ pod/ha-postgres-2 2/2 Running 0 51s NAME VERSION STATUS AGE postgres.kubedb.com/ha-postgres 18.3 Ready 2m38s -``` - Now lets check these parameters, ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql psql (18.3) @@ -122,7 +122,6 @@ postgres=# show shared_buffers; ---------------- 256MB (1 row) -``` You can check the other pods same way. So we have configured custom parameters. ### Reconfigure using new config secret @@ -139,9 +138,9 @@ max_connections = 250 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-pg-configuration --from-file=./user.conf -secret/new-pg-configuration created +kubectl create secret generic -n demo new-pg-configuration --from-file=./user.conf ``` +secret/new-pg-configuration created #### Create PostgresOpsRequest @@ -171,9 +170,9 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/reconfigure-using-secret.yaml -postgresopsrequest.ops.kubedb.com/pgops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/reconfigure-using-secret.yaml ``` +postgresopsrequest.ops.kubedb.com/pgops-reconfigure-config created #### Verify the new configuration is working @@ -182,16 +181,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CR, ```bash -$ kubectl get pgops -n demo +kubectl get pgops -n demo +``` NAME TYPE STATUS AGE pgops-reconfigure-config Reconfigure Successful 3m21s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. Now let's connect to a postgres instance and run a postgres internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql psql (18.3) @@ -203,8 +203,6 @@ postgres=# show max_connections; 250 (1 row) -``` - As we can see from the configuration has changed, the value of `max_connections` has been changed from `200` to `250`. You can check for other pods in the same way. @@ -237,9 +235,9 @@ Here, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/apply-config.yaml -postgresopsrequest.ops.kubedb.com/pgops-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/apply-config.yaml ``` +postgresopsrequest.ops.kubedb.com/pgops-reconfigure-apply-config created #### Verify the new configuration is working @@ -249,16 +247,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CR, ```bash -$ kubectl get postgresopsrequest pgops-reconfigure-apply-config -n demo +kubectl get postgresopsrequest pgops-reconfigure-apply-config -n demo +``` NAME TYPE STATUS AGE apply-config Reconfigure Successful 4m59s -``` We can see this ops request was successful. Now let's connect to a postgres instance and run a postgres internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ cat /etc/config/user.conf #________******kubedb.com/inline-config******________# @@ -282,8 +281,6 @@ postgres=# show shared_buffers; 512MB (1 row) -``` - As we can see from above the configuration has been changed, the value of `max_connections` has been changed from `250` to `230` and the `shared_buffers` has been changed `256MB` to `512MB`. @@ -318,9 +315,9 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/remove-config.yaml -postgresopsrequest.ops.kubedb.com/remove-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/reconfigure/remove-config.yaml ``` +postgresopsrequest.ops.kubedb.com/remove-config created #### Verify the new configuration is working @@ -329,16 +326,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configSec Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CR, ```bash -$ kubectl get pgops -n demo remove-config +kubectl get pgops -n demo remove-config +``` NAME TYPE STATUS AGE remove-config Reconfigure Successful 5m5s -``` - Now let's connect to a postgres instance and run a postgres internal command to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo ha-postgres-0 -- bash +kubectl exec -it -n demo ha-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, pg-coordinator, postgres-init-container (init) ha-postgres-0:/$ psql psql (18.3) @@ -356,8 +353,6 @@ postgres=# show shared_buffers; 256MB (1 row) -``` - As we can see from the configuration has changed to its default value. So removal of existing custom configuration using `PostgresOpsRequest` is successful. ## Cleaning Up @@ -365,9 +360,15 @@ As we can see from the configuration has changed to its default value. So remova To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete postgres -n demo ha-postgres -$ kubectl delete postgresopsrequest -n demo pgops-reconfigure-apply-config pgops-reconfigure-config remove-config -$ kubectl delete ns demo +kubectl delete postgres -n demo ha-postgres +``` + +```bash +kubectl delete postgresopsrequest -n demo pgops-reconfigure-apply-config pgops-reconfigure-config remove-config +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/postgres/remote-replica/remotereplica.md b/docs/guides/postgres/remote-replica/remotereplica.md index 5143a27bd4..4afbd659c5 100644 --- a/docs/guides/postgres/remote-replica/remotereplica.md +++ b/docs/guides/postgres/remote-replica/remotereplica.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/guides/postgres/remote-replica/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Remote Replica @@ -96,10 +96,10 @@ metadata: type: kubernetes.io/basic-auth ``` -```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-singapore-auth.yaml -secret/pg-singapore-auth created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-singapore-auth.yaml ``` +secret/pg-singapore-auth created ## Deploy PostgreSQL with TLS/SSL configuration ```yaml @@ -148,22 +148,25 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-singapore.yaml -postgres.kubedb.com/pg-singapore created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-singapore.yaml ``` +postgres.kubedb.com/pg-singapore created KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE pg-singapore 18.3 Ready 22h -``` # Exposing to outside world For now we will expose our postgresql with ingress with to outside world ```bash -$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx -$ helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +``` + +```bash +helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx \ --namespace demo --create-namespace \ --set tcp.5432="demo/pg-singapore:5432" ``` @@ -191,19 +194,22 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-ingres.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-ingres.yaml +``` ingress.networking.k8s.io/pg-singapore created -$ kubectl get ingress -n demo + +```bash +kubectl get ingress -n demo +``` NAME CLASS HOSTS ADDRESS PORTS AGE pg-singapore nginx pg-singapore.something.org 172.104.37.147 80 22h -``` # Prepare for Remote Replica We wil use the [kubedb_plugin](/docs/setup/README.md) for generating configuration for remote replica. It will create the appbinding and necessary secrets to connect with source server ```bash -$ kubectl dba remote-config postgres -n demo pg-singapore -uremote -ppass -d 172.104.37.147 -y -home/mehedi/go/src/kubedb.dev/yamls/postgres/pg-singapore-remote-config.yaml +kubectl dba remote-config postgres -n demo pg-singapore -uremote -ppass -d 172.104.37.147 -y ``` +home/mehedi/go/src/kubedb.dev/yamls/postgres/pg-singapore-remote-config.yaml # Create Remote Replica We have prepared another cluster in london region for replicating across cluster. follow the installation instruction [above](/docs/README.md). @@ -212,11 +218,11 @@ We have prepared another cluster in london region for replicating across cluster We will apply the generated config from kubeDB plugin to create the source refs and secrets for it ```bash -$ kubectl apply -f /home/mehedi/go/src/kubedb.dev/yamls/pg-singapore-remote-config.yaml +kubectl apply -f /home/mehedi/go/src/kubedb.dev/yamls/pg-singapore-remote-config.yaml +``` secret/pg-singapore-remote-replica-auth created secret/pg-singapore-client-cert-remote created appbinding.appcatalog.appscode.com/pg-singapore created -``` ### Create remote replica auth We will need to use the same auth secrets for remote replicas as well since operations like clone also replicated the auth-secrets from source server @@ -272,18 +278,18 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-london.yaml -postgres.kubedb.com/pg-london created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/remote-replica/yamls/pg-london.yaml ``` +postgres.kubedb.com/pg-london created Now we will be able to see kubedb will provision a Remote Replica from the source postgres instance. Lets checkout out the petSet , pvc , pv and services associated with it . KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified `PostgreSQL` object: ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE pg-london 18.3 Ready 7m17s -``` ## Validate Remote Replica @@ -292,7 +298,8 @@ At this point we want to validate the replication, we can see `pg-london-0` is c ### Validate from source ```bash -$ kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "select * from pg_stat_replication"; +kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "select * from pg_stat_replication"; +``` pid | usesysid | usename | application_name | client_addr | client_hostname | client_port | backend_start | backend_xmin | state | sent_lsn | write_lsn | flush_lsn | replay_lsn | write_lag | flush_lag | replay_lag | sync_priority | sync_state | reply_time --------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+-----------+-----------+-----------+------------+-----------------+-----------------+-----------------+---------------+------------+------------------------------- 121 | 10 | postgres | pg-singapore-1 | 10.2.1.13 | | 37990 | 2023-10-12 06:53:50.402925+00 | | streaming | 0/89758A8 | 0/89758A8 | 0/89758A8 | 0/89758A8 | 00:00:00.000745 | 00:00:00.00484 | 00:00:00.004848 | 1 | quorum | 2023-10-13 05:43:53.817575+00 @@ -302,7 +309,9 @@ $ kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "select * from ### Validate from remote replica -$ kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from pg_stat_wal_receiver"; +```bash +kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from pg_stat_wal_receiver"; +``` pid | status | receive_start_lsn | receive_start_tli | written_lsn | flushed_lsn | received_tli | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time | slot_name | sender_host | sender_port | conninfo ------+-----------+-------------------+-------------------+-------------+-------------+--------------+-------------------------------+-------------------------------+----------------+-------------------------------+-----------+----------------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 4813 | streaming | 0/8000000 | 1 | 0/8DC01E0 | 0/8DC01E0 | 1 | 2023-10-13 05:54:33.812544+00 | 2023-10-13 05:54:33.893159+00 | 0/8DC01E0 | 2023-10-13 05:54:33.812544+pplication_name=walreceiver sslmode=verify-full sslcompression=0 sslcert=/tls/certs/remote/client.crt sslkey=/tls/certs/remote/client.key sslrootcert=/tls/certs/remote/ca.crt sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres target_session_attrs=any @@ -310,10 +319,14 @@ $ kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from pg_ ## Validation data replication lets create a a database and insert some data -$ kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "create database hi"; +```bash +kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "create database hi"; +``` CREATE DATABASE -$ kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "create table tab_1 ( a int); insert into tab_1 values(generate_series(1,5))"; +```bash +kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "create table tab_1 ( a int); insert into tab_1 values(generate_series(1,5))"; +``` CREATE TABLE INSERT 0 5 @@ -330,7 +343,9 @@ kubectl exec -it -n demo pg-singapore-0 -c postgres -- psql -c "select * from ta ### Validate data on remote replica -$ kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from tab_1"; +```bash +kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from tab_1"; +``` a --- 1 @@ -340,8 +355,6 @@ $ kubectl exec -it -n demo pg-london-0 -c postgres -- psql -c "select * from tab 5 (5 rows) -``` - ## Promote Remote Replica In case your Singapore(primary) cluster goes down, you can manually promote your London(dr cluster) following below step. diff --git a/docs/guides/postgres/restart/restart.md b/docs/guides/postgres/restart/restart.md index b7c2fdd710..0f731dfa32 100644 --- a/docs/guides/postgres/restart/restart.md +++ b/docs/guides/postgres/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Postgres database via a PostgresOpsRequest. Resta - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -58,9 +58,9 @@ spec: Let's create the `Postgres` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/restart/postgres.yaml -postgres.kubedb.com/ha-postgres created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/restart/postgres.yaml ``` +postgres.kubedb.com/ha-postgres created ## Apply Restart opsRequest @@ -87,20 +87,22 @@ spec: Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/restart/ops.yaml -postgresopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/restart/ops.yaml ``` +postgresopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the general secondary pods and lastly will restart the Primary pod of the database. > Note: This will not restart the arbiter pod if you have one. Arbiter pod doesn't have any data related to your database. So you can ignore restarting this pod because no restart is necessary for arbiter pod but if you want so, just kubectl delete the arbiter pod (dbName-arbiter-0) in order to restart it. -```shell -$ kubectl get pgops -n demo restart +```bash +kubectl get pgops -n demo restart +``` NAME TYPE STATUS AGE restart Restart Successful 3m25s - -$ kubectl get pgops -n demo restart -oyaml +```bash +kubectl get pgops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: PostgresOpsRequest metadata: @@ -214,8 +216,6 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning up diff --git a/docs/guides/postgres/rotate-authentication/rotateauth.md b/docs/guides/postgres/rotate-authentication/rotateauth.md index 4f5ec1b469..0b9bca6893 100644 --- a/docs/guides/postgres/rotate-authentication/rotateauth.md +++ b/docs/guides/postgres/rotate-authentication/rotateauth.md @@ -29,9 +29,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Create a PostgreSQL database KubeDB implements a Postgres CRD to define the specification of a PostgreSQL database. @@ -59,25 +59,25 @@ spec: Command: -```shell -$ kubectl apply -f postgres.yaml -postgres.kubedb.com/quick-postgres created +```bash +kubectl apply -f postgres.yaml ``` +postgres.kubedb.com/quick-postgres created Or, you can deploy by using command: -```shell -$ kubectl create -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml -postgres.kubedb.com/quick-postgres created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/quickstart/quick-postgres-v1.yaml ``` +postgres.kubedb.com/quick-postgres created Now, wait until quick-postgres has status Ready. i.e, -```shell -$ kubectl get pg -n demo -w +```bash +kubectl get pg -n demo -w +``` NAME VERSION STATUS AGE quick-postgres 18.3 Ready 7m36s -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the secret. @@ -90,8 +90,9 @@ $ kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.password}' yFj_WnVA9rxfQlLt ```` Now, you can exec into the pod `quick-postgres-0` and connect to database using `username` and `password` -```shell -$ kubectl exec -it -n demo quick-postgres-0 -- bash +```bash +kubectl exec -it -n demo quick-postgres-0 -- bash +``` Defaulted container "postgres" out of: postgres, postgres-init-container (init) quick-postgres-0:/$ PGPASSWORD=yFj_WnVA9rxfQlLt psql -U postgres -d postgres -p 5432 -h quick-postgres.demo.svc @@ -103,7 +104,6 @@ postgres=# \dt --------+--------------------+-------+---------- public | kubedb_write_check | table | postgres (1 row) -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth PostgresOpsRequest @@ -129,19 +129,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Postgres. Let's create the `PostgresOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/rotate-auth/rotate-auth-generated.yaml + ``` postgresopsrequest.ops.kubedb.com/pgops-rotate-auth-generated created -``` Let's wait for `PostgresOpsrequest` to be `Successful`. Run the following command to watch `PostgresOpsrequest` CRO -```shell - $ kubectl get postgresopsrequest -n demo + ```bash + kubectl get postgresopsrequest -n demo + ``` NAME TYPE STATUS AGE pgops-rotate-auth-generated RotateAuth Successful 7m47s -``` If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe postgresopsrequest -n demo pgops-rotate-auth-generated +```bash +kubectl describe postgresopsrequest -n demo pgops-rotate-auth-generated +``` Name: pgops-rotate-auth-generated Namespace: demo Labels: @@ -222,38 +223,45 @@ $ kubectl describe postgresopsrequest -n demo pgops-rotate-auth-generated Normal ResumeDatabase 19m KubeDB Ops-manager Operator Resuming PostgreSQL demo/quick-postgres Normal ResumeDatabase 19m KubeDB Ops-manager Operator Successfully resumed PostgreSQL demo/quick-postgres Normal Successful 19m KubeDB Ops-manager Operator Successfully Rotated Postgres Auth secret for demo/quick-postgres - -``` **Verify Auth is rotated** -```shell -$ kubectl get pg -n demo quick-postgres -ojson | jq .spec.authSecret.name +```bash +kubectl get pg -n demo quick-postgres -ojson | jq .spec.authSecret.name +``` "quick-postgres-auth" -$ kubectl get secret -n demo quick-postgres-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo quick-postgres-auth -o=jsonpath='{.data.username}' | base64 -d +``` postgres -$ kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d - zGB9GF!NXwI.2HP9⏎ + +```bash +kubectl get secret -n demo quick-postgres-auth -o jsonpath='{.data.password}' | base64 -d ``` + zGB9GF!NXwI.2HP9⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo quick-postgres-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo quick-postgres-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` postgres -$ kubectl get secret -n demo quick-postgres-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -yFj_WnVA9rxfQlLt + +```bash +kubectl get secret -n demo quick-postgres-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +yFj_WnVA9rxfQlLt The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, > **Note:** Can not change the username while rotating authentication. The username must be same as 'postgres' which is the current username of the database. -```shell -$ kubectl create secret generic quick-postgres-user-auth -n demo \ +```bash +kubectl create secret generic quick-postgres-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=postgres \ --from-literal=password=postgres-secret - secret/quick-postgres-user-auth created ``` + secret/quick-postgres-user-auth created Now create a `PostgresOpsRequest` with `RotateAuth` type. Below is the YAML of the `PostgresOpsRequest` that we are going to create, @@ -282,21 +290,22 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/rotate-auth/rotate-auth-user.yaml -postgresopsrequest.ops.kubedb.com/pgops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/postgres/rotate-auth/rotate-auth-user.yaml ``` +postgresopsrequest.ops.kubedb.com/pgops-rotate-auth-user created Let’s wait for `PostgresOpsRequest` to be Successful. Run the following command to watch `PostgresOpsRequest` CRO: -```shell -$ kubectl get postgresopsrequest -n demo +```bash +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-rotate-auth-generated RotateAuth Successful 19h pgops-rotate-auth-user RotateAuth Successful 7m44s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe postgresopsrequest -n demo pgops-rotate-auth-user +```bash +kubectl describe postgresopsrequest -n demo pgops-rotate-auth-user +``` Name: pgops-rotate-auth-user Namespace: demo Labels: @@ -380,24 +389,31 @@ Events: Normal ResumeDatabase 9m58s KubeDB Ops-manager Operator Resuming PostgreSQL demo/quick-postgres Normal ResumeDatabase 9m58s KubeDB Ops-manager Operator Successfully resumed PostgreSQL demo/quick-postgres Normal Successful 9m58s KubeDB Ops-manager Operator Successfully Rotated Postgres Auth secret for demo/quick-postgres - -``` **Verify auth is rotate** -```shell -$ kubectl get pg -n demo quick-postgres -ojson | jq .spec.authSecret.name +```bash +kubectl get pg -n demo quick-postgres -ojson | jq .spec.authSecret.name +``` "quick-postgres-user-auth" -$ kubectl get secret -n demo quick-postgres-user-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo quick-postgres-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` postgres -$ kubectl get secret -n demo quick-postgres-user-auth -o=jsonpath='{.data.password}' | base64 -d -postgres-secret + +```bash +kubectl get secret -n demo quick-postgres-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +postgres-secret Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo quick-postgres-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo quick-postgres-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` postgres -$ kubectl get secret -n demo quick-postgres-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -zGB9GF!NXwI.2HP9 + +```bash +kubectl get secret -n demo quick-postgres-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +zGB9GF!NXwI.2HP9 The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -406,14 +422,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete postgresopsrequest pgops-rotate-auth-generated pgops-rotate-auth-user -n demo +```bash +kubectl delete postgresopsrequest pgops-rotate-auth-generated pgops-rotate-auth-user -n demo +``` postgresopsrequest.ops.kubedb.com "pgops-rotate-auth-generated" "pgops-rotate-auth-user" deleted -$ kubectl delete secret -n demo quick-postgres-user-auth + +```bash +kubectl delete secret -n demo quick-postgres-user-auth +``` secret "quick-postgres-user-auth" deleted -$ kubectl delete secret -n demo quick-postgres-auth -secret "quick-postgres-auth" deleted + +```bash +kubectl delete secret -n demo quick-postgres-auth ``` +secret "quick-postgres-auth" deleted ## Next Steps diff --git a/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/index.md b/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/index.md index 404264fcd9..9e6e2a06f7 100644 --- a/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/index.md +++ b/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to increase/decrease th To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -49,7 +49,8 @@ At first, we are going to deploy a Cluster server with 3 members. Then, we are g When you have installed `KubeDB`, it has created `PostgresVersion` CR for all supported `Postgres` versions. Let's check the supported Postgres versions, ```bash -$ kubectl get postgresversion +kubectl get postgresversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 10.16 10.16 Official postgres:10.16-alpine 63s 10.16-debian 10.16 Official postgres:10.16 63s @@ -81,7 +82,6 @@ timescaledb-2.1.0-pg11 11.11 TimescaleDB timescale/timescaledb:2.1.0- timescaledb-2.1.0-pg12 12.6 TimescaleDB timescale/timescaledb:2.1.0-pg12-oss 63s timescaledb-2.1.0-pg13 13.2 TimescaleDB timescale/timescaledb:2.1.0-pg13-oss 63s timescaledb-2.5.0-pg14.1 14.1 TimescaleDB timescale/timescaledb:2.5.0-pg14-oss 63s -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `Postgres`. You can use any non-deprecated version. Here, we are going to create a Postgres Cluster using `Postgres` `18.3`. @@ -113,9 +113,9 @@ spec: Let's create the `Postgres` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/postgres.yaml -postgres.kubedb.com/pg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/postgres.yaml ``` +postgres.kubedb.com/pg created **Wait for the cluster to be ready:** @@ -123,22 +123,24 @@ postgres.kubedb.com/pg created Now, watch `Postgres` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get postgres -n demo pg +watch -n 3 kubectl get postgres -n demo pg +``` Every 3.0s: kubectl get postgres -n demo pg emon-r7: Thu Dec 2 15:31:16 2021 NAME VERSION STATUS AGE pg 18.3 Ready 4h40m - -$ watch -n 3 kubectl get petset -n demo pg +```bash +watch -n 3 kubectl get petset -n demo pg +``` Every 3.0s: kubectl get petset -n demo pg emon-r7: Thu Dec 2 15:31:38 2021 NAME READY AGE pg 3/3 4h41m - - -$ watch -n 3 kubectl get pods -n demo +```bash +watch -n 3 kubectl get pods -n demo +``` Every 3.0s: kubectl get pod -n demo emon-r7: Thu Dec 2 15:33:24 2021 NAME READY STATUS RESTARTS AGE @@ -146,18 +148,17 @@ pg-0 2/2 Running 0 4h25m pg-1 2/2 Running 0 4h26m pg-2 2/2 Running 0 4h26m -``` - Let's verify that the PetSet's pods have joined into cluster, ```bash -$ kubectl get secrets -n demo pg-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo pg-auth -o jsonpath='{.data.username}' | base64 -d +``` postgres -$ kubectl get secrets -n demo pg-auth -o jsonpath='{.data.password}' | base64 -d -b3b5838EhjwsiuFU - +```bash +kubectl get secrets -n demo pg-auth -o jsonpath='{.data.password}' | base64 -d ``` +b3b5838EhjwsiuFU So, we can see that our cluster has 3 members. Now, we are ready to apply the horizontal scale to this Postgres cluster. @@ -192,9 +193,9 @@ Here, Let's create the `PostgresOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/pg-scale-up.yaml -postgresopsrequest.ops.kubedb.com/pg-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/pg-scale-up.yaml ``` +postgresopsrequest.ops.kubedb.com/pg-scale-up created **Verify Scale-Up Succeeded:** @@ -203,14 +204,13 @@ If everything goes well, `KubeDB` Ops Manager will scale up the PetSet's `Pod`. First, we will wait for `PostgresOpsRequest` to be successful. Run the following command to watch `PostgresOpsRequest` cr, ```bash -$ watch kubectl get postgresopsrequest -n demo pg-scale-up +watch kubectl get postgresopsrequest -n demo pg-scale-up +``` Every 2.0s: kubectl get postgresopsrequest -n demo pg-scale-up emon-r7: Thu Dec 2 17:57:36 2021 NAME TYPE STATUS AGE pg-scale-up HorizontalScaling Successful 8m23s -``` - You can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest`, we will see that the `Postgres` cluster is scaled up. ```bash @@ -299,7 +299,8 @@ Events: Now, we are going to verify whether the number of members has increased to meet up the desired state. So let's check the new pods logs to see if they have joined in the cluster as new replica. ```bash -$ kubectl logs -n demo pg-4 -c postgres -f +kubectl logs -n demo pg-4 -c postgres -f +``` waiting for the role to be decided ... running the initial script ... Running as Replica @@ -319,8 +320,6 @@ take base basebackup... 2021-12-02 11:50:11.157 UTC [17] LOG: database system is ready to accept read only connections 2021-12-02 11:50:11.162 UTC [35] LOG: started streaming WAL from primary at 0/9000000 on timeline 2 -``` - You can see above that this pod is streaming wal from primary as replica. It verifies that we have successfully scaled up. #### Scale Down @@ -348,9 +347,9 @@ spec: Let's create the `PostgresOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/pg-scale-down.yaml -postgresopsrequest.ops.kubedb.com/pg-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/horizontal-scaling/scale-horizontally/yamls/pg-scale-down.yaml ``` +postgresopsrequest.ops.kubedb.com/pg-scale-down created **Verify Scale-down Succeeded:** @@ -359,19 +358,18 @@ If everything goes well, `KubeDB` Ops Manager will scale down the PetSet's `Pod` Now, we will wait for `PostgresOpsRequest` to be successful. Run the following command to watch `PostgresOpsRequest` cr, ```bash -$ watch kubectl get postgresopsrequest -n demo pg-scale-down +watch kubectl get postgresopsrequest -n demo pg-scale-down +``` Every 2.0s: kubectl get postgresopsrequest -n demo pg-scale-down emon-r7: Thu Dec 2 18:15:37 2021 NAME TYPE STATUS AGE pg-scale-down HorizontalScaling Successful 115s - -``` - You can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest`, we shall see that the `Postgres` cluster is scaled down. ```bash -$ kubectl describe postgresopsrequest -n demo pg-scale-down +kubectl describe postgresopsrequest -n demo pg-scale-down +``` Name: pg-scale-down Namespace: demo Labels: @@ -451,19 +449,17 @@ Events: Normal ResumeDatabase 91s KubeDB Enterprise Operator Resuming PostgreSQL demo/pg Normal ResumeDatabase 91s KubeDB Enterprise Operator Successfully resumed PostgreSQL demo/pg Normal Successful 91s KubeDB Enterprise Operator Successfully Horizontally Scaled Database -``` Now, we are going to verify whether the number of members has decreased to meet up the desired state, Let's check, the postgres status if it's ready then the scale-down is successful. ```bash -$ kubectl get postgres -n demo pg +kubectl get postgres -n demo pg +``` Every 3.0s: kubectl get postgres -n demo pg emon-r7: Thu Dec 2 18:16:39 2021 NAME VERSION STATUS AGE pg 18.3 Ready 7h26m -``` - You can see above that our `Postgres` cluster now has a total of 4 members. It verifies that we have successfully scaled down. ## Cleaning Up diff --git a/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/index.md b/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/index.md index 5f3c09d925..a48195ca95 100644 --- a/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/index.md +++ b/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `kubeDB-Ops-Manager` to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls) directory of [kubedb/doc](https://github.com/kubedb/docs) repository. @@ -45,7 +45,8 @@ Here, we are going to deploy a `Postgres` instance using a supported version by When you have installed `KubeDB`, it has created `PostgresVersion` CR for all supported `Postgres` versions. Let's check the supported Postgres versions, ```bash -$ kubectl get postgresversion +kubectl get postgresversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 10.16 10.16 Official postgres:10.16-alpine 63s 10.16-debian 10.16 Official postgres:10.16 63s @@ -77,7 +78,6 @@ timescaledb-2.1.0-pg11 11.11 TimescaleDB timescale/timescaledb:2.1.0- timescaledb-2.1.0-pg12 12.6 TimescaleDB timescale/timescaledb:2.1.0-pg12-oss 63s timescaledb-2.1.0-pg13 13.2 TimescaleDB timescale/timescaledb:2.1.0-pg13-oss 63s timescaledb-2.5.0-pg14.1 14.1 TimescaleDB timescale/timescaledb:2.5.0-pg14-oss 63s -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `Postgres`. You can use any non-deprecated version. Here, we are going to create a postgres using non-deprecated `Postgres` version `18.3`. @@ -109,9 +109,9 @@ spec: Let's create the `Postgres` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls/postgres.yaml -postgres.kubedb.com/pg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls/postgres.yaml ``` +postgres.kubedb.com/pg created **Check postgres Ready to Scale:** @@ -119,19 +119,24 @@ postgres.kubedb.com/pg created Now, watch `Postgres` is going to be in `Running` state and also watch `PetSet` and its pod is created and going to be in `Running` state, ```bash -$ watch -n 3 kubectl get postgres -n demo pg +watch -n 3 kubectl get postgres -n demo pg +``` Every 3.0s: kubectl get postgres -n demo pg emon-r7: Thu Dec 2 10:53:54 2021 NAME VERSION STATUS AGE pg 18.3 Ready 3m16s -$ watch -n 3 kubectl get petset -n demo pg +```bash +watch -n 3 kubectl get petset -n demo pg +``` Every 3.0s: kubectl get petset -n demo pg emon-r7: Thu Dec 2 10:54:31 2021 NAME READY AGE pg 3/3 3m54s -$ watch -n 3 kubectl get pod -n demo +```bash +watch -n 3 kubectl get pod -n demo +``` Every 3.0s: kubectl get pod -n demo emon-r7: Thu Dec 2 10:55:29 2021 NAME READY STATUS RESTARTS AGE @@ -139,12 +144,11 @@ pg-0 2/2 Running 0 4m51s pg-1 2/2 Running 0 3m50s pg-2 2/2 Running 0 3m46s -``` - Let's check the `pg-0` Pod's postgres container's resources, As there are two containers, And Postgres container is the first container So it's index will be 0. ```bash -$ kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1Gi" @@ -155,8 +159,6 @@ $ kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' } } -``` - Now, We are ready to apply a vertical scale on this postgres database. #### Vertical Scaling @@ -197,9 +199,9 @@ Here, Let's create the `PostgresOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls/pg-vertical-scaling.yaml -postgresopsrequest.ops.kubedb.com/pg-scale-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/scaling/vertical-scaling/scale-vertically/yamls/pg-vertical-scaling.yaml ``` +postgresopsrequest.ops.kubedb.com/pg-scale-vertical created **Verify Postgres resources updated successfully:** @@ -208,19 +210,18 @@ If everything goes well, `KubeDB-Ops-Manager` will update the resources of the P First, we will wait for `PostgresOpsRequest` to be successful. Run the following command to watch `PostgresOpsRequest` cr, ```bash -$ watch kubectl get postgresopsrequest -n demo pg-scale-vertical - +watch kubectl get postgresopsrequest -n demo pg-scale-vertical +``` Every 2.0s: kubectl get postgresopsrequest -n demo pg-scale-ve... emon-r7: Thu Dec 2 11:09:49 2021 NAME TYPE STATUS AGE pg-scale-vertical VerticalScaling Successful 3m42s -``` - We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest`, we will see that the postgres resources are updated. ```bash -$ kubectl describe postgresopsrequest -n demo pg-scale-vertical +kubectl describe postgresopsrequest -n demo pg-scale-vertical +``` Name: pg-scale-vertical Namespace: demo Labels: @@ -322,12 +323,11 @@ Events: Normal ResumeDatabase 2m22s KubeDB Enterprise Operator Successfully resumed PostgreSQL demo/pg Normal Successful 2m22s KubeDB Enterprise Operator Successfully Vertically Scaled Database -``` - Now, we are going to verify whether the resources of the postgres instance has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "700m", @@ -339,8 +339,6 @@ $ kubectl get pod -n demo pg-0 -o json | jq '.spec.containers[0].resources' } } -``` - The above output verifies that we have successfully scaled up the resources of the Postgres. ## Cleaning Up diff --git a/docs/guides/postgres/synchronous/index.md b/docs/guides/postgres/synchronous/index.md index 9c1ed7981a..b4ffcab374 100644 --- a/docs/guides/postgres/synchronous/index.md +++ b/docs/guides/postgres/synchronous/index.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/postgres](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/postgres) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -35,9 +35,9 @@ namespace/demo created Now, create Postgres crd specifying `spec.streamingMode` with `Synchronous` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/synchronous/postgres.yaml -postgres.kubedb.com/demo-pg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/synchronous/postgres.yaml ``` +postgres.kubedb.com/demo-pg created Below is the YAML for the Postgres crd we just created. @@ -68,7 +68,8 @@ All participating replicas therefore report `sync_state` as `quorum`. Let's check in the postgres cluster that we have deployed. Now, exec into the current primary, in our case it is Pod `demo-pg-0`. ```bash -$ kubectl exec -it -n demo demo-pg-0 -c postgres -- bash +kubectl exec -it -n demo demo-pg-0 -c postgres -- bash +``` bash-5.1$ psql psql (18.3) Type "help" for help. @@ -78,8 +79,6 @@ postgres=# select application_name, client_addr, state, sent_lsn, write_lsn, flu ------------------+-------------+-----------+-----------+-----------+-----------+------------+------------ demo-pg-1 | 10.244.0.22 | streaming | 0/5000060 | 0/5000060 | 0/5000060 | 0/5000060 | quorum demo-pg-2 | 10.244.0.24 | streaming | 0/5000060 | 0/5000060 | 0/5000060 | 0/5000060 | quorum - -``` But Users can also configure a Synchronous replication cluster where all the replica are in `sync` with current primary. Let's see how a user can do so, Users need to provide `custom configuration` with setting the config for `synchronous_standby_names`. @@ -88,7 +87,8 @@ In this scenario, We can set all the 2 replicas server as synchronous replica wi We need to provide `synchronous_standby_names = 'FIRST 2 (*)'` inside custom configuration. That`s all, Then you can see that all the replicas are configured as synchronous replica. ```bash -$ kubectl exec -it -n demo demo-pg-0 -c postgres -- bash +kubectl exec -it -n demo demo-pg-0 -c postgres -- bash +``` bash-5.1$ psql psql (18.3) Type "help" for help. @@ -98,8 +98,6 @@ postgres=# select application_name, client_addr, state, sent_lsn, write_lsn, flu ------------------+-------------+-----------+-----------+-----------+-----------+------------+------------ demo-pg-1 | 10.244.0.22 | streaming | 0/5000060 | 0/5000060 | 0/5000060 | 0/5000060 | sync demo-pg-2 | 10.244.0.24 | streaming | 0/5000060 | 0/5000060 | 0/5000060 | 0/5000060 | sync - -``` To know how to set custom configuration for postgres please check [here](/docs/guides/postgres/configuration/using-config-file.md). ### synchronous_commit diff --git a/docs/guides/postgres/tls/configure/index.md b/docs/guides/postgres/tls/configure/index.md index 7ede111362..bb8bbae6cf 100644 --- a/docs/guides/postgres/tls/configure/index.md +++ b/docs/guides/postgres/tls/configure/index.md @@ -27,9 +27,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/postgres/tls/configure/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/postgres/tls/configure/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -50,9 +50,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls postgres-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/postgres-ca created +kubectl create secret tls postgres-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/postgres-ca created Now, we are going to create an `Issuer` using the `postgres-ca` secret that contains the ca-certificate we have just created. Below is the YAML of the `Issuer` cr that we are going to create, @@ -128,31 +128,33 @@ You can found more details from [here](/docs/guides/postgres/concepts/postgres.m Let’s create the `Postgres` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/tls/configure/yamls/tls-postgres.yaml -postgres.kubedb.com/pg created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/tls/configure/yamls/tls-postgres.yaml ``` +postgres.kubedb.com/pg created **Wait for the database to be ready:** Now, watch `Postgres` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch kubectl get postgres -n demo pg - + watch kubectl get postgres -n demo pg +``` NAMESPACE NAME VERSION STATUS AGE demo pg 18.3 Ready 62s - -$ watch -n 3 kubectl get petset -n demo pg +```bash +watch -n 3 kubectl get petset -n demo pg +``` NAME READY AGE pg 3/3 2m30s -$ watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=pg +```bash + watch -n 3 kubectl get pod -n demo -l app.kubernetes.io/name=postgreses.kubedb.com,app.kubernetes.io/instance=pg +``` NAME READY STATUS RESTARTS AGE pg-0 2/2 Running 0 3m59s pg-1 2/2 Running 0 3m54s pg-2 2/2 Running 0 3m49s -``` **Verify tls-secrets created successfully:** @@ -163,14 +165,14 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check if the tls-secrets have been created properly, ```bash -$ kubectl get secrets -n demo | grep pg +kubectl get secrets -n demo | grep pg +``` pg-auth kubernetes.io/basic-auth 2 4m41s pg-client-cert kubernetes.io/tls 3 4m40s pg-metrics-exporter-cert kubernetes.io/tls 3 4m40s pg-server-cert kubernetes.io/tls 3 4m41s postgres-ca kubernetes.io/tls 2 5m10s pg-token-xvk9p kubernetes.io/service-account-token 3 4m41s -``` **Verify Postgres Cluster configured with TLS/SSL:** @@ -179,7 +181,8 @@ Now, we are going to connect to the database to verify that `Postgres` server ha Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo pg-0 -- bash +kubectl exec -it -n demo pg-0 -- bash +``` bash-5.1$ ls /tls/certs client exporter server @@ -220,8 +223,6 @@ primary_conninfo = 'application_name=pg-0 host=pg user=postgres password=0WpDlAb #ssl_passphrase_command = '' #ssl_passphrase_command_supports_reload = off -``` - The above output shows that the `Postgres` server is configured with TLS/SSL configuration and in `/var/pv/data/postgresql.conf ` you can see that `ssl= on`. You can also see that the `.crt` and `.key` files are stored in the `/tls/certs/` directory for client and server. **Verify secure connection for SSL required user:** @@ -230,10 +231,10 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, -```bash # creating SSL required user -$ kubectl exec -it -n demo pg-0 -- bash - +```bash +kubectl exec -it -n demo pg-0 -- bash +``` bash-5.1$ psql -d "user=postgres password=$POSTGRES_PASSWORD host=pg port=5432 connect_timeout=15 dbname=postgres sslmode=verify-full sslrootcert=/tls/certs/client/ca.crt" psql (18.3) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off) @@ -244,7 +245,6 @@ postgres=# exit bash-5.1$ psql -d "user=postgres password=$POSTGRES_PASSWORD host=pg port=5432 connect_timeout=15 dbname=postgres sslmode=verify-full" psql: error: root certificate file "/var/lib/postgresql/.postgresql/root.crt" does not exist Either provide the file or change sslmode to disable server certificate verification. -``` From the above output, you can see that only using ca certificate we can access the database securely, otherwise, it ask for the ca verification. Our client certificate is stored in `ls /tls/certs/client` directory. diff --git a/docs/guides/postgres/update-version/versionupgrading/index.md b/docs/guides/postgres/update-version/versionupgrading/index.md index 65a875ab49..06f4780a7e 100644 --- a/docs/guides/postgres/update-version/versionupgrading/index.md +++ b/docs/guides/postgres/update-version/versionupgrading/index.md @@ -29,9 +29,9 @@ This guide will show you how to use `KubeDB` ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/update-version/versionupdating/yamls](/docs/guides/postgres/update-version/versionupgrading/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,7 +48,8 @@ At first, we are going to deploy a Postgres using supported `Postgres` version w When you have installed `KubeDB`, it has created `PostgresVersion` CR for all supported `Postgres` versions. Let's check support versions, ```bash -$ kubectl get postgresversion +kubectl get postgresversion +``` NAME VERSION DISTRIBUTION DB_IMAGE DEPRECATED AGE 10.16 10.16 Official postgres:10.16-alpine 63s 10.16-debian 10.16 Official postgres:10.16 63s @@ -81,9 +82,6 @@ timescaledb-2.1.0-pg12 12.6 TimescaleDB timescale/timescaledb:2.1.0- timescaledb-2.1.0-pg13 13.2 TimescaleDB timescale/timescaledb:2.1.0-pg13-oss 63s timescaledb-2.5.0-pg14.1 14.1 TimescaleDB timescale/timescaledb:2.5.0-pg14-oss 63s - -``` - The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `Postgres`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `PostgresVersion` for `Postgres` Instance that will be possible to update from this version to another version. In the next section, we are going to verify version update constraints. **Check update Constraints:** @@ -119,7 +117,8 @@ For Example: If you want to update from 9.6.21 to 14.1. From the table, you can Let's get one of the `postgresversion` YAML: ```bash -$ kubectl get postgresversion 13.2 -o yaml | kubectl neat +kubectl get postgresversion 13.2 -o yaml | kubectl neat +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: PostgresVersion metadata: @@ -157,9 +156,6 @@ spec: version: "13.13" -``` - - **Deploy Postgres Instance:** In this section, we are going to deploy a Postgres Instance. Then, in the next section, we will update the version of the database using updating. Below is the YAML of the `Postgres` cr that we are going to create, @@ -188,9 +184,9 @@ spec: Let's create the `Postgres` cr we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/update-version/versionupgrading/yamls/postgres.yaml -postgres.kubedb.com/pg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/update-version/versionupgrading/yamls/postgres.yaml ``` +postgres.kubedb.com/pg created **Wait for the database to be ready:** @@ -198,19 +194,24 @@ postgres.kubedb.com/pg created Now, watch `Postgres` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state, ```bash -$ watch -n 3 kubectl get postgres -n demo +watch -n 3 kubectl get postgres -n demo +``` Every 3.0s: kubectl get postgres -n demo NAME VERSION STATUS AGE pg 17.9 Ready 3m17s -$ watch -n 3 kubectl get petset -n demo pg +```bash +watch -n 3 kubectl get petset -n demo pg +``` Every 3.0s: kubectl get petset -n demo pg ac-emon: Tue Nov 30 11:38:12 2021 NAME READY AGE pg 3/3 4m17s -$ watch -n 3 kubectl get pod -n demo +```bash +watch -n 3 kubectl get pod -n demo +``` Every 3.0s: kubectl get pods -n demo Every 3.0s: kubectl get pods -n demo ac-emon: Tue Nov 30 11:39:03 2021 @@ -220,20 +221,22 @@ pg-0 2/2 Running 0 4m55s pg-1 2/2 Running 0 3m15s pg-2 2/2 Running 0 3m11s -``` - Let's verify the `Postgres`, the `PetSet` and its `Pod` image version, ```bash -$ kubectl get pg -n demo pg -o=jsonpath='{.spec.version}{"\n"}' +kubectl get pg -n demo pg -o=jsonpath='{.spec.version}{"\n"}' +``` 17.9 -$ kubectl get petset -n demo pg -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash + kubectl get petset -n demo pg -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/postgres:17.9-alpine -$ kubectl get pod -n demo pg-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/postgres:17.9-alpine +```bash +kubectl get pod -n demo pg-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/postgres:17.9-alpine We are ready to apply updating on this `Postgres` Instance. @@ -268,9 +271,9 @@ Here, Let's create the `PostgresOpsRequest` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/update-version/versionupgrading/yamls/upgrade_version.yaml -postgresopsrequest.ops.kubedb.com/pg-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/update-version/versionupgrading/yamls/upgrade_version.yaml ``` +postgresopsrequest.ops.kubedb.com/pg-update created **Verify Postgres version updated successfully:** @@ -279,17 +282,18 @@ If everything goes well, `KubeDB` ops-manager operator will update the image of At first, we will wait for `PostgresOpsRequest` to be successful. Run the following command to watch `PostgresOpsRequest` cr, ```bash -$ watch -n 3 kubectl get PostgresOpsRequest -n demo pg-update +watch -n 3 kubectl get PostgresOpsRequest -n demo pg-update +``` Every 3.0s: kubectl get PostgresOpsRequest -n demo pg-update NAME TYPE STATUS AGE pg-update UpdateVersion Successful 3m57s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest`, we shall see that the `Postgres`, `PetSet`, and its `Pod` have updated with a new image. ```bash -$ kubectl describe PostgresOpsRequest -n demo pg-update +kubectl describe PostgresOpsRequest -n demo pg-update +``` Name: pg-update Namespace: demo Labels: @@ -443,20 +447,22 @@ Events: Normal Successful 30s KubeDB Enterprise Operator Successfully Updated Database Normal Successful 30s KubeDB Enterprise Operator Successfully Updated Database - ``` - Now, we are going to verify whether the `Postgres`, `PetSet` and it's `Pod` have updated with new image. Let's check, ```bash -$ kubectl get postgres -n demo pg -o=jsonpath='{.spec.version}{"\n"}' +kubectl get postgres -n demo pg -o=jsonpath='{.spec.version}{"\n"}' +``` 18.3 -$ kubectl get petset -n demo pg -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo pg -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/postgres:18.3-alpine -$ kubectl get pod -n demo pg-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/postgres:18.3-alpine +```bash +kubectl get pod -n demo pg-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/postgres:18.3-alpine You can see above that our `Postgres` has been updated with the new version. It verifies that we have successfully updated our Postgres Instance. diff --git a/docs/guides/postgres/virtual_secret/guide.md b/docs/guides/postgres/virtual_secret/guide.md index fd2cd90948..a14a3c193d 100644 --- a/docs/guides/postgres/virtual_secret/guide.md +++ b/docs/guides/postgres/virtual_secret/guide.md @@ -46,19 +46,28 @@ Before you begin, ensure you have the following prerequisites in place: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## How to use Virtual Secrets ### Install Virtual Secrets Server First, install the virtual-secret-server which is a custom api server for the `secrets.virtual-secrets.dev` resource. ```bash -$ helm repo add appscode https://charts.appscode.com/stable/ -$ helm repo update -$ helm search repo appscode/virtual-secrets-server --version=v2025.3.14 -$ helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ +helm repo add appscode https://charts.appscode.com/stable/ +``` + +```bash +helm repo update +``` + +```bash +helm search repo appscode/virtual-secrets-server --version=v2025.3.14 +``` + +```bash +helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ --version=v2025.3.14 -n kubevault --create-namespace ``` @@ -69,28 +78,30 @@ read, list, delete and delete in a kv secret engine named `virtual-secrets.dev` Now let’s configure the vault server with following commands: -```shell # enable kv secret engine in the path virtual-secrets.dev -$ vault secrets enable -path=virtual-secrets.dev -version=2 kv +```bash +vault secrets enable -path=virtual-secrets.dev -version=2 kv +``` Success! Enabled the kv secrets engine at: virtual-secrets.dev/ - # creates a policy with the permission to create, update, read, list and delete -$ vault policy write virtual-secrets-policy - <}}/docs/examples/vault/secretstore.yaml -secretstore.config.virtual-secrets.dev/vault configured +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretstore.yaml ``` +secretstore.config.virtual-secrets.dev/vault configured Here, - `spec.vault` - section describes the connection information for vault. @@ -137,22 +148,23 @@ Here, - Other than that, everything else is similar to a core Kubernetes Secret. Let’s go ahead and apply the Secret, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/virtualsecret.yaml -secret.virtual-secrets.dev/virtual-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/virtualsecret.yaml ``` +secret.virtual-secrets.dev/virtual-secret created Let's list the Secrets to see if it is created or not, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo +```bash +kubectl get secrets.virtual-secrets.dev -n demo +``` NAME TYPE DATA AGE virtual-secret Opaque 2 2d19h -``` We can also get the whole definition of the `Secret`, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +```bash +kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +``` apiVersion: virtual-secrets.dev/v1alpha1 data: password: dmlydHVhbC1zZWNyZXQ= @@ -170,7 +182,6 @@ metadata: uid: c7887183-6885-4435-a3c9-c741b28130a3 secretStoreName: vault type: Opaque -``` We can see that this `Secret`actually behaves identical of the core `Secret`. But the data is not stored in the `etcd` and it is way more secure than using the native `k8s Secret`. @@ -179,15 +190,22 @@ We can see that this `Secret`actually behaves identical of the core `Secret`. Bu We will connect to the Vault by using Vault CLI. Therefore, we need to export the necessary environment variables and port-forward the service. In one terminal port-forward the vault server service, -```shell -$ kubectl port-forward -n demo service/vault 8200 +```bash +kubectl port-forward -n demo service/vault 8200 +``` Forwarding from 127.0.0.1:8200 -> 8200 Forwarding from [::1]:8200 -> 8200 +```bash +export VAULT_ADDR=http://127.0.0.1:8200 +``` + +```bash +export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) +``` + +```bash +vault kv get virtual-secrets.dev/demo/virtual-secret ``` -```shell -$ export VAULT_ADDR=http://127.0.0.1:8200 -$ export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) -$ vault kv get virtual-secrets.dev/demo/virtual-secret ================ Secret Path ================ virtual-secrets.dev/data/demo/virtual-secret @@ -205,7 +223,6 @@ Key Value --- ----- password virtual-secret username appscode -``` We can see that the secret data is stored in the `virtual-secrets.dev/demo/virtual-secret` path where, - `virtual-secret.dev` is the secret engine name. @@ -220,22 +237,30 @@ data from virtual secrets and uses the `Secrets Store CSI Driver` to mount those Let’s go ahead and install `Secrets Store CSI Driver` and `secrets-store-csi-driver-provider-virtual-secrets` into our cluster, -```shell -$ helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts -$ helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +```bash +helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts +``` + +```bash +helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +``` -$ helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 -$ helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 +```bash +helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 +``` + +```bash +helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 ``` If both of them are deployed we should see two new pods in the `kube-system` namespace. -```shell -$ kubectl get pods -n kube-system +```bash +kubectl get pods -n kube-system +``` NAME READY STATUS RESTARTS AGE csi-secrets-store-secrets-store-csi-driver-rvpvm 3/3 Running 0 61s secrets-store-csi-driver-provider-virtual-secrets-m78gv 1/1 Running 0 34s -``` The `Secrets Store CSI Driver` uses a custom resource named `SecretProviderClass` to mount the secret. Let’s go ahead and create that, ```yaml @@ -258,10 +283,10 @@ Here, > **Note:** We can also call the mount subresource of the virtual secret to create the SecretProviderClass for us. The namespace and the name of SecretProviderClass should be same as the Virtual Secret it is being used for. Let’s create the SecretProviderClass, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml -secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml ``` +secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created ### Use Virtual Secrets with Postgres @@ -298,28 +323,29 @@ Here, We can now apply the Postgres custom resource, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/virtual_secret/postgres.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/postgres/virtual_secret/postgres.yaml +``` Postgres.kubedb.com/pg created -``` Now, wait until `pg` has status `Ready`. i.e. , -```shell -$ kubectl get Postgres -n demo +```bash +kubectl get Postgres -n demo +``` NAME VERSION STATUS AGE pg 8.2.2 Ready 2m5s -``` Now, lets go ahead and check what secret it is using, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo +```bash +kubectl get secrets.virtual-secrets.dev -n demo +``` NAME TYPE DATA AGE virtual-secret Opaque 2 11d19h -``` We can see that the Postgres user password is stored in the vault server as named `virtual-secret` . Let’s get the whole definition of the virtual secret, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +```bash +kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +``` apiVersion: virtual-secrets.dev/v1alpha1 data: password: RUdKbCF0SEVHelpvWXdNaQ== @@ -348,10 +374,10 @@ metadata: uid: 5c3c2a39-698d-44e7-8c63-8c14593581ad secretStoreName: vault type: kubernetes.io/basic-auth -``` In our vault server, we can check if this data exists or not, -```shell -$ vault kv get virtual-secrets.dev/demo/virtual-secret +```bash +vault kv get virtual-secrets.dev/demo/virtual-secret +``` ============ Secret Path ============ virtual-secrets.dev/data/demo/virtual-secret @@ -369,7 +395,6 @@ Key Value --- ----- password EGJl!tHEGzZoYwMi username postgres -``` We can see that the Postgres user password is stored in the vault server. Now let’s go ahead and connect to the database using the `psql` client to check whether it is working or not. @@ -403,16 +428,31 @@ We can see that we are able to connect to the database and create a database and ## Cleanup To clean up the resources created in this guide, run the following commands: ```bash -$ kubectl delete -n demo postgres pg -$ kubectl delete secretproviderclass -n demo virtual-secret -$ kubectl delete ns demo -$ helm uninstall virtual-secrets-server -n kubevault -$ helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system -$ helm uninstall csi-secrets-store -n kube-system +kubectl delete -n demo postgres pg +``` + +```bash +kubectl delete secretproviderclass -n demo virtual-secret +``` + +```bash +kubectl delete ns demo +``` + +```bash +helm uninstall virtual-secrets-server -n kubevault +``` + +```bash +helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system +``` + +```bash +helm uninstall csi-secrets-store -n kube-system ``` If you want to uninstall the `KubeVault`, run: ```bash -$ helm uninstall kubevault --namespace kubevault +helm uninstall kubevault --namespace kubevault ``` ## Next Steps diff --git a/docs/guides/postgres/volume-expansion/ha-cluster/HA Cluster.md b/docs/guides/postgres/volume-expansion/ha-cluster/HA Cluster.md index 0252f094df..341b473d2e 100644 --- a/docs/guides/postgres/volume-expansion/ha-cluster/HA Cluster.md +++ b/docs/guides/postgres/volume-expansion/ha-cluster/HA Cluster.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/volume-expansion/ha-cluster/yamls](/docs/guides/postgres/volume-expansion/ha-cluster/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -47,10 +47,10 @@ Here, we are going to deploy a `Postgres` High Availability cluster using a supp At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE linode-block-storage linodebs.csi.linode.com Delete Immediate true 5m -``` We can see the output from the `linode-block-storage` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -84,30 +84,32 @@ spec: Let's create the `Postgres` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/ha-cluster/yamls/pg-ha-cluster.yaml -postgres.kubedb.com/pg-ha-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/ha-cluster/yamls/pg-ha-cluster.yaml ``` +postgres.kubedb.com/pg-ha-cluster created Now, wait until `pg-ha-cluster` has status `Ready`. i.e, ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE pg-ha-cluster 18.3 Ready 3m6s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo pg-ha-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo pg-ha-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "10Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-037525b1de294233 10Gi RWO Delete Bound demo/data-pg-ha-cluster-0 linode-block-storage 4m24s pvc-3bd05d8b36c84c0a 10Gi RWO Delete Bound demo/data-pg-ha-cluster-1 linode-block-storage 3m2s pvc-f03277c318c44029 10Gi RWO Delete Bound demo/data-pg-ha-cluster-2 linode-block-storage 3m35s -``` You can see the petset has 10GB storage, and the capacity of the persistent volume is also 10GB. @@ -147,9 +149,9 @@ Here, Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/ha-cluster/yamls/vol-exp-ha-cluster.yaml -postgresopsrequest.ops.kubedb.com/pgops-vol-exp-ha-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/ha-cluster/yamls/vol-exp-ha-cluster.yaml ``` +postgresopsrequest.ops.kubedb.com/pgops-vol-exp-ha-cluster created #### Verify Postgres HA Cluster volume expanded successfully @@ -158,15 +160,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CR, ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-vol-exp-ha-cluster VolumeExpansion Successful 105s -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe postgresopsrequest pgops-vol-exp-ha-cluster -n demo +kubectl describe postgresopsrequest pgops-vol-exp-ha-cluster -n demo +``` Name: pgops-vol-exp-ha-cluster Namespace: demo Labels: @@ -228,20 +231,21 @@ Events: Normal ResumeDatabase 2m3s KubeDB Ops-manager Operator Resuming PostgreSQL demo/pg-ha-cluster Normal ResumeDatabase 2m3s KubeDB Ops-manager Operator Successfully resumed PostgreSQL demo/pg-ha-cluster Normal Successful 2m2s KubeDB Ops-manager Operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the `pg-ha-cluster` has expanded to meet the desired state, Let's check that particular petset, ```bash -$ kubectl get petset -n demo pg-ha-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo pg-ha-cluster -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "12Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-037525b1de294233 10Gi RWO Delete Bound demo/data-pg-ha-cluster-0 linode-block-storage 16m pvc-3bd05d8b36c84c0a 12Gi RWO Delete Bound demo/data-pg-ha-cluster-1 linode-block-storage 14m pvc-f03277c318c44029 10Gi RWO Delete Bound demo/data-pg-ha-cluster-2 linode-block-storage 15m -``` The above output verifies that we have successfully expanded the volume of the Postgres HA cluster database. @@ -250,9 +254,11 @@ The above output verifies that we have successfully expanded the volume of the P To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete pg -n demo pg-ha-cluster +kubectl delete pg -n demo pg-ha-cluster +``` postgres.kubedb.com "pg-ha-cluster" deleted -$ kubectl delete postgresopsrequest -n demo pgops-vol-exp-ha-cluster -postgresopsrequest.ops.kubedb.com "pgops-vol-exp-ha-cluster" deleted +```bash +kubectl delete postgresopsrequest -n demo pgops-vol-exp-ha-cluster ``` +postgresopsrequest.ops.kubedb.com "pgops-vol-exp-ha-cluster" deleted diff --git a/docs/guides/postgres/volume-expansion/standalone/standalone.md b/docs/guides/postgres/volume-expansion/standalone/standalone.md index e1a613d297..4f4d391b15 100644 --- a/docs/guides/postgres/volume-expansion/standalone/standalone.md +++ b/docs/guides/postgres/volume-expansion/standalone/standalone.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/postgres/volume-expansion/standalone/yamls](/docs/guides/postgres/volume-expansion/standalone/yamls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -47,10 +47,10 @@ Here, we are going to deploy a `Postgres` standalone using a supported version b At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE linode-block-storage linodebs.csi.linode.com Delete Immediate true 13m -``` We can see the output from the `linode-block-storage` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -84,28 +84,30 @@ spec: Let's create the `Postgres` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/standalone/yamls/pg-standalone.yaml -postgres.kubedb.com/pg-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/standalone/yamls/pg-standalone.yaml ``` +postgres.kubedb.com/pg-standalone created Now, wait until `pg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get pg -n demo +kubectl get pg -n demo +``` NAME VERSION STATUS AGE pg-standalone 18.3 Ready 3m47s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo pg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo pg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "10Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-7a8a538d017a4f32 10Gi RWO Delete Bound demo/data-pg-standalone-0 linode-block-storage 7m -``` You can see the petset has 10GB storage, and the capacity of the persistent volume is also 10GB. @@ -149,9 +151,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `PostgresOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/standalone/yamls/vol-exp-standalone.yaml -postgresopsrequest.ops.kubedb.com/pgops-vol-exp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/postgres/volume-expansion/standalone/yamls/vol-exp-standalone.yaml ``` +postgresopsrequest.ops.kubedb.com/pgops-vol-exp created #### Verify Postgres Standalone volume expanded successfully @@ -160,15 +162,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `PostgresOpsRequest` to be `Successful`. Run the following command to watch `PostgresOpsRequest` CR, ```bash -$ kubectl get postgresopsrequest -n demo +kubectl get postgresopsrequest -n demo +``` NAME TYPE STATUS AGE pgops-vol-exp VolumeExpansion Successful 10m -``` We can see from the above output that the `PostgresOpsRequest` has succeeded. If we describe the `PostgresOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe postgresopsrequest pgops-vol-exp -n demo +kubectl describe postgresopsrequest pgops-vol-exp -n demo +``` Name: pgops-vol-exp Namespace: demo Labels: @@ -228,18 +231,19 @@ Events: Normal PauseDatabase 11m KubeDB Ops-manager Operator Successfully paused Postgres demo/pg-standalone Normal ReadyPetSets 10m KubeDB Ops-manager Operator PetSet is recreated Normal Successful 10m KubeDB Ops-manager Operator Successfully Expanded Volume -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo pg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo pg-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "12Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-7a8a538d017a4f32 12Gi RWO Delete Bound demo/data-pg-standalone-0 linode-block-storage 3m8s -``` The above output verifies that we have successfully expanded the volume of the Postgres standalone database. @@ -248,9 +252,11 @@ The above output verifies that we have successfully expanded the volume of the P To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete pg -n demo pg-standalone +kubectl delete pg -n demo pg-standalone +``` postgres.kubedb.com "pg-standalone" deleted -$ kubectl delete postgresopsrequest -n demo pgops-vol-exp -postgresopsrequest.ops.kubedb.com "pgops-vol-exp" deleted +```bash +kubectl delete postgresopsrequest -n demo pgops-vol-exp ``` +postgresopsrequest.ops.kubedb.com "pgops-vol-exp" deleted diff --git a/docs/guides/proxysql/autoscaler/compute/cluster/index.md b/docs/guides/proxysql/autoscaler/compute/cluster/index.md index f5fc3be661..74dc187f62 100644 --- a/docs/guides/proxysql/autoscaler/compute/cluster/index.md +++ b/docs/guides/proxysql/autoscaler/compute/cluster/index.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare MySQL backend We need a mysql backend for the proxysql server. So we are creating one with the below yaml. @@ -63,17 +63,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 3m51s -``` ## Autoscaling of ProxySQL Cluster @@ -112,22 +112,23 @@ spec: Let's create the `ProxySQL` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Now, wait until `proxy-server` has status `Ready`. i.e, ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 4m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -138,11 +139,11 @@ $ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resour "memory": "300Mi" } } -``` Let's check the ProxySQL resources, ```bash -$ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "proxysql") | .resources' +kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "proxysql") | .resources' +``` { "limits": { "cpu": "200m", @@ -153,7 +154,6 @@ $ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the proxysql. @@ -214,20 +214,23 @@ If a step doesn't finish within the specified timeout, the ops request will resu Let's create the `ProxySQLAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/proxy-as-compute.yaml -proxysqlautoscaler.autoscaling.kubedb.com/proxy-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/autoscaler/compute/cluster/examples/proxy-as-compute.yaml ``` +proxysqlautoscaler.autoscaling.kubedb.com/proxy-as-compute created #### Verify Autoscaling is set up successfully Let's check that the `proxysqlautoscaler` resource is created successfully, ```bash -$ kubectl get proxysqlautoscaler -n demo +kubectl get proxysqlautoscaler -n demo +``` NAME AGE proxy-as-compute 5m56s -$ kubectl describe proxysqlautoscaler proxy-as-compute -n demo +```bash +kubectl describe proxysqlautoscaler proxy-as-compute -n demo +``` Name: proxy-as-compute Namespace: demo Labels: @@ -380,8 +383,6 @@ Status: Memory: 1Gi Vpa Name: proxy-server Events: - -``` So, the `proxysqlautoscaler` resource is created successfully. We can verify from the above output that `status.vpas` contains the `RecommendationProvided` condition to true. And in the same time, `status.vpas.recommendation.containerRecommendations` contain the actual generated recommendation. @@ -391,23 +392,24 @@ Our autoscaler operator continuously watches the recommendation generated and cr Let's watch the `proxysqlopsrequest` in the demo namespace to see if any `proxysqlopsrequest` object is created. After some time you'll see that a `proxysqlopsrequest` will be created based on the recommendation. ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE prxops-proxy-server-6xc1kc VerticalScaling Progressing 7s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE prxops-vpa-proxy-server-z43wc8 VerticalScaling Successful 3m32s -``` We can see from the above output that the `ProxySQLOpsRequest` has succeeded. If we describe the `ProxySQLOpsRequest` we will get an overview of the steps that were followed to scale the proxysql server. ```bash -$ kubectl describe proxysqlopsrequest -n demo prxops-vpa-proxy-server-z43wc8 +kubectl describe proxysqlopsrequest -n demo prxops-vpa-proxy-server-z43wc8 +``` Name: prxops-proxy-server-6xc1kc Namespace: demo Labels: @@ -525,12 +527,12 @@ Events: Normal Starting 5m8s KubeDB Enterprise Operator Resuming ProxySQL database: demo/proxy-server Normal Successful 5m8s KubeDB Enterprise Operator Successfully resumed ProxySQL database: demo/proxy-server Normal Successful 5m8s KubeDB Enterprise Operator Controller has Successfully scaled the ProxySQL database: demo/proxy-server -``` Now, we are going to verify from the Pod, and the ProxySQL yaml whether the resources of the replicaset database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "250m", @@ -542,7 +544,9 @@ $ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resour } } -$ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "proxysql") | .resources' +```bash +kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "proxysql") | .resources' +``` { "limits": { "cpu": "250m", @@ -553,7 +557,6 @@ $ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.podTemplate.spec "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the ProxySQL replicaset database. diff --git a/docs/guides/proxysql/backends/mariadb-galera/index.md b/docs/guides/proxysql/backends/mariadb-galera/index.md index 20b7452267..be068757ba 100644 --- a/docs/guides/proxysql/backends/mariadb-galera/index.md +++ b/docs/guides/proxysql/backends/mariadb-galera/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` operator to set up a `ProxySQL` ser - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MariaDB Backend @@ -60,22 +60,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mariadb-galera/examples/mariadb-galera.yaml -mariadb.kubedb.com/mariadb-galera created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mariadb-galera/examples/mariadb-galera.yaml ``` +mariadb.kubedb.com/mariadb-galera created Let's wait for the MariaDB to be Ready. ```bash -$ kubectl get md -n demo +kubectl get md -n demo +``` NAME VERSION STATUS AGE mariadb-galera 11.6.2 Ready 4m20s -``` Let's first create a user in the backend mariadb server and a database to test the proxy traffic. ```bash -$ kubectl exec -it -n demo mariadb-galera-0 -- bash +kubectl exec -it -n demo mariadb-galera-0 -- bash +``` Defaulted container "mariadb" out of: mariadb, md-coordinator, mariadb-init (init) mysql@mariadb-galera-0:/$ mariadb -uroot -p$MYSQL_ROOT_PASSWORD Welcome to the MariaDB monitor. Commands end with ; or \g. @@ -108,7 +109,6 @@ Query OK, 0 rows affected (0.033 sec) MariaDB [test]> exit Bye -``` Now we are ready to deploy and test our ProxySQL server. @@ -134,23 +134,24 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mariadb-galera/examples/sample-proxysql.yaml -proxysql.kubedb.com/mariadb-proxy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mariadb-galera/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/mariadb-proxy created Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have given 3, so the operator will create 3 nodes for ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend MariaDB server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get prx -n demo +kubectl get prx -n demo +``` NAME VERSION STATUS AGE mariadb-proxy 3.0.1-debian Ready 96s -``` Let's check the pods and associated kubernetes objects ```bash -$ kubectl get petset,pods,svc,secrets -n demo +kubectl get petset,pods,svc,secrets -n demo +``` NAME AGE petset.apps.k8s.appscode.com/mariadb-proxy 108s @@ -167,13 +168,13 @@ NAME TYPE DATA AGE secret/mariadb-proxy-auth kubernetes.io/basic-auth 2 110s secret/mariadb-proxy-configuration Opaque 1 109s secret/mariadb-proxy-monitor kubernetes.io/basic-auth 2 110s -``` ### Check Internal Configuration Lets exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo mariadb-proxy-0 -- bash +kubectl exec -it -n demo mariadb-proxy-0 -- bash +``` proxysql@mariadb-proxy-0:/$ mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 48 @@ -184,7 +185,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_galera_hostgroups and mysql_servers table first. We didn't set it from the yaml. The KubeDB operator will do that for us. @@ -281,13 +281,13 @@ deployment.apps/ubuntu created Lets exec into the pod and install mariadb-galera-client. ```bash -$ kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +``` root@ubuntu-bb47d8d6c-7wndq:/# apt update ... ... .. root@ubuntu-bb47d8d6c-7wndq:/# apt install mysql-client -y Reading package lists... Done ... .. ... -``` Now let's try to connect with the ProxySQL server through the `mariadb-proxy` service as the `test` user. diff --git a/docs/guides/proxysql/backends/mysqlgrp/index.md b/docs/guides/proxysql/backends/mysqlgrp/index.md index cac8344042..54f73fefe3 100644 --- a/docs/guides/proxysql/backends/mysqlgrp/index.md +++ b/docs/guides/proxysql/backends/mysqlgrp/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` operator to set up a `ProxySQL` ser - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MySQL Backend @@ -62,22 +62,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get my -n demo +kubectl get my -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.3 Ready 7m6s -``` Let's first create a user in the backend mysql server and a database to test the proxy traffic. ```bash -$ kubectl exec -it -n demo mysql-server-0 -- bash +kubectl exec -it -n demo mysql-server-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) mysql@mysql-server-0:/$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -125,7 +126,6 @@ mysql> select * FROM performance_schema.replication_group_members; mysql> exit Bye -``` This output from the performance_schema.replication_group_members table in MySQL shows the status of nodes in a Group Replication (GR) setup. We have 3 nodes in your MySQL Group Replication cluster. All 3 nodes are ONLINE – they are healthy and actively participating in replication. mysql-server-0 is the PRIMARY node – it's the one accepting write queries. And mysql-server-1 and mysql-server-2 are SECONDARY – they receive updates from the primary but are read-only. @@ -154,23 +154,24 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-proxysql.yaml -proxysql.kubedb.com/mysql-proxy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/mysql-proxy created Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have given 3, so the operator will create 3 nodes for ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend MySQL server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get prx -n demo +kubectl get prx -n demo +``` NAME VERSION STATUS AGE mysql-proxy 3.0.1-debian Ready 109s -``` Let's check the pods and associated kubernetes objects ```bash -$ kubectl get petset,pods,svc,secrets -n demo +kubectl get petset,pods,svc,secrets -n demo +``` NAME AGE petset.apps.k8s.appscode.com/mysql-proxy 3m59s @@ -187,13 +188,13 @@ NAME TYPE DATA AGE secret/mysql-proxy-auth kubernetes.io/basic-auth 2 4m1s secret/mysql-proxy-configuration Opaque 1 4m1s secret/mysql-proxy-monitor kubernetes.io/basic-auth 2 4m1s -``` ### Check Internal Configuration Lets exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo mysql-proxy-0 -- bash +kubectl exec -it -n demo mysql-proxy-0 -- bash +``` proxysql@mysql-proxy-0:/$ mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 93 @@ -204,7 +205,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_group_replication_hostgroups and mysql_servers table first. We didn't set it from the yaml. The KubeDB operator will do that for us. @@ -283,13 +283,13 @@ deployment.apps/ubuntu created Lets exec into the pod and install mysql-client. ```bash -$ kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +``` root@ubuntu-bb47d8d6c-7wndq:/# apt update ... ... .. root@ubuntu-bb47d8d6c-7wndq:/# apt install mysql-client -y Reading package lists... Done ... .. ... -``` Now let's try to connect with the ProxySQL server through the `mysql-proxy` service as the `test` user. diff --git a/docs/guides/proxysql/backends/xtradb-galera/external/index.md b/docs/guides/proxysql/backends/xtradb-galera/external/index.md index d60d9dde4a..2208a1bc84 100644 --- a/docs/guides/proxysql/backends/xtradb-galera/external/index.md +++ b/docs/guides/proxysql/backends/xtradb-galera/external/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` operator to set up `ProxySQL` for e - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Percona XtraDB Backend @@ -212,16 +212,17 @@ Now we will see how we have filled out the appbinding for each fields. These are enough information to set up a ProxySQL server/cluster for the Percona XtraDB cluster. Now we will apply this to our cluster and refer the appbinding name in the ProxySQL yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/appbinding.yaml -appbinding.appcatalog.appscode.com/xtradb-galera-appbinding created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/appbinding.yaml ``` +appbinding.appcatalog.appscode.com/xtradb-galera-appbinding created We are ready with our backend appbinding. But before we proceed to the ProxySQL server, lets first create some test user and database so that we can use them for testing. Let's first create a user in the backend xtradb server and a database to test the proxy traffic . ```bash -$ kubectl exec -it -n demo xtradb-galera-0 -- bash +kubectl exec -it -n demo xtradb-galera-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -261,7 +262,6 @@ Query OK, 0 rows affected (0.00 sec) mysql> exit Bye -``` We are now ready with our backend. In the next section we will set up our ProxySQL for this backend. @@ -287,9 +287,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/external/examples/sample-proxy-v1.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/external/examples/sample-proxy-v1.yaml ``` + proxysql.kubedb.com/proxysql-server created ```yaml @@ -308,39 +308,39 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/external/examples/sample-proxy-v1alpha2.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/external/examples/sample-proxy-v1alpha2.yaml ``` + proxysql.kubedb.com/proxysql-server created This is the simplest version of a KubeDB ProxySQL server. Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have written 1, so the operator will create a single node ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend MySQL server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 4m -``` Let's check the pod. ```bash -$ kubectl get pods -n demo | grep proxy -proxy-server-0 1/1 Running 0 4m +kubectl get pods -n demo | grep proxy ``` +proxy-server-0 1/1 Running 0 4m ### Check Associated Kubernetes Objects KubeDB operator will create some services and secrets for the ProxySQL object. Let's check. ```bash -$ kubectl get svc,secret -n demo | grep proxy +kubectl get svc,secret -n demo | grep proxy +``` service/proxy-server ClusterIP 10.96.181.182 6033/TCP 4m service/proxy-server-pods ClusterIP None 6032/TCP,6033/TCP 4m secret/proxy-server-auth kubernetes.io/basic-auth 2 4m secret/proxy-server-configuration Opaque 1 4m secret/proxy-server-monitor kubernetes.io/basic-auth 2 4m -``` You can find the description of the associated objects here. @@ -349,7 +349,8 @@ You can find the description of the associated objects here. Let's exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1204 @@ -360,7 +361,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_servers table first. We didn't set it from the yaml. The KubeDB operator will do that for us. @@ -434,14 +434,14 @@ deployment.apps/ubuntu created Let's exec into the pod and install mysql-client. ```bash -$ kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +``` root@ubuntu-867d4588d8-tl7hh:/# apt update ... ... .. root@ubuntu-867d4588d8-tl7hh:/# apt install mysql-client -y Reading package lists... Done ... .. ... root@ubuntu-867d4588d8-tl7hh:/# -``` Now let's try to connect with the ProxySQL server through the `proxy-server` service as the `test` user. diff --git a/docs/guides/proxysql/backends/xtradb-galera/kubedb/index.md b/docs/guides/proxysql/backends/xtradb-galera/kubedb/index.md index 36b48a23ab..d519553833 100644 --- a/docs/guides/proxysql/backends/xtradb-galera/kubedb/index.md +++ b/docs/guides/proxysql/backends/xtradb-galera/kubedb/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` operator to set up a `ProxySQL` ser - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare PerconaXtraDB Backend @@ -60,22 +60,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/kubedb/examples/xtradb-galera.yaml -perconaxtradb.kubedb.com/xtradb-galera created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/kubedb/examples/xtradb-galera.yaml ``` +perconaxtradb.kubedb.com/xtradb-galera created Let's wait for the PerconaXtraDB to be Ready. ```bash -$ kubectl get px -n demo +kubectl get px -n demo +``` NAME VERSION STATUS AGE xtradb-galera 8.0.40 Ready 8m -``` Let's first create a user in the backend percona-xtradb server and a database to test the proxy traffic. ```bash -$ kubectl exec -it -n demo xtradb-galera-0 -- bash +kubectl exec -it -n demo xtradb-galera-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-5.1$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -114,7 +115,6 @@ Query OK, 0 rows affected (0.04 sec) mysql> exit Bye -``` Now we are ready to deploy and test our ProxySQL server. @@ -140,23 +140,24 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/kubedb/examples/xtradb-proxy.yaml -proxysql.kubedb.com/xtradb-proxy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/xtradb-galera/kubedb/examples/xtradb-proxy.yaml ``` +proxysql.kubedb.com/xtradb-proxy created Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have given 3, so the operator will create 3 nodes for ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend PerconaXtraDB server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get prx -n demo +kubectl get prx -n demo +``` NAME VERSION STATUS AGE xtradb-proxy 3.0.1-debian Ready 17m -``` Let's check the pods and associated kubernetes objects ```bash -$ kubectl get petset,pods,svc,secrets -n demo +kubectl get petset,pods,svc,secrets -n demo +``` petset.apps.k8s.appscode.com/xtradb-proxy 18m NAME READY STATUS RESTARTS AGE @@ -172,13 +173,13 @@ NAME TYPE DATA AGE secret/xtradb-proxy-auth kubernetes.io/basic-auth 2 18m secret/xtradb-proxy-configuration Opaque 1 18m secret/xtradb-proxy-monitor kubernetes.io/basic-auth 2 18m -``` ### Check Internal Configuration Lets exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo xtradb-proxy-0 -- bash +kubectl exec -it -n demo xtradb-proxy-0 -- bash +``` proxysql@xtradb-proxy-0:/$ mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 275 @@ -189,7 +190,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_galera_hostgroups and mysql_servers table first. We didn't set it from the YAML. The KubeDB operator will do that for us. @@ -287,13 +287,13 @@ deployment.apps/ubuntu created Lets exec into the pod and install mariadb-galera-client. ```bash -$ kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +kubectl exec -it -n demo ubuntu-bb47d8d6c-7wndq -- bash +``` root@ubuntu-bb47d8d6c-7wndq:/# apt update ... ... .. root@ubuntu-bb47d8d6c-7wndq:/# apt install mysql-client -y Reading package lists... Done ... .. ... -``` Now let's try to connect with the ProxySQL server through the `xtradb-proxy` service as the `test` user. diff --git a/docs/guides/proxysql/clustering/proxysql-cluster/index.md b/docs/guides/proxysql/clustering/proxysql-cluster/index.md index 8d550e6818..981585a47e 100644 --- a/docs/guides/proxysql/clustering/proxysql-cluster/index.md +++ b/docs/guides/proxysql/clustering/proxysql-cluster/index.md @@ -29,9 +29,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to set up a `Pr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare MySQL backend @@ -60,22 +60,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/clustering/proxysql-cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/clustering/proxysql-cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 3m51s -``` Let's first create an user in the backend mysql server and a database to test test the proxy traffic . ```bash -$ kubectl exec -it -n demo mysql-server-0 -- bash +kubectl exec -it -n demo mysql-server-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) root@mysql-server-0:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -114,7 +115,6 @@ Query OK, 0 rows affected (0.00 sec) mysql> exit Bye -``` ## Deploy ProxySQL Cluster @@ -139,26 +139,26 @@ To deploy a simple proxysql cluster all you need to do is just set the `.spec.re Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/clustering/proxysql-cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/clustering/proxysql-cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxysql-server created Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 4m -``` Let's see the pods ```bash -$ kubectl get pods -n demo | grep proxy +kubectl get pods -n demo | grep proxy +``` proxy-server-0 1/1 Running 3 4m proxy-server-1 1/1 Running 3 4m proxy-server-2 1/1 Running 3 4m -``` We can see that three nodes are up now. @@ -166,9 +166,10 @@ We can see that three nodes are up now. Let's check the proxysql_servers table inside the ProxySQL pods. -```bash #first node -$ kubectl exec -it -n demo proxy-server-0 -- bash +```bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 316 @@ -190,10 +191,10 @@ ProxySQLAdmin > select * from runtime_proxysql_servers; ProxySQLAdmin > exit Bye -``` -```bash #second node -$ kubectl exec -it -n demo proxy-server-1 -- bash +```bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin >" Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 316 @@ -215,11 +216,11 @@ ProxySQLAdmin > select * from runtime_proxysql_servers; ProxySQLAdmin >exit Bye -``` -```bash #third node -$ kubectl exec -it -n demo proxy-server-2 -- bash +```bash +kubectl exec -it -n demo proxy-server-2 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin >" Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 316 @@ -241,7 +242,6 @@ ProxySQLAdmin > select * from runtime_proxysql_servers; ProxySQLAdmin >exit Bye -``` From the above output we can see that the proxysql_servers tables has been successfuly set up. @@ -250,7 +250,8 @@ From the above output we can see that the proxysql_servers tables has been succe Let's insert the test user inside the proxysql server ```bash -$ kubectl exec -it -n demo proxy-server-1 -- bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin >" Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 316 @@ -269,8 +270,6 @@ Query OK, 0 rows affected (0.000 sec) ProxySQLAdmin > SAVE MYSQL USERS TO DISK; Query OK, 0 rows affected (0.009 sec) -``` - ## Check load balance Now lets check the load balancing through the cluster. @@ -278,7 +277,8 @@ Now lets check the load balancing through the cluster. First we need to create a script to sent load over the ProxySQL. We will use the test user and the test table to check and send the load. ```bash -$ kubectl exec -it -n demo proxy-server-1 -- bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-1:/# apt update ... ... ... root@proxy-server-1:/# apt install nano @@ -309,12 +309,12 @@ done root@proxy-server-1:/# chmod +x load.sh root@proxy-server-1:/# ./load.sh -``` > You can find the load.sh file [here](/docs/guides/proxysql/clustering/proxysql-cluster/examples/load.sh) ```bash -$ kubectl exec -it -n demo proxy-server-1 -- bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin >" Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 316 @@ -342,7 +342,6 @@ ProxySQLAdmin > select hostgroup,srv_host,Queries from stats_mysql_connection_po | 3 | mysql-server-standby.demo.svc | 100 | | 3 | mysql-server.demo.svc | 34 | +-----------+-------------------------------+---------+ -``` From the above output we can see that the loads are properly distributed over the proxysql servers and the backend mysqls. @@ -355,7 +354,8 @@ We will change the `admin-restapi_enabled` in one cluster and observe the change First check the current status. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ | Variable_name | Value | @@ -365,7 +365,9 @@ root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl root@proxy-server-0:/# exit exit -$ kubectl exec -it -n demo proxy-server-1 -- bash +```bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ | Variable_name | Value | @@ -375,7 +377,9 @@ root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl root@proxy-server-1:/# exit exit -$ kubectl exec -it -n demo proxy-server-2 -- bash +```bash +kubectl exec -it -n demo proxy-server-2 -- bash +``` root@proxy-server-2:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ | Variable_name | Value | @@ -385,13 +389,11 @@ root@proxy-server-2:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl root@proxy-server-2:/# exit exit -``` - Now set the value to `true` in server 0 . ```bash - -$ kubectl exec -it -n demo proxy-server-0 -- bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "set admin-restapi_enabled='true';" root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ @@ -402,7 +404,9 @@ root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl root@proxy-server-0:/# exit exit -$ kubectl exec -it -n demo proxy-server-1 -- bash +```bash +kubectl exec -it -n demo proxy-server-1 -- bash +``` root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ | Variable_name | Value | @@ -412,7 +416,9 @@ root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl root@proxy-server-1:/# exit exit -$ kubectl exec -it -n demo proxy-server-2 -- bash +```bash +kubectl exec -it -n demo proxy-server-2 -- bash +``` root@proxy-server-2:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variables like 'admin-restapi_enabled';" +-----------------------+-------+ | Variable_name | Value | @@ -421,8 +427,6 @@ root@proxy-server-2:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "show variabl +-----------------------+-------+ root@proxy-server-2:/# exit exit - -``` From the above output we can see that the cluster is always in sync and the configuration change is always propagated to other cluster nodes. ## Cluster failover recovery @@ -445,9 +449,9 @@ ProxySQLAdmin > SELECT hostname, checksum, FROM_UNIXTIME(changed_at) changed_at, Now let's delete the pod-2. ```bash -$ kubectl delete pod -n demo proxy-server-2 -pod "proxy-server-2" deleted +kubectl delete pod -n demo proxy-server-2 ``` +pod "proxy-server-2" deleted Let's watch the cluster status now. ```bash @@ -500,10 +504,10 @@ From the above output we can see that the third server is out of sync as it is n Wait for the new pod come up. ```bash -$ kubectl get pod -n demo proxy-server-2 +kubectl get pod -n demo proxy-server-2 +``` NAME READY STATUS RESTARTS AGE proxy-server-2 1/1 Running 0 94s -``` Now check the status again. @@ -536,8 +540,11 @@ From the above output we can see that the new pod is now in sync with the two ot ## Cleaning up ```bash -$ kubectl delete proxysql -n demo proxy-server +kubectl delete proxysql -n demo proxy-server +``` proxysql.kubedb.com "proxy-server" deleted -$ kubectl delete mysql -n demo mysql-server -mysql.kubedb.com "mysql-server" deleted -``` \ No newline at end of file + +```bash +kubectl delete mysql -n demo mysql-server +``` +mysql.kubedb.com "mysql-server" deleted \ No newline at end of file diff --git a/docs/guides/proxysql/concepts/proxysql/index.md b/docs/guides/proxysql/concepts/proxysql/index.md index 9fa6ac3573..6b49aad09d 100644 --- a/docs/guides/proxysql/concepts/proxysql/index.md +++ b/docs/guides/proxysql/concepts/proxysql/index.md @@ -136,11 +136,11 @@ This secret contains a `username` key and a `password` key which contains the us Example: ```bash -$ kubectl create secret generic proxysql-cluster-auth -n demo \ +kubectl create secret generic proxysql-cluster-auth -n demo \ --from-literal=username=cluster \ --from-literal=password=6q8u2jMOWOOZXk -secret "proxysql-cluster-auth" created ``` +secret "proxysql-cluster-auth" created ```yaml apiVersion: v1 @@ -181,7 +181,8 @@ Checkout this [link](/docs/guides/proxysql/concepts/declarative-configuration/in `.spec.configuration.secretName` is another field to pass the bootstrap configuration for the proxysql. If you want to pass the configuration through a secret you can just mention the secret name under this field in `spec.configuration.secretName` field. The secret should look something like the following ```bash -$ kubectl view-secret -n demo my-config-secret -a +kubectl view-secret -n demo my-config-secret -a +``` AdminVariables.cnf=admin_variables= { checksum_mysql_query_rules: true @@ -229,7 +230,6 @@ MySQLVariables.cnf=mysql_variables= max_connections=1024 default_schema="information_schema" } -``` The secret should contain keys none other than `AdminVariables.cnf`, `MySQLVariables.cnf`, `MySQLUsers.cnf`, `MySQLVariables.cnf` . The key names define the contents of the values itself. Important info to add is that the value provided with the keys will be patched to the `proxysql.cnf` file exactly as it is. So be careful with the format when you are going to bootstrap proxysql in this way. diff --git a/docs/guides/proxysql/custom-rbac/index.md b/docs/guides/proxysql/custom-rbac/index.md index 50f94fe110..e453abab1a 100644 --- a/docs/guides/proxysql/custom-rbac/index.md +++ b/docs/guides/proxysql/custom-rbac/index.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/proxysql/custom-rbac/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/proxysql/custom-rbac/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,14 +46,14 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo prx-custom-sa -serviceaccount/prx-custom-sa created +kubectl create serviceaccount -n demo prx-custom-sa ``` +serviceaccount/prx-custom-sa created It should create a service account. ```bash -$ kubectl get serviceaccount -n demo prx-custom-sa -oyaml +kubectl get serviceaccount -n demo prx-custom-sa -oyaml ``` ```yaml apiVersion: v1 @@ -72,9 +72,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the ProxySQL instance named `proxy-server`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/custom-rbac/yamls/prx-custom-role.yaml -role.rbac.authorization.k8s.io/prx-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/custom-rbac/yamls/prx-custom-role.yaml ``` +role.rbac.authorization.k8s.io/prx-custom-role created Below is the YAML for the Role we just created. @@ -100,15 +100,14 @@ This permission is required for ProxySQL pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding prx-custom-rb --role=prx-custom-role --serviceaccount=demo:prx-custom-sa --namespace=demo -rolebinding.rbac.authorization.k8s.io/prx-custom-rb created - +kubectl create rolebinding prx-custom-rb --role=prx-custom-role --serviceaccount=demo:prx-custom-sa --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/prx-custom-rb created It should bind `prx-custom-role` and `prx-custom-sa` successfully. ```bash -$ kubectl get rolebinding -n demo prx-custom-rb -o yaml +kubectl get rolebinding -n demo prx-custom-rb -o yaml ``` ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -133,9 +132,9 @@ subjects: Now, create a ProxySQL crd specifying `spec.podTemplate.spec.serviceAccountName` field to `prx-custom-sa`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/custom-rbac/yamls/my-custom-db.yaml -proxysql.kubedb.com/proxy-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/custom-rbac/yamls/my-custom-db.yaml ``` +proxysql.kubedb.com/proxy-server created Below is the YAML for the ProxySQL crd we just created. @@ -165,19 +164,18 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, PetSet, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo proxy-server-0 +kubectl get pod -n demo proxy-server-0 +``` NAME READY STATUS RESTARTS AGE proxy-server-0 1/1 Running 0 2m44s -``` Check the pod's log to see if the proxy server is ready ```bash -$ kubectl logs -f -n demo proxy-server-0 +kubectl logs -f -n demo proxy-server-0 +``` ... 2022-12-07 04:42:04 [INFO] Cluster: detected a new checksum for mysql_users from peer proxy-server-0.proxy-server-pods.demo:6032, version 2, epoch 1670388124, checksum 0xE6BB9970689336DB . Not syncing yet ... 2022-12-07 04:42:04 [INFO] Cluster: checksum for mysql_users from peer proxy-server-0.proxy-server-pods.demo:6032 matches with local checksum 0xE6BB9970689336DB , we won't sync. -``` - Once we see the local checksum matched in the log, the proxysql server is ready. diff --git a/docs/guides/proxysql/initialization/script_source.md b/docs/guides/proxysql/initialization/script_source.md index 63675c85ad..14da573a8f 100644 --- a/docs/guides/proxysql/initialization/script_source.md +++ b/docs/guides/proxysql/initialization/script_source.md @@ -32,13 +32,15 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo +kubectl create ns demo +``` namespace/demo created -$ kubectl get ns demo +```bash +kubectl get ns demo +``` NAME STATUS AGE demo Active 5s -``` > Note: YAML files used in this tutorial are stored in [docs/guides/proxysql/initialization/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,17 +71,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Wait for the MySQL cluster to be `Ready`: ```bash -$ kubectl get mysql -n demo mysql-server +kubectl get mysql -n demo mysql-server +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 5m -``` ## Option 1: Bootstrap using a raw configuration Secret @@ -167,34 +169,37 @@ Here, Apply the Secret and the ProxySQL object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/proxysql-init-secret.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/proxysql-init-secret.yaml +``` secret/proxysql-init-raw created proxysql.kubedb.com/proxy-init-secret created -``` Wait until ProxySQL goes into the `Ready` state: ```bash -$ kubectl get proxysql -n demo proxy-init-secret +kubectl get proxysql -n demo proxy-init-secret +``` NAME VERSION STATUS AGE proxy-init-secret 3.0.1-debian Ready 2m -``` ### Verify Get the admin credentials and connect to the ProxySQL admin interface (port `6032`): ```bash -$ kubectl get secret -n demo proxy-init-secret-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo proxy-init-secret-auth -o jsonpath='{.data.username}' | base64 -d +``` cluster -$ kubectl get secret -n demo proxy-init-secret-auth -o jsonpath='{.data.password}' | base64 -d -S3cur3P@ssw0rd +```bash +kubectl get secret -n demo proxy-init-secret-auth -o jsonpath='{.data.password}' | base64 -d ``` +S3cur3P@ssw0rd ```bash -$ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT username, active, default_hostgroup, default_schema FROM mysql_users;" +``` +-----------+--------+-------------------+------------------+ | username | active | default_hostgroup | default_schema | +-----------+--------+-------------------+------------------+ @@ -202,8 +207,10 @@ $ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw | superman | 1 | 3 | | +-----------+--------+-------------------+------------------+ -$ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +```bash +kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT rule_id, match_pattern, destination_hostgroup FROM mysql_query_rules;" +``` +---------+---------------+------------------------+ | rule_id | match_pattern | destination_hostgroup | +---------+---------------+------------------------+ @@ -211,8 +218,10 @@ $ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw | 101 | ^SELECT | 3 | +---------+---------------+------------------------+ -$ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +```bash +kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT variable_name, variable_value FROM global_variables WHERE variable_name IN ('mysql-max_connections','mysql-threads','mysql-default_query_timeout','admin-restapi_enabled','admin-restapi_port','admin-refresh_interval');" +``` +------------------------------+----------------+ | variable_name | variable_value | +------------------------------+----------------+ @@ -223,7 +232,6 @@ $ kubectl exec -it -n demo proxy-init-secret-0 -- mysql -u cluster -pS3cur3P@ssw | admin-restapi_port | 6090 | | admin-refresh_interval | 3500 | +------------------------------+----------------+ -``` The `mysql_users`, `mysql_query_rules` and the global variables all reflect exactly what was written in the `proxysql-init-raw` Secret. @@ -288,31 +296,34 @@ See the [Declarative Configuration](/docs/guides/proxysql/concepts/declarative-c Apply the YAML: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/proxysql-init-inline.yaml -proxysql.kubedb.com/proxy-init-inline created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/initialization/examples/proxysql-init-inline.yaml ``` +proxysql.kubedb.com/proxy-init-inline created Wait until ProxySQL goes into the `Ready` state: ```bash -$ kubectl get proxysql -n demo proxy-init-inline +kubectl get proxysql -n demo proxy-init-inline +``` NAME VERSION STATUS AGE proxy-init-inline 3.0.1-debian Ready 2m -``` ### Verify ```bash -$ kubectl get secret -n demo proxy-init-inline-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo proxy-init-inline-auth -o jsonpath='{.data.username}' | base64 -d +``` cluster -$ kubectl get secret -n demo proxy-init-inline-auth -o jsonpath='{.data.password}' | base64 -d -S3cur3P@ssw0rd +```bash +kubectl get secret -n demo proxy-init-inline-auth -o jsonpath='{.data.password}' | base64 -d ``` +S3cur3P@ssw0rd ```bash -$ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT username, active, default_hostgroup, default_schema FROM mysql_users;" +``` +-----------+--------+-------------------+------------------+ | username | active | default_hostgroup | default_schema | +-----------+--------+-------------------+------------------+ @@ -320,8 +331,10 @@ $ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw | superman | 1 | 3 | | +-----------+--------+-------------------+------------------+ -$ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +```bash +kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT rule_id, match_pattern, destination_hostgroup FROM mysql_query_rules;" +``` +---------+----------------------------+------------------------+ | rule_id | match_pattern | destination_hostgroup | +---------+----------------------------+------------------------+ @@ -329,8 +342,10 @@ $ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw | 2 | ^SELECT | 3 | +---------+----------------------------+------------------------+ -$ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ +```bash +kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw0rd -h 127.0.0.1 -P 6032 \ -e "SELECT variable_name, variable_value FROM global_variables WHERE variable_name IN ('mysql-max_connections','mysql-threads','admin-restapi_enabled','admin-restapi_port');" +``` +------------------------+----------------+ | variable_name | variable_value | +------------------------+----------------+ @@ -339,7 +354,6 @@ $ kubectl exec -it -n demo proxy-init-inline-0 -- mysql -u cluster -pS3cur3P@ssw | admin-restapi_enabled | true | | admin-restapi_port | 6070 | +------------------------+----------------+ -``` Since `wolverine` and `superman` also exist on the MySQL backend, ProxySQL was able to log in and fetch their passwords automatically - you can verify a client can actually connect through ProxySQL using those credentials without ever having put a password in the YAML. @@ -348,17 +362,35 @@ Since `wolverine` and `superman` also exist on the MySQL backend, ProxySQL was a To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo proxysql/proxy-init-secret -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo proxysql/proxy-init-secret +kubectl patch -n demo proxysql/proxy-init-secret -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl patch -n demo proxysql/proxy-init-inline -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo proxysql/proxy-init-inline +```bash +kubectl delete -n demo proxysql/proxy-init-secret +``` -$ kubectl patch -n demo mysql/mysql-server -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -$ kubectl delete -n demo mysql/mysql-server +```bash +kubectl patch -n demo proxysql/proxy-init-inline -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete -n demo secret/proxysql-init-raw -$ kubectl delete ns demo +```bash +kubectl delete -n demo proxysql/proxy-init-inline +``` + +```bash +kubectl patch -n demo mysql/mysql-server -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` + +```bash +kubectl delete -n demo mysql/mysql-server +``` + +```bash +kubectl delete -n demo secret/proxysql-init-raw +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/proxysql/monitoring/builtin-prometheus/index.md b/docs/guides/proxysql/monitoring/builtin-prometheus/index.md index 924c91ea31..0f35142463 100644 --- a/docs/guides/proxysql/monitoring/builtin-prometheus/index.md +++ b/docs/guides/proxysql/monitoring/builtin-prometheus/index.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor ProxySQL database using builtin [Prom - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/proxysql/monitoring/builtin-prometheus/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -65,9 +67,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/mysql.yaml -mysql.kubedb.com/mysql-grp created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/mysql.yaml ``` +mysql.kubedb.com/mysql-grp created After applying the above yaml wait for the MySQL to be Ready. @@ -102,32 +104,33 @@ Here, Let's create the ProxySQL crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/proxysql.yaml -proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/proxysql.yaml ``` +proxysql.kubedb.com/proxysql-server created Now, wait for the server to go into `Running` state. ```bash -$ kubectl get proxysql -n demo proxy-server +kubectl get proxysql -n demo proxy-server +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 76s -``` KubeDB will create a separate stats service with name `{ProxySQL crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=proxy-server" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=proxy-server" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE proxy-server ClusterIP 10.106.32.194 6033/TCP 2m3s proxy-server-pods ClusterIP None 6032/TCP,6033/TCP 2m3s proxy-server-stats ClusterIP 10.109.106.92 6070/TCP 2m2s -``` Here, `proxy-server-stats ` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo proxy-server-stats +kubectl describe svc -n demo proxy-server-stats +``` Name: proxy-server-stats Namespace: demo Labels: app.kubernetes.io/instance=proxy-server @@ -146,7 +149,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.34:6070 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -310,20 +312,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/builtin-prometheus/examples/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -334,9 +336,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -345,18 +347,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-5dff66b455-cz9td 1/1 Running 0 42s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `proxy-server-stats` service as one of the targets. diff --git a/docs/guides/proxysql/monitoring/prometheus-operator/index.md b/docs/guides/proxysql/monitoring/prometheus-operator/index.md index 416563d1cd..f78d342dbf 100644 --- a/docs/guides/proxysql/monitoring/prometheus-operator/index.md +++ b/docs/guides/proxysql/monitoring/prometheus-operator/index.md @@ -25,9 +25,9 @@ section_menu_id: guides - To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -42,10 +42,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE default prometheus 1 2m19s -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -96,9 +96,9 @@ KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add l Let's add label `prometheus: prometheus` to `demo` namespace, ```bash -$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' -namespace/demo patched +kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' ``` +namespace/demo patched ## Deploy MySQL as ProxySQL Backend @@ -127,9 +127,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/prometheus-operator/examples/mysql.yaml -mysql.kubedb.com/mysql-grp created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/prometheus-operator/examples/mysql.yaml ``` +mysql.kubedb.com/mysql-grp created After applying the above yaml wait for the MySQL to be Ready. @@ -173,27 +173,27 @@ Here, Let's create the ProxySQL object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/prometheus-operator/examples/proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/monitoring/prometheus-operator/examples/proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Now, wait for the server to go into `Ready` state. ```bash -$ kubectl get proxysql -n demo proxy-server +kubectl get proxysql -n demo proxy-server +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 59s -``` KubeDB will create a separate stats service with name `{ProxySQL crd name}-stats` for monitoring purpose. ```bash -$ $ kubectl get svc -n demo --selector="app.kubernetes.io/instance=proxy-server" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=proxy-server" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE proxy-server ClusterIP 10.99.96.226 6033/TCP 107s proxy-server-pods ClusterIP None 6032/TCP,6033/TCP 107s proxy-server-stats ClusterIP 10.101.190.67 6070/TCP 107s -``` Here, `proxy-server-stats` service has been created for monitoring purpose. @@ -223,10 +223,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `proxy-server-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE proxy-server-stats 4m8s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of ProxySQL crd. @@ -313,20 +313,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n default -l=app=prometheus +kubectl get pod -n default -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 16m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n default prometheus-prometheus-0 9090 +kubectl port-forward -n default prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `proxy-server-stats` service as one of the targets. diff --git a/docs/guides/proxysql/quickstart/mysqlgrp/index.md b/docs/guides/proxysql/quickstart/mysqlgrp/index.md index 70c81c5461..89d589607f 100644 --- a/docs/guides/proxysql/quickstart/mysqlgrp/index.md +++ b/docs/guides/proxysql/quickstart/mysqlgrp/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to set up a `Pr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare MySQL Backend @@ -62,9 +62,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-mysql-v1.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-mysql-v1.yaml ``` +mysql.kubedb.com/mysql-server created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -89,22 +89,23 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-mysql-v1alpha2.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-mysql-v1alpha2.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 3m51s -``` Let's first create a user in the backend mysql server and a database to test the proxy traffic . ```bash -$ kubectl exec -it -n demo mysql-server-0 -- bash +kubectl exec -it -n demo mysql-server-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) root@mysql-server-0:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -143,7 +144,6 @@ Query OK, 0 rows affected (0.00 sec) mysql> exit Bye -``` Now we are ready to deploy and test our ProxySQL server. @@ -169,9 +169,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1.yaml ``` + proxysql.kubedb.com/proxysql-server created @@ -192,39 +192,39 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1alpha2.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/mysqlgrp/examples/sample-proxysql-v1alpha2.yaml ``` + proxysql.kubedb.com/proxysql-server created This is the simplest version of a KubeDB ProxySQL server. Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have written 1, so the operator will create a single node ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend MySQL server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 4m -``` Let's check the pod. ```bash -$ kubectl get pods -n demo | grep proxy -proxy-server-0 1/1 Running 0 4m +kubectl get pods -n demo | grep proxy ``` +proxy-server-0 1/1 Running 0 4m ### Check Associated Kubernetes Objects KubeDB operator will create some services and secrets for the ProxySQL object. Let's check. ```bash -$ kubectl get svc,secret -n demo | grep proxy +kubectl get svc,secret -n demo | grep proxy +``` service/proxy-server ClusterIP 10.96.181.182 6033/TCP 4m service/proxy-server-pods ClusterIP None 6032/TCP,6033/TCP 4m secret/proxy-server-auth kubernetes.io/basic-auth 2 4m secret/proxy-server-configuration Opaque 1 4m secret/proxy-server-monitor kubernetes.io/basic-auth 2 4m -``` You can find the description of the associated objects here. @@ -233,7 +233,8 @@ You can find the description of the associated objects here. Let's exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +``` root@proxy-mysql-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1204 @@ -244,7 +245,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_servers table first. We didn't set it from the yaml. The KubeDB operator will do that for us. @@ -319,14 +319,14 @@ deployment.apps/ubuntu created Let's exec into the pod and install mysql-client. ```bash -$ kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +``` root@ubuntu-867d4588d8-tl7hh:/# apt update ... ... .. root@ubuntu-867d4588d8-tl7hh:/# apt install mysql-client -y Reading package lists... Done ... .. ... root@ubuntu-867d4588d8-tl7hh:/# -``` Now let's try to connect with the ProxySQL server through the `proxy-server` service as the `test` user. diff --git a/docs/guides/proxysql/quickstart/xtradbext/index.md b/docs/guides/proxysql/quickstart/xtradbext/index.md index daef5e0c49..04d3f2395e 100644 --- a/docs/guides/proxysql/quickstart/xtradbext/index.md +++ b/docs/guides/proxysql/quickstart/xtradbext/index.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to set up a `Pr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Percona XtraDB Backend @@ -212,16 +212,17 @@ Now we will see how we have filled out the appbinding for each fields. These are enough information to set up a ProxySQL server/cluster for the Percona XtraDB cluster. Now we will apply this to our cluster and refer the appbinding name in the ProxySQL yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/appbinding.yaml -appbinding.appcatalog.appscode.com/xtradb-galera-appbinding created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/appbinding.yaml ``` +appbinding.appcatalog.appscode.com/xtradb-galera-appbinding created We are ready with our backend appbinding. But before we proceed to the ProxySQL server, lets first create some test user and database so that we can use them for testing. Let's first create a user in the backend xtradb server and a database to test the proxy traffic . ```bash -$ kubectl exec -it -n demo xtradb-galera-0 -- bash +kubectl exec -it -n demo xtradb-galera-0 -- bash +``` Defaulted container "perconaxtradb" out of: perconaxtradb, px-coordinator, px-init (init) bash-4.4$ mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -261,7 +262,6 @@ Query OK, 0 rows affected (0.00 sec) mysql> exit Bye -``` We are now ready with our backend. In the next section we will set up our ProxySQL for this backend. @@ -287,9 +287,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/sample-proxy-v1.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/sample-proxy-v1.yaml ``` + proxysql.kubedb.com/proxysql-server created ```yaml @@ -308,39 +308,39 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/sample-proxy-v1alpha2.yaml - proxysql.kubedb.com/proxysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/quickstart/xtradbext/examples/sample-proxy-v1alpha2.yaml ``` + proxysql.kubedb.com/proxysql-server created This is the simplest version of a KubeDB ProxySQL server. Here in the `.spec.version` field we are saying that we want a ProxySQL-3.0.1 with base image of debian. In the `.spec.replicas` section we have written 1, so the operator will create a single node ProxySQL. The `spec.syncUser` field is set to true, which means all the users in the backend MySQL server will be fetched to the ProxySQL server. Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 4m -``` Let's check the pod. ```bash -$ kubectl get pods -n demo | grep proxy -proxy-server-0 1/1 Running 0 4m +kubectl get pods -n demo | grep proxy ``` +proxy-server-0 1/1 Running 0 4m ### Check Associated Kubernetes Objects KubeDB operator will create some services and secrets for the ProxySQL object. Let's check. ```bash -$ kubectl get svc,secret -n demo | grep proxy +kubectl get svc,secret -n demo | grep proxy +``` service/proxy-server ClusterIP 10.96.181.182 6033/TCP 4m service/proxy-server-pods ClusterIP None 6032/TCP,6033/TCP 4m secret/proxy-server-auth kubernetes.io/basic-auth 2 4m secret/proxy-server-configuration Opaque 1 4m secret/proxy-server-monitor kubernetes.io/basic-auth 2 4m -``` You can find the description of the associated objects here. @@ -349,7 +349,8 @@ You can find the description of the associated objects here. Let's exec into the ProxySQL server pod and get into the admin panel. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +kubectl exec -it -n demo proxy-server-0 -- bash 11:20 +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt="ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1204 @@ -360,7 +361,6 @@ Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > -``` Let's check the mysql_servers table first. We didn't set it from the yaml. The KubeDB operator will do that for us. @@ -434,14 +434,14 @@ deployment.apps/ubuntu created Let's exec into the pod and install mysql-client. ```bash -$ kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +kubectl exec -it -n demo ubuntu-867d4588d8-tl7hh -- bash 12:00 +``` root@ubuntu-867d4588d8-tl7hh:/# apt update ... ... .. root@ubuntu-867d4588d8-tl7hh:/# apt install mysql-client -y Reading package lists... Done ... .. ... root@ubuntu-867d4588d8-tl7hh:/# -``` Now let's try to connect with the ProxySQL server through the `proxy-server` service as the `test` user. diff --git a/docs/guides/proxysql/reconfigure-tls/cluster/index.md b/docs/guides/proxysql/reconfigure-tls/cluster/index.md index 1e035a0663..2ac6cf8f4b 100644 --- a/docs/guides/proxysql/reconfigure-tls/cluster/index.md +++ b/docs/guides/proxysql/reconfigure-tls/cluster/index.md @@ -31,9 +31,9 @@ Below, we are providing some examples for the ops-request. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ### Prepare MySQL Backend @@ -65,24 +65,26 @@ spec: Let's apply the yaml, -``` bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's now wait for the mysql instance to be ready, ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 3m16s -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE mysql-server-0 2/2 Running 0 3m11s mysql-server-1 2/2 Running 0 113s mysql-server-2 2/2 Running 0 109s -``` We need a user to test all the ssl functionalities. So let's create one user inside the mysql servers, @@ -138,17 +140,18 @@ spec: deletionPolicy: WipeOut ``` -``` bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created ## Check User and current TLS status Let's exec into the proxysql pod and see the current status. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 18 @@ -177,7 +180,6 @@ MySQL [(none)]> show variables like '%have_ssl%'; MySQL [(none)]> exit Bye -``` We can see that the users have been fetched. Also the mysql-have_ssl variables is set to false. The use_ssl column is also set to 0 which means that there is no need for ssl-ca or cert for connect. Let's check it with the follwing command. @@ -230,24 +232,22 @@ Now we want to add TLS to our proxysql server and we want the frontend connectio First we need an issuer for this. We can create one with the following command. Make sure that you have cert-manager running in your cluster and openssl installed. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mysql/O=kubedb" - +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mysql/O=kubedb" +``` Generating a RSA private key .......................................+++++ ...........................+++++ writing new private key to './ca.key' -``` - Let's create the ca-secret with the above created ca.crt and ca.key by using the following command, ```bash -$ kubectl create secret tls proxy-ca \ +kubectl create secret tls proxy-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/proxy-ca created ``` +secret/proxy-ca created Now create issuer with the following yaml, @@ -263,9 +263,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/issuer.yaml -issuer.cert-manager.io/proxy-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/issuer.yaml ``` +issuer.cert-manager.io/proxy-issuer created ### Apply ops-request to add TLS @@ -302,23 +302,25 @@ spec: Let's apply and wait for the ops-request to be succeeded. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-add-tls.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-add-tls.yaml +``` proxysqlopsrequest.ops.kubedb.com/recon-tls-add created -$ kubectl get proxysqlopsrequest -n demo +```bash +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE recon-tls-add ReconfigureTLS Successful 5m -``` ### Check ops-request effects Following secrets should be created ```bash -$ kubectl get secrets -n demo | grep cert +kubectl get secrets -n demo | grep cert +``` proxy-server-server-cert kubernetes.io/tls 3 4m53s proxy-server-client-cert kubernetes.io/tls 3 4m53s -``` The directory `/var/lib/frontend/` should carry the certificates and other files within the directories as seen below. ```bash @@ -376,9 +378,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-activate-ssl.yaml -proxysqlopsrequest.ops.kubedb.com/activate-ssl created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-activate-ssl.yaml ``` +proxysqlopsrequest.ops.kubedb.com/activate-ssl created Let's check the effect from the admin panel. @@ -544,16 +546,16 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-rotate-tls.yaml -proxysqlopsrequest.ops.kubedb.com/recon-tls-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-rotate-tls.yaml ``` +proxysqlopsrequest.ops.kubedb.com/recon-tls-rotate created ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE recon-tls-add ReconfigureTLS Successful 15m recon-tls-rotate ReconfigureTLS Successful 5m -``` ### Check ops-request effect @@ -566,8 +568,9 @@ notAfter=Feb 6 09:05:54 2023 GMT The expiration time has been updated. Now lets check the certificate crd. -```bash - $ kubectl describe certificate -n demo proxy-server-server-cert + ```bash + kubectl describe certificate -n demo proxy-server-server-cert + ``` Name: proxy-server-server-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -642,7 +645,6 @@ Events: Normal Requested 2m2s cert-manager Created new CertificateRequest resource "proxy-server-server-cert-l2xgk" Normal Reused 2m2s (x5 over 4m22s) cert-manager Reusing private key stored in existing Secret resource "proxy-server-server-cert" Normal Issuing 2m1s (x6 over 23m) cert-manager The certificate has been successfully issued -``` This has also been updated. @@ -702,15 +704,17 @@ spec: Let's apply and then wait for it to be succeed. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-update-tls.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-update-tls.yaml +``` proxysqlopsrequest.ops.kubedb.com/recon-tls-update created -$ kubectl get proxysqlopsrequest -n demo +```bash +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE recon-tls-update ReconfigureTLS Successful 5m recon-tls-add ReconfigureTLS Successful 15m recon-tls-rotate ReconfigureTLS Successful 10m -``` Let's check the info now. @@ -743,16 +747,18 @@ spec: Let's apply and check the effects. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-remove-tls.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure-tls/cluster/examples/proxyops-remove-tls.yaml +``` proxysqlopsrequest.ops.kubedb.com/recon-tls-remove created -$ kubectl get proxysqlopsrequest -n demo +```bash +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE recon-tls-remove ReconfigureTLS Successful 3m recon-tls-update ReconfigureTLS Successful 7m recon-tls-add ReconfigureTLS Successful 17m recon-tls-rotate ReconfigureTLS Successful 12m -``` ### Check ops-request effect @@ -809,8 +815,17 @@ We can see the user has been successfuly connected without the tls information. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete proxysql -n demo --all -$ kubectl delete issuer -n demo --all -$ kubectl delete proxysqlopsrequest -n demo --all -$ kubectl delete ns demo +kubectl delete proxysql -n demo --all +``` + +```bash +kubectl delete issuer -n demo --all +``` + +```bash +kubectl delete proxysqlopsrequest -n demo --all +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/proxysql/reconfigure/cluster/index.md b/docs/guides/proxysql/reconfigure/cluster/index.md index 80c27949f6..503a50c4d3 100644 --- a/docs/guides/proxysql/reconfigure/cluster/index.md +++ b/docs/guides/proxysql/reconfigure/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare MySQL backend @@ -62,17 +62,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get mysql -n demo +kubectl get mysql -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.8 Ready 3m51s -``` ### Prepare ProxySQL Cluster @@ -93,17 +93,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -ndemo +kubectl get proxysql -ndemo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 98s -``` ## Reconfigure MYSQL USERS @@ -114,7 +114,8 @@ With `KubeDB` `ProxySQL` ops-request you can reconfigure `mysql_users` table. Yo Let's first create two users in the backend mysql server. ```bash -$ kubectl exec -it -n demo mysql-server-0 -- bash +kubectl exec -it -n demo mysql-server-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) root@mysql-server-0:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -150,14 +151,14 @@ Query OK, 0 rows affected (0.00 sec) mysql> exit Bye -``` ### Check current mysql_users table in ProxySQL Let's check the current mysql_users table in the proxysql server. Make sure that the spec.syncUsers field was not set to true when the proxysql was deployed. Otherwise it will fetch all the users from the mysql backend and we won't be able to see the effects of reconfigure users ops requests. ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt "ProxySQLAdmin > " Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 71 @@ -169,7 +170,6 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. ProxySQLAdmin > select * from mysql_users; Empty set (0.001 sec) -``` ### Add Users @@ -200,17 +200,17 @@ spec: Let's applly the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-add-users.yaml -proxysqlopsrequest.ops.kubedb.com/add-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-add-users.yaml ``` +proxysqlopsrequest.ops.kubedb.com/add-user created Let's wait for the ops-request to be Successful. ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE add-user Reconfigure Successful 20s -``` Now let's check the `mysql_users` table in the proxysql server. @@ -258,18 +258,18 @@ spec: Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-update-users.yaml -proxysqlopsrequest.ops.kubedb.com/update-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-update-users.yaml ``` +proxysqlopsrequest.ops.kubedb.com/update-user created Now wait for the ops-request to be Successful. ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE add-user Reconfigure Successful 2m36s update-user Reconfigure Successful 6s -``` Let's check the `mysql_users` table from the admin interface. @@ -309,18 +309,18 @@ spec: Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-remove-users.yaml -proxysqlopsrequest.ops.kubedb.com/delete-user created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-remove-users.yaml ``` +proxysqlopsrequest.ops.kubedb.com/delete-user created Let's wait for the ops-request to be successful. ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE add-user Reconfigure Successful 5m29s delete-user Reconfigure Successful 12s update-user Reconfigure Successful 2m59s -``` Now check the `mysql_users` table in the proxysql server. @@ -386,16 +386,16 @@ spec: Let's apply the ops-request yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-add-rules.yaml -proxysqlopsrequest.ops.kubedb.com/add-rule created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-add-rules.yaml ``` +proxysqlopsrequest.ops.kubedb.com/add-rule created Wait for the ops-request to be successful. ```bash -$ kubectl get proxysqlopsrequest -n demo | grep rule -add-rule Reconfigure Successful 59s +kubectl get proxysqlopsrequest -n demo | grep rule ``` +add-rule Reconfigure Successful 59s Now let's check the mysql_query_rules table in the proxysql server. ```bash @@ -437,16 +437,16 @@ spec: Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-update-rules.yaml -proxysqlopsrequest.ops.kubedb.com/update-rule created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-update-rules.yaml ``` +proxysqlopsrequest.ops.kubedb.com/update-rule created Now wait for the ops-request to be successful. ```bash -$ kubectl get proxysqlopsrequest -n demo | grep rule +kubectl get proxysqlopsrequest -n demo | grep rule +``` add-rule Reconfigure Successful 3m10s update-rule Reconfigure Successful 71s -``` Let's check the `mysql_query_rules` table from the admin interface. ```bash @@ -486,17 +486,17 @@ spec: Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-remove-rules.yaml -proxysqlopsrequest.ops.kubedb.com/delete-rule created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-remove-rules.yaml ``` +proxysqlopsrequest.ops.kubedb.com/delete-rule created Let's wait for the ops-request to be Successful. ```bash -$ kubectl get proxysqlopsrequest -n demo | grep rule +kubectl get proxysqlopsrequest -n demo | grep rule +``` add-rule Reconfigure Successful 4m13s delete-rule Reconfigure Successful 12s update-rule Reconfigure Successful 2m14s -``` Now check the `mysql_query_rules` table in the proxysql server. @@ -563,16 +563,16 @@ spec: Let's apply the yaml. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-recon-vars.yaml -proxysqlopsrequest.ops.kubedb.com/recofigure-vars created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/reconfigure/cluster/examples/proxyops-recon-vars.yaml ``` +proxysqlopsrequest.ops.kubedb.com/recofigure-vars created Wait for the ops-request to be successful. ```bash -$ kubectl get proxysqlopsrequest -n demo | grep reco -reconfigure-vars Reconfigure Successful 30s +kubectl get proxysqlopsrequest -n demo | grep reco ``` +reconfigure-vars Reconfigure Successful 30s Now let's check the variables we wanted to reconfigure. @@ -598,8 +598,17 @@ From the above output we can see the variables has been successfuly updated with ### Clean-up ```bash -$ kubectl delete proxysql -n demo proxy-server -$ kubectl delete proxysqlopsrequest -n demo --all -$ kubectl delete mysql -n demo mysql-server -$ kubectl delete ns demo +kubectl delete proxysql -n demo proxy-server +``` + +```bash +kubectl delete proxysqlopsrequest -n demo --all +``` + +```bash +kubectl delete mysql -n demo mysql-server +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/proxysql/restart/index.md b/docs/guides/proxysql/restart/index.md index b79c8fb94b..ed984ef54e 100644 --- a/docs/guides/proxysql/restart/index.md +++ b/docs/guides/proxysql/restart/index.md @@ -25,9 +25,9 @@ KubeDB supports restarting the ProxySQL database via a `ProxySQLOpsRequest`. Res - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in the [docs/examples/proxysql](https://github.com/kubedb/docs/tree/{{ < param "info.version" >}}/docs/examples/proxysql) folder in the GitHub repository kubedb/docs. @@ -61,17 +61,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created Let's wait for the MySQL to be Ready. ```bash -$ kubectl get my -n demo +kubectl get my -n demo +``` NAME VERSION STATUS AGE mysql-server 8.4.3 Ready 7m6s -``` > Here you can use MariaDB or PerconXtraDB as well as backend. Have a look at other [ProxySQL backend examples](/docs/guides/proxysql/backends/) Now we are ready to deploy and test our ProxySQL server. @@ -98,18 +98,18 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-proxysql.yaml -proxysql.kubedb.com/mysql-proxy created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/backends/mysqlgrp/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/mysql-proxy created Let's wait for the ProxySQL to be Ready. ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE mysql-proxy 3.0.1-debian Ready 3m45s -``` ## Apply Restart opsRequest ```yaml apiVersion: ops.kubedb.com/v1alpha1 @@ -176,12 +176,15 @@ mysql-server-2 2/2 Running 0 16m ``` Now let's check the status of our `ProxySQLOpsRequest` and the Yaml output of the created `ProxySQLOpsRequest` CR. -```shell -$ kubectl get Proxysqlopsrequest -n demo +```bash +kubectl get Proxysqlopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 31m -$ kubectl get Proxysqlopsrequest -n demo restart -oyaml +```bash +kubectl get Proxysqlopsrequest -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: ProxySQLOpsRequest metadata: @@ -253,8 +256,6 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/proxysql/scaling/horizontal-scaling/cluster/index.md b/docs/guides/proxysql/scaling/horizontal-scaling/cluster/index.md index 8098888854..c7f8f1d94b 100644 --- a/docs/guides/proxysql/scaling/horizontal-scaling/cluster/index.md +++ b/docs/guides/proxysql/scaling/horizontal-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to scale the cl To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Also we need a mysql backend for the proxysql server. So we are creating one with the below yaml. @@ -61,9 +61,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created After applying the above yaml wait for the MySQL to be Ready. @@ -93,26 +93,29 @@ spec: Let's create the `ProxySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Now, wait until `proxy-server` has status `Ready`. i.e, ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 2m36s -``` Let's check the number of replicas this cluster has from the ProxySQL object, number of pods the petset have, ```bash -$ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' -3 -$ kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' +kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' +``` 3 + +```bash +kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' ``` +3 We can see from both command that the server has 3 replicas in the cluster. @@ -121,7 +124,8 @@ Also, we can verify the replicas of the replicaset from an internal proxysql com Now let's connect to a proxysql instance and run a proxysql internal command to check the cluster status, ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash + kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * from runtime_proxysql_servers;" +---------------------------------------+------+--------+---------+ | hostname | port | weight | comment | @@ -130,7 +134,6 @@ root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * fro | proxy-server-1.proxy-server-pods.demo | 6032 | 1 | | | proxy-server-0.proxy-server-pods.demo | 6032 | 1 | | +---------------------------------------+------+--------+---------+ -``` We can see from the above output that the cluster has 3 nodes. @@ -168,9 +171,9 @@ Here, Let's create the `ProxySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/proxyops-upscale.yaml -proxysqlopsrequest.ops.kubedb.com/scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/proxyops-upscale.yaml ``` +proxysqlopsrequest.ops.kubedb.com/scale-up created ### Verify Cluster replicas scaled up successfully @@ -179,25 +182,29 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `ProxySQLOpsRequest` to be `Successful`. Run the following command to watch `ProxySQLOpsRequest` CR, ```bash -$ watch kubectl get proxysqlopsrequest -n demo +watch kubectl get proxysqlopsrequest -n demo +``` Every 2.0s: kubectl get proxysqlopsrequest -n demo NAME TYPE STATUS AGE scale-up HorizontalScaling Successful 106s -``` We can see from the above output that the `ProxySQLOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the ProxySQL object, number of pods the petset have, ```bash -$ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' -5 -$ kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' +kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' +``` 5 + +```bash +kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' ``` +5 Now let's connect to a proxysql instance and run a proxysql internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash + kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * from runtime_proxysql_servers;" +---------------------------------------+------+--------+---------+ | hostname | port | weight | comment | @@ -210,9 +217,6 @@ root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * fro +---------------------------------------+------+--------+---------+ root@proxy-server-1:/# - -``` - From all the above outputs we can see that the replicas of the cluster is `5`. That means we have successfully scaled up the replicas of the ProxySQL replicaset. ## Scale Down Replicas @@ -246,9 +250,9 @@ Here, Let's create the `ProxySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/proxyops-downscale.yaml -proxysqlopsrequest.ops.kubedb.com/scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/horizontal-scaling/cluster/examples/proxyops-downscale.yaml ``` +proxysqlopsrequest.ops.kubedb.com/scale-down created #### Verify Cluster replicas scaled down successfully @@ -257,24 +261,28 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `ProxySQLOpsRequest` to be `Successful`. Run the following command to watch `ProxySQLOpsRequest` CR, ```bash -$ watch kubectl get proxysqlopsrequest -n demo +watch kubectl get proxysqlopsrequest -n demo +``` Every 2.0s: kubectl get proxysqlopsrequest -n demo NAME TYPE STATUS AGE scale-down HorizontalScaling Successful 2m32s -``` We can see from the above output that the `ProxySQLOpsRequest` has succeeded. Now, we are going to verify the number of replicas this database has from the ProxySQL object, number of pods the petset have, ```bash -$ kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' -4 -$ kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' +kubectl get proxysql -n demo proxy-server -o json | jq '.spec.replicas' +``` 4 + +```bash +kubectl get petset -n demo proxy-server -o json | jq '.spec.replicas' ``` +4 Now let's connect to a proxysql instance and run a proxysql internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash + kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * from runtime_proxysql_servers;" +---------------------------------------+------+--------+---------+ | hostname | port | weight | comment | @@ -284,7 +292,6 @@ root@proxy-server-1:/# mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "select * fro | proxy-server-0.proxy-server-pods.demo | 6032 | 1 | | | proxy-server-3.proxy-server-pods.demo | 6032 | 1 | | +---------------------------------------+------+--------+---------+ -``` From all the above outputs we can see that the replicas of the cluster is `4`. That means we have successfully scaled down the replicas of the ProxySQL replicaset. @@ -293,6 +300,9 @@ From all the above outputs we can see that the replicas of the cluster is `4`. T To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete proxysql -n demo proxy-server -$ kubectl delete proxysqlopsrequest -n demo scale-up scale-down +kubectl delete proxysql -n demo proxy-server +``` + +```bash +kubectl delete proxysqlopsrequest -n demo scale-up scale-down ``` \ No newline at end of file diff --git a/docs/guides/proxysql/scaling/vertical-scaling/cluster/index.md b/docs/guides/proxysql/scaling/vertical-scaling/cluster/index.md index c91fb74b8a..507588b62b 100644 --- a/docs/guides/proxysql/scaling/vertical-scaling/cluster/index.md +++ b/docs/guides/proxysql/scaling/vertical-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Also we need a mysql backend for the proxysql server. So we are creating one with the below yaml. @@ -60,9 +60,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created After applying the above yaml wait for the MySQL to be Ready. @@ -105,22 +105,23 @@ spec: Let's create the `ProxySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Now, wait until `proxy-server` has status `Ready`. i.e, ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 3m46s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -131,7 +132,6 @@ $ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resour "memory": "1Gi" } } -``` You can see the Pod has the default resources which is assigned by KubeDB operator. @@ -175,9 +175,9 @@ Here, Let's create the `ProxySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/proxyops-vscale.yaml -proxysqlopsrequest.ops.kubedb.com/proxyops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/scaling/vertical-scaling/cluster/example/proxyops-vscale.yaml ``` +proxysqlopsrequest.ops.kubedb.com/proxyops-vscale created #### Verify ProxySQL Cluster resources updated successfully @@ -186,16 +186,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `ProxySQLOpsRequest` to be `Successful`. Run the following command to watch `ProxySQLOpsRequest` CR, ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` Every 2.0s: kubectl get proxysqlopsrequest -n demo NAME TYPE STATUS AGE proxyops-vscale VerticalScaling Successful 3m56s -``` We can see from the above output that the `ProxySQLOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -206,7 +207,6 @@ $ kubectl get pod -n demo proxy-server-0 -o json | jq '.spec.containers[].resour "memory": "1288490188800m" } } -``` The above output verifies that we have successfully scaled up the resources of the ProxySQL instance. @@ -215,6 +215,9 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete proxysql -n demo proxy-server -$ kubectl delete proxysqlopsrequest -n demo proxyops-vscale +kubectl delete proxysql -n demo proxy-server +``` + +```bash +kubectl delete proxysqlopsrequest -n demo proxyops-vscale ``` \ No newline at end of file diff --git a/docs/guides/proxysql/tls/configure/index.md b/docs/guides/proxysql/tls/configure/index.md index 6b1fa2d1ad..7f4d51c26f 100644 --- a/docs/guides/proxysql/tls/configure/index.md +++ b/docs/guides/proxysql/tls/configure/index.md @@ -30,9 +30,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/proxysql/tls/configure/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,9 +64,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created After applying the above yaml wait for the MySQL to be Ready. @@ -81,12 +81,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=proxysql/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=proxysql/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -114,9 +114,9 @@ spec: Let’s create the `Issuer` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/issuer.yaml -issuer.cert-manager.io/proxy-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/issuer.yaml ``` +issuer.cert-manager.io/proxy-issuer created ### Deploy ProxySQL Cluster with TLS/SSL configuration @@ -163,23 +163,25 @@ You can find more details from [here](/docs/guides/proxysql/concepts/proxysql/in Let’s create the `ProxySQL` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/tls/configure/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created **Wait for the database to be ready:** Now, wait for `ProxySQL` going on `Ready` state and also wait for `PetSet` and its pod to be created and going to `Running` state, ```bash -$ kubectl get proxysql -n demo proxy-server +kubectl get proxysql -n demo proxy-server +``` NAME VERSION STATUS AGE proxy-server 3.0.1-debian Ready 5m48s -$ kubectl get petset -n demo proxy-server +```bash +kubectl get petset -n demo proxy-server +``` NAME READY AGE proxy-server 3/3 7m5s -``` **Verify tls-secrets created successfully:** @@ -190,14 +192,14 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secrets -n demo | grep proxy-server +kubectl get secrets -n demo | grep proxy-server +``` proxy-server-auth kubernetes.io/basic-auth 2 7m54s proxy-server-configuration Opaque 1 7m54s proxy-server-monitor kubernetes.io/basic-auth 2 7m54s proxy-server-token-4w4mb kubernetes.io/service-account-token 3 7m54s proxy-server-server-cert kubernetes.io/tls 3 7m53s proxy-server-client-cert kubernetes.io/tls 3 7m53s -``` **Verify ProxySQL Cluster configured with TLS/SSL:** @@ -206,8 +208,8 @@ Now, we are going to connect to the proxysql server for verifying the proxysql s Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash - +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/ ls /var/lib/frontend/client ca.crt tls.crt tls.key root@proxy-server-0:/ ls /var/lib/frontend/server @@ -232,7 +234,6 @@ ProxySQLAdmin [(none)]> show variables like '%have_ssl%'; ProxySQLAdmin [(none)]> quit; Bye -``` The above output shows that the proxy server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/var/lib/frontend/client/` and `/var/lib/frontend/server/` directory for client and server respectively. @@ -243,7 +244,8 @@ Now, you can create an user that will be used to connect to the server with a se First, lets create the user in the backend mysql server. ```bash -$ kubectl exec -it -n demo mysql-server-0 -- bash +kubectl exec -it -n demo mysql-server-0 -- bash +``` Defaulted container "mysql" out of: mysql, mysql-coordinator, mysql-init (init) root@mysql-server-0:/# mysql -uroot -p$MYSQL_ROOT_PASSWORD mysql: [Warning] Using a password on the command line interface can be insecure. @@ -267,7 +269,6 @@ Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) -``` As we deployed the ProxySQL with `.spec.syncUsers` turned true, the user will automatically be fetched into the proxysql server. @@ -298,7 +299,8 @@ Query OK, 0 rows affected (0.008 sec) Let's connect to the proxysql server with a secure connection, ```bash -$ kubectl exec -it -n demo proxy-server-0 -- bash +kubectl exec -it -n demo proxy-server-0 -- bash +``` root@proxy-server-0:/ mysql -utest -ppass -h127.0.0.1 -P6033 ERROR 1045 (28000): ProxySQL Error: Access denied for user 'test' (using password: YES). SSL is required @@ -334,7 +336,6 @@ TCP port: 6033 Uptime: 2 hours 30 min 27 sec Threads: 1 Questions: 12 Slow queries: 12 -``` In the above output section we can see there is cipher in user at the SSL field. Which means the connection is TLS secured. @@ -343,8 +344,17 @@ In the above output section we can see there is cipher in user at the SSL field. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete proxysql -n demo proxy-server -$ kubectl delete mysql -n demo mysql-server -$ kubectl delete issuer -n demo --all -$ kubectl delete ns demo +kubectl delete proxysql -n demo proxy-server +``` + +```bash +kubectl delete mysql -n demo mysql-server +``` + +```bash +kubectl delete issuer -n demo --all +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/proxysql/update-version/cluster/index.md b/docs/guides/proxysql/update-version/cluster/index.md index a6f8c7fe9e..d4aa789cfd 100644 --- a/docs/guides/proxysql/update-version/cluster/index.md +++ b/docs/guides/proxysql/update-version/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Also we need a mysql backend for the proxysql server. So we are creating one with the below yaml. @@ -60,9 +60,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/sample-mysql.yaml -mysql.kubedb.com/mysql-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/sample-mysql.yaml ``` +mysql.kubedb.com/mysql-server created After applying the above yaml wait for the MySQL to be Ready. @@ -94,17 +94,17 @@ spec: Let's create the `ProxySQL` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/sample-proxysql.yaml -proxysql.kubedb.com/proxy-server created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/sample-proxysql.yaml ``` +proxysql.kubedb.com/proxy-server created Now, wait until `proxy-server` created has status `Ready`. i.e, ```bash -$ kubectl get proxysql -n demo +kubectl get proxysql -n demo +``` NAME VERSION STATUS AGE proxy-server 2.7.3-debian Ready 3m15s -``` We are now ready to apply the `ProxySQLOpsRequest` CR to update this database. @@ -139,9 +139,9 @@ Here, Let's create the `ProxySQLOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/proxyops-upgrade.yaml -proxysqlopsrequest.ops.kubedb.com/proxyops-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/proxysql/update-version/cluster/examples/proxyops-upgrade.yaml ``` +proxysqlopsrequest.ops.kubedb.com/proxyops-update created ### Verify ProxySQL version updated successfully @@ -150,27 +150,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `ProxySQLOpsRequest` to be `Successful`. Run the following command to watch `ProxySQLOpsRequest` CR, ```bash -$ kubectl get proxysqlopsrequest -n demo +kubectl get proxysqlopsrequest -n demo +``` Every 2.0s: kubectl get proxysqlopsrequest -n demo NAME TYPE STATUS AGE proxyops-update UpdateVersion Successful 84s -``` We can see from the above output that the `ProxySQLOpsRequest` has succeeded. Now, we are going to verify whether the `ProxySQL` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get proxysql -n demo proxy-server -o=jsonpath='{.spec.version}{"\n"}' +kubectl get proxysql -n demo proxy-server -o=jsonpath='{.spec.version}{"\n"}' +``` 3.0.1-debian -$ kubectl get petset -n demo proxy-server -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' -kubedb/proxysql:3.0.1-debian@sha256.... - -$ kubectl get pods -n demo proxy-server-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo proxy-server -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` kubedb/proxysql:3.0.1-debian@sha256.... +```bash +kubectl get pods -n demo proxy-server-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +kubedb/proxysql:3.0.1-debian@sha256.... You can see from above, our `ProxySQL` cluster database has been updated with the new version. So, the update process is successfully completed. @@ -179,6 +182,9 @@ You can see from above, our `ProxySQL` cluster database has been updated with th To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete proxysql -n demo proxy-server -$ kubectl delete proxysqlopsrequest -n demo proxyops-update +kubectl delete proxysql -n demo proxy-server +``` + +```bash +kubectl delete proxysqlopsrequest -n demo proxyops-update ``` \ No newline at end of file diff --git a/docs/guides/qdrant/autoscaler/compute/compute-autoscale.md b/docs/guides/qdrant/autoscaler/compute/compute-autoscale.md index 25fc627acd..9e71db7d98 100644 --- a/docs/guides/qdrant/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/qdrant/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to auto-scale compute resources i.e To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Database @@ -79,22 +79,23 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/compute/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/compute/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 51s -``` Let's check the Pod container resources: ```bash -$ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -105,7 +106,6 @@ $ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resou "memory": "512Mi" } } -``` We are now ready to apply the `QdrantAutoscaler` CRD to set up autoscaling for this database. @@ -160,20 +160,23 @@ Here, Let's create the `QdrantAutoscaler` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/compute/qdrant-as-compute.yaml -qdrantautoscaler.autoscaling.kubedb.com/qdrant-as-compute created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/compute/qdrant-as-compute.yaml ``` +qdrantautoscaler.autoscaling.kubedb.com/qdrant-as-compute created #### Verify Autoscaler is set up successfully Let's check that the `QdrantAutoscaler` resource is created successfully: ```bash -$ kubectl get qdrantautoscaler -n demo +kubectl get qdrantautoscaler -n demo +``` NAME AGE qdrant-as-compute 0s -$ kubectl describe qdrantautoscaler qdrant-as-compute -n demo +```bash +kubectl describe qdrantautoscaler qdrant-as-compute -n demo +``` Name: qdrant-as-compute Namespace: demo Labels: @@ -206,22 +209,22 @@ Status: Vpas: Vpa Name: qdrant-sample Events: -``` So, the `QdrantAutoscaler` resource is created successfully. The operator will now watch the resource usage of the Qdrant pods and create `QdrantOpsRequest` resources to scale when needed. After some time, you can observe that the autoscaler has created a `QdrantOpsRequest` with type `VerticalScaling`: ```bash -$ kubectl get qdrantopsrequest -n demo +kubectl get qdrantopsrequest -n demo +``` NAME TYPE STATUS AGE qdops-qdrant-sample-829lnp VerticalScaling Successful 45s -``` You can then verify the updated resources on the pods: ```bash -$ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -232,7 +235,6 @@ $ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[].resou "memory": "400Mi" } } -``` The above output verifies that we have successfully autoscaled the resources of the Qdrant database. diff --git a/docs/guides/qdrant/autoscaler/storage/storage-autoscale.md b/docs/guides/qdrant/autoscaler/storage/storage-autoscale.md index 12ac9574a3..6fbbca55c4 100644 --- a/docs/guides/qdrant/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/qdrant/autoscaler/storage/storage-autoscale.md @@ -37,21 +37,21 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Qdran To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Database At first, verify that your cluster has a storage class that supports volume expansion: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 28d longhorn (default) driver.longhorn.io Delete Immediate true 25d longhorn-static driver.longhorn.io Delete Immediate true 28d -``` We can see from the output that `longhorn` storage class has `ALLOWVOLUMEEXPANSION` set to `true`. We will use it for this tutorial. @@ -84,29 +84,31 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/storage/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/storage/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 101s -``` Let's check the volume size from the Petset and from the persistent volumes: ```bash -$ kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -o custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage,STORAGECLASS:.spec.storageClassName,CLAIM:.spec.claimRef.name | grep qdrant-sample +```bash +kubectl get pv -o custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage,STORAGECLASS:.spec.storageClassName,CLAIM:.spec.claimRef.name | grep qdrant-sample +``` pvc-31485d1d-5048-4dc2-a2c3-18910b27b661 1Gi longhorn data-qdrant-sample-0 pvc-683755b9-023d-4d36-8318-8a22d5b79acb 1Gi longhorn data-qdrant-sample-1 pvc-d494f0aa-41b8-458d-ab56-39946c9b9bfe 1Gi longhorn data-qdrant-sample-2 -``` You can see the Petset has 1GB storage and the capacity of all the persistent volumes is also 1GB. @@ -148,20 +150,23 @@ Here, Let's create the `QdrantAutoscaler` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/storage/qdrant-as-storage.yaml -qdrantautoscaler.autoscaling.kubedb.com/qdrant-as-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/autoscaler/storage/qdrant-as-storage.yaml ``` +qdrantautoscaler.autoscaling.kubedb.com/qdrant-as-storage created #### Verify Autoscaler is set up successfully Let's check that the `QdrantAutoscaler` resource is created successfully: ```bash -$ kubectl get qdrantautoscaler -n demo +kubectl get qdrantautoscaler -n demo +``` NAME AGE qdrant-as-storage 33s -$ kubectl describe qdrantautoscaler qdrant-as-storage -n demo +```bash +kubectl describe qdrantautoscaler qdrant-as-storage -n demo +``` Name: qdrant-as-storage Namespace: demo Labels: @@ -178,42 +183,43 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `QdrantAutoscaler` resource is created successfully. The operator will now continuously watch the storage usage of the Qdrant pods. When the usage crosses the `usageThreshold`, it will create a `QdrantOpsRequest` to expand the storage. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` using the `dd` command to see if storage autoscaling is working: ```bash -$ kubectl exec -n demo qdrant-sample-0 -- df -h /qdrant/storage +kubectl exec -n demo qdrant-sample-0 -- df -h /qdrant/storage +``` Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-9d79a391-6777-4be5-8f9e-0139d178aada 974M 296K 958M 1% /qdrant/storage -$ kubectl exec -n demo qdrant-sample-0 -- bash -c "dd if=/dev/zero of=/qdrant/storage/file.img bs=250M count=1 && df -h /qdrant/storage" +```bash +kubectl exec -n demo qdrant-sample-0 -- bash -c "dd if=/dev/zero of=/qdrant/storage/file.img bs=250M count=1 && df -h /qdrant/storage" +``` 1+0 records in 1+0 records out 262144000 bytes (262 MB, 250 MiB) copied, 2.01673 s, 130 MB/s Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-9d79a391-6777-4be5-8f9e-0139d178aada 974M 251M 708M 27% /qdrant/storage -``` Now let's watch the `QdrantOpsRequest` in the demo namespace: ```bash -$ kubectl get qdrantopsrequest -n demo -w +kubectl get qdrantopsrequest -n demo -w +``` NAME TYPE STATUS AGE qdops-qdrant-sample-ka4wgv VolumeExpansion Progressing 2s qdops-qdrant-sample-ka4wgv VolumeExpansion Successful 8m -``` After the `QdrantOpsRequest` completes successfully, let's check the updated storage: ```bash -$ kubectl get pv -o custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage,STORAGECLASS:.spec.storageClassName,CLAIM:.spec.claimRef.name | grep qdrant-sample +kubectl get pv -o custom-columns=NAME:.metadata.name,CAPACITY:.spec.capacity.storage,STORAGECLASS:.spec.storageClassName,CLAIM:.spec.claimRef.name | grep qdrant-sample +``` pvc-31485d1d-5048-4dc2-a2c3-18910b27b661 1168Mi longhorn data-qdrant-sample-0 pvc-683755b9-023d-4d36-8318-8a22d5b79acb 1168Mi longhorn data-qdrant-sample-1 pvc-d494f0aa-41b8-458d-ab56-39946c9b9bfe 1168Mi longhorn data-qdrant-sample-2 -``` The storage has been automatically scaled from 1Gi to ~1168Mi as we specified a `scalingThreshold` of 20%. diff --git a/docs/guides/qdrant/backup/logical/index.md b/docs/guides/qdrant/backup/logical/index.md index 68a31aa729..4a00f7d41f 100644 --- a/docs/guides/qdrant/backup/logical/index.md +++ b/docs/guides/qdrant/backup/logical/index.md @@ -30,9 +30,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/backup/logical](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,32 +73,34 @@ spec: Create the above `Qdrant` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created KubeDB will deploy a Qdrant database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=qdrant-sample +kubectl get secret -n demo -l=app.kubernetes.io/instance=qdrant-sample +``` NAME TYPE DATA AGE qdrant-sample-auth Opaque 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=qdrant-sample +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=qdrant-sample +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE qdrant-sample ClusterIP 10.96.55.61 6333/TCP 97s qdrant-sample-pods ClusterIP None 6333/TCP 97s -``` KubeDB creates an AppBinding CR that holds the necessary information to connect with the database. @@ -107,15 +109,15 @@ KubeDB creates an AppBinding CR that holds the necessary information to connect Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE qdrant-sample 9m24s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo qdrant-sample -o yaml +kubectl get appbindings -n demo qdrant-sample -o yaml ``` ```yaml @@ -169,28 +171,36 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, let's get the API key and port-forward to create a collection with sample data: -```bash # Get the API key from the auth secret -$ export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` # Port-forward to the Qdrant service -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +```bash +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +``` + # Create a collection -$ curl -X PUT 'http://localhost:6333/collections/demo_collection' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_collection' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{"vectors": {"size": 4, "distance": "Cosine"}}' +``` + # Insert points -$ curl -X PUT 'http://localhost:6333/collections/demo_collection/points' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_collection/points' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{ +``` "points": [ { "id": 1, "vector": [0.1, 0.2, 0.3, 0.4], "payload": {"label": "a"} }, { "id": 2, "vector": [0.5, 0.6, 0.7, 0.8], "payload": {"label": "b"} } ] }' -``` Now, we are ready to backup the database. @@ -203,11 +213,11 @@ We are going to store our backed up data into a MinIO bucket. We have to create Let's create a secret called `storage-secret` with access credentials to our desired MinIO backend, ```bash -$ kubectl create secret generic -n demo storage-secret \ +kubectl create secret generic -n demo storage-secret \ --from-literal=AWS_ACCESS_KEY_ID=minioadmin \ --from-literal=AWS_SECRET_ACCESS_KEY=minioadmin -secret/storage-secret created ``` +secret/storage-secret created **Create BackupStorage:** @@ -239,9 +249,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/backup-storage.yaml -backupstorage.storage.kubestash.com/minio-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/backup-storage.yaml ``` +backupstorage.storage.kubestash.com/minio-storage created Now, we are ready to backup our database to our desired backend. @@ -269,9 +279,9 @@ spec: Let's create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/retention-policy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/retention-policy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -284,11 +294,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create BackupConfiguration:** @@ -342,27 +355,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/backup-configuration.yaml -backupconfiguration.core.kubestash.com/qdrant-sample-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/backup-configuration.yaml ``` +backupconfiguration.core.kubestash.com/qdrant-sample-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE qdrant-sample-backup Ready 54s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE minio-qdrant-repo true 3 8.613 KiB Ready 48s 58s -``` **Verify CronJob:** @@ -371,21 +384,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-qdrant-sample-backup-frequent-backup */5 * * * * False 0 51s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE qdrant-sample-backup-frequent-backup-1779330454 BackupConfiguration qdrant-sample-backup Succeeded 7s 51s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -394,18 +406,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `minio-qdrant-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo minio-qdrant-repo +kubectl get repository -n demo minio-qdrant-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE minio-qdrant-repo true 3 8.613 KiB Ready 48s 58s -``` Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=minio-qdrant-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=minio-qdrant-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE minio-qdrant-repo-qdrant-sample-ckup-frequent-backup-1779330454 minio-qdrant-repo frequent-backup 2026-05-21T02:27:44Z Delete Succeeded 51s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -450,17 +462,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/qdrant-restore.yaml -qdrant.kubedb.com/qdrant-sample-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/qdrant-restore.yaml ``` +qdrant.kubedb.com/qdrant-sample-restore created Check the database status, ```bash -$ kubectl get qdrant -n demo qdrant-sample-restore +kubectl get qdrant -n demo qdrant-sample-restore +``` NAME VERSION STATUS AGE qdrant-sample-restore 1.17.0 Ready 48s -``` #### Create RestoreSession: @@ -501,18 +513,17 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/restore-session.yaml -restoresession.core.kubestash.com/restore-qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/logical/restore-session.yaml ``` +restoresession.core.kubestash.com/restore-qdrant-sample created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ kubectl get restoresession -n demo -w - +kubectl get restoresession -n demo -w +``` NAME REPOSITORY PHASE DURATION AGE restore-qdrant-sample minio-qdrant-repo Succeeded 3s 53s -``` Now, let's verify the restored data. @@ -523,28 +534,33 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get qdrant -n demo qdrant-sample-restore +kubectl get qdrant -n demo qdrant-sample-restore +``` NAME VERSION STATUS AGE qdrant-sample-restore 1.17.0 Ready 34m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=qdrant-sample-restore" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=qdrant-sample-restore" +``` NAME READY STATUS RESTARTS AGE qdrant-sample-restore-0 1/1 Running 0 39m -``` Now, let's get the API key and port-forward to verify the restored data, -```bash # Get the API key from the restored auth secret -$ export API_KEY=$(kubectl get secret -n demo qdrant-sample-restore-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo qdrant-sample-restore-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` + +```bash +kubectl port-forward -n demo svc/qdrant-sample-restore 6333:6333 & +``` -$ kubectl port-forward -n demo svc/qdrant-sample-restore 6333:6333 & # Scroll points to verify the restored data -$ curl -X POST 'http://localhost:6333/collections/demo_collection/points/scroll' \ +```bash +curl -X POST 'http://localhost:6333/collections/demo_collection/points/scroll' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{"limit": 10, "with_payload": true, "with_vector": true}' diff --git a/docs/guides/qdrant/backup/volume-snapshot/index.md b/docs/guides/qdrant/backup/volume-snapshot/index.md index 0a151134c1..9336b22938 100644 --- a/docs/guides/qdrant/backup/volume-snapshot/index.md +++ b/docs/guides/qdrant/backup/volume-snapshot/index.md @@ -19,19 +19,19 @@ KubeStash allows you to take volume snapshot backups of Qdrant databases. Volume To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/backup/volume-snapshot](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. ### Ensure VolumeSnapshotClass ```bash -$ kubectl get volumesnapshotclasses +kubectl get volumesnapshotclasses +``` NAME DRIVER DELETIONPOLICY AGE longhorn-snapshot-vsc driver.longhorn.io Delete 7d22h -``` If not any, create a `VolumeSnapshotClass` using the following YAML, @@ -47,9 +47,9 @@ parameters: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/volume-snapshot-class.yaml -volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/volume-snapshot-class.yaml ``` +volumesnapshotclass.snapshot.storage.k8s.io/longhorn-snapshot-vsc created > **Note:** Ensure that the `VolumeSnapshotClass` is provisioned with the same storage class driver used for provisioning your Qdrant database. In our case, we are using the `longhorn` storageclass as our database provisioner, with the driver set to `driver.longhorn.io`. @@ -62,11 +62,11 @@ We are going to store our backed up data into a MinIO bucket. We have to create Let's create a secret called `storage-secret` with access credentials to our desired MinIO backend, ```bash -$ kubectl create secret generic -n demo storage-secret \ +kubectl create secret generic -n demo storage-secret \ --from-literal=AWS_ACCESS_KEY_ID=minioadmin \ --from-literal=AWS_SECRET_ACCESS_KEY=minioadmin -secret/storage-secret created ``` +secret/storage-secret created **Create BackupStorage:** @@ -98,9 +98,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/backup-storage.yaml -backupstorage.storage.kubestash.com/minio-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/backup-storage.yaml ``` +backupstorage.storage.kubestash.com/minio-storage created Now, we are ready to backup our database to our desired backend. @@ -128,9 +128,9 @@ spec: Let's create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/retention-policy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/retention-policy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ## Deploy Sample Qdrant Database @@ -163,32 +163,34 @@ spec: Create the above `Qdrant` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created KubeDB will deploy a Qdrant database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 65s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=qdrant-sample +kubectl get secret -n demo -l=app.kubernetes.io/instance=qdrant-sample +``` NAME TYPE DATA AGE qdrant-sample-auth Opaque 2 65s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=qdrant-sample +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=qdrant-sample +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE qdrant-sample ClusterIP 10.43.69.124 6333/TCP,6334/TCP 65s qdrant-sample-pods ClusterIP None 6335/TCP 65s -``` KubeDB creates an AppBinding CR that holds the necessary information to connect with the database. @@ -197,37 +199,45 @@ KubeDB creates an AppBinding CR that holds the necessary information to connect Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE qdrant-sample kubedb.com/qdrant 1.17.0 64s -``` **Insert Sample Data:** Now, let's get the API key and port-forward to create a collection with sample data: -```bash # Get the API key from the auth secret -$ export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` # Port-forward to the Qdrant service -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +```bash +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +``` + # Create a collection -$ curl -X PUT 'http://localhost:6333/collections/demo_collection' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_collection' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{"vectors": {"size": 4, "distance": "Cosine"}}' +``` + # Insert points -$ curl -X PUT 'http://localhost:6333/collections/demo_collection/points' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_collection/points' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{ +``` "points": [ { "id": 1, "vector": [0.1, 0.2, 0.3, 0.4], "payload": {"label": "a"} }, { "id": 2, "vector": [0.5, 0.6, 0.7, 0.8], "payload": {"label": "b"} } ] }' -``` Now, we are ready to backup the database. @@ -242,11 +252,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created **Create BackupConfiguration:** @@ -301,27 +314,27 @@ Here, Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/backup-configuration.yaml -backupconfiguration.core.kubestash.com/qdrant-sample-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/backup-configuration.yaml ``` +backupconfiguration.core.kubestash.com/qdrant-sample-backup created **Verify Backup Setup Successful:** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE qdrant-sample-backup Ready 36s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE minio-qdrant-repo true 5 19.914 KiB Ready 91s 101s -``` **Verify VolumeSnapshot:** @@ -330,23 +343,22 @@ It will create a `VolumeSnapshot` for each PVC of the Qdrant database. Verify that the `VolumeSnapshot` has been created using the following command, ```bash -$ kubectl get volumesnapshot -n demo +kubectl get volumesnapshot -n demo +``` NAME READYTOUSE SOURCEPVC RESTORESIZE SNAPSHOTCLASS CREATIONTIME AGE qdrant-sample-0-1779334719 true data-qdrant-sample-0 200Mi longhorn-snapshot-vsc 2m38s 2m38s qdrant-sample-1-1779334729 true data-qdrant-sample-1 200Mi longhorn-snapshot-vsc 2m28s 2m28s qdrant-sample-2-1779334744 true data-qdrant-sample-2 200Mi longhorn-snapshot-vsc 2m13s 2m13s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE qdrant-sample-backup-frequent-backup-1779334706 BackupConfiguration qdrant-sample-backup Succeeded 41s 91s -``` We can see from the above output that the backup session has succeeded. @@ -355,9 +367,9 @@ We can see from the above output that the backup session has succeeded. In this section, we are going to restore the database from the volume snapshot backup we have taken in the previous section. First, delete the original database, then deploy a new one initialized from the backup using the `init.archiver` field. ```bash -$ kubectl delete qdrant -n demo qdrant-sample -qdrant.kubedb.com "qdrant-sample" deleted +kubectl delete qdrant -n demo qdrant-sample ``` +qdrant.kubedb.com "qdrant-sample" deleted #### Deploy Restored Database: @@ -397,17 +409,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/qdrant-restore.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/backup/volume-snapshot/qdrant-restore.yaml ``` +qdrant.kubedb.com/qdrant-sample created KubeDB will automatically restore the database from the volume snapshot backup. Wait for the database to become `Ready`, ```bash -$ kubectl get qdrant -n demo qdrant-sample +kubectl get qdrant -n demo qdrant-sample +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 2m1s -``` #### Verify Restored Data: @@ -415,13 +427,18 @@ In this section, we are going to verify whether the desired data has been restor Now, let's get the API key and port-forward to verify the restored data, -```bash # Get the API key from the auth secret -$ export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` + +```bash +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +``` -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & # Scroll points to verify the restored data -$ curl -X POST 'http://localhost:6333/collections/demo_collection/points/scroll' \ +```bash +curl -X POST 'http://localhost:6333/collections/demo_collection/points/scroll' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{"limit": 10, "with_payload": true, "with_vector": true}' diff --git a/docs/guides/qdrant/concepts/catalog.md b/docs/guides/qdrant/concepts/catalog.md index f7fc209e34..777068ed12 100644 --- a/docs/guides/qdrant/concepts/catalog.md +++ b/docs/guides/qdrant/concepts/catalog.md @@ -59,12 +59,12 @@ The default value of this field is `false`. If `spec.deprecated` is set to `true `spec.db.image` is a required field that specifies the Docker image which will be used to create the Petset by KubeDB operator to create the expected Qdrant database. ```bash -$ kubectl get qdrantversions +kubectl get qdrantversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.15.4 1.15.4 docker.io/qdrant/qdrant:v1.15.4-unprivileged 28d 1.16.2 1.16.2 docker.io/qdrant/qdrant:v1.16.2-unprivileged 28d 1.17.0 1.17.0 docker.io/qdrant/qdrant:v1.17.0-unprivileged 28d -``` ### spec.endOfLife diff --git a/docs/guides/qdrant/concepts/qdrant.md b/docs/guides/qdrant/concepts/qdrant.md index ebfa9fb213..3bb32c9e90 100644 --- a/docs/guides/qdrant/concepts/qdrant.md +++ b/docs/guides/qdrant/concepts/qdrant.md @@ -89,12 +89,12 @@ spec: `spec.version` (required) specifies the name of the [QdrantVersion](/docs/guides/qdrant/concepts/catalog.md) CRD where the docker images are specified. ```bash -$ kubectl get qdrantversions +kubectl get qdrantversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.15.4 1.15.4 docker.io/qdrant/qdrant:v1.15.4-unprivileged 28d 1.16.2 1.16.2 docker.io/qdrant/qdrant:v1.16.2-unprivileged 28d 1.17.0 1.17.0 docker.io/qdrant/qdrant:v1.17.0-unprivileged 28d -``` ### spec.replicas diff --git a/docs/guides/qdrant/configuration/using-config-file.md b/docs/guides/qdrant/configuration/using-config-file.md index 6f7678bfbf..79f2478b5f 100644 --- a/docs/guides/qdrant/configuration/using-config-file.md +++ b/docs/guides/qdrant/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Qdrant. This tutorial will sh - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/configuration](/docs/examples/qdrant/configuration) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -68,9 +68,9 @@ type: Opaque Let's create the `Secret` we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/configuration/configuration-secret.yaml -secret/qdrant-configuration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/configuration/configuration-secret.yaml ``` +secret/qdrant-configuration created Verify the Secret has the configuration file: @@ -92,9 +92,9 @@ type: Opaque Now, create the `Qdrant` CR specifying `spec.configuration.secretName` field: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/configuration/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/configuration/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Below is the YAML for the `Qdrant` CR we just created: @@ -122,29 +122,29 @@ spec: Now, wait a few minutes. KubeDB operator will create the necessary PVC, PetSet, services, and secrets. Let's check the status: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 68s -``` Check that all pods are running: ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 61s qdrant-sample-1 1/1 Running 0 57s qdrant-sample-2 1/1 Running 0 42s -``` Now, let's verify that the custom configuration has been applied by checking the config file inside the pod: ```bash -$ kubectl exec -n demo qdrant-sample-0 -- cat /qdrant/config/config.yaml +kubectl exec -n demo qdrant-sample-0 -- cat /qdrant/config/config.yaml +``` log_level: DEBUG service: max_request_size_mb: 64 -``` The output confirms the database is running with our custom `log_level` and `max_request_size_mb` values. diff --git a/docs/guides/qdrant/distributed-deployment/overview.md b/docs/guides/qdrant/distributed-deployment/overview.md index 0fc3e53ea0..b25ef50a5c 100644 --- a/docs/guides/qdrant/distributed-deployment/overview.md +++ b/docs/guides/qdrant/distributed-deployment/overview.md @@ -27,9 +27,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/quickstart](/docs/examples/qdrant/quickstart) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -38,12 +38,12 @@ namespace/demo created We will need to provide `StorageClass` in the Qdrant CR specification. Check available `StorageClass` in your cluster using the following command: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 29d longhorn (default) driver.longhorn.io Delete Immediate true 26d standard rancher.io/local-path Delete WaitForFirstConsumer false 21h -``` We will use `standard` StorageClass in this tutorial. @@ -52,12 +52,12 @@ We will use `standard` StorageClass in this tutorial. When you install KubeDB, it creates `QdrantVersion` CRDs for all supported Qdrant versions. Let's check available `QdrantVersion`s: ```bash -$ kubectl get qdrantversions +kubectl get qdrantversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.15.4 1.15.4 docker.io/qdrant/qdrant:v1.15.4-unprivileged 29d 1.16.2 1.16.2 docker.io/qdrant/qdrant:v1.16.2-unprivileged 29d 1.17.0 1.17.0 docker.io/qdrant/qdrant:v1.17.0-unprivileged 29d -``` In this tutorial, we will use `1.17.0` QdrantVersion CR to create a distributed Qdrant cluster. @@ -96,29 +96,29 @@ Here, Let's create the Qdrant object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/quickstart/distributed.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/quickstart/distributed.yaml ``` +qdrant.kubedb.com/qdrant-sample created ## Verify the Deployment Let's check the status of the Qdrant object: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 50s -``` To see the distributed nodes, check the pods: ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=qdrant-sample +kubectl get pod -n demo -l app.kubernetes.io/instance=qdrant-sample +``` NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 48s qdrant-sample-1 1/1 Running 0 43s qdrant-sample-2 1/1 Running 0 39s -``` In distributed mode, Qdrant creates a Petset with the specified number of replicas. @@ -127,19 +127,22 @@ In distributed mode, Qdrant creates a Petset with the specified number of replic Now let's interact with the distributed Qdrant cluster. First, get the API key and forward a port: ```bash -$ kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d +kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d +``` F1UxwGOleYzmofu3 -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +```bash +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & ``` Create a collection with sharding and replication: ```bash -$ curl -X PUT http://localhost:6333/collections/demo_vectors \ +curl -X PUT http://localhost:6333/collections/demo_vectors \ -H "Content-Type: application/json" \ -H "api-key: F1UxwGOleYzmofu3" \ -d '{ +``` "shard_number": 6, "replication_factor": 2, "vectors": { @@ -148,15 +151,15 @@ $ curl -X PUT http://localhost:6333/collections/demo_vectors \ } }' {"result":true,"status":"ok","time":0.912871278} -``` Add some points to the collection: ```bash -$ curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" \ +curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" \ -H "Content-Type: application/json" \ -H "api-key: F1UxwGOleYzmofu3" \ -d '{ +``` "points": [ {"id": 1, "vector": [0.15, 0.22, 0.31, 0.44, 0.51, 0.68, 0.73, 0.89], "payload": {"label": "apple"}}, {"id": 2, "vector": [0.12, 0.28, 0.35, 0.42, 0.53, 0.64, 0.71, 0.85], "payload": {"label": "banana"}}, @@ -166,12 +169,12 @@ $ curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" ] }' {"result":{"operation_id":1,"status":"completed"},"status":"ok","time":0.002696282} -``` Verify that clustering is enabled by checking the root cluster endpoint: ```bash -$ curl http://localhost:6333/cluster -H "api-key: F1UxwGOleYzmofu3" | jq +curl http://localhost:6333/cluster -H "api-key: F1UxwGOleYzmofu3" | jq +``` { "result": { "status": "enabled", @@ -202,15 +205,15 @@ $ curl http://localhost:6333/cluster -H "api-key: F1UxwGOleYzmofu3" | jq }, "status": "ok" } -``` The output confirms distributed mode is **enabled** with 3 peers and Raft consensus active. Now check the collection-level shard distribution: ```bash -$ curl http://localhost:6333/collections/demo_vectors/cluster \ +curl http://localhost:6333/collections/demo_vectors/cluster \ -H "api-key: F1UxwGOleYzmofu3" | jq +``` { "result": { "peer_id": 5887768058245046, @@ -235,7 +238,6 @@ $ curl http://localhost:6333/collections/demo_vectors/cluster \ }, "status": "ok" } -``` The output shows that the collection `demo_vectors` is distributed across 3 peers with 6 shards and a replication factor of 2. Each shard is in `Active` state, and local/remote shards are balanced across the cluster nodes. @@ -244,8 +246,8 @@ The output shows that the collection `demo_vectors` is distributed across 3 peer To delete the Qdrant database and all associated resources: ```bash -$ kubectl delete qdrant -n demo qdrant-sample -qdrant.kubedb.com "qdrant-sample" deleted +kubectl delete qdrant -n demo qdrant-sample ``` +qdrant.kubedb.com "qdrant-sample" deleted > **Warning:** If you delete the Qdrant object with `deletionPolicy: WipeOut`, all data will be permanently deleted. diff --git a/docs/guides/qdrant/migration/storageMigration.md b/docs/guides/qdrant/migration/storageMigration.md index ae85e50acf..dca7966fef 100644 --- a/docs/guides/qdrant/migration/storageMigration.md +++ b/docs/guides/qdrant/migration/storageMigration.md @@ -28,9 +28,9 @@ This guide will show you how to use `KubeDB` Ops Manager to migrate `StorageClas To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Qdrant Database @@ -71,13 +71,14 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/migration/sample-qdrant.yaml -qdrant.kubedb.com/sample-qdrant created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/migration/sample-qdrant.yaml ``` +qdrant.kubedb.com/sample-qdrant created Now, wait until sample-qdrant has status `Ready` and check the `StorageClass`, ```bash -$ kubectl get qdrant,pvc -n demo +kubectl get qdrant,pvc -n demo +``` NAME VERSION STATUS AGE sample-qdrant 1.17.0 Ready 101s @@ -85,32 +86,38 @@ NAME STATUS VOLUME persistentvolumeclaim/data-sample-qdrant-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 2Gi RWO standard 96s persistentvolumeclaim/data-sample-qdrant-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 2Gi RWO standard 90s persistentvolumeclaim/data-sample-qdrant-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 2Gi RWO standard 85s -``` The database is `Ready` and all the `PersistentVolumeClaim` uses `standard` StorageClass. Let's create a collection and insert some data. -```bash # get the API key from the auth secret -$ export API_KEY=$(kubectl get secret -n demo sample-qdrant-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo sample-qdrant-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` # port-forward the Qdrant service -$ kubectl port-forward -n demo svc/sample-qdrant 6333:6333 & +```bash +kubectl port-forward -n demo svc/sample-qdrant 6333:6333 & +``` Forwarding from 127.0.0.1:6333 -> 6333 # create a collection -$ curl -X PUT 'http://localhost:6333/collections/demo_vectors' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_vectors' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{ +``` "vectors": { "size": 4, "distance": "Cosine" } }' {"result":true,"status":"ok","time":0.123} # insert points -$ curl -X PUT 'http://localhost:6333/collections/demo_vectors/points' \ +```bash +curl -X PUT 'http://localhost:6333/collections/demo_vectors/points' \ -H "api-key: $API_KEY" \ -H 'Content-Type: application/json' \ -d '{ +``` "points": [ { "id": 1, "vector": [0.1, 0.2, 0.3, 0.4], "payload": { "label": "a" } }, { "id": 2, "vector": [0.2, 0.3, 0.4, 0.5], "payload": { "label": "b" } } @@ -119,10 +126,11 @@ $ curl -X PUT 'http://localhost:6333/collections/demo_vectors/points' \ {"result":null,"status":"ok","time":0.045} # verify points count -$ curl 'http://localhost:6333/collections/demo_vectors' \ +```bash +curl 'http://localhost:6333/collections/demo_vectors' \ -H "api-key: $API_KEY" -{"result":{"status":"green","vectors_count":2,"segments_count":4,...},"status":"ok","time":0.001} ``` +{"result":{"status":"green","vectors_count":2,"segments_count":4,...},"status":"ok","time":0.001} ## Apply StorageMigration Ops-Request @@ -154,50 +162,53 @@ Here, Let's create the `QdrantOpsRequest` CR we have shown above, -``` bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/migration/storage-migration.yaml -qdrantopsrequest.ops.kubedb.com/storage-migration created +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/migration/storage-migration.yaml ``` +qdrantopsrequest.ops.kubedb.com/storage-migration created ## Verify the StorageClass Migrated Successfully If everything goes well, `KubeDB` operator will migrate the `StorageClass` along with the data. Let's wait for `QdrantOpsRequest` to be `Successful`. Run the following command to watch QdrantOpsRequest CR, -``` bash -$ watch kubectl get qdrantopsrequest -n demo - +```bash +watch kubectl get qdrantopsrequest -n demo +``` Every 2.0s: kubectl get qdrantopsrequest -n demo NAME TYPE STATUS AGE storage-migration StorageMigration Successful 13m -``` We can see from the above output that the `QdrantOpsRequest` has succeeded. Let's verify the StorageClass. -``` bash -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-sample-qdrant-0 Bound pvc-64cca3c6-85aa-426f-abc3-b300ecfe365a 2Gi RWO longhorn-custom 21m data-sample-qdrant-1 Bound pvc-1de36b06-8e32-4e9a-a01b-3b6d7c618688 2Gi RWO longhorn-custom 21m data-sample-qdrant-2 Bound pvc-a75bd538-8a71-4f62-8d38-3f4e42ffb225 2Gi RWO longhorn-custom 21m -``` The `PersistentVolumeClaim` StorageClass has changed to `longhorn-custom`. Now, we will verify that the data remains intact after the `StorageMigration` operation. -```bash # get the API key from the auth secret -$ export API_KEY=$(kubectl get secret -n demo sample-qdrant-auth -o jsonpath='{.data.api-key}' | base64 -d) +```bash +export API_KEY=$(kubectl get secret -n demo sample-qdrant-auth -o jsonpath='{.data.api-key}' | base64 -d) +``` # port-forward the Qdrant service -$ kubectl port-forward -n demo svc/sample-qdrant 6333:6333 & +```bash +kubectl port-forward -n demo svc/sample-qdrant 6333:6333 & +``` Forwarding from 127.0.0.1:6333 -> 6333 # check the collection exists and data is intact -$ curl 'http://localhost:6333/collections/demo_vectors' \ +```bash +curl 'http://localhost:6333/collections/demo_vectors' \ -H "api-key: $API_KEY" -{"result":{"status":"green","vectors_count":2,"segments_count":4,...},"status":"ok","time":0.001} ``` +{"result":{"status":"green","vectors_count":2,"segments_count":4,...},"status":"ok","time":0.001} From the above output we can verify that data remains intact after the `StorageMigration` operation. @@ -206,7 +217,13 @@ From the above output we can verify that data remains intact after the `StorageM To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete qdrantopsrequest -n demo storage-migration -$ kubectl delete qdrant -n demo sample-qdrant -$ kubectl delete ns demo +kubectl delete qdrantopsrequest -n demo storage-migration +``` + +```bash +kubectl delete qdrant -n demo sample-qdrant +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/qdrant/monitoring/using-prometheus-operator.md b/docs/guides/qdrant/monitoring/using-prometheus-operator.md index 3b24203af7..b38e56e0f6 100644 --- a/docs/guides/qdrant/monitoring/using-prometheus-operator.md +++ b/docs/guides/qdrant/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, you can deploy one using this helm chart [here](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack). @@ -45,17 +47,17 @@ We need to know the labels used to select `ServiceMonitor` by `Prometheus` Opera At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v3.11.3-distroless 1 1 True True 5m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus-kube-prometheus-prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml ``` ```yaml apiVersion: monitoring.coreos.com/v1 @@ -210,34 +212,34 @@ Here, Let's create the Qdrant object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/monitoring/qdrant-monitoring.yaml -qdrant.kubedb.com/qdrant-monitoring created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/monitoring/qdrant-monitoring.yaml ``` +qdrant.kubedb.com/qdrant-monitoring created Now, wait for the database to go into `Ready` state. ```bash -$ kubectl get qdrant -n demo qdrant-monitoring +kubectl get qdrant -n demo qdrant-monitoring +``` NAME VERSION STATUS AGE qdrant-monitoring 1.17.0 Ready 48s -``` KubeDB will create a separate stats service with name `{qdrant cr name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=qdrant-monitoring" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=qdrant-monitoring" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE qdrant-monitoring ClusterIP 10.43.55.60 6333/TCP,6334/TCP 103s qdrant-monitoring-pods ClusterIP None 6335/TCP 103s qdrant-monitoring-stats ClusterIP 10.43.130.160 6333/TCP 103s -``` Here, `qdrant-monitoring-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo qdrant-monitoring-stats +kubectl describe svc -n demo qdrant-monitoring-stats ``` ```yaml Name: qdrant-monitoring-stats @@ -260,15 +262,15 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` CR in `demo` namespace that select the endpoints of `qdrant-monitoring-stats` service. Verify that the `ServiceMonitor` CR has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE qdrant-monitoring-stats 1m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Qdrant CR. ```bash -$ kubectl get servicemonitor -n demo qdrant-monitoring-stats -o yaml +kubectl get servicemonitor -n demo qdrant-monitoring-stats -o yaml ``` ```yaml @@ -332,20 +334,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus-kube-prometheus-prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 0 3m27s -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `qdrant-monitoring-stats` service as one of the targets. diff --git a/docs/guides/qdrant/quickstart/quickstart.md b/docs/guides/qdrant/quickstart/quickstart.md index 33cb064648..ccf9fa99c9 100644 --- a/docs/guides/qdrant/quickstart/quickstart.md +++ b/docs/guides/qdrant/quickstart/quickstart.md @@ -25,9 +25,9 @@ This tutorial will show you how to use KubeDB to run a Qdrant database. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/quickstart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/qdrant/quickstart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -36,10 +36,10 @@ namespace/demo created We will need to provide `StorageClass` in the Qdrant CR specification. Check available `StorageClass` in your cluster using the following command: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 10d -``` Here, we have `standard` StorageClass in our cluster. @@ -48,12 +48,12 @@ Here, we have `standard` StorageClass in our cluster. When you install KubeDB, it creates `QdrantVersion` CRDs for all supported Qdrant versions. Let's check available `QdrantVersion`s: ```bash -$ kubectl get qdrantversions +kubectl get qdrantversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.15.4 1.15.4 docker.io/qdrant/qdrant:v1.15.4-unprivileged 13d 1.16.2 1.16.2 docker.io/qdrant/qdrant:v1.16.2-unprivileged 13d 1.17.0 1.17.0 docker.io/qdrant/qdrant:v1.17.0-unprivileged 13d -``` Notice the `DEPRECATED` column. `true` means that QdrantVersion is deprecated for the current KubeDB version and KubeDB will not work for that version. @@ -85,9 +85,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/quickstart/qdrant-sample.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/quickstart/qdrant-sample.yaml ``` +qdrant.kubedb.com/qdrant-sample created Here, @@ -101,19 +101,20 @@ Here, Now, let's watch the progress of creating the `Qdrant` cluster: ```bash -$ kubectl get qdrant -n demo qdrant-sample -w +kubectl get qdrant -n demo qdrant-sample -w +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Provisioning 5s qdrant-sample 1.17.0 Provisioning 30s qdrant-sample 1.17.0 Ready 2m -``` ## Describe Qdrant Let's describe the `Qdrant` object to see its current state: ```bash -$ kubectl describe qdrant -n demo qdrant-sample +kubectl describe qdrant -n demo qdrant-sample +``` Name: qdrant-sample Namespace: demo Labels: @@ -210,39 +211,41 @@ Status: Phase: Ready Events: -``` - ## Find Underlying Kubernetes Resources KubeDB operator creates a Petset, PVCs, PVs, and Services for the Qdrant database. Let's check them: ```bash -$ kubectl get petset -n demo qdrant-sample +kubectl get petset -n demo qdrant-sample +``` NAME AGE qdrant-sample 2m34s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-qdrant-sample-0 Bound pvc-0015c0ad-4ddd-404c-9d8b-b9ea1f6cc15f 1Gi RWO standard -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-0015c0ad-4ddd-404c-9d8b-b9ea1f6cc15f 1Gi RWO Delete Bound demo/data-qdrant-sample-0 standard 4m14s - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE qdrant-sample ClusterIP 10.43.18.112 6333/TCP,6334/TCP 5m36s qdrant-sample-pods ClusterIP None 6335/TCP 5m36s -``` - ## Verify Qdrant YAML Output KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created and is able to accept client connections. Run the following command to see the modified Qdrant object: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o yaml +kubectl get qdrant -n demo qdrant-sample -o yaml ``` ```yaml @@ -348,7 +351,7 @@ status: KubeDB creates a Secret containing authentication credentials for the Qdrant cluster. Let's check it: ```bash -$ kubectl get secret -n demo qdrant-sample-auth -o yaml +kubectl get secret -n demo qdrant-sample-auth -o yaml ``` ```yaml apiVersion: v1 @@ -382,20 +385,26 @@ type: Opaque Now, let's connect to the Qdrant cluster using port forwarding: ```bash -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 -$ export QDRANT_API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 +``` -$ curl -H "api-key: $QDRANT_API_KEY" http://localhost:6333/collections -{"result":{"collections":[{"name":"KubeDBHealthCheckCollection"}]},"status":"ok","time":0.00001235} +```bash +export QDRANT_API_KEY=$(kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d) ``` +```bash +curl -H "api-key: $QDRANT_API_KEY" http://localhost:6333/collections +``` +{"result":{"collections":[{"name":"KubeDBHealthCheckCollection"}]},"status":"ok","time":0.00001235} + Let's create a collection with some vector data: ```bash -$ curl -X PUT http://localhost:6333/collections/demo_vectors \ +curl -X PUT http://localhost:6333/collections/demo_vectors \ -H "Content-Type: application/json" \ -H "api-key: $QDRANT_API_KEY" \ -d '{ +``` "vectors": { "size": 8, "distance": "Cosine" @@ -403,10 +412,12 @@ $ curl -X PUT http://localhost:6333/collections/demo_vectors \ }' {"result":true,"status":"ok","time":0.050803361} -$ curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" \ +```bash +curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" \ -H "Content-Type: application/json" \ -H "api-key: $QDRANT_API_KEY" \ -d '{ +``` "points": [ {"id": 1, "vector": [0.15, 0.22, 0.31, 0.44, 0.51, 0.68, 0.73, 0.89], "payload": {"label": "apple"}}, {"id": 2, "vector": [0.12, 0.28, 0.35, 0.42, 0.53, 0.64, 0.71, 0.85], "payload": {"label": "banana"}}, @@ -414,15 +425,15 @@ $ curl -X PUT "http://localhost:6333/collections/demo_vectors/points?wait=true" ] }' {"result":{"operation_id":1,"status":"completed"},"status":"ok","time":0.001645376} -``` Now scroll through the points to verify they were stored: ```bash -$ curl -X POST http://localhost:6333/collections/demo_vectors/points/scroll \ +curl -X POST http://localhost:6333/collections/demo_vectors/points/scroll \ -H "Content-Type: application/json" \ -H "api-key: $QDRANT_API_KEY" \ -d '{"limit": 5, "with_payload": true, "with_vector": false}' | jq +``` { "result": { "points": [ @@ -435,14 +446,13 @@ $ curl -X POST http://localhost:6333/collections/demo_vectors/points/scroll \ "status": "ok", "time": 0.000086921 } -``` ## AppBinding KubeDB creates an AppBinding CR that holds the necessary information to connect with the database. ```bash -$ kubectl get appbinding -n demo -o yaml +kubectl get appbinding -n demo -o yaml ``` ```yaml @@ -503,12 +513,14 @@ This field regulates the deletion process of the related resources when the `Qdr When `deletionPolicy` is set to `DoNotTerminate`, KubeDB prevents deletion of the database using admission webhooks. If you try to delete it, you will get an error: ```bash -$ kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +``` qdrant.kubedb.com/qdrant-sample patched -$ kubectl delete qdrant -n demo qdrant-sample -The Qdrant "qdrant-sample" is invalid: spec.deletionPolicy: Invalid value: "qdrant-sample": Can not delete as deletionPolicy is set to "DoNotTerminate" +```bash +kubectl delete qdrant -n demo qdrant-sample ``` +The Qdrant "qdrant-sample" is invalid: spec.deletionPolicy: Invalid value: "qdrant-sample": Can not delete as deletionPolicy is set to "DoNotTerminate" **Halt:** @@ -517,17 +529,20 @@ When `deletionPolicy` is set to `Halt`, KubeDB deletes the `Qdrant` object and i At first, set the `deletionPolicy` to `Halt` and then delete the database: ```bash -$ kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" +kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" +``` qdrant.kubedb.com/qdrant-sample patched -$ kubectl delete qdrant -n demo qdrant-sample -qdrant.kubedb.com "qdrant-sample" deleted +```bash +kubectl delete qdrant -n demo qdrant-sample ``` +qdrant.kubedb.com "qdrant-sample" deleted Now, check that the PVCs and Secrets still exist: ```bash -$ kubectl get secret,pvc -n demo +kubectl get secret,pvc -n demo +``` NAME TYPE DATA AGE secret/qdrant-sample-auth Opaque 2 11m secret/qdrant-sample-f36f30 Opaque 1 11m @@ -535,8 +550,6 @@ secret/qdrant-sample-f36f30 Opaque 1 11m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE persistentvolumeclaim/data-qdrant-sample-0 Bound pvc-0015c0ad-4ddd-404c-9d8b-b9ea1f6cc15f 1Gi RWO standard 11m -``` - You can recreate your Qdrant database later using these PVCs and Secrets. **Delete:** @@ -548,9 +561,9 @@ When `deletionPolicy` is set to `Delete`, KubeDB deletes the `Qdrant` object, po When `deletionPolicy` is set to `WipeOut`, KubeDB deletes all resources of this database (pods, PVCs, Secrets, snapshots, etc.). There is no option to recreate the database once deleted with this policy. ```bash -$ kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -qdrant.kubedb.com/qdrant-sample patched +kubectl patch -n demo qdrant/qdrant-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" ``` +qdrant.kubedb.com/qdrant-sample patched > Be careful when using `WipeOut` — there is no way to recover the database after deletion. diff --git a/docs/guides/qdrant/reconfigure-tls/reconfigure-tls.md b/docs/guides/qdrant/reconfigure-tls/reconfigure-tls.md index ef1ec574f8..68e26b7bff 100644 --- a/docs/guides/qdrant/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/qdrant/reconfigure-tls/reconfigure-tls.md @@ -32,9 +32,9 @@ KubeDB supports reconfiguring TLS certificates for Qdrant — adding, removing, To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/reconfigure-tls](/docs/examples/qdrant/reconfigure-tls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -67,19 +67,19 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ watch -n 3 kubectl get qdrant -n demo qdrant-sample +watch -n 3 kubectl get qdrant -n demo qdrant-sample +``` Every 3.0s: kubectl get qdrant -n demo qdrant-sample NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 2m -``` ### Create Issuer @@ -88,19 +88,19 @@ Now, we are going to create an example `Issuer` that will be used to enable TLS 1. Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=qdrant/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=qdrant/O=kubedb" +``` Generating a RSA private key ................+++++ ........................+++++ writing new private key to './ca.key' -``` 2. Create a secret using the certificate files we have just generated, ```bash -$ kubectl create secret tls qdrant-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/qdrant-ca created +kubectl create secret tls qdrant-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/qdrant-ca created 3. Now we are going to create an `Issuer` using the `qdrant-ca` secret that contains the CA certificate we have just created: @@ -116,9 +116,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/qdrant-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/qdrant-issuer created ### Add TLS @@ -162,29 +162,30 @@ Here, - `spec.apply` specifies when to apply the operation (learn more [here](/docs/guides/qdrant/concepts/opsrequest.md#specapply)). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/add-tls.yaml -qdrantopsrequest.ops.kubedb.com/qdops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/add-tls.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-add-tls created Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdrantopsrequest -n demo qdops-add-tls -w +kubectl get qdrantopsrequest -n demo qdops-add-tls -w +``` NAME TYPE STATUS AGE qdops-add-tls ReconfigureTLS Successful 111s -``` **Verify the TLS secrets:** ```bash -$ kubectl get secrets -n demo | grep qdrant-sample +kubectl get secrets -n demo | grep qdrant-sample +``` qdrant-sample-auth Opaque 2 3m qdrant-sample-client-cert kubernetes.io/tls 4 108s qdrant-sample-server-cert kubernetes.io/tls 3 108s -``` ```bash -$ kubectl describe secret -n demo qdrant-sample-client-cert +kubectl describe secret -n demo qdrant-sample-client-cert +``` Name: qdrant-sample-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -209,7 +210,6 @@ ca.crt: 1151 bytes tls-combined.pem: 2811 bytes tls.crt: 1131 bytes tls.key: 1679 bytes -``` **Connect to the TLS-enabled database:** @@ -224,20 +224,22 @@ kubectl get secret -n demo qdrant-sample-client-cert -o jsonpath='{.data.tls\.ke Get the API key: ```bash -$ kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d -XEHmg7bc4grSjWlH +kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 -d ``` +XEHmg7bc4grSjWlH Port-forward and connect: ```bash -$ kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +kubectl port-forward -n demo svc/qdrant-sample 6333:6333 & +``` Forwarding from 127.0.0.1:6333 -> 6333 -$ curl --cacert ca.crt --cert tls.crt --key tls.key -H "api-key: XEHmg7bc4grSjWlH" \ +```bash +curl --cacert ca.crt --cert tls.crt --key tls.key -H "api-key: XEHmg7bc4grSjWlH" \ 'https://localhost:6333/collections' -{"result":{"collections":[]},"status":"ok","time":7.87e-6} ``` +{"result":{"collections":[]},"status":"ok","time":7.87e-6} ## Rotate Certificates @@ -262,17 +264,17 @@ Here, - `spec.tls.rotateCertificates` specifies that we are requesting to rotate the certificates of the `qdrant-sample` database. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/rotate-tls.yaml -qdrantopsrequest.ops.kubedb.com/qdops-rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/rotate-tls.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-rotate-tls created Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdrantopsrequest -n demo qdops-rotate-tls -w +kubectl get qdrantopsrequest -n demo qdops-rotate-tls -w +``` NAME TYPE STATUS AGE qdops-rotate-tls ReconfigureTLS Successful 101s -``` ## Remove TLS from the Database @@ -297,22 +299,22 @@ Here, - `spec.tls.remove` specifies that we are removing the TLS configuration from `qdrant-sample` database. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/remove-tls.yaml -qdrantopsrequest.ops.kubedb.com/qdops-remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure-tls/remove-tls.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-remove-tls created Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdrantopsrequest -n demo qdops-remove-tls -w +kubectl get qdrantopsrequest -n demo qdops-remove-tls -w +``` NAME TYPE STATUS AGE qdops-remove-tls ReconfigureTLS Successful 3m -``` Verify that TLS has been removed: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o yaml | grep tls +kubectl get qdrant -n demo qdrant-sample -o yaml | grep tls ``` No TLS fields should appear in the output. diff --git a/docs/guides/qdrant/reconfigure/reconfigure.md b/docs/guides/qdrant/reconfigure/reconfigure.md index f7df535f59..a057e73122 100644 --- a/docs/guides/qdrant/reconfigure/reconfigure.md +++ b/docs/guides/qdrant/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/reconfigure](/docs/examples/qdrant/reconfigure) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -62,9 +62,9 @@ type: Opaque Let's create the `Secret` we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/configuration-secret.yaml -secret/qdrant-configuration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/configuration-secret.yaml ``` +secret/qdrant-configuration created Below is the YAML of the `Qdrant` CR that we are going to create: @@ -91,17 +91,17 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 3m42s -``` ## Reconfigure using new config secret @@ -127,9 +127,9 @@ type: Opaque Let's create the `Secret` we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/new-configuration-secret.yaml -secret/new-qdrant-configuration created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/new-configuration-secret.yaml ``` +secret/new-qdrant-configuration created ### Create QdrantOpsRequest @@ -163,9 +163,9 @@ Here, Let's create the `QdrantOpsRequest` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/reconfigure-using-secret.yaml -qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/reconfigure-using-secret.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-config created ### Verify the new configuration is working @@ -174,10 +174,10 @@ If everything goes well, `KubeDB` Enterprise operator will update the `configura Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdops -n demo +kubectl get qdops -n demo +``` NAME TYPE STATUS AGE qdops-reconfigure-config Reconfigure Successful 3m -``` ## Reconfigure using applyConfig @@ -211,19 +211,19 @@ Here, - `spec.configuration.applyConfig` contains the inline configuration to apply. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/apply-config.yaml -qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/apply-config.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-apply-config created ### Verify the new configuration is working Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdops qdops-reconfigure-apply-config -n demo +kubectl get qdops qdops-reconfigure-apply-config -n demo +``` NAME TYPE STATUS AGE qdops-reconfigure-apply-config Reconfigure Successful 5m30s -``` ## Remove Custom Configuration @@ -244,17 +244,17 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/remove-config.yaml -qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/reconfigure/remove-config.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-reconfigure-remove created Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ kubectl get qdops qdops-reconfigure-remove -n demo +kubectl get qdops qdops-reconfigure-remove -n demo +``` NAME TYPE STATUS AGE qdops-reconfigure-remove Reconfigure Successful 97s -``` After this, the `Qdrant` CR will no longer reference a configuration secret and the database will use its default configuration. @@ -269,14 +269,18 @@ After this, the `Qdrant` CR will no longer reference a configuration secret and To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete qdrantopsrequest -n demo qdops-reconfigure-config qdops-reconfigure-apply-config qdops-reconfigure-remove +kubectl delete qdrantopsrequest -n demo qdops-reconfigure-config qdops-reconfigure-apply-config qdops-reconfigure-remove +``` qdrantopsrequest.ops.kubedb.com "qdops-reconfigure-config" deleted qdrantopsrequest.ops.kubedb.com "qdops-reconfigure-apply-config" deleted qdrantopsrequest.ops.kubedb.com "qdops-reconfigure-remove" deleted -$ kubectl delete qdrant -n demo qdrant-sample +```bash +kubectl delete qdrant -n demo qdrant-sample +``` qdrant.kubedb.com "qdrant-sample" deleted -$ kubectl delete ns demo -namespace "demo" deleted -``` \ No newline at end of file +```bash +kubectl delete ns demo +``` +namespace "demo" deleted \ No newline at end of file diff --git a/docs/guides/qdrant/restart/restart.md b/docs/guides/qdrant/restart/restart.md index ffbba14bd9..54790e2402 100644 --- a/docs/guides/qdrant/restart/restart.md +++ b/docs/guides/qdrant/restart/restart.md @@ -29,9 +29,9 @@ KubeDB supports restarting the Qdrant database via a `QdrantOpsRequest`. Restart To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/restart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/qdrant/restart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,17 +60,17 @@ spec: Let's create the `Qdrant` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/restart/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/restart/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 3m47s -``` ## Apply Restart OpsRequest @@ -95,20 +95,21 @@ spec: Let's create the `QdrantOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/restart/ops-request.yaml -qdrantopsrequest.ops.kubedb.com/qdops-restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/restart/ops-request.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-restart created Now the Ops-manager operator will restart the Qdrant pods one by one, waiting for each pod to come back to `Running` state before proceeding to the next. ```bash -$ kubectl get qdops -n demo qdops-restart +kubectl get qdops -n demo qdops-restart +``` NAME TYPE STATUS AGE qdops-restart Restart Successful 66s -``` ```bash -$ kubectl get qdops -n demo qdops-restart -o yaml +kubectl get qdops -n demo qdops-restart -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: QdrantOpsRequest metadata: @@ -195,7 +196,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Next Steps @@ -208,12 +208,16 @@ status: To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete qdrantopsrequest -n demo qdops-restart +kubectl delete qdrantopsrequest -n demo qdops-restart +``` qdrantopsrequest.ops.kubedb.com "qdops-restart" deleted -$ kubectl delete qdrant -n demo qdrant-sample +```bash +kubectl delete qdrant -n demo qdrant-sample +``` qdrant.kubedb.com "qdrant-sample" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/qdrant/rotate-auth/rotate-auth.md b/docs/guides/qdrant/rotate-auth/rotate-auth.md index 631e99f084..d616f59bee 100644 --- a/docs/guides/qdrant/rotate-auth/rotate-auth.md +++ b/docs/guides/qdrant/rotate-auth/rotate-auth.md @@ -33,9 +33,9 @@ KubeDB supports two methods for rotating credentials: To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/rotate-auth](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,24 +64,24 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 3m22s -``` When Qdrant is deployed, KubeDB creates a secret called `qdrant-sample-auth` (format: `{db-name}-auth`) that stores the API key used for authentication. ```bash -$ kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 --decode - +kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 --decode ``` + ## Apply RotateAuth OpsRequest @@ -111,9 +111,9 @@ Here, Let's create the `QdrantOpsRequest` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/ops-request.yaml -qdrantopsrequest.ops.kubedb.com/qdops-rotate-auth created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/ops-request.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-rotate-auth created ## Verify Authentication Rotated @@ -122,19 +122,19 @@ If everything goes well, `KubeDB` ops-manager operator will rotate the authentic Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-rotate-auth +watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-rotate-auth +``` Every 3.0s: kubectl get QdrantOpsRequest -n demo qdops-rotate-auth NAME TYPE STATUS AGE qdops-rotate-auth RotateAuth Successful 2m15s -``` We can see from the above output that the `QdrantOpsRequest` has succeeded. Now let's check if the authentication secret has been updated: ```bash -$ kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 --decode - +kubectl get secret -n demo qdrant-sample-auth -o jsonpath='{.data.api-key}' | base64 --decode ``` + You can see that the API key has been rotated. The new key is different from the initial key. KubeDB has automatically updated the Qdrant instances to use the new credentials. @@ -159,9 +159,9 @@ type: Opaque Let's create the `Secret` we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/custom-auth-secret.yaml -secret/my-custom-auth-secret created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/custom-auth-secret.yaml ``` +secret/my-custom-auth-secret created Now, create a `QdrantOpsRequest` with the custom secret reference: @@ -182,9 +182,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/ops-custom.yaml -qdrantopsrequest.ops.kubedb.com/qdops-rotate-auth-custom created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/rotate-auth/ops-custom.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-rotate-auth-custom created ## Next Steps @@ -197,16 +197,22 @@ qdrantopsrequest.ops.kubedb.com/qdops-rotate-auth-custom created To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete qdrantopsrequest -n demo qdops-rotate-auth qdops-rotate-auth-custom +kubectl delete qdrantopsrequest -n demo qdops-rotate-auth qdops-rotate-auth-custom +``` qdrantopsrequest.ops.kubedb.com "qdops-rotate-auth" deleted qdrantopsrequest.ops.kubedb.com "qdops-rotate-auth-custom" deleted -$ kubectl delete secret -n demo my-custom-auth-secret +```bash +kubectl delete secret -n demo my-custom-auth-secret +``` secret "my-custom-auth-secret" deleted -$ kubectl delete qdrant -n demo qdrant-sample +```bash +kubectl delete qdrant -n demo qdrant-sample +``` qdrant.kubedb.com "qdrant-sample" deleted -$ kubectl delete ns demo -namespace "demo" deleted -``` \ No newline at end of file +```bash +kubectl delete ns demo +``` +namespace "demo" deleted \ No newline at end of file diff --git a/docs/guides/qdrant/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/qdrant/scaling/horizontal-scaling/horizontal-scaling.md index b3f26f8152..297831b7e6 100644 --- a/docs/guides/qdrant/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/qdrant/scaling/horizontal-scaling/horizontal-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to increase/decrease th To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/scaling/horizontal-scaling](/docs/examples/qdrant/scaling/horizontal-scaling) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -71,9 +71,9 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created **Wait for the cluster to be ready:** @@ -82,35 +82,37 @@ qdrant.kubedb.com/qdrant-sample created Now, watch `Qdrant` is going to `Running` state and also watch `PetSet` and its pods: ```bash -$ watch -n 3 kubectl get qdrant -n demo qdrant-sample +watch -n 3 kubectl get qdrant -n demo qdrant-sample +``` Every 3.0s: kubectl get qdrant -n demo qdrant-sample NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 4m40m - -$ watch -n 3 kubectl get petset -n demo qdrant-sample +```bash +watch -n 3 kubectl get petset -n demo qdrant-sample +``` Every 3.0s: kubectl get petset -n demo qdrant-sample NAME READY AGE qdrant-sample 3/3 4m41m - -$ watch -n 3 kubectl get pods -n demo +```bash +watch -n 3 kubectl get pods -n demo +``` Every 3.0s: kubectl get pod -n demo NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 4m25m qdrant-sample-1 1/1 Running 0 4m26m qdrant-sample-2 1/1 Running 0 4m26m -``` Let's check the current number of nodes: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' -3 +kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' ``` +3 We are ready to apply the `QdrantOpsRequest` CR to scale horizontally. @@ -147,34 +149,36 @@ Here, Let's create the `QdrantOpsRequest` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/hscale-up.yaml -qdrantopsrequest.ops.kubedb.com/qdops-hscale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/hscale-up.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-hscale-up created **Verify Qdrant scale-up completed successfully:** ```bash -$ watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-hscale-up +watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-hscale-up +``` Every 3.0s: kubectl get QdrantOpsRequest -n demo qdops-hscale-up NAME TYPE STATUS AGE qdops-hscale-up HorizontalScaling Successful 3m57s -``` Now let's verify that the number of nodes has increased: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' +kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' +``` 5 -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 10m qdrant-sample-1 1/1 Running 0 10m qdrant-sample-2 1/1 Running 0 10m qdrant-sample-3 1/1 Running 0 2m qdrant-sample-4 1/1 Running 0 1m -``` ### Scale Down @@ -199,33 +203,35 @@ spec: Let's create the `QdrantOpsRequest` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/hscale-down.yaml -qdrantopsrequest.ops.kubedb.com/qdops-hscale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/horizontal-scaling/hscale-down.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-hscale-down created **Verify Qdrant scale-down completed successfully:** ```bash -$ watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-hscale-down +watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-hscale-down +``` Every 3.0s: kubectl get QdrantOpsRequest -n demo qdops-hscale-down NAME TYPE STATUS AGE qdops-hscale-down HorizontalScaling Successful 2m15s -``` Now let's verify that the number of nodes has decreased: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' +kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.replicas}{"\n"}' +``` 4 -$ kubectl get pods -n demo +```bash +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 14m qdrant-sample-1 1/1 Running 0 14m qdrant-sample-2 1/1 Running 0 14m qdrant-sample-3 1/1 Running 0 6m -``` We have successfully performed horizontal scaling on the Qdrant cluster. diff --git a/docs/guides/qdrant/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/qdrant/scaling/vertical-scaling/vertical-scaling.md index ca44014553..7db5a1a621 100644 --- a/docs/guides/qdrant/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/qdrant/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops Manager to update the resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/scaling/vertical-scaling](/docs/examples/qdrant/scaling/vertical-scaling) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,38 +66,43 @@ spec: Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/vertical-scaling/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/vertical-scaling/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created **Wait for the cluster to be ready:** ```bash -$ watch -n 3 kubectl get qdrant -n demo qdrant-sample +watch -n 3 kubectl get qdrant -n demo qdrant-sample +``` Every 3.0s: kubectl get qdrant -n demo qdrant-sample NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 3m16s -$ watch -n 3 kubectl get petset -n demo qdrant-sample +```bash +watch -n 3 kubectl get petset -n demo qdrant-sample +``` Every 3.0s: kubectl get petset -n demo qdrant-sample NAME READY AGE qdrant-sample 3/3 3m54s -$ watch -n 3 kubectl get pod -n demo +```bash +watch -n 3 kubectl get pod -n demo +``` Every 3.0s: kubectl get pod -n demo NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 4m51s qdrant-sample-1 1/1 Running 0 3m50s qdrant-sample-2 1/1 Running 0 3m46s -``` Let's check the resources of the `qdrant-sample-0` pod: ```bash -$ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1Gi" @@ -107,7 +112,6 @@ $ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].reso "memory": "1Gi" } } -``` We are ready to apply the `QdrantOpsRequest` CR to vertically scale the cluster. @@ -149,9 +153,9 @@ Here, Let's create the `QdrantOpsRequest` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/vertical-scaling/vscale.yaml -qdrantopsrequest.ops.kubedb.com/qdops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/scaling/vertical-scaling/vscale.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-vscale created #### Verify Qdrant vertical scaling completed successfully @@ -160,17 +164,18 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `QdrantOpsRequest` to be `Successful`: ```bash -$ watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-vscale +watch -n 3 kubectl get QdrantOpsRequest -n demo qdops-vscale +``` Every 3.0s: kubectl get QdrantOpsRequest -n demo qdops-vscale NAME TYPE STATUS AGE qdops-vscale VerticalScaling Successful 3m12s -``` Now, let's verify that the resources of the pods have been updated: ```bash -$ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -181,7 +186,6 @@ $ kubectl get pod -n demo qdrant-sample-0 -o json | jq '.spec.containers[0].reso "memory": "1Gi" } } -``` You can see from the above output that the resources of the `qdrant-sample-0` pod have been updated successfully. All pods in the cluster will have the same updated resource configuration. diff --git a/docs/guides/qdrant/tls/configure-tls.md b/docs/guides/qdrant/tls/configure-tls.md index 0340f7c8e7..38732286e6 100644 --- a/docs/guides/qdrant/tls/configure-tls.md +++ b/docs/guides/qdrant/tls/configure-tls.md @@ -31,9 +31,9 @@ KubeDB supports providing TLS encryption for Qdrant. This tutorial will show you To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/tls](/docs/examples/qdrant/tls) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -50,9 +50,9 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - Now create a ca-secret using the certificate files you have just generated: ```bash -$ kubectl create secret tls qdrant-ca --cert=ca.crt --key=ca.key --namespace=demo -secret/qdrant-ca created +kubectl create secret tls qdrant-ca --cert=ca.crt --key=ca.key --namespace=demo ``` +secret/qdrant-ca created Now, create an `Issuer` using the `qdrant-ca` secret you have just created. Below is the YAML of the `Issuer` CR: @@ -70,9 +70,9 @@ spec: Let's create the `Issuer` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/tls/issuer.yaml -issuer.cert-manager.io/qdrant-ca-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/tls/issuer.yaml ``` +issuer.cert-manager.io/qdrant-ca-issuer created ## TLS Encryption in Qdrant @@ -113,44 +113,47 @@ Here, Let's create the `Qdrant` CR we have shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/tls/tls-qdrant.yaml -qdrant.kubedb.com/qdrant-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/tls/tls-qdrant.yaml ``` +qdrant.kubedb.com/qdrant-tls created Now, wait until `qdrant-tls` has status `Ready`: ```bash -$ watch -n 3 kubectl get qdrant -n demo qdrant-tls +watch -n 3 kubectl get qdrant -n demo qdrant-tls +``` Every 3.0s: kubectl get qdrant -n demo qdrant-tls NAME VERSION STATUS AGE qdrant-tls 1.17.0 Ready 7m -$ watch -n 3 kubectl get pods -n demo -l app.kubernetes.io/instance=qdrant-tls +```bash +watch -n 3 kubectl get pods -n demo -l app.kubernetes.io/instance=qdrant-tls +``` Every 3.0s: kubectl get pods -n demo -l app.kubernetes.io/instance=qdrant-tls NAME READY STATUS RESTARTS AGE qdrant-tls-0 1/1 Running 0 7m qdrant-tls-1 1/1 Running 0 2m qdrant-tls-2 1/1 Running 0 117s -``` ### Verify TLS Configuration Now, let's verify the TLS certificates were created for the Qdrant database: ```bash -$ kubectl get secrets -n demo | grep qdrant-tls +kubectl get secrets -n demo | grep qdrant-tls +``` qdrant-tls-160bbc Opaque 1 7m qdrant-tls-auth Opaque 2 7m qdrant-tls-client-cert kubernetes.io/tls 4 7m qdrant-tls-server-cert kubernetes.io/tls 3 7m -``` The `qdrant-tls-client-cert` secret contains the client TLS certificate. Let's inspect it: ```bash -$ kubectl describe secret -n demo qdrant-tls-client-cert +kubectl describe secret -n demo qdrant-tls-client-cert +``` Name: qdrant-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -175,12 +178,12 @@ ca.crt: 1151 bytes tls-combined.pem: 2811 bytes tls.crt: 1131 bytes tls.key: 1679 bytes -``` We can also verify that the TLS configuration has been applied inside the Qdrant pod: ```bash -$ kubectl exec -n demo qdrant-tls-0 -- cat /qdrant/config/config.yaml +kubectl exec -n demo qdrant-tls-0 -- cat /qdrant/config/config.yaml +``` Defaulted container "qdrant" out of: qdrant, update-raft-state (init) cluster: enabled: true @@ -195,7 +198,9 @@ tls: cert: /tls/cert.pem key: /tls/key.pem -$ kubectl exec -n demo qdrant-tls-0 -- ls /tls/ +```bash +kubectl exec -n demo qdrant-tls-0 -- ls /tls/ +``` Defaulted container "qdrant" out of: qdrant, update-raft-state (init) ca.crt ca.pem @@ -203,7 +208,6 @@ cert.pem client.crt client.key key.pem -``` The TLS certificates are mounted at `/tls/` inside the container, and the Qdrant config shows `service.enable_tls: true`. @@ -220,24 +224,24 @@ kubectl get secret -n demo qdrant-tls-client-cert -o jsonpath='{.data.tls\.key}' Then, port-forward the Qdrant service and connect using TLS: ```bash -$ kubectl port-forward -n demo svc/qdrant-tls 6333:6333 & -Forwarding from 127.0.0.1:6333 -> 6333 +kubectl port-forward -n demo svc/qdrant-tls 6333:6333 & ``` +Forwarding from 127.0.0.1:6333 -> 6333 Get the API key from the auth secret: ```bash -$ kubectl get secret -n demo qdrant-tls-auth -o jsonpath='{.data.api-key}' | base64 -d -GuBrzentGdAcZuqh +kubectl get secret -n demo qdrant-tls-auth -o jsonpath='{.data.api-key}' | base64 -d ``` +GuBrzentGdAcZuqh Now you can connect to the Qdrant cluster using TLS: ```bash -$ curl --cacert ca.crt --cert tls.crt --key tls.key -H "api-key: GuBrzentGdAcZuqh" \ +curl --cacert ca.crt --cert tls.crt --key tls.key -H "api-key: GuBrzentGdAcZuqh" \ 'https://localhost:6333/collections' -{"result":{"collections":[{"name":"KubeDBHealthCheckCollection"}]},"status":"ok","time":3.63e-6} ``` +{"result":{"collections":[{"name":"KubeDBHealthCheckCollection"}]},"status":"ok","time":3.63e-6} > Without the TLS certificates or the API key, the connection will be rejected. diff --git a/docs/guides/qdrant/update-version/update-version.md b/docs/guides/qdrant/update-version/update-version.md index 51fe6b426f..1574d0577a 100644 --- a/docs/guides/qdrant/update-version/update-version.md +++ b/docs/guides/qdrant/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/update-version](/docs/examples/qdrant/update-version) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -49,12 +49,12 @@ At first, we are going to deploy a Qdrant instance using a supported `Qdrant` ve When you have installed `KubeDB`, it has created `QdrantVersion` CR for all supported `Qdrant` versions. Let's check the supported versions: ```bash -$ kubectl get qdrantversion +kubectl get qdrantversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.15.4 1.15.4 docker.io/qdrant/qdrant:v1.15.4-unprivileged 24d 1.16.2 1.16.2 docker.io/qdrant/qdrant:v1.16.2-unprivileged 24d 1.17.0 1.17.0 docker.io/qdrant/qdrant:v1.17.0-unprivileged 24d -``` The version above that does not show `DEPRECATED` `true` is supported by `KubeDB` for `Qdrant`. You can use any non-deprecated version. Now, we are going to select a non-deprecated version from `QdrantVersion` for the `Qdrant` instance that we will update from this version to another. In the next section, we are going to verify version update constraints. @@ -65,7 +65,8 @@ Qdrant supports rolling version updates. You can update from any currently runni Let's get one of the `qdrantversion` YAMLs: ```bash -$ kubectl get qdrantversion 1.17.0 -o yaml +kubectl get qdrantversion 1.17.0 -o yaml +``` apiVersion: catalog.kubedb.com/v1alpha1 kind: QdrantVersion metadata: @@ -78,7 +79,6 @@ spec: db: image: docker.io/qdrant/qdrant:v1.17.0-unprivileged version: "1.17.0" -``` **Deploy Qdrant Instance:** @@ -105,9 +105,9 @@ spec: Let's create the `Qdrant` cr we have shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/update-version/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/update-version/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created **Wait for the database to be ready:** @@ -116,37 +116,46 @@ qdrant.kubedb.com/qdrant-sample created Now, watch `Qdrant` is going to `Running` state and also watch `PetSet` and its pod is created and going to `Running` state: ```bash -$ watch -n 3 kubectl get qdrant -n demo +watch -n 3 kubectl get qdrant -n demo +``` Every 3.0s: kubectl get qdrant -n demo NAME VERSION STATUS AGE qdrant-sample 1.16.2 Ready 3m42s -$ watch -n 3 kubectl get petset -n demo qdrant-sample +```bash +watch -n 3 kubectl get petset -n demo qdrant-sample +``` Every 3.0s: kubectl get petset -n demo qdrant-sample NAME READY AGE qdrant-sample 3/3 4m17s -$ watch -n 3 kubectl get pod -n demo +```bash +watch -n 3 kubectl get pod -n demo +``` Every 3.0s: kubectl get pods -n demo NAME READY STATUS RESTARTS AGE qdrant-sample-0 1/1 Running 0 4m55s qdrant-sample-1 1/1 Running 0 4m12s qdrant-sample-2 1/1 Running 0 3m38s -``` Let's verify the `Qdrant`, the `PetSet` and its `Pod` image version: ```bash -$ kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.version}{"\n"}' +kubectl get qdrant -n demo qdrant-sample -o=jsonpath='{.spec.version}{"\n"}' +``` 1.16.2 -$ kubectl get petset -n demo qdrant-sample -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo qdrant-sample -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` docker.io/qdrant/qdrant:v1.16.2-unprivileged -$ kubectl get pod -n demo qdrant-sample-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +```bash +kubectl get pod -n demo qdrant-sample-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` docker.io/qdrant/qdrant:v1.16.2-unprivileged We are ready to apply version updating on this `Qdrant` instance. @@ -158,8 +167,6 @@ Here, we are going to update `Qdrant` from version `1.16.2` to `1.17.0`. **Create QdrantOpsRequest:** To update the instance, you have to create a `QdrantOpsRequest` cr with your desired version that is supported by `KubeDB`. Below is the YAML of the `QdrantOpsRequest` cr that we are going to create: - -```yaml apiVersion: ops.kubedb.com/v1alpha1 kind: QdrantOpsRequest metadata: diff --git a/docs/guides/qdrant/volume-expansion/volume-expansion.md b/docs/guides/qdrant/volume-expansion/volume-expansion.md index ee83537b03..87b8f93f03 100644 --- a/docs/guides/qdrant/volume-expansion/volume-expansion.md +++ b/docs/guides/qdrant/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/qdrant/volume-expansion](/docs/examples/qdrant/volume-expansion) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -47,12 +47,12 @@ Here, we are going to deploy a `Qdrant` cluster using a supported version by `Ku At first verify that your cluster has a storage class that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 2d longhorn (default) driver.longhorn.io Delete Immediate true 3m25s longhorn-static driver.longhorn.io Delete Immediate true 3m19s -``` We can see from the output that `longhorn (default)` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. @@ -84,30 +84,32 @@ spec: Let's create the `Qdrant` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/volume-expansion/qdrant.yaml -qdrant.kubedb.com/qdrant-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/volume-expansion/qdrant.yaml ``` +qdrant.kubedb.com/qdrant-sample created Now, wait until `qdrant-sample` has status `Ready`: ```bash -$ kubectl get qdrant -n demo +kubectl get qdrant -n demo +``` NAME VERSION STATUS AGE qdrant-sample 1.17.0 Ready 3m47s -``` Let's check volume size from the PetSet and from the persistent volumes: ```bash -$ kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS AGE pvc-0e300ccf-49f1-4e11-b630-bc3756baeaa0 1Gi RWO Delete Bound demo/data-qdrant-sample-0 longhorn 4m pvc-20ab1d50-23d7-409a-ba2e-759250f9f758 1Gi RWO Delete Bound demo/data-qdrant-sample-2 longhorn 4m pvc-ccee01bf-9551-4efc-8945-5a3d25c60c7b 1Gi RWO Delete Bound demo/data-qdrant-sample-1 longhorn 4m -``` You can see the PetSet has 1Gi storage, and the capacity of all the persistent volumes are also 1Gi. @@ -151,9 +153,9 @@ During `Online` VolumeExpansion KubeDB expands volume without deleting the pods, Let's create the `QdrantOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/volume-expansion/ops-request.yaml -qdrantopsrequest.ops.kubedb.com/qdops-vol-exp created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/qdrant/volume-expansion/ops-request.yaml ``` +qdrantopsrequest.ops.kubedb.com/qdops-vol-exp created #### Verify Qdrant volume expanded successfully @@ -162,15 +164,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `QdrantOpsRequest` to be `Successful`. Run the following command to watch `QdrantOpsRequest` CR, ```bash -$ kubectl get qdrantopsrequest -n demo +kubectl get qdrantopsrequest -n demo +``` NAME TYPE STATUS AGE qdops-vol-exp VolumeExpansion Successful 10m -``` We can see from the above output that the `QdrantOpsRequest` has succeeded. If we describe the `QdrantOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe qdrantopsrequest qdops-vol-exp -n demo +kubectl describe qdrantopsrequest qdops-vol-exp -n demo +``` Name: qdops-vol-exp Namespace: demo Labels: @@ -286,20 +289,21 @@ Events: Normal ReadyPetSets 10s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 10s KubeDB Ops-manager Operator Resuming Qdrant database: demo/qdrant-sample Normal Successful 10s KubeDB Ops-manager Operator Successfully resumed Qdrant database: demo/qdrant-sample for QdrantOpsRequest: qdops-vol-exp -``` Now, we are going to verify from the `PetSet` and `Persistent Volumes` whether the volume of the Qdrant database has expanded to meet the desired state: ```bash -$ kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo qdrant-sample -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "3Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS AGE pvc-0e300ccf-49f1-4e11-b630-bc3756baeaa0 3Gi RWO Delete Bound demo/data-qdrant-sample-0 longhorn 5m pvc-20ab1d50-23d7-409a-ba2e-759250f9f758 3Gi RWO Delete Bound demo/data-qdrant-sample-2 longhorn 5m pvc-ccee01bf-9551-4efc-8945-5a3d25c60c7b 3Gi RWO Delete Bound demo/data-qdrant-sample-1 longhorn 5m -``` The above output verifies that we have successfully expanded the volume of the Qdrant database. @@ -314,9 +318,11 @@ The above output verifies that we have successfully expanded the volume of the Q To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete qdrant -n demo qdrant-sample +kubectl delete qdrant -n demo qdrant-sample +``` qdrant.kubedb.com "qdrant-sample" deleted -$ kubectl delete qdrantopsrequest -n demo qdops-vol-exp -qdrantopsrequest.ops.kubedb.com "qdops-vol-exp" deleted -``` \ No newline at end of file +```bash +kubectl delete qdrantopsrequest -n demo qdops-vol-exp +``` +qdrantopsrequest.ops.kubedb.com "qdops-vol-exp" deleted \ No newline at end of file diff --git a/docs/guides/rabbitmq/autoscaler/compute/compute-autoscale.md b/docs/guides/rabbitmq/autoscaler/compute/compute-autoscale.md index 71479c91eb..d99d15aef1 100644 --- a/docs/guides/rabbitmq/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/rabbitmq/autoscaler/compute/compute-autoscale.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscaling compute resources i. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/rabbitmq](/docs/examples/rabbitmq) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -81,22 +81,23 @@ spec: Let's create the `RabbitMQ` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/autoscaling/compute/rabbitmq-autoscale.yaml -rabbitmq.kubedb.com/rabbitmq-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/autoscaling/compute/rabbitmq-autoscale.yaml ``` +rabbitmq.kubedb.com/rabbitmq-autoscale created Now, wait until `rabbitmq-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME TYPE VERSION STATUS AGE rabbitmq-autoscale kubedb.com/v1alpha2 4.2.4 Ready 22s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -107,11 +108,11 @@ $ kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[]. "memory": "1Gi" } } -``` Let's check the RabbitMQ resources, ```bash -$ kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -122,7 +123,6 @@ $ kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplat "memory": "1Gi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the rabbitmq. @@ -176,20 +176,23 @@ Here, Let's create the `RabbitMQAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/autoscaling/compute/rabbitmq-autoscaler.yaml -rabbitmqautoscaler.autoscaling.kubedb.com/rabbitmq-autoscaler-ops created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/autoscaling/compute/rabbitmq-autoscaler.yaml ``` +rabbitmqautoscaler.autoscaling.kubedb.com/rabbitmq-autoscaler-ops created #### Verify Autoscaling is set up successfully Let's check that the `rabbitmqautoscaler` resource is created successfully, ```bash -$ kubectl get rabbitmqautoscaler -n demo +kubectl get rabbitmqautoscaler -n demo +``` NAME AGE rabbitmq-autoscale-ops 6m55s -$ kubectl describe rabbitmqautoscaler rabbitmq-autoscale-ops -n demo +```bash +kubectl describe rabbitmqautoscaler rabbitmq-autoscale-ops -n demo +``` Name: rabbitmq-autoscale-ops Namespace: demo Labels: @@ -272,7 +275,6 @@ Status: Memory: 2Gi Vpa Name: rabbitmq-autoscale Events: -``` So, the `RabbitMQautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our RabbitMQ. Our autoscaler operator continuously watches the recommendation generated and creates an `rabbitmqopsrequest` based on the recommendations, if the rabbitmq pods are needed to scaled up or down. @@ -280,25 +282,26 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `rabbitmqopsrequest` in the demo namespace to see if any `rabbitmqopsrequest` object is created. After some time you'll see that a `rabbitmqopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get rabbitmqopsrequest -n demo +watch kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-rabbitmq-autoscale-zzell6 VerticalScaling Progressing 1m48s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get rabbitmqopsrequest -n demo +watch kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-rabbitmq-autoscale-zzell6 VerticalScaling Successful 3m40s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to scale the RabbitMQ. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-rabbitmq-autoscale-zzell6 +kubectl describe rabbitmqopsrequest -n demo rmops-rabbitmq-autoscale-zzell6 +``` Name: rmops-rabbitmq-autoscale-zzell6 Namespace: demo Labels: app.kubernetes.io/component=connection-pooler @@ -397,12 +400,12 @@ Events: Normal RestartPods 7m31s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 7m31s KubeDB Ops-manager Operator Resuming rabbitmq database: demo/rabbitmq-autoscale Normal Successful 7m30s KubeDB Ops-manager Operator Successfully resumed RabbitMQ database: demo/rabbitmq-autoscale for RabbitMQOpsRequest: rmops-rabbitmq-autoscale-zzell6 -``` Now, we are going to verify from the Pod, and the RabbitMQ yaml whether the resources of the RabbitMQ has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -414,7 +417,9 @@ $ kubectl get pod -n demo rabbitmq-autoscale-0 -o json | jq '.spec.containers[]. } } -$ kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +```bash +kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplate.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -425,7 +430,6 @@ $ kubectl get rabbitmq -n demo rabbitmq-autoscale -o json | jq '.spec.podTemplat "memory": "1.2Gi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the rabbitmq. diff --git a/docs/guides/rabbitmq/autoscaler/storage/storage-autoscale.md b/docs/guides/rabbitmq/autoscaler/storage/storage-autoscale.md index 0a2c8f4d02..fe5ca7c097 100644 --- a/docs/guides/rabbitmq/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/rabbitmq/autoscaler/storage/storage-autoscale.md @@ -37,20 +37,20 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Rabbi To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Cluster Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 79m topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 78m -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -100,30 +100,32 @@ spec: Let's create the `RabbitMQ` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/rabbitmq/autoscaler/storage/cluster/examples/sample-rabbitmq.yaml -rabbitmq.kubedb.com/rabbitmq-autoscale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/rabbitmq/autoscaler/storage/cluster/examples/sample-rabbitmq.yaml ``` +rabbitmq.kubedb.com/rabbitmq-autoscale created Now, wait until `rabbitmq-autoscale` has status `Ready`. i.e, ```bash -$ kubectl get rabbitmq -n demo +kubectl get rabbitmq -n demo +``` NAME VERSION STATUS AGE rabbitmq-autoscale 4.2.4 Ready 3m46s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo rabbitmq-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rabbitmq-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 1Gi RWO Delete Bound demo/data-sample-rabbitmq-2 topolvm-provisioner 57s pvc-4a509b05-774b-42d9-b36d-599c9056af37 1Gi RWO Delete Bound demo/data-sample-rabbitmq-0 topolvm-provisioner 58s pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 1Gi RWO Delete Bound demo/data-sample-rabbitmq-1 topolvm-provisioner 57s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volume is also 1GB. @@ -165,20 +167,23 @@ Here, Let's create the `rabbitmqAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/rabbitmq/autoscaler/storage/cluster/examples/rm-storage-autoscale-ops.yaml -rabbitmqautoscaler.autoscaling.kubedb.com/rabbitmq-storage-autosclaer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/rabbitmq/autoscaler/storage/cluster/examples/rm-storage-autoscale-ops.yaml ``` +rabbitmqautoscaler.autoscaling.kubedb.com/rabbitmq-storage-autosclaer created #### Storage Autoscaling is set up successfully Let's check that the `rabbitmqautoscaler` resource is created successfully, ```bash -$ kubectl get rabbitmqautoscaler -n demo +kubectl get rabbitmqautoscaler -n demo +``` NAME AGE rabbitmq-storage-autosclaer 33s -$ kubectl describe rabbitmqautoscaler rabbitmq-storage-autoscaler -n demo +```bash +kubectl describe rabbitmqautoscaler rabbitmq-storage-autoscaler -n demo +``` Name: rabbitmq-storage-autosclaer Namespace: demo Labels: @@ -200,7 +205,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` So, the `rabbitmqautoscaler` resource is created successfully. @@ -215,7 +219,8 @@ kubectl run perf-test --image=pivotalrabbitmq/perf-test -- --uri "amqp://admin:p You can check the log for this pod which shows publish and consume rates of messages in RabbitMQ. ```bash -$ kubectl logs pod/perf-test -f +kubectl logs pod/perf-test -f +``` id: test-104606-706, starting consumer #0 id: test-104606-706, starting consumer #0, channel #0 id: test-104606-706, starting producer #0 @@ -230,28 +235,28 @@ id: test-104606-706, time 7.000 s, sent: 38117 msg/s, received: 30759 msg/s, min id: test-104606-706, time 8.000 s, sent: 35088 msg/s, received: 31676 msg/s, min/median/75th/95th/99th consumer latency: 1578860/1799719/1915632/1985467/2024141 µs id: test-104606-706, time 9.000 s, sent: 29706 msg/s, received: 31375 msg/s, min/median/75th/95th/99th consumer latency: 1516415/1743385/1877037/1972570/1988962 µs id: test-104606-706, time 10.000 s, sent: 15903 msg/s, received: 26711 msg/s, min/median/75th/95th/99th consumer latency: 1569546/1884700/1992762/2096417/2136613 µs -``` Let's watch the `rabbitmqopsrequest` in the demo namespace to see if any `rabbitmqopsrequest` object is created. After some time you'll see that a `rabbitmqopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` NAME TYPE STATUS AGE rmops-rabbitmq-autoscale-xojkua VolumeExpansion Progressing 15s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` NAME TYPE STATUS AGE rmops-rabbitmq-autoscale-xojkua VolumeExpansion Successful 97s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-rabbitmq-autoscale-xojkua +kubectl describe rabbitmqopsrequest -n demo rmops-rabbitmq-autoscale-xojkua +``` Name: rmops-rabbitmq-autoscaleq-xojkua Namespace: demo Labels: app.kubernetes.io/component=database @@ -314,19 +319,21 @@ Events: Normal Starting 103s KubeDB Enterprise Operator Resuming rabbitmq database: demo/rabbitmq-autoscale Normal Successful 103s KubeDB Enterprise Operator Successfully resumed rabbitmq database: demo/rabbitmq-autoscale Normal Successful 103s KubeDB Enterprise Operator Controller has Successfully expand the volume of rabbitmq: demo/rabbitmq-autoscale -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the replicaset database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo rabbitmq-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rabbitmq-autoscale -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-43266d76-f280-4cca-bd78-d13660a84db9 2Gi RWO Delete Bound demo/data-rabbitmq-autoscale-2 topolvm-provisioner 23m pvc-4a509b05-774b-42d9-b36d-599c9056af37 2Gi RWO Delete Bound demo/data-srabbitmq-autoscale-0 topolvm-provisioner 24m pvc-c27eee12-cd86-4410-b39e-b1dd735fc14d 2Gi RWO Delete Bound demo/data-rabbitmq-autoscale-1 topolvm-provisioner 23m -``` The above output verifies that we have successfully autoscaled the volume of the rabbitmq cluster. diff --git a/docs/guides/rabbitmq/concepts/catalog.md b/docs/guides/rabbitmq/concepts/catalog.md index b72ba96754..658f618ccc 100644 --- a/docs/guides/rabbitmq/concepts/catalog.md +++ b/docs/guides/rabbitmq/concepts/catalog.md @@ -27,7 +27,7 @@ Using a separate crd for specifying respective docker images, and pod security p As with all other Kubernetes objects, a RabbitMQVersion needs `apiVersion`, `kind`, and `metadata` fields. It also needs a `.spec` section. Get `RabbitMQVersion` CR with a simple kubectl command. ```bash -$ kubectl get rmversion 4.2.4 -oyaml +kubectl get rmversion 4.2.4 -oyaml ``` ```yaml diff --git a/docs/guides/rabbitmq/concepts/rabbitmq.md b/docs/guides/rabbitmq/concepts/rabbitmq.md index 75f3645fe8..74c42f040f 100644 --- a/docs/guides/rabbitmq/concepts/rabbitmq.md +++ b/docs/guides/rabbitmq/concepts/rabbitmq.md @@ -135,11 +135,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic -n demo rabbit-auth \ +kubectl create secret generic -n demo rabbit-auth \ --from-literal=username=rabbit-admin \ --from-literal=password=mypassword -secret/rabbit-auth created ``` +secret/rabbit-auth created ```yaml apiVersion: v1 diff --git a/docs/guides/rabbitmq/configuration/using-config-file.md b/docs/guides/rabbitmq/configuration/using-config-file.md index 7a6acc0540..6c0772ecf4 100644 --- a/docs/guides/rabbitmq/configuration/using-config-file.md +++ b/docs/guides/rabbitmq/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for RabbitMQ. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/rabbitmq](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -44,23 +44,24 @@ At first, you have to create a secret with your configuration file contents as t At first, create `rabbitmq.conf` file containing required configuration settings. ```bash -$ cat rabbitmq.conf +cat rabbitmq.conf +``` vm_memory_high_watermark.absolute = 4GB heartbeat = 100 collect_statistics = coarse -``` Now, create the secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rm-configuration --from-file=./rabbitmq.conf -secret/rm-configuration created +kubectl create secret generic -n demo rm-configuration --from-file=./rabbitmq.conf ``` +secret/rm-configuration created Verify the secret has the configuration file. ```bash -$ kubectl get secret -n demo rm-configuration -o yaml + kubectl get secret -n demo rm-configuration -o yaml +``` apiVersion: v1 data: rabbitmq.conf: bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== @@ -73,11 +74,12 @@ metadata: uid: 80f5324a-9a65-4801-b136-21d2fa001b12 type: Opaque -$ echo bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== | base64 -d +```bash +echo bnVtX2luaXRfY2hpbGRyZW4gPSA2Cm1heF9wb29sID0gNjUKY2hpbGRfbGlmZV90aW1lID0gNDAwCg== | base64 -d +``` vm_memory_high_watermark.absolute = 4GB heartbeat = 100 collect_statistics = coarse -``` Now, create rabbitmq crd specifying `spec.configuration.secretName` field. @@ -104,26 +106,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-config-file.yaml -rabbitmq.kubedb.com/rm-custom-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-config-file.yaml ``` +rabbitmq.kubedb.com/rm-custom-config 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 `rm-custom-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo rm-custom-config-0 +kubectl get pod -n demo rm-custom-config-0 +``` NAME READY STATUS RESTARTS AGE rm-custom-config-0 1/1 Running 0 35s -``` Now, we will check if the pgpool has started with the custom configuration we have provided. Now, you can exec into the pgpool pod and find if the custom configuration is there, ```bash -$ kubectl exec -it -n demo rm-custom-config-0 -- bash +kubectl exec -it -n demo rm-custom-config-0 -- bash +``` rm-custom-config-0:/$ cat /config/rabbitmq.conf log.console.level= info stomp.default_user= $(RABBITMQ_DEFAULT_USER) @@ -150,7 +153,6 @@ queue_master_locator= min-masters cluster_formation.k8s.address_type= hostname rm-custom-config-0:/$ exit exit -``` As we can see from the configuration of running rabbitmq, the value of `collect_statistics`, `heartbeat` and `vm_memory_high_watermark.absolute` has been set to our desired value successfully. diff --git a/docs/guides/rabbitmq/configuration/using-podtemplate.md b/docs/guides/rabbitmq/configuration/using-podtemplate.md index c8c0f90528..70c45242cc 100644 --- a/docs/guides/rabbitmq/configuration/using-podtemplate.md +++ b/docs/guides/rabbitmq/configuration/using-podtemplate.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for RabbitMQ via [PodTemplate](/d - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/rabbitmq](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -95,24 +95,25 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rm-misc-config.yaml -rabbitmq.kubedb.com/rm-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rm-misc-config.yaml ``` +rabbitmq.kubedb.com/rm-misc-config 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 `rm-misc-config-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE rm-misc-config-0 1/1 Running 0 68s -``` Now, check if the rabbitmq has started with the custom configuration we have provided. We will fetch log in the pod and see the `RABBITMQ_LOG_BASE`, the new log directory exists of not. ```bash -$ kubectl exec -it -n demo -- bash +kubectl exec -it -n demo -- bash +``` ## ## RabbitMQ 4.2.4 ## ## ########## Copyright (c) 2007-2024 Broadcom Inc and/or its subsidiaries @@ -131,7 +132,6 @@ $ kubectl exec -it -n demo -- bash Logs: /var/log/rabbitmq/cluster/rabbit@rm-misc-config-0.rm-misc-config-pods.demo.log -``` So, we can see that that logs are being written to **Logs: /var/log/rabbitmq/cluster**/rabbit@rm-misc-config-0.rm-misc-config-pods.demo.log file. ## Custom Sidecar Containers @@ -157,8 +157,11 @@ 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 +docker build -t repository_name/custom_filebeat:latest . +``` + +```bash +docker push repository_name/custom_filebeat:latest ``` Now we will deploy our RabbitMQ with custom sidecar container to mount filebeats input directory as a shared directory with rabbitmq's log base directory. Here is the yaml of our RabbitMQ: ```yaml @@ -198,23 +201,22 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-config-sidecar.yaml -rabbitmq.kubedb.com/rabbitmq-custom-sidecar created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-config-sidecar.yaml ``` +rabbitmq.kubedb.com/rabbitmq-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 `rabbitmq-custom-sidecar-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE rabbitmq-custom-sidecar-0 2/2 Running 0 33s - -``` Now, Let’s fetch the logs shipped to filebeat console output. The outputs will be generated in json format. ```bash -$ kubectl logs -f -n demo rabbitmq-custom-sidecar-0 -c filebeat +kubectl logs -f -n demo rabbitmq-custom-sidecar-0 -c filebeat ``` We will find the query logs in filebeat console output. So, we have successfully extracted logs from rabbitmq to our sidecar filebeat container. @@ -224,31 +226,32 @@ So, we have successfully extracted logs from rabbitmq to our sidecar filebeat co Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our RabbitMQ 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -264,7 +267,6 @@ Labels: beta.kubernetes.io/arch=amd64 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 RabbitMQ with this new label as nodeSelector. Below is the yaml we are going to apply: @@ -292,24 +294,24 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-node-selector.yaml -rabbitmq.kubedb.com/rabbitmq-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-node-selector.yaml ``` +rabbitmq.kubedb.com/rabbitmq-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 `rabbitmq-node-selector-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE rabbitmq-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 rabbitmq-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo rabbitmq-node-selector-0 -o wide +kubectl get pods -n demo rabbitmq-node-selector-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES rabbitmq-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 @@ -317,28 +319,33 @@ We can successfully verify that our pod was scheduled to our desired node. Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our rabbitmq 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +```bash +kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +``` node/lke212553-307295-5541798e0000 tainted -$ kubectl taint nodes lke212553-307295-5b53c5520000 key1=node3:NoSchedule -node/lke212553-307295-5b53c5520000 tainted +```bash +kubectl taint nodes lke212553-307295-5b53c5520000 key1=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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -363,7 +370,6 @@ lke212553-307295-5b53c5520000 "value": "node3" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a rabbitmq without proper tolerations. Here is the yaml of rabbitmq we are going to create - ```yaml apiVersion: kubedb.com/v1alpha2 @@ -385,20 +391,21 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-without-tolerations.yaml -rabbitmq.kubedb.com/rabbitmq-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-without-tolerations.yaml ``` +rabbitmq.kubedb.com/rabbitmq-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 `rabbitmq-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE rabbitmq-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 rabbitmq-without-tolerations-0 +kubectl describe pods -n demo rabbitmq-without-tolerations-0 +``` Name: rabbitmq-without-tolerations-0 Namespace: demo Priority: 0 @@ -456,7 +463,6 @@ Events: 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 rabbitmq. Here is the yaml we are going to apply, @@ -487,24 +493,24 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-with-tolerations.yaml -rabbitmq.kubedb.com/rabbitmq-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/configuration/rabbitmq-with-tolerations.yaml ``` +rabbitmq.kubedb.com/rabbitmq-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 `rabbitmq-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE rabbitmq-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 rabbitmq-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo rabbitmq-with-tolerations-0 -o wide +kubectl get pods -n demo rabbitmq-with-tolerations-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES rabbitmq-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 diff --git a/docs/guides/rabbitmq/monitoring/using-builtin-prometheus.md b/docs/guides/rabbitmq/monitoring/using-builtin-prometheus.md index eb49abb54e..4f076ab854 100644 --- a/docs/guides/rabbitmq/monitoring/using-builtin-prometheus.md +++ b/docs/guides/rabbitmq/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor RabbitMQ database using builtin [Prom - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/RabbitMQ](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,32 +71,33 @@ Here, Let's create the RabbitMQ crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/monitoring/builtin-prom-rm.yaml -rabbitmq.kubedb.com/builtin-prom-rm created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/monitoring/builtin-prom-rm.yaml ``` +rabbitmq.kubedb.com/builtin-prom-rm created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get rm -n demo builtin-rabbitmq +kubectl get rm -n demo builtin-rabbitmq +``` NAME VERSION STATUS AGE builtin-rabbitmq 4.2.4 Ready 2m34s -``` KubeDB will create a separate stats service with name `{RabbitMQ crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-rabbitmq" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-rabbitmq" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-rabbitmq ClusterIP 10.99.28.40 27017/TCP 55s builtin-rabbitmq ClusterIP None 27017/TCP 55s builtin-rabbitmq ClusterIP 10.98.202.26 56790/TCP 36s -``` Here, `builtin-prom-rm-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-rabbitmq-stats +kubectl describe svc -n demo builtin-rabbitmq-stats +``` Name: builtin-rabbitmq-stats Namespace: demo Labels: app.kubernetes.io/name=rabbitms.kubedb.com @@ -111,7 +114,6 @@ TargetPort: prom-http/TCP Endpoints: 172.17.0.7:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -275,20 +277,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -299,9 +301,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -310,18 +312,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-7bd56c6865-8dlpv 1/1 Running 0 28s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +kubectl port-forward -n monitoring prometheus-7bd56c6865-8dlpv 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-mgo-stats` service as one of the targets. diff --git a/docs/guides/rabbitmq/monitoring/using-prometheus-operator.md b/docs/guides/rabbitmq/monitoring/using-prometheus-operator.md index 5406dc7cc2..d416ed6f7f 100644 --- a/docs/guides/rabbitmq/monitoring/using-prometheus-operator.md +++ b/docs/guides/rabbitmq/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE monitoring prometheus-kube-prometheus-prometheus v2.39.0 1 13d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -165,27 +167,27 @@ Here, Let's create the RabbitMQ object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/monitoring/prom-rm.yaml -rabbitmq.kubedb.com/prom-rm created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/monitoring/prom-rm.yaml ``` +rabbitmq.kubedb.com/prom-rm created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get rm -n demo prom-rm +kubectl get rm -n demo prom-rm +``` NAME VERSION STATUS AGE prom-rm 4.2.4 Ready 34s -``` KubeDB will create a separate stats service with name `{RabbitMQ crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=prom-rm" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=prom-rm" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prom-rm ClusterIP 10.96.150.171 27017/TCP 84s prom-rm-pods ClusterIP None 27017/TCP 84s prom-rm-stats ClusterIP 10.96.218.41 56790/TCP 64s -``` Here, `prom-rm-stats` service has been created for monitoring purpose. @@ -220,10 +222,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this informatio KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `prom-rm-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE prom-rm-stats 2m40s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of RabbitMQ crd. @@ -280,20 +282,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 13d -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `prom-rm-stats` service as one of the targets. diff --git a/docs/guides/rabbitmq/quickstart/quickstart.md b/docs/guides/rabbitmq/quickstart/quickstart.md index 3f3c570100..44cd97d24f 100644 --- a/docs/guides/rabbitmq/quickstart/quickstart.md +++ b/docs/guides/rabbitmq/quickstart/quickstart.md @@ -31,27 +31,27 @@ This tutorial will show you how to use KubeDB to run a RabbitMQ database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available RabbitMQVersion When you have installed KubeDB, it has created `RabbitMQVersion` CR for all supported RabbitMQ versions. Check it by using the `kubectl get rabbitmqversions` command. You can also use `rmv` shorthand instead of `rabbitmqversions`. ```bash -$ kubectl get rabbitmqversion +kubectl get rabbitmqversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 3.12.12 3.12.12 ghcr.io/appscode-images/rabbitmq:3.12.12-management-alpine 7d1h -``` ## Create a RabbitMQ database @@ -93,9 +93,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/quickstart/quickstart.yaml -rabbitmq.kubedb.com/rm-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/quickstart/quickstart.yaml ``` +rabbitmq.kubedb.com/rm-quickstart created Here, - `.spec.replica` is used to provide the number of required replicas or, peers for intended rabbitmq cluster. @@ -110,37 +110,45 @@ Here, KubeDB operator watches for `RabbitMQ` objects using Kubernetes API. When a `RabbitMQ` object is created, KubeDB provisioner operator will create new PetSet (aka StatefulSet 2.0), Services with the matching RabbitMQ object name and Required secrets for cluster communication and authentication if not present. The services will include a primary service for Client communication with AMQP,MQTT,STOMP or WebSocket, a governing service for inter-node cluster governance, a dashboard service for connecting to management UI and interact with http endpointsm and a stats service to provide metrics endpoint if enabled. KubeDB operator will also create an AppBinding resource. `AppBinding` is a Kubernetes `CustomResourceDefinition`(CRD) which points to an application using either its URL (usually for a non-Kubernetes resident service instance) or a Kubernetes service object (if self-hosted in a Kubernetes cluster), some optional parameters and a credential secret. ```bash -$ kubectl get petset -n demo +kubectl get petset -n demo +``` NAME AGE rm-quickstart 6m14s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE rm-quickstart-data-rm-quickstart-0 Bound pvc-596bd8de-4123-40fd-a8d1-a864b9acddc2 1Gi RWO standard 6m38s rm-quickstart-data-rm-quickstart-1 Bound pvc-c94bd3d0-8fa7-4794-9221-8295bc3e7b38 1Gi RWO standard 6m32s rm-quickstart-data-rm-quickstart-2 Bound pvc-ddfd1987-c8b2-4c72-90ad-a8361ed4de56 1Gi RWO standard 6m26s -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-596bd8de-4123-40fd-a8d1-a864b9acddc2 1Gi RWO Delete Bound demo/rm-quickstart-data-rm-quickstart-0 standard 7m4s pvc-c94bd3d0-8fa7-4794-9221-8295bc3e7b38 1Gi RWO Delete Bound demo/rm-quickstart-data-rm-quickstart-1 standard 6m58s pvc-ddfd1987-c8b2-4c72-90ad-a8361ed4de56 1Gi RWO Delete Bound demo/rm-quickstart-data-rm-quickstart-2 standard 6m52s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rm-quickstart LoadBalancer 10.128.221.60 172.232.241.73 5672:31803/TCP,1883:31938/TCP,61613:31884/TCP,15675:32567/TCP,15674:32599/TCP 8m59s rm-quickstart-dashboard ClusterIP 10.128.240.53 15672/TCP 8m58s rm-quickstart-pods ClusterIP None 4369/TCP,25672/TCP 8m59s -$ kubectl get appbinding -n demo +```bash +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE rm-quickstart kubedb.com/rabbitmq 4.2.4 23h -``` KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified `RabbitMQ` object: ```bash -$ kubectl get rm -n demo rm-quickstart -oyaml +kubectl get rm -n demo rm-quickstart -oyaml ``` ```yaml apiVersion: kubedb.com/v1alpha2 @@ -275,11 +283,14 @@ If you want to use an existing secret please specify that when creating the Rabb Now, we need `username` and `password` to connect to this database. ```bash -$ kubectl get secrets -n demo rm-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo rm-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secrets -n demo rm-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -password + +```bash +kubectl get secrets -n demo rm-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +password We can check client connectivity using an opensource load-testing tool called `perf-test`. It runs producers and consumers to continuously publish and consume messages in RabbitMQ cluster. Here's how to run it on kubernetes using the credentials and the address for operator generated primary service. ```bash @@ -289,7 +300,8 @@ kubectl run perf-test --image=pivotalrabbitmq/perf-test -- --uri "amqp://admin:p You can check the log for this pod which shows publish and consume rates of messages in RabbitMQ. ```bash -$ kubectl logs pod/perf-test -f +kubectl logs pod/perf-test -f +``` id: test-104606-706, starting consumer #0 id: test-104606-706, starting consumer #0, channel #0 id: test-104606-706, starting producer #0 @@ -304,15 +316,14 @@ id: test-104606-706, time 7.000 s, sent: 38117 msg/s, received: 30759 msg/s, min id: test-104606-706, time 8.000 s, sent: 35088 msg/s, received: 31676 msg/s, min/median/75th/95th/99th consumer latency: 1578860/1799719/1915632/1985467/2024141 µs id: test-104606-706, time 9.000 s, sent: 29706 msg/s, received: 31375 msg/s, min/median/75th/95th/99th consumer latency: 1516415/1743385/1877037/1972570/1988962 µs id: test-104606-706, time 10.000 s, sent: 15903 msg/s, received: 26711 msg/s, min/median/75th/95th/99th consumer latency: 1569546/1884700/1992762/2096417/2136613 µs -``` You can also connect with the RabbitMQ Management UI. It can be accessed through Dashboard service's 15672 Port or from a localhost port if the port is forwarded. ```bash -$ kubectl port-forward -n demo svc/rm-quickstart-dashboard 15672 +kubectl port-forward -n demo svc/rm-quickstart-dashboard 15672 +``` Forwarding from 127.0.0.1:15672 -> 15672 Forwarding from [::1]:15672 -> 15672 -``` Lets, open your browser and go to the **http://localhost:15672** then access using the credentials. @@ -329,9 +340,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete rm rm-quickstart -n demo -The RabbitMQ "rm-quickstart" is invalid: spec.deletionPolicy: Invalid value: "rm-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" +kubectl delete rm rm-quickstart -n demo ``` +The RabbitMQ "rm-quickstart" is invalid: spec.deletionPolicy: Invalid value: "rm-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl patch -n demo rm rm-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"` to set `spec.deletionPolicy` to `Halt` (which deletes the RabbitMQ object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -346,14 +357,15 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele At first, run `kubectl patch -n demo rm rm-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"`. Then delete the RabbitMQ object, ```bash -$ kubectl delete rm rm-quickstart -n demo -rabbitmq.kubedb.com "rm-quickstart" deleted +kubectl delete rm rm-quickstart -n demo ``` +rabbitmq.kubedb.com "rm-quickstart" deleted Now, run the following command to get all rabbitmq resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/rm-quickstart-auth kubernetes.io/basic-auth 2 3m35s @@ -362,8 +374,6 @@ rm-quickstart-data-rm-quickstart-0 Bound pvc-596bd8de-4123-40fd-a8d1-a864b9 rm-quickstart-data-rm-quickstart-1 Bound pvc-c94bd3d0-8fa7-4794-9221-8295bc3e7b38 1Gi RWO standard 6m32s rm-quickstart-data-rm-quickstart-2 Bound pvc-ddfd1987-c8b2-4c72-90ad-a8361ed4de56 1Gi RWO standard 6m26s -``` - From the above output, you can see that all RabbitMQ resources(`PetSet`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your RabbitMQ again using these resources. >You can also set the `deletionPolicy` to `Halt`(deprecated). It's behavior same as `halt` and right now `Halt` is replaced by `Halt`. @@ -377,17 +387,17 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete rm rm-quickstart -n demo -rabbitmq.kubedb.com "rm-quickstart" deleted +kubectl delete rm rm-quickstart -n demo ``` +rabbitmq.kubedb.com "rm-quickstart" deleted Now, run the following command to get all RabbitMQ resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/rm-quickstart-auth kubernetes.io/basic-auth 2 17m -``` From the above output, you can see that all RabbitMQ resources(`PetSet`, `Service`, `PVCs` etc.) are deleted except `Secret`. @@ -407,9 +417,9 @@ rabbitmq.kubedb.com "rm-quickstart" deleted Now, run the following command to get all RabbitMQ resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo -No resources found in demo namespace. +kubectl get petset,svc,secret,pvc -n demo ``` +No resources found in demo namespace. From the above output, you can see that all RabbitMQ resources are deleted. There is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. diff --git a/docs/guides/rabbitmq/reconfigure-tls/reconfigure-tls.md b/docs/guides/rabbitmq/reconfigure-tls/reconfigure-tls.md index ce6cb5c9ff..87dc4bc2ee 100644 --- a/docs/guides/rabbitmq/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/rabbitmq/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/rabbitmq](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,19 +62,17 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/rm.yaml -rabbitmq.kubedb.com/rm created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/rm.yaml ``` +rabbitmq.kubedb.com/rm created Now, wait until `rm` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME VERSION STATUS AGE rm 4.2.4 Ready 10m - - -```bash $ kubectl get secrets -n demo rm-auth -o jsonpath='{.data.username}' | base64 -d root @@ -90,23 +88,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 rabbitmq-ca \ +kubectl create secret tls rabbitmq-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/rabbitmq-ca created ``` +secret/rabbitmq-ca created Now, Let's create an `Issuer` using the `mongo-ca` secret that we have just created. The `YAML` file looks like this: @@ -124,9 +122,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/issuer.yaml -issuer.cert-manager.io/rm-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/issuer.yaml ``` +issuer.cert-manager.io/rm-issuer created ### Create RabbitMQOpsRequest @@ -168,25 +166,26 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/rmops-add-tls.yaml -rabbitmqopsrequest.ops.kubedb.com/rmops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/rmops-add-tls.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rmops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CRO, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-add-tls ReconfigureTLS Successful 91s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-add-tls +kubectl describe rabbitmqopsrequest -n demo rmops-add-tls +``` Name: rmops-add-tls Namespace: demo Labels: @@ -289,17 +288,16 @@ Events: Normal ResumeDatabase 10s KubeDB Ops-manager operator Resuming RabbitMQ demo/rm Normal ResumeDatabase 10s KubeDB Ops-manager operator Successfully resumed RabbitMQ demo/rm Normal Successful 10s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` ## Rotate Certificate Now we are going to rotate the certificate of this database. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it rm-2 -n demo bash +kubectl exec -it rm-2 -n demo bash +``` root@rm-2:/# openssl x509 -in /var/private/ssl/client.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 13:32:20 2021 GMT -``` So, the certificate will expire on this time `Jun 9 13:32:20 2021 GMT`. @@ -330,25 +328,26 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/reconfigure-tls/rmops-rotate.yaml -RabbitMQopsrequest.ops.kubedb.com/rmops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/reconfigure-tls/rmops-rotate.yaml ``` +RabbitMQopsrequest.ops.kubedb.com/rmops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CRO, ```bash -$ kubectl get RabbitMQopsrequest -n demo +kubectl get RabbitMQopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-rotate ReconfigureTLS Successful 112s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-rotate +kubectl describe rabbitmqopsrequest -n demo rmops-rotate +``` Name: rmops-rotate Namespace: demo Labels: @@ -438,15 +437,14 @@ Events: Normal CertificateIssuingSuccessful 2m10s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 25s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 25s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it rm-2 -n demo bash +kubectl exec -it rm-2 -n demo bash +``` root@rm-2:/# openssl x509 -in /var/run/rabbitmq/tls/client.pem -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jun 9 16:17:55 2021 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -457,23 +455,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 rm-new-ca \ +kubectl create secret tls rm-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/rm-new-ca created ``` +secret/rm-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -491,9 +489,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/rm-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/rm-new-issuer created ### Create RabbitMQOpsRequest @@ -525,25 +523,26 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/rm-change-issuer.yaml -rabbitmqopsrequest.ops.kubedb.com/rm-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/rm-change-issuer.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rm-change-issuer created #### Verify Issuer is changed successfully Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CRO, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rm-change-issuer ReconfigureTLS Successful 105s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rm-change-issuer +kubectl describe rabbitmqopsrequest -n demo rm-change-issuer +``` Name: rm-change-issuer Namespace: demo Labels: @@ -634,15 +633,14 @@ Events: Normal CertificateIssuingSuccessful 2m27s KubeDB Ops-manager operator Successfully Issued New Certificates Normal RestartReplicaSet 42s KubeDB Ops-manager operator Successfully Restarted ReplicaSet nodes Normal Successful 42s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it rm-2 -n demo bash +kubectl exec -it rm-2 -n demo bash +``` root@mgo-rs-tls-2:/$ openssl x509 -in /var/run/rabbitmq/tls/ca.crt -inform PEM -subject -nameopt RFC2253 -noout subject=O=kubedb-updated,CN=ca-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. @@ -677,25 +675,26 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/mops-remove.yaml -rabbitmqopsrequest.ops.kubedb.com/mops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/reconfigure-tls/mops-remove.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/mops-remove created #### Verify TLS Removed Successfully Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CRO, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE mops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe rabbitmqopsrequest -n demo mops-remove +kubectl describe rabbitmqopsrequest -n demo mops-remove +``` Name: mops-remove Namespace: demo Labels: @@ -783,7 +782,6 @@ Events: Normal ResumeDatabase 35s KubeDB Ops-manager operator Resuming RabbitMQ demo/rm Normal ResumeDatabase 35s KubeDB Ops-manager operator Successfully resumed RabbitMQ demo/rm Normal Successful 35s KubeDB Ops-manager operator Successfully Reconfigured TLS -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/rabbitmq/reconfigure/reconfigure.md b/docs/guides/rabbitmq/reconfigure/reconfigure.md index 694031946f..cacf6b8a0f 100644 --- a/docs/guides/rabbitmq/reconfigure/reconfigure.md +++ b/docs/guides/rabbitmq/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [examples](/docs/examples/rabbitmq) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -55,9 +55,9 @@ Here, `default_vhost` is set to `/customvhost` instead of the default vhost `/`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rabbit-custom-config --from-file=./rabbitmq.conf -secret/rabbit-custom-config created +kubectl create secret generic -n demo rabbit-custom-config --from-file=./rabbitmq.conf ``` +secret/rabbit-custom-config created In this section, we are going to create a RabbitMQ object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `RabbitMQ` CR that we are going to create, @@ -84,39 +84,41 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/cluster/rabbit-custom-config.yaml -rabbitmq.kubedb.com/rm-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/cluster/rabbit-custom-config.yaml ``` +rabbitmq.kubedb.com/rm-cluster created Now, wait until `rm-cluster` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME TYPE VERSION STATUS AGE rm-cluster kubedb.com/v1alpha2 4.2.4 Ready 79m -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a RabbitMQ instance, ```bash -$ kubectl get secrets -n demo rm-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo rm-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` admin -$ kubectl get secrets -n demo rm-cluster-auth -o jsonpath='{.data.password}' | base64 -d -m6lXjZugrC4VEpB8 +```bash +kubectl get secrets -n demo rm-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +m6lXjZugrC4VEpB8 Now let's check the configuration we have provided by using rabbitmq's inbuilt cli. ```bash -$ kubectl exec -it -n demo rm-cluster-0 -- bash +kubectl exec -it -n demo rm-cluster-0 -- bash +``` Defaulted container "rabbitmq" out of: rabbitmq, rabbitmq-init (init) rm-cluster-0:/$ rabbitmqctl list_vhosts Listing vhosts ... name /customvhost -``` Provided custom vhost is there and is defaulted. @@ -127,15 +129,15 @@ Now we will update this default vhost to `/newvhost` using Reconfigure Ops-Reque Now, Let's edit the `rabbitmq.conf` file containing required configuration settings. ```bash -$ echo "default_vhost = /newvhost" > rabbitmq.conf +echo "default_vhost = /newvhost" > rabbitmq.conf ``` Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./rabbitmq.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./rabbitmq.conf ``` +secret/new-custom-config created #### Create RabbitMQOpsRequest @@ -168,9 +170,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/opsrequests/rabbit-reconfigure-with-secret.yaml -rabbitmqopsrequest.ops.kubedb.com/reconfigure-rm-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/opsrequests/rabbit-reconfigure-with-secret.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/reconfigure-rm-cluster created #### Verify the new configuration is working @@ -179,16 +181,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ watch kubectl get rabbitmqopsrequest -n demo +watch kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE reconfigure-rm-cluster Reconfigure Successful 3m -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe rabbitmqopsrequest -n demo reconfigure-rm-cluster +kubectl describe rabbitmqopsrequest -n demo reconfigure-rm-cluster +``` Name: reconfigure-rm-cluster Namespace: demo Labels: @@ -265,19 +268,18 @@ Events: Normal RestartNodes 5m40s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5m40s KubeDB Ops-manager Operator Resuming RabbitMQ database: demo/rm-cluster Normal Successful 5m39s KubeDB Ops-manager Operator Successfully resumed RabbitMQ database: demo/rm-cluster for RabbitMQOpsRequest: reconfigure-rm-cluster -``` Now let's check the configuration we have provided after reconfiguration. ```bash -$ kubectl exec -it -n demo rm-cluster-0 -- bash +kubectl exec -it -n demo rm-cluster-0 -- bash +``` Defaulted container "rabbitmq" out of: rabbitmq, rabbitmq-init (init) rm-cluster-0:/$ rabbitmqctl list_vhosts Listing vhosts ... name /newvhost /customvhost -``` As we can see from the configuration of running RabbitMQ, `/newvhost` is in the list of vhosts. ### Reconfigure using apply config @@ -315,9 +317,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/opsrequests/rabbitmq-reconfigure-apply.yaml -rabbitmqopsrequest.ops.kubedb.com/reconfigure-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/opsrequests/rabbitmq-reconfigure-apply.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/reconfigure-apply created ## Cleaning Up diff --git a/docs/guides/rabbitmq/restart/restart.md b/docs/guides/rabbitmq/restart/restart.md index 6a21178b11..2ede14238b 100644 --- a/docs/guides/rabbitmq/restart/restart.md +++ b/docs/guides/rabbitmq/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the RabbitMQ database via a RabbitMQOpsRequest. Resta - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/rabbitmq](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -58,9 +58,9 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/restart/rm.yaml -rabbitmq.kubedb.com/rm created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/restart/rm.yaml ``` +rabbitmq.kubedb.com/rm created ## Apply Restart opsRequest @@ -87,18 +87,21 @@ spec: Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/restart/ops.yaml -rabbitmqopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/restart/ops.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will restrart the pods sequetially by their cardinal suffix. -```shell -$ kubectl get rabbitmqopsrequest -n demo +```bash +kubectl get rabbitmqopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 10m -$ kubectl get rabbitmqopsrequest -n demo -oyaml restart +```bash +kubectl get rabbitmqopsrequest -n demo -oyaml restart +``` apiVersion: ops.kubedb.com/v1alpha1 kind: RabbitMQOpsRequest metadata: @@ -139,7 +142,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/rabbitmq/rotate-auth/guide.md b/docs/guides/rabbitmq/rotate-auth/guide.md index b2e8db06dd..8757718466 100644 --- a/docs/guides/rabbitmq/rotate-auth/guide.md +++ b/docs/guides/rabbitmq/rotate-auth/guide.md @@ -36,31 +36,31 @@ RabbitMQ CRDs. KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available RabbitMQVersion When you have installed KubeDB, it has created `RabbitMQVersion` CR for all supported RabbitMQ versions. Check it by using the `kubectl get rabbitmqversions` command. You can also use `rmv` shorthand instead of `rabbitmqversions`. ```bash -$ kubectl get rabbitmqversion +kubectl get rabbitmqversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 3.12.12 3.12.12 ghcr.io/appscode-images/rabbitmq:3.12.12-management-alpine 3h13m 3.13.2 3.13.2 ghcr.io/appscode-images/rabbitmq:3.13.2-management-alpine 3h13m 4.0.4 4.0.4 ghcr.io/appscode-images/rabbitmq:4.0.4-management-alpine 3h13m 4.2.4 4.2.4 ghcr.io/appscode-images/rabbitmq:4.2.4-management-alpine 3h13m -``` ## Create a RabbitMQ server @@ -87,9 +87,9 @@ spec: ``` ```bash -$ kubectl apply -f rabbit.yaml -RabbitMQ.kubedb.com/rabbitmq created +kubectl apply -f rabbit.yaml ``` +RabbitMQ.kubedb.com/rabbitmq created ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database. Below is an example showing how to retrieve the credentials from the secret. @@ -104,7 +104,8 @@ $ kubectl get secret -n demo rabbitmq-auth -o jsonpath='{.data.password}' | base ```` Now, you can exec into the pod `rabbitmq-0` and connect to database using `username` and `password` ```bash -$ kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +``` rabbitmq-0:/$ rabbitmqadmin -u admin -p '4TC.R7hXc1g;kA)P' list queues +---------------+----------+ | name | messages | @@ -113,7 +114,6 @@ rabbitmq-0:/$ rabbitmqadmin -u admin -p '4TC.R7hXc1g;kA)P' list queues +---------------+----------+ rabbitmq-0:/$ exit exit -``` If you can access the data table and run queries, it means the secrets are working correctly. ## Create RotateAuth RabbitMQOpsRequest @@ -140,19 +140,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on RabbitMQ. Let's create the `RabbitMQOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/rabbitmq/rotate-auth/rotate-auth-generated.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/rabbitmq/rotate-auth/rotate-auth-generated.yaml + ``` RabbitMQopsrequest.ops.kubedb.com/rm-rotate-auth-generated created -``` Let's wait for `RabbitMQOpsrequest` to be `Successful`. Run the following command to watch `RabbitMQOpsrequest` CR -```shell - $ kubectl get RabbitMQopsrequest -n demo + ```bash + kubectl get RabbitMQopsrequest -n demo + ``` NAME TYPE STATUS AGE rm-rotate-auth-generated RotateAuth Successful 3m14s -``` If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe RabbitMQopsrequest -n demo rm-rotate-auth-generated +```bash +kubectl describe RabbitMQopsrequest -n demo rm-rotate-auth-generated +``` Name: rm-rotate-auth-generated Namespace: demo Labels: @@ -287,22 +288,26 @@ Events: Warning running pod; ConditionStatus:False 2m55s KubeDB Ops-manager Operator running pod; ConditionStatus:False Warning running pod; ConditionStatus:True; PodName:rabbitmq-2 2m50s KubeDB Ops-manager Operator running pod; ConditionStatus:True; PodName:rabbitmq-2 Normal RestartNodes 2m45s KubeDB Ops-manager Operator Successfully restarted all nodes - -``` **Verify Auth is rotated** -```shell -$ kubectl get rm -n demo rabbitmq -ojson | jq .spec.authSecret.name +```bash +kubectl get rm -n demo rabbitmq -ojson | jq .spec.authSecret.name +``` "rabbitmq-auth" -$ kubectl get secret -n demo rabbitmq-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo rabbitmq-auth -o jsonpath='{.data.username}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo rabbitmq-auth -o jsonpath='{.data.password}' | base64 -d -tB7;0ATxvhxeau15⏎ + +```bash +kubectl get secret -n demo rabbitmq-auth -o jsonpath='{.data.password}' | base64 -d ``` +tB7;0ATxvhxeau15⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash - +```bash +kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +``` rabbitmq-0:/$ rabbitmqadmin -u admin -p 'tB7;0ATxvhxeau15' list queues +---------------+----------+ | name | messages | @@ -311,37 +316,36 @@ rabbitmq-0:/$ rabbitmqadmin -u admin -p 'tB7;0ATxvhxeau15' list queues +---------------+----------+ rabbitmq-0:/$ -``` - Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo rabbitmq-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo rabbitmq-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo rabbitmq-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -4TC.R7hXc1g;kA)P⏎ + +```bash +kubectl get secret -n demo rabbitmq-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +4TC.R7hXc1g;kA)P⏎ Now verify whether the previous credential is workable or not -```shell -$ kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash - +```bash +kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +``` rabbitmq-0:/$ rabbitmqadmin -u admin -p '4TC.R7hXc1g;kA)P' list queues *** Access refused: /api/queues?columns=name,messages -``` The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, -```shell -$ kubectl create secret generic rm-auth-user -n demo \ +```bash +kubectl create secret generic rm-auth-user -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=rabbit \ --from-literal=password=RabbitMQ2 -secret/rm-auth-user created - ``` +secret/rm-auth-user created Now create a `RabbitMQOpsRequest` with `RotateAuth` type. Below is the YAML of the `RabbitMQOpsRequest` that we are going to create, ```shell @@ -370,21 +374,22 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/rabbitmq/rotate-auth/rotate-auth-user.yaml -RabbitMQopsrequest.ops.kubedb.com/rmops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{ .version }}/docs/examples/rabbitmq/rotate-auth/rotate-auth-user.yaml ``` +RabbitMQopsrequest.ops.kubedb.com/rmops-rotate-auth-user created Let’s wait for `RabbitMQOpsRequest` to be Successful. Run the following command to watch `RabbitMQOpsRequest` CR: -```shell -$ kubectl get RabbitMQopsrequest -n demo +```bash +kubectl get RabbitMQopsrequest -n demo +``` NAME TYPE STATUS AGE rm-rotate-auth-generated RotateAuth Successful 28m rmops-rotate-auth-user RotateAuth Successful 80s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe RabbitMQopsrequest -n demo rmops-rotate-auth-user +```bash +kubectl describe RabbitMQopsrequest -n demo rmops-rotate-auth-user +``` Name: rmops-rotate-auth-user Namespace: demo Labels: @@ -522,45 +527,48 @@ Events: Warning running pod; ConditionStatus:False 52s KubeDB Ops-manager Operator running pod; ConditionStatus:False Warning running pod; ConditionStatus:True; PodName:rabbitmq-2 47s KubeDB Ops-manager Operator running pod; ConditionStatus:True; PodName:rabbitmq-2 Normal RestartNodes 42s KubeDB Ops-manager Operator Successfully restarted all nodes - -``` **Verify auth is rotate** -```shell -$ kubectl get rm -n demo rabbitmq -ojson | jq .spec.authSecret.name +```bash +kubectl get rm -n demo rabbitmq -ojson | jq .spec.authSecret.name +``` "rm-auth-user" -$ kubectl get secret -n demo rm-auth-user -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo rm-auth-user -o=jsonpath='{.data.username}' | base64 -d +``` rabbit⏎ -$ kubectl get secret -n demo rm-auth-user -o=jsonpath='{.data.password}' | base64 -d -RabbitMQ2⏎ + +```bash +kubectl get secret -n demo rm-auth-user -o=jsonpath='{.data.password}' | base64 -d ``` +RabbitMQ2⏎ Let's verify if we can connect to the database using the new credentials. -```shell -$ kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash - +```bash + kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +``` rabbitmq-0:/$ rabbitmqadmin -u rabbit -p 'RabbitMQ2' list queues +---------------+----------+ | name | messages | +---------------+----------+ | kubedb_system | 0 | +---------------+----------+ - -``` Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo rm-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d +```bash +kubectl get secret -n demo rm-auth-user -o go-template='{{ index .data "password.prev" }}' | base64 -d +``` tB7;0ATxvhxeau15⏎ -$ kubectl get secret -n demo rm-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d -admin⏎ + +```bash +kubectl get secret -n demo rm-auth-user -o go-template='{{ index .data "username.prev" }}' | base64 -d ``` +admin⏎ Let's confirm that the previous credentials no longer work. -```shell -$ kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash - +```bash +kubectl exec -it -n demo rabbitmq-0 -c rabbitmq -- bash +``` rabbitmq-0:/$ rabbitmqadmin -u admin -p 'tB7;0ATxvhxeau15' list queues *** Access refused: /api/queues?columns=name,messages - -``` The above output shows that the credential has been changed successfully. The previous username & password is stored in the secret for rollback purpose. ## Cleaning up @@ -568,15 +576,20 @@ The above output shows that the credential has been changed successfully. The pr To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete RabbitMQopsrequest rm-rotate-auth-generated rmops-rotate-auth-user -n demo +```bash +kubectl delete RabbitMQopsrequest rm-rotate-auth-generated rmops-rotate-auth-user -n demo +``` RabbitMQopsrequest.ops.kubedb.com "rm-rotate-auth-generated" "rmops-rotate-auth-user" deleted -$ kubectl delete secret -n rm-auth-user + +```bash +kubectl delete secret -n rm-auth-user +``` secret "rm-auth-user" deleted -$ kubectl delete secret -n demo rabbitmq-auth -secret "rabbitmq-auth " deleted +```bash +kubectl delete secret -n demo rabbitmq-auth ``` +secret "rabbitmq-auth " deleted ## Next Steps diff --git a/docs/guides/rabbitmq/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/rabbitmq/scaling/horizontal-scaling/horizontal-scaling.md index 392ec2c5bf..d4a07ee387 100644 --- a/docs/guides/rabbitmq/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/rabbitmq/scaling/horizontal-scaling/horizontal-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the R To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/rabbitmq](/docs/examples/rabbitmq) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,27 +66,29 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/rabbitmq-cluster.yaml -rabbitmq.kubedb.com/rabbitmq created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/rabbitmq-cluster.yaml ``` +rabbitmq.kubedb.com/rabbitmq created Now, wait until `rabbitmq` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME TYPE VERSION STATUS AGE rabbitmq kubedb.com/v1alpha2 4.2.4 Ready 2m -``` Let's check the number of replicas this rabbitmq has from the RabbitMQ object, number of pods the PetSet have, ```bash -$ kubectl get rabbitmq -n demo rabbitmq -o json | jq '.spec.replicas' +kubectl get rabbitmq -n demo rabbitmq -o json | jq '.spec.replicas' +``` 1 -$ kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' -1 +```bash +kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' ``` +1 We can see from both command that the rabbitmq has 3 replicas. @@ -123,9 +125,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/horizontal-scaling/rm-hscale-up-ops.yaml -rabbitmqopsrequest.ops.kubedb.com/rabbitmq-horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/horizontal-scaling/rm-hscale-up-ops.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rabbitmq-horizontal-scale-up created #### Verify replicas scaled up successfully @@ -134,16 +136,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ watch kubectl get rabbitmqopsrequest -n demo +watch kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rabbitmq-horizontal-scale-up HorizontalScaling Successful 2m49s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to scale the rabbitmq. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rabbitmq-horizontal-scale-up +kubectl describe rabbitmqopsrequest -n demo rabbitmq-horizontal-scale-up +``` Name: rabbitmq-horizontal-scale-up Namespace: demo Labels: @@ -225,17 +228,18 @@ Events: Normal UpdatePetSets 7m42s KubeDB Ops-manager Operator successfully reconciled the RabbitMQ with modified node Normal Starting 7m42s KubeDB Ops-manager Operator Resuming RabbitMQ database: demo/rabbitmq Normal Successful 7m42s KubeDB Ops-manager Operator Successfully resumed RabbitMQ database: demo/rabbitmq for RabbitMQOpsRequest: rabbitmq-horizontal-scale-up -``` Now, we are going to verify the number of replicas this rabbitmq has from the Pgpool object, number of pods the PetSet have, ```bash -$ kubectl get rm -n demo rabbitmq -o json | jq '.spec.replicas' +kubectl get rm -n demo rabbitmq -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the rabbitmq is `3`. That means we have successfully scaled up the replicas of the RabbitMQ. @@ -270,9 +274,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/horizontal-scaling/rmops-hscale-down-ops.yaml -rabbitmqopsrequest.ops.kubedb.com/rabbitmq-horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/horizontal-scaling/rmops-hscale-down-ops.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rabbitmq-horizontal-scale-down created #### Verify replicas scaled down successfully @@ -281,16 +285,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ watch kubectl get rabbitmqopsrequest -n demo +watch kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rabbitmq-horizontal-scale-down HorizontalScaling Successful 75s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to scale the rabbitmq. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rabbitmq-horizontal-scale-down +kubectl describe rabbitmqopsrequest -n demo rabbitmq-horizontal-scale-down +``` Name: rabbitmq-horizontal-scale-down Namespace: demo Labels: @@ -377,17 +382,18 @@ Events: Normal UpdateDatabase 48s KubeDB Ops-manager Operator Successfully updated RabbitMQ Normal Starting 48s KubeDB Ops-manager Operator Resuming Pgpool database: demo/rabbitmq Normal Successful 48s KubeDB Ops-manager Operator Successfully resumed RabbitMQ database: demo/rabbitmq for RabbitMQOpsRequest: rabbitmq-horizontal-scale-down -``` Now, we are going to verify the number of replicas this rabbitmq has from the RabbitMQ object, number of pods the petset have, ```bash -$ kubectl get rm -n demo rabbitmq -o json | jq '.spec.replicas' +kubectl get rm -n demo rabbitmq -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' -2 +```bash +kubectl get petset -n demo rabbitmq -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the rabbitmq is `2`. That means we have successfully scaled up the replicas of the RabbitMQ. ## Cleaning Up diff --git a/docs/guides/rabbitmq/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/rabbitmq/scaling/vertical-scaling/vertical-scaling.md index 2db0af08c7..1aa97332f4 100644 --- a/docs/guides/rabbitmq/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/rabbitmq/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/rabbitmq](/docs/examples/rabbitmq) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -69,22 +69,23 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/mg-standalone.yaml -rabbitmq.kubedb.com/rm-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/mg-standalone.yaml ``` +rabbitmq.kubedb.com/rm-standalone created Now, wait until `mg-standalone` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME VERSION STATUS AGE rm-standalone 4.2.4 Ready 5m56s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -95,7 +96,6 @@ $ kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resou "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -142,9 +142,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/vertical-scaling/rmops-vscale-standalone.yaml -rabbitmqopsrequest.ops.kubedb.com/rmops-vscale-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/scaling/vertical-scaling/rmops-vscale-standalone.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rmops-vscale-standalone created #### Verify RabbitMQ Standalone resources updated successfully @@ -153,16 +153,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-vscale-standalone VerticalScaling Successful 108s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-vscale-standalone +kubectl describe rabbitmqopsrequest -n demo rmops-vscale-standalone +``` Name: rmops-vscale-standalone Namespace: demo Labels: @@ -273,12 +274,11 @@ Events: Normal ResumeDatabase 3s KubeDB Ops-manager Operator Successfully resumed RabbitMQ demo/mg-standalone Normal Successful 3s KubeDB Ops-manager Operator Successfully Vertically Scaled Database -``` - Now, we are going to verify from the Pod yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -289,7 +289,6 @@ $ kubectl get pod -n demo rm-standalone-0 -o json | jq '.spec.containers[].resou "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the RabbitMQ standalone database. diff --git a/docs/guides/rabbitmq/tls/tls.md b/docs/guides/rabbitmq/tls/tls.md index c750b3cc8f..fb6ba84e06 100644 --- a/docs/guides/rabbitmq/tls/tls.md +++ b/docs/guides/rabbitmq/tls/tls.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption (via, `.spec.enableSSL`) for Rabbit - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/RabbitMQ](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/RabbitMQ) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -82,9 +82,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/tls/issuer.yaml -issuer.cert-manager.io/rabbitmq-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/tls/issuer.yaml ``` +issuer.cert-manager.io/rabbitmq-ca-issuer created ## TLS/SSL encryption in RabbitMQ Standalone @@ -115,18 +115,18 @@ spec: ### Deploy RabbitMQ Standalone ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/tls/rm-standalone-ssl.yaml -rabbitmq.kubedb.com/rabbitmq-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/tls/rm-standalone-ssl.yaml ``` +rabbitmq.kubedb.com/rabbitmq-tls created Now, wait until `rabbitmq-tls created` has status `Ready`. i.e, ```bash -$ watch kubectl get rm -n demo +watch kubectl get rm -n demo +``` Every 2.0s: kubectl get rm -n demo NAME VERSION STATUS AGE rabbitmq-tls 4.2.4 Ready 14s -``` ## Cleaning up diff --git a/docs/guides/rabbitmq/update-version/update-version.md b/docs/guides/rabbitmq/update-version/update-version.md index 686b9dd214..0173d3e04b 100644 --- a/docs/guides/rabbitmq/update-version/update-version.md +++ b/docs/guides/rabbitmq/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/rabbitmq](/docs/examples/rabbitmq) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -66,17 +66,17 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/update-version/rm-cluster.yaml -rabbitmq.kubedb.com/rm-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/update-version/rm-cluster.yaml ``` +rabbitmq.kubedb.com/rm-cluster created Now, wait until `rm-cluster` created has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME VERSION STATUS AGE rm-cluster 4.0.4 Ready 109s -``` We are now ready to apply the `RabbitMQOpsRequest` CR to update this database. @@ -114,9 +114,9 @@ Here, Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/update-version/rmops-cluster-update .yaml -rabbitmqopsrequest.ops.kubedb.com/rmops-cluster-update created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/update-version/rmops-cluster-update .yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rmops-cluster-update created #### Verify RabbitMQ version updated successfully @@ -125,16 +125,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` Every 2.0s: kubectl get rabbitmqopsrequest -n demo NAME TYPE STATUS AGE rmops-cluster-update UpdateVersion Successful 84s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-cluster-update +kubectl describe rabbitmqopsrequest -n demo rmops-cluster-update +``` Name: rmops-cluster-update Namespace: demo Labels: @@ -232,20 +233,23 @@ Events: Normal ResumeDatabase 38s KubeDB Ops-manager Operator Resuming RabbitMQ demo/rm-cluster Normal ResumeDatabase 38s KubeDB Ops-manager Operator Successfully resumed RabbitMQ demo/rm-cluster Normal Successful 38s KubeDB Ops-manager Operator Successfully Updated Database -``` Now, we are going to verify whether the `RabbitMQ` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get rm -n demo rm-cluster -o=jsonpath='{.spec.version}{"\n"}' +kubectl get rm -n demo rm-cluster -o=jsonpath='{.spec.version}{"\n"}' +``` 4.2.4 -$ kubectl get petset -n demo rm-cluster -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo rm-cluster -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/rabbitmq:4.2.4-management-alpine -$ kubectl get pods -n demo rm-cluster-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/rabbitmq:4.2.4-management-alpine +```bash +kubectl get pods -n demo rm-cluster-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/rabbitmq:4.2.4-management-alpine You can see from above, our `RabbitMQ` cluster has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/rabbitmq/volume-expansion/volume-expansion.md b/docs/guides/rabbitmq/volume-expansion/volume-expansion.md index c02a0ddd75..48c04034a3 100644 --- a/docs/guides/rabbitmq/volume-expansion/volume-expansion.md +++ b/docs/guides/rabbitmq/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/RabbitMQ](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/rabbitmq) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,10 +47,10 @@ Here, we are going to deploy a `RabbitMQ` standalone using a supported version b At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` We can see from the output the `standard` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -81,28 +81,30 @@ spec: Let's create the `RabbitMQ` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/volume-expansion/rm-standalone.yaml -RabbitMQ.kubedb.com/rm-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/RabbitMQ/volume-expansion/rm-standalone.yaml ``` +RabbitMQ.kubedb.com/rm-standalone created Now, wait until `rm-standalone` has status `Ready`. i.e, ```bash -$ kubectl get rm -n demo +kubectl get rm -n demo +``` NAME VERSION STATUS AGE rm-standalone 4.2.4 Ready 2m53s -``` Let's check volume size from PetSet, and from the persistent volume, ```bash -$ kubectl get petset -n demo rm-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rm-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 1Gi RWO Delete Bound demo/datadir-rm-standalone-0 standard 49s -``` You can see the PetSet has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -143,9 +145,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `RabbitMQOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/volume-expansion/rmops-volume-exp-standalone.yaml -rabbitmqopsrequest.ops.kubedb.com/rmops-volume-exp-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/rabbitmq/volume-expansion/rmops-volume-exp-standalone.yaml ``` +rabbitmqopsrequest.ops.kubedb.com/rmops-volume-exp-standalone created #### Verify RabbitMQ Standalone volume expanded successfully @@ -154,15 +156,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `RabbitMQOpsRequest` to be `Successful`. Run the following command to watch `RabbitMQOpsRequest` CR, ```bash -$ kubectl get rabbitmqopsrequest -n demo +kubectl get rabbitmqopsrequest -n demo +``` NAME TYPE STATUS AGE rmops-volume-exp-standalone VolumeExpansion Successful 75s -``` We can see from the above output that the `RabbitMQOpsRequest` has succeeded. If we describe the `RabbitMQOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe rabbitmqopsrequest -n demo rmops-volume-exp-standalone +kubectl describe rabbitmqopsrequest -n demo rmops-volume-exp-standalone +``` Name: rmops-volume-exp-standalone Namespace: demo Labels: @@ -217,18 +220,19 @@ $ kubectl describe rabbitmqopsrequest -n demo rmops-volume-exp-standalone Normal ResumeDatabase 29s KubeDB Ops-manager operator Resuming RabbitMQ Normal ResumeDatabase 29s KubeDB Ops-manager operator Successfully Resumed RabbitMQ Normal Successful 29s KubeDB Ops-manager operator Successfully Scaled Database -``` Now, we are going to verify from the `Statefulset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo rm-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rm-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-d0b07657-a012-4384-862a-b4e437774287 2Gi RWO Delete Bound demo/datadir-mg-standalone-0 standard 4m29s -``` The above output verifies that we have successfully expanded the volume of the RabbitMQ standalone database. diff --git a/docs/guides/redis/autoscaler/compute/redis.md b/docs/guides/redis/autoscaler/compute/redis.md index 1f1a086aa9..7cf569622d 100644 --- a/docs/guides/redis/autoscaler/compute/redis.md +++ b/docs/guides/redis/autoscaler/compute/redis.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -79,22 +79,23 @@ spec: Let's create the `Redis` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/rd-standalone.yaml -redis.kubedb.com/rd-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/rd-standalone.yaml ``` +redis.kubedb.com/rd-standalone created Now, wait until `rd-standalone` has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE rd-standalone 6.2.14 Ready 2m53s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -105,11 +106,11 @@ $ kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resou "memory": "300Mi" } } -``` Let's check the Redis resources, ```bash -$ kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redis") | .resources' +kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redis") | .resources' +``` { "limits": { "cpu": "200m", @@ -120,7 +121,6 @@ $ kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.c "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the redis. @@ -179,20 +179,23 @@ Here, Let's create the `RedisAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/rd-as-standalone.yaml -redisautoscaler.autoscaling.kubedb.com/rd-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/rd-as-standalone.yaml ``` +redisautoscaler.autoscaling.kubedb.com/rd-as created #### Verify Autoscaling is set up successfully Let's check that the `redisautoscaler` resource is created successfully, ```bash -$ kubectl get redisautoscaler -n demo +kubectl get redisautoscaler -n demo +``` NAME AGE rd-as 102s -$ kubectl describe redisautoscaler rd-as -n demo +```bash +kubectl describe redisautoscaler rd-as -n demo +``` Name: rd-as Namespace: demo Labels: @@ -288,8 +291,6 @@ Status: Recommendation: Vpa Name: rd-standalone Events: - -``` So, the `redisautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `redisopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -297,27 +298,28 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `redisopsrequest` in the demo namespace to see if any `redisopsrequest` object is created. After some time you'll see that a `redisopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-rd-standalone-q2zozm VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-rd-standalone-q2zozm VerticalScaling Successful 68s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the Pod, and the Redis yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -329,7 +331,9 @@ $ kubectl get pod -n demo rd-standalone-0 -o json | jq '.spec.containers[].resou } } -$ kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redis") | .resources' +```bash +kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redis") | .resources' +``` { "limits": { "cpu": "400m", @@ -340,7 +344,6 @@ $ kubectl get redis -n demo rd-standalone -o json | jq '.spec.podTemplate.spec.c "memory": "400Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the Redis standalone database. @@ -352,12 +355,16 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/rd-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/rd-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-standalone patched -$ kubectl delete rd -n demo rd-standalone +```bash +kubectl delete rd -n demo rd-standalone +``` redis.kubedb.com "rd-standalone" deleted -$ kubectl delete redisautoscaler -n demo rd-as -redisautoscaler.autoscaling.kubedb.com "rd-as" deleted -``` \ No newline at end of file +```bash +kubectl delete redisautoscaler -n demo rd-as +``` +redisautoscaler.autoscaling.kubedb.com "rd-as" deleted \ No newline at end of file diff --git a/docs/guides/redis/autoscaler/compute/sentinel.md b/docs/guides/redis/autoscaler/compute/sentinel.md index 391aa4f79f..c4ae95be96 100644 --- a/docs/guides/redis/autoscaler/compute/sentinel.md +++ b/docs/guides/redis/autoscaler/compute/sentinel.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -78,22 +78,23 @@ spec: Let's create the `RedisSentinel` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/sentinel.yaml -redissentinel.kubedb.com/sen-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/sentinel.yaml ``` +redissentinel.kubedb.com/sen-demo created Now, wait until `sen-demo` has status `Ready`. i.e, ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-demo 6.2.14 Ready 86s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "200m", @@ -104,11 +105,11 @@ $ kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' "memory": "300Mi" } } -``` Let's check the RedisSentinel resources, ```bash -$ kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redissentinel") | .resources' +kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redissentinel") | .resources' +``` { "limits": { "cpu": "200m", @@ -119,7 +120,6 @@ $ kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spe "memory": "300Mi" } } -``` You can see from the above outputs that the resources are same as the one we have assigned while deploying the redissentinel. @@ -178,20 +178,23 @@ If it was an `InMemory database`, we could also autoscaler the inMemory resource Let's create the `RedisAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/sen-as.yaml -redissentinelautoscaler.autoscaling.kubedb.com/sen-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/compute/sen-as.yaml ``` +redissentinelautoscaler.autoscaling.kubedb.com/sen-as created #### Verify Autoscaling is set up successfully Let's check that the `redisautoscaler` resource is created successfully, ```bash -$ kubectl get redissentinelautoscaler -n demo +kubectl get redissentinelautoscaler -n demo +``` NAME AGE sen-as 102s -$ kubectl describe redissentinelautoscaler sen-as -n demo +```bash +kubectl describe redissentinelautoscaler sen-as -n demo +``` Name: sen-as Namespace: demo Labels: @@ -318,7 +321,6 @@ Status: Memory: 1Gi Vpa Name: sen-demo Events: -``` So, the `redisautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `redissentinelopsrequest` based on the recommendations, if the database pods are needed to scaled up or down. @@ -326,27 +328,28 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `redissentinelopsrequest` in the demo namespace to see if any `redissentinelopsrequest` object is created. After some time you'll see that a `redissentinelopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE rdsops-sen-demo-5emii6 VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE rdsops-sen-demo-5emii6 VerticalScaling Successfull 10s -``` We can see from the above output that the `RedisSentinelOpsRequest` has succeeded. Now, we are going to verify from the Pod, and the Redis yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "400m", @@ -358,7 +361,9 @@ $ kubectl get pod -n demo sen-demo-0 -o json | jq '.spec.containers[].resources' } } -$ kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redissentinel") | .resources' +```bash +kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "redissentinel") | .resources' +``` { "limits": { "cpu": "400m", @@ -369,7 +374,6 @@ $ kubectl get redissentinel -n demo sen-demo -o json | jq '.spec.podTemplate.spe "memory": "400Mi" } } -``` The above output verifies that we have successfully auto-scaled the resources of the Redis standalone database. @@ -381,12 +385,16 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-demo patched -$ kubectl delete redissentinel -n demo sen-demo +```bash +kubectl delete redissentinel -n demo sen-demo +``` redissentinel.kubedb.com "sen-demo" deleted -$ kubectl delete redissentinelautoscaler -n demo sen-as -redissentinelautoscaler.autoscaling.kubedb.com "sen-as" deleted -``` \ No newline at end of file +```bash +kubectl delete redissentinelautoscaler -n demo sen-as +``` +redissentinelautoscaler.autoscaling.kubedb.com "sen-as" deleted \ No newline at end of file diff --git a/docs/guides/redis/autoscaler/storage/redis.md b/docs/guides/redis/autoscaler/storage/redis.md index 8440751d0b..980fd72fbd 100644 --- a/docs/guides/redis/autoscaler/storage/redis.md +++ b/docs/guides/redis/autoscaler/storage/redis.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Redis To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,11 +48,11 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 9h topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 9h -``` We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) @@ -85,28 +85,30 @@ spec: Let's create the `Redis` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/storage/rd-standalone.yaml -redis.kubedb.com/rd-standalone created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/storage/rd-standalone.yaml ``` +redis.kubedb.com/rd-standalone created Now, wait until `rd-standalone` has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE rd-standalone 6.2.14 Ready 2m53s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo rd-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rd-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-cf469ed8-a89a-49ca-bf7c-8c76b7889428 1Gi RWO Delete Bound demo/datadir-rd-standalone-0 topolvm-provisioner 7m41s -``` You can see the petset has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -151,20 +153,23 @@ Here, Let's create the `RedisAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/storage/rd-as.yaml -redisautoscaler.autoscaling.kubedb.com/rd-as created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/autoscaling/storage/rd-as.yaml ``` +redisautoscaler.autoscaling.kubedb.com/rd-as created #### Storage Autoscaling is set up successfully Let's check that the `redisautoscaler` resource is created successfully, ```bash -$ kubectl get redisautoscaler -n demo +kubectl get redisautoscaler -n demo +``` NAME AGE rd-as 102s -$ kubectl describe redisautoscaler rd-as -n demo +```bash +kubectl describe redisautoscaler rd-as -n demo +``` Name: rd-as Namespace: demo Labels: @@ -209,7 +214,6 @@ Spec: Trigger: On Usage Threshold: 60 Events: -``` So, the `redisautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. @@ -217,7 +221,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Lets exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo rd-standalone-0 -- bash +kubectl exec -it -n demo rd-standalone-0 -- bash +``` root@rd-standalone-0:/# df -h /data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/1df4ee9e-b900-4c0f-9d2c-8493fb30bdc0 1014M 334M 681M 33% /data/db @@ -228,39 +233,41 @@ root@rd-standalone-0:/# dd if=/dev/zero of=/data/file.img bs=500M count=1 root@rd-standalone-0:/# df -h /data Filesystem Size Used Avail Use% Mounted on /dev/topolvm/1df4ee9e-b900-4c0f-9d2c-8493fb30bdc0 1014M 835M 180M 83% /data/db -``` So, from the above output we can see that the storage usage is 84%, which exceeded the `usageThreshold` 60%. Let's watch the `redisopsrequest` in the demo namespace to see if any `redisopsrequest` object is created. After some time you'll see that a `redisopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-rd-standalone-p27c11 VolumeExpansion Progressing 26s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-rd-standalone-p27c11 VolumeExpansion Successful 73s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo rd-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo rd-standalone -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1594884096" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-cf469ed8-a89a-49ca-bf7c-8c76b7889428 2Gi RWO Delete Bound demo/datadir-rd-standalone-0 topolvm-provisioner 26m -``` The above output verifies that we have successfully autoscaled the volume of the Redis standalone database. @@ -269,12 +276,16 @@ The above output verifies that we have successfully autoscaled the volume of the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/rd-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/rd-standalone -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-standalone patched -$ kubectl delete rd -n demo rd-standalone +```bash +kubectl delete rd -n demo rd-standalone +``` redis.kubedb.com "rd-standalone" deleted -$ kubectl delete redisautoscaler -n demo rd-as -redisautoscaler.autoscaling.kubedb.com "rd-as" deleted +```bash +kubectl delete redisautoscaler -n demo rd-as ``` +redisautoscaler.autoscaling.kubedb.com "rd-as" deleted diff --git a/docs/guides/redis/backup/kubestash/application-level/index.md b/docs/guides/redis/backup/kubestash/application-level/index.md index 3b4f58ff16..5b44f91042 100644 --- a/docs/guides/redis/backup/kubestash/application-level/index.md +++ b/docs/guides/redis/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/redis/backup/kubestash/application-level/examples](/docs/guides/redis/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -80,33 +80,35 @@ spec: Create the above `Redis` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/application-level/examples/sample-redis.yaml -redis.kubedb.com/sample-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/application-level/examples/sample-redis.yaml ``` +redis.kubedb.com/sample-redis created KubeDB will deploy a `Redis` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get rd -n demo sample-redis +kubectl get rd -n demo sample-redis +``` NAME VERSION STATUS AGE sample-redis 7.4.0 Ready 2m -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-redis-auth kubernetes.io/basic-auth 2 3m5s sample-redis-config Opaque 1 2m14s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-redis +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-redis +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-redis ClusterIP 10.96.131.142 6379/TCP 2m53s sample-redis-pods ClusterIP None 6379/TCP 2m53s -``` Here, we have to use service `sample-redis` and secret `sample-redis-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/redis/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -116,15 +118,15 @@ Here, we have to use service `sample-redis` and secret `sample-redis-auth` to co Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-redis kubedb.com/redis 7.4.0 2m53s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-redis -o yaml +kubectl get appbindings -n demo sample-redis -o yaml ``` ```yaml @@ -191,15 +193,16 @@ Here, Now, we are going to exec into the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-redis" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-redis" +``` NAME READY STATUS RESTARTS AGE sample-redis-0 1/1 Running 0 5m39s -``` Now, let’s exec into the pod and insert some data, ```bash -$ kubectl exec -it -n demo sample-redis-0 -c redis -- bash +kubectl exec -it -n demo sample-redis-0 -c redis -- bash +``` redis@sample-redis-0:/data$ redis-cli 127.0.0.1:6379> set db redis OK @@ -210,7 +213,6 @@ OK 127.0.0.1:6379> exit redis@sample-redis-0:/data$ exit exit -``` Now, we are ready to backup the database. @@ -223,13 +225,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -258,9 +266,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -291,9 +299,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -306,8 +314,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -363,27 +374,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-redis-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-redis-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-redis-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-redis-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/redis` directory. @@ -394,20 +405,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-redis-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-redis-backup-frequent-backup-1725449400 BackupConfiguration sample-redis-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -416,18 +427,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `gcs-redis-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-redis-repo +kubectl get repository -n demo gcs-redis-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-redis-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-redis-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-redis-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-redis-repo-sample-redis-backup-frequent-backup-1725449400 gcs-redis-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -440,7 +451,7 @@ gcs-redis-repo-sample-redis-backup-frequent-backup-1725449400 gcs-redis- If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-redis-repo-sample-redis-backup-frequent-backup-1725449400 -oyaml +kubectl get snapshots -n demo gcs-redis-repo-sample-redis-backup-frequent-backup-1725449400 -oyaml ``` ```yaml @@ -531,9 +542,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -575,18 +586,18 @@ Here, Let's create the RestoreSession CR object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/restore-sample-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/restore-sample-redis created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE restore-sample-redis gcs-redis-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -596,10 +607,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `Redis` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get redis -n dev +kubectl get redis -n dev +``` NAME VERSION STATUS AGE sample-redis 7.4.0 Ready 9m46s -``` The output confirms that the `Redis` database has been successfully created with the same configuration as it had at the time of backup. @@ -611,24 +622,25 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get redis -n dev sample-redis +kubectl get redis -n dev sample-redis +``` NAME VERSION STATUS AGE sample-redis 7.4.0 Ready 9m46s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-redis" +kubectl get pods -n dev --selector="app.kubernetes.io/instance=sample-redis" +``` NAME READY STATUS RESTARTS AGE sample-redis-0 1/1 Running 0 12m -``` Now, lets exec one of the Pod and verify restored data. ```bash -$ kubectl exec -it -n dev sample-redis-0 -c redis -- bash +kubectl exec -it -n dev sample-redis-0 -c redis -- bash +``` redis@sample-redis-0:/data$ redis-cli 127.0.0.1:6379> get db "redis" @@ -639,7 +651,6 @@ redis@sample-redis-0:/data$ redis-cli 127.0.0.1:6379> exit redis@sample-redis-0:/data$ exit exit -``` So, from the above output, we can see the `demo` database we had created in the original database `sample-redis` has been restored successfully. diff --git a/docs/guides/redis/backup/kubestash/auto-backup/index.md b/docs/guides/redis/backup/kubestash/auto-backup/index.md index 6536e030cc..c9b49df672 100644 --- a/docs/guides/redis/backup/kubestash/auto-backup/index.md +++ b/docs/guides/redis/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/redis/backup/kubestash/auto-backup/examples](/docs/guides/redis/backup/kubestash/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -53,13 +53,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -88,9 +94,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -121,9 +127,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -132,8 +138,11 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -196,9 +205,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/redis-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/redis-default-backup-blueprint created Now, we are ready to backup our `Redis` databases using few annotations. @@ -238,24 +247,24 @@ Here, Let's create the `Redis` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/redis-standalone.yaml -redis.kubedb.com/redis-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/redis-standalone.yaml ``` +redis.kubedb.com/redis-standalone created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our Redis in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-redis-standalone Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-redis-standalone -o yaml +kubectl get backupconfiguration -n demo appbinding-redis-standalone -o yaml ``` ```yaml @@ -362,10 +371,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-redis-standalone-frequent-backup-1726661707 BackupConfiguration appbinding-redis-standalone Succeeded 2m26s 9m56s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -374,18 +383,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `redis-standalone-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 1.111 KiB Ready 3m7s 13m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-redlone-frequent-backup-1726661707 default-blueprint frequent-backup 2024-09-18T12:15:38Z Delete Succeeded 14m -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -398,7 +407,7 @@ NAME REPOSITORY If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-redlone-frequent-backup-1726661707 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-redlone-frequent-backup-1726661707 -oyaml ``` ```yaml @@ -541,9 +550,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/redis-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/redis-customize-backup-blueprint created Now, we are ready to backup our `Redis` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -584,24 +593,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `Redis` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/redis-standalone-2.yaml -redis.kubedb.com/redis-standalone-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/auto-backup/examples/redis-standalone-2.yaml ``` +redis.kubedb.com/redis-standalone-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our `Redis` in `demo` namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-redis-standalone-2 Ready 61s -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-redis-standalone-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-redis-standalone-2 -o yaml ``` ```yaml @@ -708,10 +717,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-redis-standalone-2-frequent-backup-1726664655 BackupConfiguration appbinding-redis-standalone-2 Succeeded 2m33s 4m16s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -720,18 +729,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 380 B Ready 5m44s 6m4s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-rne-2-frequent-backup-1726664655 customize-blueprint frequent-backup 2024-09-18T13:04:35Z Delete Succeeded 6m7s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -745,7 +754,7 @@ customize-blueprint-appbinding-rne-2-frequent-backup-1726664655 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-rne-2-frequent-backup-1726664655 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-rne-2-frequent-backup-1726664655 -oyaml ``` ```yaml diff --git a/docs/guides/redis/backup/kubestash/customization/index.md b/docs/guides/redis/backup/kubestash/customization/index.md index 314c75bbc9..e5b4806fbb 100644 --- a/docs/guides/redis/backup/kubestash/customization/index.md +++ b/docs/guides/redis/backup/kubestash/customization/index.md @@ -263,13 +263,13 @@ spec: You can also restore a specific snapshot. At first, list the available snapshot as bellow, ```bash -$ kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-redis-repo +kubectl get snapshots.storage.kubestash.com -n demo -l=kubestash.com/repo-name=gcs-redis-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-redis-repo-sample-redis-backup-frequent-backup-1725257849 gcs-redis-repo frequent-backup 2024-09-02T06:18:01Z Delete Succeeded 15m gcs-redis-repo-sample-redis-backup-frequent-backup-1725258000 gcs-redis-repo frequent-backup 2024-09-02T06:20:00Z Delete Succeeded 13m gcs-redis-repo-sample-redis-backup-frequent-backup-1725258300 gcs-redis-repo frequent-backup 2024-09-02T06:25:00Z Delete Succeeded 8m34s gcs-redis-repo-sample-redis-backup-frequent-backup-1725258600 gcs-redis-repo frequent-backup 2024-09-02T06:30:00Z Delete Succeeded 3m34s -``` The below example shows how you can pass a specific snapshot name in `.spec.dataSource` section. diff --git a/docs/guides/redis/backup/kubestash/logical/index.md b/docs/guides/redis/backup/kubestash/logical/index.md index 03f14aa00f..4965125162 100644 --- a/docs/guides/redis/backup/kubestash/logical/index.md +++ b/docs/guides/redis/backup/kubestash/logical/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/redis/backup/kubestash/logical/examples](/docs/guides/redis/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -87,34 +87,35 @@ spec: Create the above `Redis` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/redis-cluster.yaml -redis.kubedb.com/redis-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/redis-cluster.yaml ``` +redis.kubedb.com/redis-cluster created KubeDB will deploy a `Redis` database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get rd -n demo redis-cluster +kubectl get rd -n demo redis-cluster +``` NAME VERSION STATUS AGE redis-cluster 7.4.0 Ready 5m2s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE redis-cluster-auth kubernetes.io/basic-auth 2 6m16s redis-cluster-config Opaque 1 6m16s - -$ kubectl get service -n demo -l=app.kubernetes.io/instance=redis-cluster +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=redis-cluster +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE redis-cluster ClusterIP 10.96.185.242 6379/TCP 7m25s redis-cluster-pods ClusterIP None 6379/TCP 7m25s -``` Here, we have to use service `redis-cluster` and secret `redis-cluster-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/redis/concepts/appbinding.md) CR that holds the necessary information to connect with the database. @@ -124,15 +125,15 @@ Here, we have to use service `redis-cluster` and secret `redis-cluster-auth` to Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE redis-cluster kubedb.com/redis 7.4.0 7m14s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo redis-cluster -o yaml +kubectl get appbindings -n demo redis-cluster -o yaml ``` ```yaml @@ -200,7 +201,8 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=redis-cluster" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=redis-cluster" +``` NAME READY STATUS RESTARTS AGE redis-cluster-shard0-0 1/1 Running 0 11m redis-cluster-shard0-1 1/1 Running 0 11m @@ -208,7 +210,6 @@ redis-cluster-shard1-0 1/1 Running 0 11m redis-cluster-shard1-1 1/1 Running 0 11m redis-cluster-shard2-0 1/1 Running 0 10m redis-cluster-shard2-1 1/1 Running 0 10m -``` #### Connection Information @@ -219,20 +220,21 @@ redis-cluster-shard2-1 1/1 Running 0 10m - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.username}' | base64 -d - default + kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + default - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.password}' | base64 -d - 8UnSPM;(~cXWWs60 + kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + 8UnSPM;(~cXWWs60 Now, let’s exec into the pod and insert some data, ```bash -$ kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- bash +kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- bash +``` redis@redis-cluster-shard0-0:/data$ redis-cli -c 127.0.0.1:6379> auth default 8UnSPM;(~cXWWs60 OK @@ -247,7 +249,6 @@ OK 10.244.0.52:6379> exit redis@redis-cluster-shard0-0:/data$ exit exit -``` Now, we are ready to backup the database. @@ -260,13 +261,19 @@ We are going to store our backed up data into a `GCS` bucket. We have to create Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -294,9 +301,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -327,9 +334,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -342,11 +349,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created Below is the YAML for `BackupConfiguration` CR to backup the `redis-cluster` database that we have deployed earlier, @@ -395,27 +405,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/redis-cluster-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/redis-cluster-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE redis-cluster-backup Ready 71s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-redis-repo 0 0 B Ready 2m30s -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/redis` directory. @@ -426,20 +436,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-redis-cluster-backup-frequent-backup */5 * * * * False 0 45s 2m38s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE redis-cluster-backup-frequent-backup-1726651666 BackupConfiguration redis-cluster-backup Succeeded 2m25s 2m56s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -448,18 +458,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `gcs-redis-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-redis-repo +kubectl get repository -n demo gcs-redis-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-redis-repo true 1 416 B Ready 4m40s 5m -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-redis-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-redis-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-redis-repo-redis-cluster-backup-frequent-backup-1726651666 gcs-redis-repo frequent-backup 2024-09-18T09:28:07Z Delete Succeeded 5m14s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -472,7 +482,7 @@ gcs-redis-repo-redis-cluster-backup-frequent-backup-1726651666 gcs-redis-repo If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-redis-repo-redis-cluster-backup-frequent-backup-1726651666 -oyaml +kubectl get snapshots -n demo gcs-redis-repo-redis-cluster-backup-frequent-backup-1726651666 -oyaml ``` ```yaml @@ -591,17 +601,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/restored-redis-cluster.yaml -redis.kubedb.com/restore-redis-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/restored-redis-cluster.yaml ``` +redis.kubedb.com/restore-redis-cluster created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get redis -n demo restored-redis-cluster +kubectl get redis -n demo restored-redis-cluster +``` NAME VERSION STATUS AGE restored-redis-cluster 7.4.0 Provisioning 2m35s -``` #### Create RestoreSession: @@ -642,18 +652,18 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/redis-cluster-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/redis-cluster-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restoresession -n demo batman-desktop: Wed Sep 18 15:53:42 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE redis-cluster-restore gcs-redis-repo Succeeded 1m26s 4m49s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -664,15 +674,16 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get redis -n demo restored-redis-cluster +kubectl get redis -n demo restored-redis-cluster +``` NAME VERSION STATUS AGE restored-redis-cluster 7.4.0 Ready 8m42s -``` Now, find out the database `Pods` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-redis-cluster" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-redis-cluster" +``` NAME READY STATUS RESTARTS AGE restored-redis-cluster-shard0-0 1/1 Running 0 5m53s restored-redis-cluster-shard0-1 1/1 Running 0 5m47s @@ -680,12 +691,12 @@ restored-redis-cluster-shard1-0 1/1 Running 0 5m31s restored-redis-cluster-shard1-1 1/1 Running 0 5m24s restored-redis-cluster-shard2-0 1/1 Running 0 5m9s restored-redis-cluster-shard2-1 1/1 Running 0 5m2s -``` Now, lets exec one of the `Pod` and verify restored data. ```bash -$ kubectl exec -it -n demo restored-redis-cluster-shard0-0 -c redis -- bash +kubectl exec -it -n demo restored-redis-cluster-shard0-0 -c redis -- bash +``` redis@restored-redis-cluster-shard0-0:/data$ redis-cli -c 127.0.0.1:6379> auth default lm~;mv7H~eahvZCc OK @@ -700,7 +711,6 @@ OK 10.244.0.70:6379> exit redis@restored-redis-cluster-shard0-0:/data$ exit exit -``` So, from the above output, we can see the `redis-cluster` database we had created earlier has been restored in the `restored-redis-cluster` database successfully. diff --git a/docs/guides/redis/backup/stash/standalone/index.md b/docs/guides/redis/backup/stash/standalone/index.md index 248da90848..0044f302e6 100644 --- a/docs/guides/redis/backup/stash/standalone/index.md +++ b/docs/guides/redis/backup/stash/standalone/index.md @@ -35,9 +35,9 @@ You have to be familiar with following custom resources: To keep things isolated, we are going to use a separate namespace called `demo` throughout this tutorial. Create the `demo` namespace if you haven't created it already. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Backup Redis @@ -72,9 +72,9 @@ spec: Create the above `Redis` crd, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/redis.yaml -redis.kubedb.com/sample-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/redis.yaml ``` +redis.kubedb.com/sample-redis created KubeDB will deploy a Redis database according to the above specification. It will also create the necessary secrets and services to access the database. @@ -166,12 +166,12 @@ In this section, we are going to prepare the necessary resources (i.e. database When you install the Stash, it automatically installs all the official database addons. Verify that it has installed the Redis addons using the following command. ```bash -$ kubectl get tasks.stash.appscode.com | grep redis +kubectl get tasks.stash.appscode.com | grep redis +``` redis-backup-5.0.13 1h redis-backup-6.2.5 1h redis-restore-5.0.13 1h redis-restore-6.2.5 1h -``` ### Ensure AppBinding Stash needs to know how to connect with the database. An `AppBinding` exactly provides this information. It holds the Service and Secret information of the database. You have to point to the respective `AppBinding` as a target of backup instead of the database itself. @@ -239,15 +239,24 @@ We are going to store our backed up data into a GCS bucket. So, we need to creat At first, let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./RESTIC_PASSWORD \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create Repository:** @@ -270,9 +279,9 @@ spec: Let's create the `Repository` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/repository.yaml -repository.stash.appscode.com/gcs-repo created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/repository.yaml ``` +repository.stash.appscode.com/gcs-repo created Now, we are ready to backup our database into our GCS bucket. @@ -315,19 +324,19 @@ Here, Let's create the `BackupConfiguration` object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/backupconfiguration.yaml -backupconfiguration.stash.appscode.com/sample-redis-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/backupconfiguration.yaml ``` +backupconfiguration.stash.appscode.com/sample-redis-backup created #### Verify Backup Setup Successful If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME TASK SCHEDULE PAUSED PHASE AGE sample-redis-backup redis-backup-6.2.5 */5 * * * * Ready 11s -``` #### Verify CronJob @@ -362,10 +371,10 @@ Here, the phase `Succeeded` means that the backup process has been completed suc Now, we are going to verify whether the backed up data is present in the backend or not. Once a backup is completed, Stash will update the respective `Repository` object to reflect the backup completion. Check that the repository `gcs-repo` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-repo +kubectl get repository -n demo gcs-repo +``` NAME INTEGRITY SIZE SNAPSHOT-COUNT LAST-SUCCESSFUL-BACKUP AGE gcs-repo true 1.327 MiB 1 60s 8m -``` Now, if we navigate to the GCS bucket, we will see the backed up data has been stored in `demo/redis/sample-redis` directory as specified by `.spec.backend.gcs.prefix` field of the `Repository` object.
@@ -468,9 +477,9 @@ Here, Let's create the `RestoreSession` object object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/restoresession.yaml -restoresession.stash.appscode.com/sample-redis-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/redis/backup/standalone/examples/restoresession.yaml ``` +restoresession.stash.appscode.com/sample-redis-restore created Once, you have created the `RestoreSession` object, Stash will create a restore Job. Run the following command to watch the phase of the `RestoreSession` object, diff --git a/docs/guides/redis/cli/cli.md b/docs/guides/redis/cli/cli.md index 9d341334ef..f577ed1ff3 100644 --- a/docs/guides/redis/cli/cli.md +++ b/docs/guides/redis/cli/cli.md @@ -23,16 +23,16 @@ KubeDB comes with its own cli. It is called `kubedb` cli. `kubedb` can be used t `kubectl create` creates a database CRD object in `default` namespace by default. Following command will create a Redis object as specified in `redis.yaml`. ```bash -$ kubectl create -f redis-demo.yaml -redis.kubedb.com/redis-demo created +kubectl create -f redis-demo.yaml ``` +redis.kubedb.com/redis-demo created You can provide namespace as a flag `--namespace`. Provided namespace should match with namespace specified in input file. ```bash -$ kubectl create -f redis-demo.yaml --namespace=kube-system -redis.kubedb.com/redis-demo created +kubectl create -f redis-demo.yaml --namespace=kube-system ``` +redis.kubedb.com/redis-demo created `kubectl create` command also considers `stdin` as input. @@ -45,13 +45,13 @@ cat redis-demo.yaml | kubectl create -f - `kubectl get` command allows users to list or find any KubeDB object. To list all Redis objects in `default` namespace, run the following command: ```bash -$ kubectl get redis +kubectl get redis +``` NAME VERSION STATUS AGE redis-demo 4.0-v1 Running 13s redis-dev 4.0-v1 Running 13s redis-prod 4.0-v1 Running 13s redis-qa 4.0-v1 Running 13s -``` To get YAML of an object, use `--output=yaml` flag. @@ -103,13 +103,13 @@ kubectl get redis redis-demo --output=json To list all KubeDB objects, use following command: ```bash -$ kubectl get all -o wide +kubectl get all -o wide +``` NAME VERSION STATUS AGE redis.kubedb.com/redis-demo 4.0-v1 Running 3m redis.kubedb.com/redis-dev 4.0-v1 Running 3m redis.kubedb.com/redis-prod 4.0-v1 Running 3m redis.kubedb.com/redis-qa 4.0-v1 Running 3m -``` Flag `--output=wide` is used to print additional information. @@ -121,27 +121,28 @@ List command supports short names for each object types. You can use it like `ku You can print labels with objects. The following command will list all Redis with their corresponding labels. ```bash -$ kubectl get rd --show-labels +kubectl get rd --show-labels +``` NAME VERSION STATUS AGE LABELS redis-demo 4.0-v1 Running 4m kubedb=cli-demo -``` To print only object name, run the following command: ```bash -$ kubectl get all -o name +kubectl get all -o name +``` redis/redis-demo redis/redis-dev redis/redis-prod redis/redis-qa -``` ### How to Describe Objects `kubectl dba describe` command allows users to describe any KubeDB object. The following command will describe Redis server `redis-demo` with relevant information. ```bash -$ kubectl dba describe rd redis-demo +kubectl dba describe rd redis-demo +``` Name: redis-demo Namespace: default CreationTimestamp: Mon, 01 Oct 2018 14:14:27 +0600 @@ -186,7 +187,6 @@ Events: Normal Successful 5m Redis operator Successfully created Redis Normal Successful 5m Redis operator Successfully patched PetSet Normal Successful 5m Redis operator Successfully patched Redis -``` `kubectl dba describe` command provides following basic information about a Redis server. @@ -230,13 +230,13 @@ To learn about various options of `describe` command, please visit [here](/docs/ Let's edit an existing running Redis object to setup [Monitoring](/docs/guides/redis/monitoring/using-builtin-prometheus.md). The following command will open Redis `redis-demo` in editor. ```bash -$ kubectl edit rd redis-demo +kubectl edit rd redis-demo +``` #spec: # monitor: # agent: prometheus.io/builtin redis "redis-demo" edited -``` #### Edit Restrictions @@ -261,16 +261,16 @@ For DormantDatabase, `spec.origin` can't be edited using `kubectl edit` `kubectl delete` command will delete an object in `default` namespace by default unless namespace is provided. The following command will delete a Redis `redis-dev` in default namespace ```bash -$ kubectl delete redis redis-dev -redis.kubedb.com "redis-dev" deleted +kubectl delete redis redis-dev ``` +redis.kubedb.com "redis-dev" deleted You can also use YAML files to delete objects. The following command will delete a redis using the type and name specified in `redis.yaml`. ```bash -$ kubectl delete -f redis-demo.yaml -redis.kubedb.com "redis-dev" deleted +kubectl delete -f redis-demo.yaml ``` +redis.kubedb.com "redis-dev" deleted `kubectl delete` command also takes input from `stdin`. @@ -288,13 +288,18 @@ kubectl delete redis -l redis.app.kubernetes.io/instance=redis-demo You can use Kubectl with KubeDB objects like any other CRDs. Below are some common examples of using Kubectl with KubeDB objects. -```bash # List objects -$ kubectl get redis -$ kubectl get redis.kubedb.com +```bash +kubectl get redis +``` + +```bash +kubectl get redis.kubedb.com +``` # Delete objects -$ kubectl delete redis +```bash +kubectl delete redis ``` ## Next Steps diff --git a/docs/guides/redis/clustering/overview.md b/docs/guides/redis/clustering/overview.md index 34a6cf73b1..7d67556eb1 100644 --- a/docs/guides/redis/clustering/overview.md +++ b/docs/guides/redis/clustering/overview.md @@ -168,11 +168,11 @@ For more Valkey parameters, see [here](https://github.com/valkey-io/valkey/blob/ The following is sample output of the [CLUSTER NODES](https://redis.io/commands/cluster-nodes) command sent to a master node in a small cluster of three nodes. ```bash - $ redis-cli cluster nodes + redis-cli cluster nodes + ``` d1861060fe6a534d42d8a19aeb36600e18785e04 127.0.0.1:6379 myself - 0 1318428930 1 connected 0-1364 3886e65cc906bfd9b1f7e7bde468726a052d1dae 127.0.0.1:6380 master - 1318428930 1318428931 2 connected 1365-2729 d289c575dcbc4bdd2931585fd4339089e461a27d 127.0.0.1:6381 master - 1318428931 1318428931 3 connected 2730-4095 - ``` Reference: https://redis.io/docs/management/scaling/ @@ -201,7 +201,7 @@ For more Valkey parameters, see [here](https://github.com/valkey-io/valkey/blob/ - If a node presents itself with a `MEET` message. A meet message is exactly like a [PING](https://redis.io/commands/ping) message but forces the receiver to accept the node as part of the cluster. Nodes will send `MEET` messages to other nodes **only if** the system administrator requests this via the following command: ```bash - $ CLUSTER MEET ip port + CLUSTER MEET ip port ``` - A node will also register another node as part of the cluster if a node that is already trusted will gossip about this other node. So if A knows B, and B knows C, eventually B will send gossip messages to A about C. When this happens, A will register C as part of the network, and will try to connect with C. diff --git a/docs/guides/redis/clustering/redis-cluster.md b/docs/guides/redis/clustering/redis-cluster.md index c9af3ece59..7cf9a1d87c 100644 --- a/docs/guides/redis/clustering/redis-cluster.md +++ b/docs/guides/redis/clustering/redis-cluster.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -65,9 +65,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/clustering/demo-1.yaml -redis.kubedb.com/redis-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/clustering/demo-1.yaml ``` +redis.kubedb.com/redis-cluster created Here, @@ -80,18 +80,22 @@ Here, KubeDB operator watches for `Redis` objects using Kubernetes API. When a `Redis` object is created, KubeDB operator will create a new PetSet and a Service with the matching Redis object name. KubeDB operator will also create a governing service for PetSets named `kubedb`, if one is not already present. ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-cluster 6.2.14 Ready 82s - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE redis-cluster-shard0 2/2 92s redis-cluster-shard1 2/2 88s redis-cluster-shard2 2/2 84s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-redis-cluster-shard0-0 Bound pvc-4dd44ddd-06d8-4f2d-bb57-4324c3385d06 1Gi RWO standard 112s data-redis-cluster-shard0-1 Bound pvc-fb431bb5-036d-4bd8-a89d-4b2477136c1c 1Gi RWO standard 105s @@ -100,8 +104,9 @@ data-redis-cluster-shard1-1 Bound pvc-3206ff9e-1ca3-4cef-846d-f91f60c5d572 data-redis-cluster-shard2-0 Bound pvc-40ccbe7c-e414-4e7b-b40b-2816f42efa63 1Gi RWO standard 104s data-redis-cluster-shard2-1 Bound pvc-be02792b-b033-407b-a376-9b34001c561f 1Gi RWO standard 92s - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-1be09fa7-6c26-4d5c-8aae-c0cc99e41c73 1Gi RWO Delete Bound demo/data-redis-cluster-shard1-0 standard 2m33s pvc-3206ff9e-1ca3-4cef-846d-f91f60c5d572 1Gi RWO Delete Bound demo/data-redis-cluster-shard1-1 standard 2m21s @@ -110,16 +115,17 @@ pvc-4dd44ddd-06d8-4f2d-bb57-4324c3385d06 1Gi RWO Delete pvc-be02792b-b033-407b-a376-9b34001c561f 1Gi RWO Delete Bound demo/data-redis-cluster-shard2-1 standard 2m17s pvc-fb431bb5-036d-4bd8-a89d-4b2477136c1c 1Gi RWO Delete Bound demo/data-redis-cluster-shard0-1 standard 2m30s -$ kubectl get svc -n demo +```bash +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE redis-cluster ClusterIP 10.96.115.92 6379/TCP 3m4s redis-cluster-pods ClusterIP None 6379/TCP 3m4s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified `Redis` object: ```bash -$ kubectl get rd -n demo redis-cluster -o yaml +kubectl get rd -n demo redis-cluster -o yaml ``` ``` yaml apiVersion: kubedb.com/v1 @@ -219,25 +225,26 @@ status: - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.username}' | base64 -d - default + kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.username}' | base64 -d ``` + default - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.password}' | base64 -d - AO8iK)s);o5kQVFs + kubectl get secrets -n demo redis-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` + AO8iK)s);o5kQVFs Now, you can connect to this database using the service using the credentials. ## Check Cluster Scenario The operator creates a cluster according to the newly created `Redis` object. This cluster has 3 shards and one replica per shard. And every node in the cluster is responsible for a subset of the total **16384** hash slots. -```bash # first list the redis pods list -$ kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep redis +```bash +kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep redis +``` redis-cluster-shard0-0 ---------- 10.244.0.140:6379 redis-cluster-shard0-1 ---------- 10.244.0.145:6379 redis-cluster-shard1-0 ---------- 10.244.0.144:6379 @@ -246,7 +253,9 @@ redis-cluster-shard2-0 ---------- 10.244.0.146:6379 redis-cluster-shard2-1 ---------- 10.244.0.150:637 # enter into any pod's container named redis -$ kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +```bash +kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +``` /data # # now inside this container, see which ones are the masters @@ -258,7 +267,6 @@ b49398da2eefac62a3b668a60f36bf4ccc3ccf4f 10.244.0.144:6379@16379 master - 0 1675 31d3f90e1bde3835ca7b08ae8b145b230d9b1ba8 10.244.0.146:6379@16379 master - 0 1675337399000 3 connected 10923-16383 6acca34b192445b888649a839bb7537d2cbb1cf4 10.244.0.150:6379@16379 slave 31d3f90e1bde3835ca7b08ae8b145b230d9b1ba8 0 1675337400553 3 connected f9af25d8db7bb742346b0130fb1cc749ffcd4d1e 10.244.0.140:6379@16379 myself,master - 0 1675337398000 1 connected 0-5460 -``` Each master has assigned some slots from slot 0 to slot 16383, and each master has one replica following it. ## Data Availability @@ -269,14 +277,17 @@ Now, you can connect to this database through [redis-cli](https://redis.io/topic `Note`: If you are using Valkey database image, use [valkey-cli](https://valkey.io/topics/cli/) instead. -```bash # here the hash slot for key 'hello' is 866 which is in 1st node # named 'redis-cluster-shard0-0' (0-5460) -$ kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- redis-cli -c cluster keyslot hello +```bash +kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- redis-cli -c cluster keyslot hello +``` (integer) 866 # connect to any node -$ kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +```bash +kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +``` /data # # now ensure that you are connected to the 1st pod @@ -302,7 +313,6 @@ OK -> Redirected to slot [866] located at 10.244.0.140:6379 "world" 10.244.0.146:6379> exit -``` ## Automatic Failover @@ -310,9 +320,10 @@ To test automatic failover, we will force a master node to sleep for a period. S > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # connect to any node and get the master nodes info -$ kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +```bash +kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +``` /data # redis-cli -c cluster nodes | grep master b49398da2eefac62a3b668a60f36bf4ccc3ccf4f 10.244.0.144:6379@16379 master - 0 1675338070000 2 connected 5461-10922 31d3f90e1bde3835ca7b08ae8b145b230d9b1ba8 10.244.0.146:6379@16379 master - 0 1675338070000 3 connected 10923-16383 @@ -323,7 +334,9 @@ f9af25d8db7bb742346b0130fb1cc749ffcd4d1e 10.244.0.140:6379@16379 myself,master - OK # now again connect to a node and get the master nodes info -$ kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +```bash +kubectl exec -it redis-cluster-shard0-0 -n demo -c redis -- bash +``` /data # redis-cli -c cluster nodes | grep master 3b4048d43fa982dd246703c899602f5c2472a995 10.244.0.149:6379@16379 master - 0 1675338334000 4 connected 5461-10922 31d3f90e1bde3835ca7b08ae8b145b230d9b1ba8 10.244.0.146:6379@16379 master - 0 1675338335355 3 connected 10923-16383 @@ -339,7 +352,6 @@ b49398da2eefac62a3b668a60f36bf4ccc3ccf4f 10.244.0.144:6379@16379 slave 3b4048d43 f9af25d8db7bb742346b0130fb1cc749ffcd4d1e 10.244.0.140:6379@16379 myself,master - 0 1675338355000 1 connected 0-5460 /data # exit -``` Notice that 110.244.0.149 is the new master and 10.244.0.144 has become the replica of 10.244.0.149. @@ -349,12 +361,14 @@ First set termination policy to `WipeOut` all the things created by KubeDB opera to clean what you created in this tutorial. ```bash -$ kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-cluster patched -$ kubectl delete rd redis-cluster -n demo -redis.kubedb.com "redis-cluster" deleted +```bash +kubectl delete rd redis-cluster -n demo ``` +redis.kubedb.com "redis-cluster" deleted ## Next Steps diff --git a/docs/guides/redis/concepts/redis.md b/docs/guides/redis/concepts/redis.md index 4a44aaa677..149ea0af3c 100644 --- a/docs/guides/redis/concepts/redis.md +++ b/docs/guides/redis/concepts/redis.md @@ -207,11 +207,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic redis1-auth -n demo \ +kubectl create secret generic redis1-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "redis1-auth" created ``` +secret "redis1-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/redis/concepts/redissentinel.md b/docs/guides/redis/concepts/redissentinel.md index 2e3a611b57..f26804ccf4 100644 --- a/docs/guides/redis/concepts/redissentinel.md +++ b/docs/guides/redis/concepts/redissentinel.md @@ -154,11 +154,11 @@ AuthSecret contains a `user` key and a `password` key which contains the `userna Example: ```bash -$ kubectl create secret generic sentinel1-auth -n demo \ +kubectl create secret generic sentinel1-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "sentinel1-auth" created ``` +secret "sentinel1-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/redis/configuration/acl.md b/docs/guides/redis/configuration/acl.md index 9d4b32f25b..795632dfaf 100644 --- a/docs/guides/redis/configuration/acl.md +++ b/docs/guides/redis/configuration/acl.md @@ -25,13 +25,15 @@ KubeDB supports providing ACL configuration for Redis. This tutorial will show y - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - $ kubectl get ns demo + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). diff --git a/docs/guides/redis/configuration/redis.md b/docs/guides/redis/configuration/redis.md index 85d6b9a11b..c3f3c80709 100644 --- a/docs/guides/redis/configuration/redis.md +++ b/docs/guides/redis/configuration/redis.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for Redis. This tutorial will sho - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - $ kubectl get ns demo + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,30 +50,32 @@ In this tutorial, we will configure `databases` and `maxclients` via a custom co At first, let's create `redis.conf` file setting `databases` and `maxclients` parameters. Default value of `databases` is 16 and `maxclients` is 10000. ```bash -$ cat <redis.conf +cat <redis.conf databases 10 maxclients 425 EOF +``` -$ cat redis.conf +```bash +cat redis.conf +``` databases 10 maxclients 425 -``` > Note that config file name must be `redis.conf` Now, create a Secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rd-configuration --from-file=./redis.conf -secret/rd-configuration created +kubectl create secret generic -n demo rd-configuration --from-file=./redis.conf ``` +secret/rd-configuration created Verify the Secret has the configuration file. ```bash -$ kubectl get secret -n demo rd-configuration -o yaml - +kubectl get secret -n demo rd-configuration -o yaml +``` apiVersion: v1 data: redis.conf: ZGF0YWJhc2VzIDEwCm1heGNsaWVudHMgNDI1Cgo= @@ -83,16 +87,15 @@ metadata: resourceVersion: "676133" uid: 73c4e8b5-9e9c-45e6-8b83-b6bc6f090663 type: Opaque -``` The configurations are encrypted in the secret. Now, create Redis crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-config/redis-custom.yaml -redis.kubedb.com "custom-redis" created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-config/redis-custom.yaml ``` +redis.kubedb.com "custom-redis" created Below is the YAML for the Redis crd we just created. @@ -121,16 +124,17 @@ Now, wait a few minutes. KubeDB operator will create necessary petset, services Check if the database is ready ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE custom-redis 6.2.14 Ready 10m -``` Now, we will check if the database has started with the custom configuration we have provided. We will `exec` into the pod and use [CONFIG GET](https://redis.io/commands/config-get) command to check the configuration. ```bash -$ kubectl exec -it -n demo custom-redis-0 -- bash +kubectl exec -it -n demo custom-redis-0 -- bash +``` root@custom-redis-0:/data# redis-cli 127.0.0.1:6379> ping PONG @@ -142,25 +146,30 @@ PONG 2) "425" 127.0.0.1:6379> exit root@custom-redis-0:/data# -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/custom-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/custom-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/custom-redis patched -$ kubectl delete -n demo redis custom-redis +```bash +kubectl delete -n demo redis custom-redis +``` redis.kubedb.com "custom-redis" deleted -$ kubectl delete -n demo secret rd-configuration +```bash +kubectl delete -n demo secret rd-configuration +``` secret "rd-configuration" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/redis/configuration/valkey.md b/docs/guides/redis/configuration/valkey.md index c2ed912df4..6b8b2826b5 100644 --- a/docs/guides/redis/configuration/valkey.md +++ b/docs/guides/redis/configuration/valkey.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for Redis. This tutorial will sho - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - $ kubectl get ns demo + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,27 +50,30 @@ In this tutorial, we will configure `databases` and `maxclients` via a custom co At first, let's create `valkey.conf` file setting `databases` and `maxclients` parameters. Default value of `databases` is 16 and `maxclients` is 10000. ```bash -$ cat <valkey.conf +cat <valkey.conf maxclients 425 EOF +``` -$ cat valkey.conf -maxclients 425 +```bash +cat valkey.conf ``` +maxclients 425 > Note that config file name must be `valkey.conf` Now, create a Secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rd-configuration --from-file=./valkey.conf -secret/rd-configuration created +kubectl create secret generic -n demo rd-configuration --from-file=./valkey.conf ``` +secret/rd-configuration created Verify the Secret has the configuration file. ```bash -$ kubectl get secret -n demo rd-configuration -o yaml +kubectl get secret -n demo rd-configuration -o yaml +``` apiVersion: v1 data: valkey.conf: bWF4Y2xpZW50cyA0MjUK @@ -80,16 +85,15 @@ metadata: resourceVersion: "1077435" uid: 402d38aa-e05b-4f2b-97e8-4771a2547872 type: Opaque -``` The configurations are encrypted in the secret. Now, create Redis crd specifying `spec.configuration.secretName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-config/valkey-custom.yaml -redis.kubedb.com "custom-valkey" created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-config/valkey-custom.yaml ``` +redis.kubedb.com "custom-valkey" created Below is the YAML for the Redis crd we just created. @@ -118,16 +122,17 @@ Now, wait a few minutes. KubeDB operator will create necessary petset, services Check if the database is ready ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE custom-valkey valkey-8.1.1 Ready 32s -``` Now, we will check if the database has started with the custom configuration we have provided. We will `exec` into the pod and use [CONFIG GET](https://redis.io/commands/config-get) command to check the configuration. ```bash -$ kubectl exec -it -n demo custom-valkey-0 -- bash +kubectl exec -it -n demo custom-valkey-0 -- bash +``` custom-valkey-0:/data$ valkey-cli 127.0.0.1:6379> ping PONG @@ -136,25 +141,30 @@ PONG 2) "425" 127.0.0.1:6379> exit custom-valkey-0:/data$ -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/custom-valkey -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/custom-valkey -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/custom-valkey patched -$ kubectl delete -n demo redis custom-valkey +```bash +kubectl delete -n demo redis custom-valkey +``` redis.kubedb.com "custom-redis" deleted -$ kubectl delete -n demo secret rd-configuration +```bash +kubectl delete -n demo secret rd-configuration +``` secret "rd-configuration" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/redis/custom-rbac/using-custom-rbac.md b/docs/guides/redis/custom-rbac/using-custom-rbac.md index 0b37c07e18..56d585a20c 100644 --- a/docs/guides/redis/custom-rbac/using-custom-rbac.md +++ b/docs/guides/redis/custom-rbac/using-custom-rbac.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,14 +46,14 @@ This guide will show you how to create custom `Service Account`, `Role`, and `Ro At first, let's create a `Service Acoount` in `demo` namespace. ```bash -$ kubectl create serviceaccount -n demo my-custom-serviceaccount -serviceaccount/my-custom-serviceaccount created +kubectl create serviceaccount -n demo my-custom-serviceaccount ``` +serviceaccount/my-custom-serviceaccount created It should create a service account. ```bash -$ kubectl get serviceaccount -n demo my-custom-serviceaccount -o yaml +kubectl get serviceaccount -n demo my-custom-serviceaccount -o yaml ``` ```yaml apiVersion: v1 @@ -71,9 +71,9 @@ secrets: Now, we need to create a role that has necessary access permissions for the Redis instance named `quick-redis`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-role.yaml -role.rbac.authorization.k8s.io/my-custom-role created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-role.yaml ``` +role.rbac.authorization.k8s.io/my-custom-role created Below is the YAML for the Role we just created. @@ -99,15 +99,14 @@ This permission is required for Redis pods running on PSP enabled clusters. Now create a `RoleBinding` to bind this `Role` with the already created service account. ```bash -$ kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo -rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created - +kubectl create rolebinding my-custom-rolebinding --role=my-custom-role --serviceaccount=demo:my-custom-serviceaccount --namespace=demo ``` +rolebinding.rbac.authorization.k8s.io/my-custom-rolebinding created It should bind `my-custom-role` and `my-custom-serviceaccount` successfully. ```bash -$ kubectl get rolebinding -n demo my-custom-rolebinding -o yaml +kubectl get rolebinding -n demo my-custom-rolebinding -o yaml ``` ```yaml apiVersion: rbac.authorization.k8s.io/v1 @@ -131,9 +130,9 @@ subjects: Now, create a Redis crd specifying `spec.podTemplate.spec.serviceAccountName` field to `my-custom-serviceaccount`. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-db.yaml -redis.kubedb.com/quick-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-db.yaml ``` +redis.kubedb.com/quick-redis created Below is the YAML for the Redis crd we just created. @@ -161,18 +160,18 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo quick-redis-0 +kubectl get pod -n demo quick-redis-0 +``` NAME READY STATUS RESTARTS AGE quick-redis-0 1/1 Running 0 61s -``` Check if database is in Ready state ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE quick-redis 6.2.14 Ready 117s -``` ## Reusing Service Account @@ -181,9 +180,9 @@ An existing service account can be reused in another Redis instance. No new acce Now, create Redis crd `minute-redis` using the existing service account name `my-custom-serviceaccount` in the `spec.podTemplate.spec.serviceAccountName` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-db-two.yaml -redis.kubedb.com/quick-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/custom-rbac/rd-custom-db-two.yaml ``` +redis.kubedb.com/quick-redis created Below is the YAML for the Redis crd we just created. @@ -215,49 +214,63 @@ Now, wait a few minutes. the KubeDB operator will create necessary PVC, petset, Check that the petset's pod is running ```bash -$ kubectl get pod -n demo minute-redis-0 +kubectl get pod -n demo minute-redis-0 +``` NAME READY STATUS RESTARTS AGE minute-redis-0 1/1 Running 0 14m -``` Check if database is in Ready state ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE minute-redis 6.2.14 Ready 76s quick-redis 6.2.14 Ready 4m26s -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/quick-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/quick-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/quick-redis patched -$ kubectl delete -n demo rd/quick-redis +```bash +kubectl delete -n demo rd/quick-redis +``` redis.kubedb.com "quick-redis" deleted -$ kubectl patch -n demo rd/minute-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo rd/minute-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/minute-redis patched -$ kubectl delete -n demo rd/minute-redis +```bash +kubectl delete -n demo rd/minute-redis +``` redis.kubedb.com "minute-redis" deleted -$ kubectl delete -n demo role my-custom-role +```bash +kubectl delete -n demo role my-custom-role +``` role.rbac.authorization.k8s.io "my-custom-role" deleted -$ kubectl delete -n demo rolebinding my-custom-rolebinding +```bash +kubectl delete -n demo rolebinding my-custom-rolebinding +``` rolebinding.rbac.authorization.k8s.io "my-custom-rolebinding" deleted -$ kubectl delete sa -n demo my-custom-serviceaccount +```bash +kubectl delete sa -n demo my-custom-serviceaccount +``` serviceaccount "my-custom-serviceaccount" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted If you would like to uninstall the KubeDB operator, please follow the steps [here](/docs/setup/README.md). diff --git a/docs/guides/redis/external-connections/exposure.md b/docs/guides/redis/external-connections/exposure.md index 295ca82a3c..3545603831 100644 --- a/docs/guides/redis/external-connections/exposure.md +++ b/docs/guides/redis/external-connections/exposure.md @@ -25,9 +25,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Prerequisites @@ -102,9 +102,9 @@ spec: > If you want to use `NodePort` service. Update `.spec.provider.kubernetes.envoyService.type` to `NodePort` in the above YAML. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/envoyproxy.yaml -envoyproxy.gateway.envoyproxy.io/ace created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/envoyproxy.yaml ``` +envoyproxy.gateway.envoyproxy.io/ace created Create `GatewayClass` using the following command: ```yaml @@ -135,16 +135,16 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/gatewayclass.yaml -gatewayclass.gateway.networking.k8s.io/ace created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/gatewayclass.yaml ``` +gatewayclass.gateway.networking.k8s.io/ace created Check the `GatewayClass` status `True`. ```bash -$ kubectl get gatewayclass +kubectl get gatewayclass +``` NAME CONTROLLER ACCEPTED AGE ace gateway.envoyproxy.io/gatewayclass-controller True 16s -``` ### Install `FluxCD` in your cluster Install `FluxCD` in your cluster using the following command: @@ -160,16 +160,20 @@ helm upgrade -i flux2 \ Install `Keda` in your cluster using the following command: ```bash -$ kubectl create ns kubeops +kubectl create ns kubeops +``` namespace/kubeops created -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/helmrepo.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/helmrepo.yaml +``` helmrepository.source.toolkit.fluxcd.io/appscode-charts-oci created -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/keda.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/keda.yaml +``` helmrelease.helm.toolkit.fluxcd.io/keda created helmrelease.helm.toolkit.fluxcd.io/keda-add-ons-http created -``` ### Install `Catalog Manager` @@ -256,18 +260,18 @@ Here, ### Deploy Redis Cluster Announce ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/redis.yaml -redis.kubedb.com/redis-announce created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/redis.yaml ``` +redis.kubedb.com/redis-announce created Now, wait until `redis-announce` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get rd -n demo NAME VERSION STATUS AGE redis-announce 7.4.0 Ready 6m56s -``` Now, create `RedisBinding` object to configure the whole process. @@ -283,20 +287,20 @@ spec: namespace: demo ``` -```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/binding.yaml +```bash +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/announce/binding.yaml +``` redisbinding.catalog.appscode.com/redis-bind created -``` Now, check the status of `redisbinding` objects and ops requests. ```bash -$ kubectl get redisbinding,rdopsrequest -n demo +kubectl get redisbinding,rdopsrequest -n demo +``` NAME SRC_NS SRC_NAME STATUS AGE redisbinding.catalog.appscode.com/redis-bind demo redis-announce Current 3m28s NAME TYPE STATUS AGE redisopsrequest.ops.kubedb.com/redis-announce-jddiql Announce Successful 2m58s -``` ### Connect to Redis as Cluster @@ -304,7 +308,8 @@ To connect to the Redis replica set, you can use the following command: Collect the announces from the `redis` object: ```bash -$ kubectl get redis -n demo redis-announce -ojson | jq .spec.cluster.announce +kubectl get redis -n demo redis-announce -ojson | jq .spec.cluster.announce +``` { "shards": [ { @@ -327,20 +332,19 @@ $ kubectl get redis -n demo redis-announce -ojson | jq .spec.cluster.announce } ], } -``` Connect with the database: ```bash -$ redis-cli -h rd0-0.kubedb.appscode -p 10050 -a -c ping -PONG +redis-cli -h rd0-0.kubedb.appscode -p 10050 -a -c ping ``` +PONG Set data in different shards: ```bash -$ redis-cli -h rd1-0.kubedb.appscode -p 10051 -a -c set batman appscode --> Redirected to slot [13947] located at rd0-0.kubedb.appscode:10050 +redis-cli -h rd1-0.kubedb.appscode -p 10051 -a -c set batman appscode ``` +-> Redirected to slot [13947] located at rd0-0.kubedb.appscode:10050 ## Cleaning up diff --git a/docs/guides/redis/external-connections/initialization.md b/docs/guides/redis/external-connections/initialization.md index c551032469..c68ecbaf37 100644 --- a/docs/guides/redis/external-connections/initialization.md +++ b/docs/guides/redis/external-connections/initialization.md @@ -26,9 +26,9 @@ Now, install KubeDB cli on your workstation and KubeDB operator in your cluster To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). ## Redis Cluster with Announce @@ -94,23 +94,23 @@ Here, Now, wait until `redis-announce` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get rd -n demo NAME VERSION STATUS AGE redis-announce 7.4.0 Ready 6m56s -``` To check assigned DNS/IP or port or bust port list for every pod you can run: ```bash -$ kubectl exec -it -n demo redis-announce-shard0-0 -- cat /tmp/db-endpoints.txt +kubectl exec -it -n demo redis-announce-shard0-0 -- cat /tmp/db-endpoints.txt +``` redis-announce-shard0-0 rd0-0.kubedb.appscode 10050 10056 redis-announce-shard0-1 rd0-1.kubedb.appscode 10051 10057 redis-announce-shard1-0 rd1-0.kubedb.appscode 10052 10058 redis-announce-shard1-1 rd1-1.kubedb.appscode 10053 10059 redis-announce-shard2-0 rd2-0.kubedb.appscode 10054 10060 redis-announce-shard2-1 rd2-1.kubedb.appscode 10055 10061 -``` ## Redis Cluster without Announce @@ -144,30 +144,30 @@ spec: Now, wait until `redis` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get rd -n demo NAME VERSION STATUS AGE redis 7.4.0 Ready 6m56s -``` To check the endpoint type run: ```bash -$ kubectl exec -it -n demo redis-shard0-0 -- cat /tmp/endpoint-type.txt -ip +kubectl exec -it -n demo redis-shard0-0 -- cat /tmp/endpoint-type.txt ``` +ip To check assigned DNS/IP or port or bust port list for every pod you can run: ```bash -$ kubectl exec -it -n demo redis-shard0-0 -- cat /tmp/db-endpoints.txt +kubectl exec -it -n demo redis-shard0-0 -- cat /tmp/db-endpoints.txt +``` redis-shard0-0 10.244.0.34 6379 16379 redis-shard0-1 10.244.0.27 6379 16379 redis-shard1-0 10.244.0.30 6379 16379 redis-shard1-1 10.244.0.28 6379 16379 redis-shard2-0 10.244.0.33 6379 16379 redis-shard2-1 10.244.0.32 6379 16379 -``` ## Cleaning up diff --git a/docs/guides/redis/gitops/gitops.md b/docs/guides/redis/gitops/gitops.md index e1f0b52bd4..f93e4eaeb3 100644 --- a/docs/guides/redis/gitops/gitops.md +++ b/docs/guides/redis/gitops/gitops.md @@ -26,12 +26,14 @@ This guide will show you how to use `KubeDB` GitOps operator to create Redis dat - You need to install GitOps tools like `ArgoCD` or `FluxCD` and configure with your Git Repository to monitor the Git repository and synchronize the state of the Kubernetes cluster with the desired state defined in Git. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Redis](/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). We are going to use `ArgoCD` in this tutorial. You can install `ArgoCD` in your cluster by following the steps [here](https://argo-cd.readthedocs.io/en/stable/getting_started/). Also, you need to install `argocd` CLI in your local machine. You can install `argocd` CLI by following the steps [here](https://argo-cd.readthedocs.io/en/stable/cli_installation/). @@ -94,11 +96,11 @@ spec: Create a directory like below, ```bash -$ tree . +tree . +``` ├── kubedb └── Redis.yaml 1 directories, 1 files -``` Now commit the changes and push to your Git repository. Your repository is synced with `ArgoCD` and the `Redis` CR is created in your cluster. @@ -106,18 +108,19 @@ Our `gitops` operator will create an actual `Redis` database CR in the cluster. ```bash -$ kubectl get redis.gitops.kubedb.com,redis.kubedb.com -n demo +kubectl get redis.gitops.kubedb.com,redis.kubedb.com -n demo +``` NAME AGE redis.gitops.kubedb.com/rd-gitops 8m37s NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 8.0.4 Ready 8m37s -``` List the resources created by `kubedb` operator created for `kubedb.com/v1` Redis. ```bash -$ kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=rd-gitops' +kubectl get petset,pod,secret,service,appbinding -n demo -l 'app.kubernetes.io/instance=rd-gitops' +``` NAME AGE petset.apps.k8s.appscode.com/rd-gitops-shard0 8m58s petset.apps.k8s.appscode.com/rd-gitops-shard1 8m55s @@ -141,7 +144,6 @@ service/rd-gitops-pods ClusterIP None 6379/TCP,16379 NAME TYPE VERSION AGE appbinding.appcatalog.appscode.com/rd-gitops kubedb.com/redis 8.0.4 8m53s -``` ## Update Redis Database using GitOps @@ -161,7 +163,7 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - Now create a ca-secret using the certificate files you have just generated. ```bash -$ kubectl create secret tls redis-ca \ +kubectl create secret tls redis-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo @@ -183,19 +185,19 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml -issuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml ``` +issuer.cert-manager.io/redis-ca-issuer created Let's add that to our `kubedb /rd-issuer.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── rd-issuer.yaml │ ├── rd-secret.yaml │ └── redis.yaml 1 directories, 3 files -``` Update the `redis.yaml` with the following, ```yaml @@ -232,7 +234,8 @@ Add `tls` fields in the spec. Commit the changes and push to your Git repositor Now, `gitops` operator will detect the tls changes and create a `ReconfigureTLS` RedisOpsRequest to update the `Redis` database tls. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 7.4.1 Ready 15m @@ -241,7 +244,6 @@ redis.gitops.kubedb.com/rd-gitops 15m NAME TYPE STATUS AGE redisopsrequest.ops.kubedb.com/rd-gitops-reconfiguretls-qcdjjd ReconfigureTLS Successful 9m47s -``` > We can also rotate the certificates updating `.spec.tls.certificates` field. Also you can remove the `.spec.tls` field to remove tls for Redis. @@ -277,7 +279,8 @@ Update the `replicas` to `3`. Commit the changes and push to your Git repository Now, `gitops` operator will detect the replica changes and create a `HorizontalScaling` RedisOpsRequest to update the `Redis` database replicas. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 8.0.4 Ready 19m @@ -286,11 +289,11 @@ redis.gitops.kubedb.com/rd-gitops 19m NAME TYPE STATUS AGE redisopsrequest.ops.kubedb.com/rd-gitops-horizontalscaling-4ecw03 HorizontalScaling Successful 4m2s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the number of pods, ```bash -$ kubectl get pod -n demo -l 'app.kubernetes.io/instance=rd-gitops' +kubectl get pod -n demo -l 'app.kubernetes.io/instance=rd-gitops' +``` NAME READY STATUS RESTARTS AGE rd-gitops-shard0-0 1/1 Running 0 20m rd-gitops-shard0-1 1/1 Running 0 19m @@ -301,7 +304,6 @@ rd-gitops-shard1-2 1/1 Running 0 4m6s rd-gitops-shard2-0 1/1 Running 0 20m rd-gitops-shard2-1 1/1 Running 0 19m rd-gitops-shard2-2 1/1 Running 0 3m46s -``` We can also scale down the replicas by updating the `replicas` fields. @@ -310,7 +312,8 @@ We can also scale down the replicas by updating the `replicas` fields. Before the Ops Request reaches the `Successful` state, the configured memory limits are as follows: ```bash -$ kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].resources' +kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "memory": "1Gi" @@ -320,7 +323,6 @@ $ kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].r "memory": "1Gi" } } -``` Update the `Redis.yaml` with the following, @@ -364,7 +366,8 @@ Resource Requests and Limits are updated to `1000m` CPU and `1.5Gi` Memory. Comm Now, `gitops` operator will detect the resource changes and create a `RedisOpsRequest` to update the `Redis` database. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 8.0.4 Ready 17h @@ -374,10 +377,10 @@ redis.gitops.kubedb.com/rd-gitops 17h NAME TYPE STATUS AGE redisopsrequest.ops.kubedb.com/rd-gitops-horizontalscaling-ule15j HorizontalScaling Successful 16h redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-lliwo8 VerticalScaling Successful 16h -``` -```bash -$ kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].resources' +```bash +kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].resources' +``` { "limits": { "cpu": "1", @@ -388,7 +391,6 @@ $ kubectl get pod -n demo rd-gitops-shard0-0 -o json | jq '.spec.containers[0].r "memory": "1536Mi" } } -``` ### Expand Redis Volume @@ -433,7 +435,8 @@ Update the `storage.resources.requests.storage` to `2Gi`. Commit the changes and Now, `gitops` operator will detect the volume changes and create a `VolumeExpansion` RedisOpsRequest to update the `Redis` database volume. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 8.0.4 Ready 39m @@ -444,11 +447,11 @@ NAME TYPE redisopsrequest.ops.kubedb.com/rd-gitops-horizontalscaling-4ecw03 HorizontalScaling Successful 24m redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-r0oosa VerticalScaling Successful 17m redisopsrequest.ops.kubedb.com/rd-gitops-volumeexpansion-0ubdaw VolumeExpansion Successful 7m31s -``` After Ops Request becomes `Successful`, We can validate the changes by checking the pvc size, ```bash -$ kubectl get pvc -n demo -l 'app.kubernetes.io/instance=rd-gitops' +kubectl get pvc -n demo -l 'app.kubernetes.io/instance=rd-gitops' +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-rd-gitops-shard0-0 Bound pvc-97afbd7c-5887-4381-bef8-4584411b4ed5 2Gi RWO longhorn 39m data-rd-gitops-shard0-1 Bound pvc-461c6122-94ba-4b96-805b-1bf2619a10d4 2Gi RWO longhorn 38m @@ -459,7 +462,6 @@ data-rd-gitops-shard1-2 Bound pvc-6d3d1e55-689e-4884-a3cc-ed6080e48cf0 2G data-rd-gitops-shard2-0 Bound pvc-e6b9fa56-40b2-45aa-8ebd-ab360522a294 2Gi RWO longhorn 39m data-rd-gitops-shard2-1 Bound pvc-6fdfd395-d2b8-45df-8369-f9897e3d678c 2Gi RWO longhorn 38m data-rd-gitops-shard2-2 Bound pvc-1570c37b-63da-456c-af59-b60ed544e651 2Gi RWO longhorn 23m -``` ### Update Version @@ -508,7 +510,8 @@ Update the `version` field to `7.4.1`. Commit the changes and push to your Git r Now, `gitops` operator will detect the version changes and create a `VersionUpdate` RedisOpsRequest to update the `Redis` database version. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 7.4.1 Ready 21m @@ -520,7 +523,6 @@ redisopsrequest.ops.kubedb.com/rd-gitops-horizontalscaling-4ecw03 HorizontalSc redisopsrequest.ops.kubedb.com/rd-gitops-versionupdate-wbsjct UpdateVersion Successful 12m redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-r0oosa VerticalScaling Successful 137m redisopsrequest.ops.kubedb.com/rd-gitops-volumeexpansion-0ubdaw VolumeExpansion Successful 127m -``` ## Reconfigure Redis @@ -541,14 +543,14 @@ stringData: Let's add that to `kubedb/rd_conf.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── rd-config.yaml │ ├── rd-issuer.yaml │ ├── rd-secret.yaml │ └── redis.yaml 1 directories, 4 files -``` @@ -594,7 +596,8 @@ Commit the changes and push to your Git repository. Your repository is synced wi Now, `gitops` operator will detect the configuration changes and create a `Reconfigure` RedisOpsRequest to update the `Redis` database configuration. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 7.4.1 Ready 51m @@ -607,7 +610,6 @@ redisopsrequest.ops.kubedb.com/rd-gitops-reconfigure-uc97bo Reconfigure redisopsrequest.ops.kubedb.com/rd-gitops-versionupdate-wbsjct UpdateVersion Successful 91m redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-r0oosa VerticalScaling Successful 3h35m redisopsrequest.ops.kubedb.com/rd-gitops-volumeexpansion-0ubdaw VolumeExpansion Successful 3h26m -``` We can also reconfigure the parameters creating another secret and reference the secret in the `configuration.secretName` field. Also you can remove the `configuration.secretName` field to use the default parameters. @@ -633,7 +635,8 @@ stringData: Let's add that to our `kubedb/rdauth.yaml` file. File structure will look like this, ```bash -$ tree . +tree . +``` ├── kubedb │ ├── rd-auth.yaml │ ├── rd-config.yaml @@ -641,7 +644,6 @@ $ tree . │ ├── rd-secret.yaml │ └── redis.yaml 1 directories, 5 files -``` Update the `Redis.yaml` with the following, ```yaml @@ -688,7 +690,8 @@ Change the `authSecret` field to `rd-rotate-auth`. Commit the changes and push t Now, `gitops` operator will detect the auth changes and create a `RotateAuth` RedisOpsRequest to update the `Redis` database auth. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo + kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 7.4.1 Ready 77m @@ -702,7 +705,6 @@ redisopsrequest.ops.kubedb.com/rd-gitops-rotate-auth-2l0psh RotateAuth redisopsrequest.ops.kubedb.com/rd-gitops-versionupdate-wbsjct UpdateVersion Successful 117m redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-r0oosa VerticalScaling Successful 4h2m redisopsrequest.ops.kubedb.com/rd-gitops-volumeexpansion-0ubdaw VolumeExpansion Successful 3h52m -``` ### Enable Monitoring If you already don't have a Prometheus server running, deploy one following tutorial from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md#deploy-prometheus-server). @@ -758,7 +760,8 @@ Add `monitor` field in the spec. Commit the changes and push to your Git reposit Now, `gitops` operator will detect the monitoring changes and create a `Restart` RedisOpsRequest to add the `Redis` database monitoring. List the resources created by `gitops` operator in the `demo` namespace. ```bash -$ kubectl get rd,redis,redisopsrequest -n demo +kubectl get rd,redis,redisopsrequest -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/rd-gitops 7.4.1 Ready 117m @@ -773,7 +776,6 @@ redisopsrequest.ops.kubedb.com/rd-gitops-rotate-auth-2l0psh RotateAuth redisopsrequest.ops.kubedb.com/rd-gitops-versionupdate-wbsjct UpdateVersion Successful 157m redisopsrequest.ops.kubedb.com/rd-gitops-verticalscaling-r0oosa VerticalScaling Successful 4h41m redisopsrequest.ops.kubedb.com/rd-gitops-volumeexpansion-0ubdaw VolumeExpansion Successful 4h32m -``` Verify the monitoring is enabled by checking the prometheus targets. diff --git a/docs/guides/redis/initialization/gitsync.md b/docs/guides/redis/initialization/gitsync.md index e72ba5c01e..622b8f5677 100644 --- a/docs/guides/redis/initialization/gitsync.md +++ b/docs/guides/redis/initialization/gitsync.md @@ -25,9 +25,9 @@ In this example, we will initialize Redis using a `.sh` script from the GitHub r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## From Public Git Repository @@ -79,15 +79,16 @@ The `git-sync` container has two required flags: Now, wait until `redis-demo` has status `Ready`. i.e, ```bash -$ kubectl get Redis -n demo +kubectl get Redis -n demo +``` NAME VERSION STATUS AGE redis-demo 8.2.2 Ready 5m -``` Next, we will connect to the Redis database and verify the data inserted from the `*.sh` script stored in the Git repository. ```bash -$ kubectl exec -n demo -it redis-demo-0 -- bash +kubectl exec -n demo -it redis-demo-0 -- bash +``` Defaulted container "redis" out of: redis, redis-init (init) # Inside the pod @@ -120,7 +121,6 @@ root@redis-demo-0:/data# redis-cli 11) "user:6:name" 12) "user:6:email" 127.0.0.1:6379> QUIT -``` ## From Private Git Repository ### 1. Using SSH Key @@ -130,7 +130,7 @@ Git-sync supports using SSH protocol for pulling git content. First, Obtain the host keys for your git server: ```bash -$ ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts +ssh-keyscan $YOUR_GIT_HOST > /tmp/known_hosts ``` > `$YOUR_GIT_HOST` refers to the hostname of your Git server.
@@ -143,7 +143,7 @@ Use the `kubectl create secret` command to create a secret from your local SSH k This secret will be used by git-sync to authenticate with the Git repository. > Here, we are using the default SSH key file located at `$HOME/.ssh/id_rsa`. If your SSH key is stored in a different location, please update the command accordingly. Also, you can use any name instead of `git-creds` to create the secret. ```bash -$ kubectl create secret generic -n demo git-creds \ +kubectl create secret generic -n demo git-creds \ --from-file=ssh=$HOME/.ssh/id_rsa \ --from-file=known_hosts=/tmp/known_hosts ``` @@ -208,15 +208,15 @@ NAME VERSION STATUS AGE redis-demo 8.2.2 Ready 48m ``` -```shell -$ kubectl exec -n demo -it redis-demo-shard0-0 -- bash +```bash +kubectl exec -n demo -it redis-demo-shard0-0 -- bash +``` Defaulted container "redis" out of: redis, redis-init (init), git-sync (init) redis@redis-demo-shard0-0:/data$ redis-cli -c 127.0.0.1:6379> get user:1:name -> Redirected to slot [12440] located at 10.42.0.241:6379 "John Doe" 10.42.0.241:6379> exit -``` ### 2. Using Username and Personal Access Token(PAT) @@ -224,7 +224,7 @@ First, create a `Personal Access Token (PAT)` on your Git host server with the r Then create a Kubernetes secret using the `Personal Access Token (PAT)`: > Here, you can use any key name instead of `git-pat` to store the token in the secret. ```bash -$ kubectl create secret generic -n demo git-pat \ +kubectl create secret generic -n demo git-pat \ --from-literal=github-pat= ``` @@ -281,22 +281,28 @@ NAME VERSION STATUS AGE redis-demo 8.2.2 Ready 48m ``` -```shell -$ kubectl exec -n demo -it redis-demo-shard0-0 -- bash +```bash +kubectl exec -n demo -it redis-demo-shard0-0 -- bash +``` Defaulted container "redis" out of: redis, redis-init (init), git-sync (init) redis@redis-demo-shard0-0:/data$ redis-cli -c 127.0.0.1:6379> get user:1:name -> Redirected to slot [12440] located at 10.42.0.241:6379 "John Doe" 10.42.0.241:6379> exit -``` ## CleanUp To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete Redis -n demo redis-demo -$ kubectl delete secret -n demo git-pat git-creds -$ kubectl delete ns demo +kubectl delete Redis -n demo redis-demo +``` + +```bash +kubectl delete secret -n demo git-pat git-creds +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/redis/initialization/using-script.md b/docs/guides/redis/initialization/using-script.md index 1ac6e65ae1..28b481b591 100644 --- a/docs/guides/redis/initialization/using-script.md +++ b/docs/guides/redis/initialization/using-script.md @@ -25,9 +25,9 @@ This tutorial will show you how to use KubeDB to initialize a Redis and Valkey d - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,9 +42,9 @@ At first, we will create a ConfigMap from `init.sh` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo redis-init-script --from-literal=init.sh="redis-cli set hello world" -configmap/redis-init-script created +kubectl create configmap -n demo redis-init-script --from-literal=init.sh="redis-cli set hello world" ``` +configmap/redis-init-script created ## Create a Redis database with Init-Script @@ -77,9 +77,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/initialization/demo-1.yaml -redis.kubedb.com/rd-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/initialization/demo-1.yaml ``` +redis.kubedb.com/rd-init-script created Here, @@ -88,7 +88,8 @@ Here, KubeDB operator watches for `Redis` objects using Kubernetes api. When a `Redis` object is created, KubeDB operator will create a new PetSet and a Service with the matching Redis object name. KubeDB operator will also create a governing service for PetSets with the name `-gvr`, if one is not already present. No Redis specific RBAC roles are required for [RBAC enabled clusters](/docs/setup/README.md#using-yaml). ```bash -$ kubectl describe rd -n demo rd-init-script +kubectl describe rd -n demo rd-init-script +``` Name: rd-init-script Namespace: demo Labels: @@ -186,31 +187,36 @@ Events: Normal Successful 82s KubeDB Operator Successfully created Service Normal Successful 79s KubeDB Operator Successfully created appbinding - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE rd-init-script 1/1 30s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-rd-init-script-0 Bound pvc-31dbab22-09af-4eeb-b032-1df287d9e579 1Gi RWO standard 2m17s - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-31dbab22-09af-4eeb-b032-1df287d9e579 1Gi RWO Delete Bound demo/data-rd-init-script-0 standard 2m37s - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rd-init-script ClusterIP 10.96.3.28 6379/TCP 3m11s rd-init-script-pods ClusterIP None 6379/TCP 3m11s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified Redis object: ```bash -$ kubectl get rd -n demo rd-init-script -o yaml +kubectl get rd -n demo rd-init-script -o yaml +``` apiVersion: kubedb.com/v1alpha2 kind: Redis metadata: @@ -302,13 +308,13 @@ status: type: Provisioned observedGeneration: 2 phase: Ready -``` Please note that KubeDB operator has created a new Secret called `rd-init-script-auth` *(format: {redis-object-name}-auth)* for storing the password for Redis superuser. This secret contains a `username` key which contains the *username* for Redis superuser and a `password` key which contains the *password* for Redis superuser. If you want to use an existing secret please specify that when creating the Redis object using `spec.authSecret.name`. While creating this secret manually, make sure the secret contains these two keys containing data `username` and `password`. ```bash -$ kubectl get secrets -n demo rd-init-script-auth -o yaml +kubectl get secrets -n demo rd-init-script-auth -o yaml +``` apiVersion: v1 data: password: STRMTl9fVjJuaDlsdndhcg== @@ -326,26 +332,28 @@ metadata: resourceVersion: "133291" uid: ece22594-6c5f-4428-ac0f-5f2d2690785f type: kubernetes.io/basic-auth -``` Now, you can connect to this database through redis cli. In this tutorial, we are connecting to the Redis server from inside the pod. ```bash -$ kubectl get secrets -n demo rd-init-script-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo rd-init-script-auth -o jsonpath='{.data.username}' | base64 -d +``` default -$ kubectl get secrets -n demo rd-init-script-auth -o jsonpath='{.data.password}' | base64 -d +```bash +kubectl get secrets -n demo rd-init-script-auth -o jsonpath='{.data.password}' | base64 -d +``` I4LN__V2nh9lvwar -$ kubectl exec -it rd-init-script-0 -n demo -- bash - +```bash +kubectl exec -it rd-init-script-0 -n demo -- bash +``` Defaulted container "redis" out of: redis, redis-init (init) redis@rd-init-script-0:/data$ redis@rd-init-script-0:/data$ redis-cli get hello "world" redis@rd-init-script-0:/data$ exit exit -``` As you can see here, the initial script has successfully created a database named `kubedb` and inserted data into that database successfully. diff --git a/docs/guides/redis/monitoring/using-builtin-prometheus.md b/docs/guides/redis/monitoring/using-builtin-prometheus.md index ab0a651995..562b591f2c 100644 --- a/docs/guides/redis/monitoring/using-builtin-prometheus.md +++ b/docs/guides/redis/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor Redis server using builtin [Prometheu - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -69,31 +71,32 @@ Here, Let's create the Redis crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/monitoring/builtin-prom-redis.yaml -redis.kubedb.com/builtin-prom-redis created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/monitoring/builtin-prom-redis.yaml ``` +redis.kubedb.com/builtin-prom-redis created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get rd -n demo builtin-prom-redis +kubectl get rd -n demo builtin-prom-redis +``` NAME VERSION STATUS AGE builtin-prom-redis 4.0-v1 Running 41s -``` KubeDB will create a separate stats service with name `{Redis crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-redis" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-redis" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-redis ClusterIP 10.109.162.108 6379/TCP 59s builtin-prom-redis-stats ClusterIP 10.106.243.251 56790/TCP 41s -``` Here, `builtin-prom-redis-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-redis-stats +kubectl describe svc -n demo builtin-prom-redis-stats +``` Name: builtin-prom-redis-stats Namespace: demo Labels: app.kubernetes.io/name=redises.kubedb.com @@ -110,7 +113,6 @@ TargetPort: prom-http/TCP Endpoints: 172.17.0.14:56790 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -274,20 +276,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -298,9 +300,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -309,18 +311,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-redis-stats` service as one of the targets. @@ -337,16 +339,31 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo rd/builtin-prom-redis +kubectl delete -n demo rd/builtin-prom-redis +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` ## Next Steps diff --git a/docs/guides/redis/monitoring/using-prometheus-operator.md b/docs/guides/redis/monitoring/using-prometheus-operator.md index 586fad9494..d051b8a9af 100644 --- a/docs/guides/redis/monitoring/using-prometheus-operator.md +++ b/docs/guides/redis/monitoring/using-prometheus-operator.md @@ -25,12 +25,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME AGE monitoring prometheus 18m -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -125,26 +127,26 @@ Here, Let's create the Redis object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/monitoring/coreos-prom-redis.yaml -redis.kubedb.com/coreos-prom-redis created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/monitoring/coreos-prom-redis.yaml ``` +redis.kubedb.com/coreos-prom-redis created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get rd -n demo coreos-prom-redis +kubectl get rd -n demo coreos-prom-redis +``` NAME VERSION STATUS AGE coreos-prom-redis 4.0-v1 Running 15s -``` KubeDB will create a separate stats service with name `{Redis crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-redis" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=coreos-prom-redis" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE coreos-prom-redis ClusterIP 10.110.70.53 6379/TCP 35s coreos-prom-redis-stats ClusterIP 10.99.161.76 56790/TCP 31s -``` Here, `coreos-prom-redis-stats` service has been created for monitoring purpose. @@ -172,15 +174,15 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `coreos-prom-redis-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE kubedb-demo-coreos-prom-redis 1m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Redis crd. ```bash -$ kubectl get servicemonitor -n demo kubedb-demo-coreos-prom-redis -o yaml +kubectl get servicemonitor -n demo kubedb-demo-coreos-prom-redis -o yaml ``` ```yaml @@ -221,20 +223,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 63m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `coreos-prom-redis-stats` service as one of the targets. diff --git a/docs/guides/redis/private-registry/using-private-registry.md b/docs/guides/redis/private-registry/using-private-registry.md index ad883ae194..8cc45a30b6 100644 --- a/docs/guides/redis/private-registry/using-private-registry.md +++ b/docs/guides/redis/private-registry/using-private-registry.md @@ -25,16 +25,17 @@ KubeDB operator supports using private Docker registry. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - You will also need a docker private [registry](https://docs.docker.com/registry/) or [private repository](https://docs.docker.com/docker-hub/repos/#private-repositories). In this tutorial we will use private repository of [docker hub](https://hub.docker.com/). - You have to push the required images from KubeDB's [Docker hub account](https://hub.docker.com/r/kubedb/) into your private registry. For redis, push `DB_IMAGE`, `TOOLS_IMAGE`, `EXPORTER_IMAGE` of following RedisVersions, where `deprecated` is not true, to your private registry. ```bash -$ kubectl get redisversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,INITCONTAINER_IMAGE:.spec.initContainer.image,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image +kubectl get redisversions -n kube-system -o=custom-columns=NAME:.metadata.name,VERSION:.spec.version,INITCONTAINER_IMAGE:.spec.initContainer.image,DB_IMAGE:.spec.db.image,EXPORTER_IMAGE:.spec.exporter.image +``` NAME VERSION INITCONTAINER_IMAGE DB_IMAGE EXPORTER_IMAGE 4.0.11 4.0.11 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/kubedb/redis:4.0.11 ghcr.io/kubedb/redis_exporter:1.66.0 5.0.14 5.0.14 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/appscode-images/redis:5.0.14-bullseye ghcr.io/kubedb/redis_exporter:1.66.0 @@ -52,7 +53,6 @@ valkey-7.2.5 7.2.5 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/appscode-ima valkey-7.2.9 7.2.9 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/appscode-images/valkey:7.2.9 ghcr.io/kubedb/redis_exporter:1.66.0 valkey-8.0.3 8.0.3 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/appscode-images/valkey:8.0.3 ghcr.io/kubedb/redis_exporter:1.66.0 valkey-8.1.1 8.1.1 ghcr.io/kubedb/redis-init:0.12.0 ghcr.io/appscode-images/valkey:8.1.1 ghcr.io/kubedb/redis_exporter:1.66.0 -``` Docker hub repositories: @@ -90,13 +90,13 @@ ImagePullSecrets is a type of Kubernetes Secret whose sole purpose is to pull pr Run the following command, substituting the appropriate uppercase values to create an image pull secret for your private Docker registry: ```bash -$ kubectl create secret docker-registry -n demo myregistrykey \ +kubectl create secret docker-registry -n demo myregistrykey \ --docker-server=DOCKER_REGISTRY_SERVER \ --docker-username=DOCKER_USER \ --docker-email=DOCKER_EMAIL \ --docker-password=DOCKER_PASSWORD -secret/myregistrykey created ``` +secret/myregistrykey created If you wish to follow other ways to pull private images see [official docs](https://kubernetes.io/docs/concepts/containers/images/) of Kubernetes. @@ -135,25 +135,26 @@ spec: Now run the command to deploy this `Redis` object: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/private-registry/demo-2.yaml -redis.kubedb.com/redis-pvt-reg created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/private-registry/demo-2.yaml ``` +redis.kubedb.com/redis-pvt-reg created To check if the images pulled successfully from the repository, see if the `Redis` is in running state: ```bash -$ kubectl get pods -n demo -w +kubectl get pods -n demo -w +``` NAME READY STATUS RESTARTS AGE redis-pvt-reg-0 0/1 Pending 0 0s redis-pvt-reg-0 0/1 Pending 0 0s redis-pvt-reg-0 0/1 ContainerCreating 0 0s redis-pvt-reg-0 1/1 Running 0 2m - -$ kubectl get rd -n demo +```bash +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-pvt-reg 6.2.14 Running 40s -``` ## Cleaning up @@ -170,18 +171,24 @@ kubectl delete ns demo ``` ```bash -$ kubectl patch -n demo rd/redis-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-pvt-reg -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-pvt-reg patched -$ kubectl delete -n demo rd/redis-pvt-reg +```bash +kubectl delete -n demo rd/redis-pvt-reg +``` redis.kubedb.com "redis-pvt-reg" deleted -$ kubectl delete -n demo secret myregistrykey +```bash +kubectl delete -n demo secret myregistrykey +``` secret "myregistrykey" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Next Steps diff --git a/docs/guides/redis/quickstart/overview/redis.md b/docs/guides/redis/quickstart/overview/redis.md index 1e21d31694..7e5657007a 100644 --- a/docs/guides/redis/quickstart/overview/redis.md +++ b/docs/guides/redis/quickstart/overview/redis.md @@ -29,21 +29,23 @@ This tutorial will show you how to use KubeDB to run a Redis server. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 4h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create namespace demo + kubectl create namespace demo + ``` namespace/demo created - $ kubectl get namespaces + ```bash + kubectl get namespaces + ``` NAME STATUS AGE demo Active 10s - ``` > Note: The yaml files used in this tutorial are stored in [docs/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -52,7 +54,8 @@ This tutorial will show you how to use KubeDB to run a Redis server. When you have installed KubeDB, it has created `RedisVersion` crd for all supported Redis versions. Check: ```bash -$ kubectl get redisversions +kubectl get redisversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 4.0.11 4.0.11 ghcr.io/kubedb/redis:4.0.11 14d 5.0.14 5.0.14 ghcr.io/appscode-images/redis:5.0.14-bullseye 14d @@ -70,7 +73,6 @@ valkey-7.2.5 7.2.5 ghcr.io/appscode-images/valkey:7.2.5 valkey-7.2.9 7.2.9 ghcr.io/appscode-images/valkey:7.2.9 14d valkey-8.0.3 8.0.3 ghcr.io/appscode-images/valkey:8.0.3 14d valkey-8.1.1 8.1.1 ghcr.io/appscode-images/valkey:8.1.1 14d -``` `Note`: RedisVersion which contains redis database image, will have `spec.distribution` as `Official` ## Create a Redis server @@ -99,9 +101,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1.yaml -redis.kubedb.com/redis-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1.yaml ``` +redis.kubedb.com/redis-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -123,9 +125,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1alpha2.yaml -redis.kubedb.com/redis-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1alpha2.yaml ``` +redis.kubedb.com/redis-quickstart created Here, @@ -139,11 +141,14 @@ Here, KubeDB operator watches for `Redis` objects using Kubernetes api. When a `Redis` object is created, KubeDB operator will create a new PetSet and a Service with the matching Redis object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-quickstart 6.2.14 Running 1m -$ kubectl describe rd -n demo redis-quickstart +```bash +kubectl describe rd -n demo redis-quickstart +``` Name: redis-quickstart Namespace: demo CreationTimestamp: Tue, 31 May 2022 10:31:38 +0600 @@ -234,29 +239,36 @@ Events: Normal Successful 2m Redis Operator Successfully created Service Normal Successful 2m Redis Operator Successfully created appbinding - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE redis-quickstart 1/1 1m -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-redis-quickstart-0 Bound pvc-6e457226-c53f-11e8-9ba7-0800274bef12 1Gi RWO standard 2m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-6e457226-c53f-11e8-9ba7-0800274bef12 1Gi RWO Delete Bound demo/data-redis-quickstart-0 standard 2m -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE redis-quickstart-pods ClusterIP None 2m redis-quickstart ClusterIP 10.108.149.205 6379/TCP 2m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified Redis object: ```bash -$ kubectl get rd -n demo redis-quickstart -o yaml +kubectl get rd -n demo redis-quickstart -o yaml +``` apiVersion: kubedb.com/v1 kind: Redis metadata: @@ -332,13 +344,11 @@ status: observedGeneration: 2 phase: Ready -``` - Now, you can connect to this database through [redis-cli](https://redis.io/topics/rediscli). In this tutorial, we are connecting to the Redis server from inside of pod. ```bash -$ kubectl exec -it -n demo redis-quickstart-0 -- sh - +kubectl exec -it -n demo redis-quickstart-0 -- sh +``` /data > redis-cli 127.0.0.1:6379> ping @@ -355,16 +365,15 @@ OK 127.0.0.1:6379> exit /data > exit -``` ## DoNotTerminate Property When `deletionPolicy` is `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete rd redis-quickstart -n demo -Error from server (BadRequest): admission webhook "redis.validators.kubedb.com" denied the request: redis "redis-quickstart" can't be halted. To delete, change spec.deletionPolicy +kubectl delete rd redis-quickstart -n demo ``` +Error from server (BadRequest): admission webhook "redis.validators.kubedb.com" denied the request: redis "redis-quickstart" can't be halted. To delete, change spec.deletionPolicy Now, run `kubectl edit rd redis-quickstart -n demo` to set `spec.deletionPolicy` to `Halt` . Then you will be able to delete/halt the database. @@ -379,21 +388,22 @@ You can also keep the redis object and halt the database to resume it again late To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -redis.kubedb.com/redis-quickstart patched +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +redis.kubedb.com/redis-quickstart patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"halted":true}}' --type="merge" -redis.kubedb.com/redis-quickstart patched +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"halted":true}}' --type="merge" ``` +redis.kubedb.com/redis-quickstart patched After that, kubedb will delete the petsets and services, and you can see the database Phase as `Halted`. Now, you can run the following command to get all redis resources in demo namespaces, ```bash -$ kubectl get redis,secret,pvc -n demo +kubectl get redis,secret,pvc -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/redis-quickstart 6.2.14 Halted 5m26s @@ -408,29 +418,28 @@ secret/vault-server-certs kubernetes.io/tls 3 NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/data-redis-quickstart-0 Bound pvc-ee1c2fd3-4c0e-4dad-812b-8f83e20284f8 1Gi RWO standard 5m24s -``` ## Resume Halted Redis Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"halted":false}}' --type="merge" -redis.kubedb.com/redis-quickstart patched +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"halted":false}}' --type="merge" ``` +redis.kubedb.com/redis-quickstart patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-quickstart 6.2.14 Ready 7m52s -``` Now, If you again exec into the `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it -n demo redis-quickstart-0 -- sh - +kubectl exec -it -n demo redis-quickstart-0 -- sh +``` /data > redis-cli 127.0.0.1:6379> ping @@ -443,22 +452,24 @@ PONG 127.0.0.1:6379> exit /data > exit -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-quickstart patched -$ kubectl delete -n demo rd/redis-quickstart +```bash +kubectl delete -n demo rd/redis-quickstart +``` redis.kubedb.com "redis-quickstart" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/redis/quickstart/overview/valkey.md b/docs/guides/redis/quickstart/overview/valkey.md index 34b7e5599a..3071ffafa4 100644 --- a/docs/guides/redis/quickstart/overview/valkey.md +++ b/docs/guides/redis/quickstart/overview/valkey.md @@ -29,21 +29,23 @@ This tutorial will show you how to use KubeDB to run a Valkey server. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 4h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create namespace demo + kubectl create namespace demo + ``` namespace/demo created - $ kubectl get namespaces + ```bash + kubectl get namespaces + ``` NAME STATUS AGE demo Active 10s - ``` > Note: The yaml files used in this tutorial are stored in [docs/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -52,7 +54,8 @@ This tutorial will show you how to use KubeDB to run a Valkey server. When you have installed KubeDB, it has created `RedisVersion` crd for all supported Redis and Valkey versions. Check: ```bash -$ kubectl get redisversions +kubectl get redisversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 4.0.11 4.0.11 ghcr.io/kubedb/redis:4.0.11 14d 5.0.14 5.0.14 ghcr.io/appscode-images/redis:5.0.14-bullseye 14d @@ -70,7 +73,6 @@ valkey-7.2.5 7.2.5 ghcr.io/appscode-images/valkey:7.2.5 valkey-7.2.9 7.2.9 ghcr.io/appscode-images/valkey:7.2.9 14d valkey-8.0.3 8.0.3 ghcr.io/appscode-images/valkey:8.0.3 14d valkey-8.1.1 8.1.1 ghcr.io/appscode-images/valkey:8.1.1 14d -``` `Note`: RedisVersion which contains valkey database image, will have `spec.distribution` as `valkey` ## Create a Valkey server @@ -99,9 +101,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-valkey-v1.yaml -redis.kubedb.com/valkey-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-valkey-v1.yaml ``` +redis.kubedb.com/valkey-quickstart created ```yaml apiVersion: kubedb.com/v1alpha2 @@ -123,9 +125,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-valkey-v1alpha2.yaml -redis.kubedb.com/valkey-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-valkey-v1alpha2.yaml ``` +redis.kubedb.com/valkey-quickstart created Here, @@ -139,11 +141,14 @@ Here, KubeDB operator watches for `Redis` objects using Kubernetes api. When a `Redis` object is created, KubeDB operator will create a new PetSet and a Service with the matching Redis object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE valkey-quickstart valkey-8.1.1 Ready 6m16s -$ kubectl describe rd -n demo valkey-quickstart +```bash +kubectl describe rd -n demo valkey-quickstart +``` Name: valkey-quickstart Namespace: demo Labels: @@ -263,12 +268,12 @@ Events: Normal Successful 6m29s KubeDB Operator Successfully created governing service Normal Successful 6m29s KubeDB Operator Successfully created Service Normal Successful 6m27s KubeDB Operator Successfully created appbinding -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified Redis object: ```bash -$ kubectl get rd -n demo valkey-quickstart -o yaml +kubectl get rd -n demo valkey-quickstart -o yaml +``` apiVersion: kubedb.com/v1 kind: Redis metadata: @@ -383,12 +388,12 @@ status: type: Provisioned observedGeneration: 2 phase: Ready -``` Now, you can connect to this database through [redis-cli](https://redis.io/topics/rediscli). In this tutorial, we are connecting to the Redis server from inside of pod. ```bash -$ kubectl exec -it -n demo valkey-quickstart-0 -- sh +kubectl exec -it -n demo valkey-quickstart-0 -- sh +``` /data $ valkey-cli 127.0.0.1:6379> ping PONG @@ -398,7 +403,6 @@ OK "hello" 127.0.0.1:6379> exit /data $ exit -``` ## DoNotTerminate Property Learn details of all `DeletionPolicy` [here](/docs/guides/redis/concepts/redis.md#specdeletionpolicy) @@ -414,21 +418,22 @@ You can also keep the redis object and halt the database to resume it again late To halt the database, first you have to set the deletionPolicy to `Halt` in existing database. You can use the below command to set the deletionPolicy to `Halt`, if it is not already set. ```bash -$ kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -redis.kubedb.com/valkey-quickstart patched +kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +redis.kubedb.com/valkey-quickstart patched Then, you have to set the `spec.halted` as true to set the database in a `Halted` state. You can use the below command. ```bash -$ kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"halted":true}}' --type="merge" -redis.kubedb.com/valkey-quickstart patched +kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"halted":true}}' --type="merge" ``` +redis.kubedb.com/valkey-quickstart patched After that, kubedb will delete the petsets and services, and you can see the database Phase as `Halted`. Now, you can run the following command to get all redis resources in demo namespaces, ```bash -$ kubectl get redis,secret,pvc -n demo +kubectl get redis,secret,pvc -n demo +``` NAME VERSION STATUS AGE redis.kubedb.com/valkey-quickstart valkey-8.1.1 Halted 19m @@ -438,29 +443,28 @@ secret/valkey-quickstart-config Opaque 1 19m NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE persistentvolumeclaim/data-valkey-quickstart-0 Bound pvc-c7d0fc32-c863-42eb-a7db-23a7852fbfac 1Gi RWO standard 19m -``` ## Resume Halted Redis Now, to resume the database, i.e. to get the same database setup back again, you have to set the `spec.halted` as false. You can use the below command. ```bash -$ kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"halted":false}}' --type="merge" -redis.kubedb.com/valkey-quickstart patched +kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"halted":false}}' --type="merge" ``` +redis.kubedb.com/valkey-quickstart patched When the database is resumed successfully, you can see the database Status is set to `Ready`. ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE valkey-quickstart valkey-8.1.1 Ready 20m -``` Now, If you again exec into the `pod` and look for previous data, you will see that, all the data persists. ```bash -$ kubectl exec -it -n demo valkey-quickstart-0 -- sh - +kubectl exec -it -n demo valkey-quickstart-0 -- sh +``` /data > valkey-cli 127.0.0.1:6379> ping @@ -473,22 +477,24 @@ PONG 127.0.0.1:6379> exit /data > exit -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/valkey-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/valkey-quickstart patched -$ kubectl delete -n demo rd/valkey-quickstart +```bash +kubectl delete -n demo rd/valkey-quickstart +``` redis.kubedb.com "valkey-quickstart" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/redis/reconfigure-tls/sentinel.md b/docs/guides/redis/reconfigure-tls/sentinel.md index 931b513962..2453eced03 100644 --- a/docs/guides/redis/reconfigure-tls/sentinel.md +++ b/docs/guides/redis/reconfigure-tls/sentinel.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -65,17 +65,17 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sentinel.yaml -redissentinel.kubedb.com/sen-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sentinel.yaml ``` +redissentinel.kubedb.com/sen-sample created Now, wait until `sen-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-sample 6.2.14 Ready 5m20s -``` ### Deploy Redis without TLS @@ -108,24 +108,24 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-sentinel.yaml -redis.kubedb.com/rd-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-sentinel.yaml ``` +redis.kubedb.com/rd-sample created Now, wait until `redis-standalone` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get rd -n demo NAME VERSION STATUS AGE rd-sample 6.2.14 Ready 88s -``` Now, we can connect to this database through redis-cli verify that the TLS is disabled. ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash - +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` root@rd-sample-0:/data# redis-cli 127.0.0.1:6379> config get tls-cert-file @@ -133,7 +133,6 @@ root@rd-sample-0:/data# redis-cli 2) "" 127.0.0.1:6379> exit root@rd-sample-0:/data# -``` We can verify from the above output that TLS is disabled for this database. @@ -144,18 +143,18 @@ Now, We are going to create an example `ClusterIssuer` that will be used to enab - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/O=kubedb" +``` Generating a RSA private key ................+++++ ........................+++++ writing new private key to './ca.key' ----- -``` - Now create a ca-secret using the certificate files you have just generated. The secret should be created in `cert-manager` namespace to create the `ClusterIssuer`. ```bash -$ kubectl create secret tls redis-ca \ +kubectl create secret tls redis-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=cert-manager @@ -176,9 +175,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/clusterissuer.yaml -clusterissuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/clusterissuer.yaml ``` +clusterissuer.cert-manager.io/redis-ca-issuer created ### Create RedisOpsRequest There are two basic things to keep in mind when securing Redis using TLS in Sentinel Mode. @@ -230,33 +229,34 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-add-tls.yaml -redisopsrequest.ops.kubedb.com/rd-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-add-tls.yaml ``` +redisopsrequest.ops.kubedb.com/rd-add-tls created #### Verify TLS Enabled Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-add-tls ReconfigureTLS Successful 9m -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Let's check if new sentinel named `sen-demo-tls` is created ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-demo-tls 6.2.14 Ready 17m -``` 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 rd-sample-client-cert +kubectl describe secret -n demo rd-sample-client-cert +``` Name: rd-sample-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -279,13 +279,12 @@ Data ca.crt: 1139 bytes tls.crt: 1168 bytes tls.key: 1675 bytes -``` Now, Lets exec into a redis container and find out the username to connect in a redis shell, ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash - +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` root@rd-sample-0:/data# ls /certs ca.crt client.crt client.key server.crt server.key @@ -293,12 +292,11 @@ root@rd-sample-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs 1) "tls-cert-file" 2) "/certs/server.crt -``` - Now, we can connect using tls-certs to the redis and write some data ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` # Trying to connect without tls certificates root@rd-sample-0:/data# redis-cli 127.0.0.1:6379> @@ -312,7 +310,6 @@ root@rd-sample-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> exit -``` ## Rotate Certificate @@ -345,20 +342,20 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-rotate.yaml -redisopsrequest.ops.kubedb.com/rd-ops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-rotate.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-ops-rotate ReconfigureTLS Successful 5m5s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. @@ -389,20 +386,20 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sen-ops-rotate.yaml -redisopsrequest.ops.kubedb.com/rd-ops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sen-ops-rotate.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE sen-ops-rotate ReconfigureTLS Successful 78s -``` We can see from the above output that the `RedisSentinelOpsRequest` has succeeded. @@ -447,33 +444,34 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sen-ops-remove.yaml -redisopsrequest.ops.kubedb.com/rd-ops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/sen-ops-remove.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-remove created #### Verify TLS Removed Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-ops-remove ReconfigureTLS Successful 2m5s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Let's check if new sentinel named `sen-sample` is created ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-sample 6.2.14 Ready 7m56s -``` Now, Lets exec into the database primary node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` # root@rd-sample-0:/data# redis-cli @@ -482,7 +480,6 @@ root@rd-sample-0:/data# redis-cli 2) "" 127.0.0.1:6379> exit root@rd-sample-0:/data# -``` So, we can see from the above that, output that tls is disabled successfully. @@ -490,29 +487,39 @@ So, we can see from the above that, output that tls is disabled successfully. To clean up the Kubernetes resources created by this tutorial, run: -```bash # Delete Redis and RedisOpsRequest -$ kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-sample patched -$ kubectl delete -n demo redis rd-sample +```bash +kubectl delete -n demo redis rd-sample +``` redis.kubedb.com "rd-sample" deleted -$ kubectl delete -n demo redisopsrequest rd-add-tls rd-ops-remove rd-ops-rotate +```bash +kubectl delete -n demo redisopsrequest rd-add-tls rd-ops-remove rd-ops-rotate +``` redisopsrequest.ops.kubedb.com "rd-add-tls" deleted redisopsrequest.ops.kubedb.com "rd-ops-remove" deleted redisopsrequest.ops.kubedb.com "rd-ops-rotate" deleted # Delete RedisSentinel and RedisSentinelOpsRequest -$ kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-sample patched -$ kubectl delete -n demo redissentinel sen-sample +```bash +kubectl delete -n demo redissentinel sen-sample +``` redissentinel.kubedb.com "sen-sample" deleted -$ kubectl delete -n demo redissentinelopsrequests sen-ops-rotate -redissentinelopsrequest.ops.kubedb.com "sen-ops-rotate" deleted +```bash +kubectl delete -n demo redissentinelopsrequests sen-ops-rotate ``` +redissentinelopsrequest.ops.kubedb.com "sen-ops-rotate" deleted ## Next Steps diff --git a/docs/guides/redis/reconfigure-tls/standalone.md b/docs/guides/redis/reconfigure-tls/standalone.md index 56d5b430d4..e04f7c25f1 100644 --- a/docs/guides/redis/reconfigure-tls/standalone.md +++ b/docs/guides/redis/reconfigure-tls/standalone.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -65,24 +65,24 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/redis-standalone.yaml -redis.kubedb.com/rd-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/redis-standalone.yaml ``` +redis.kubedb.com/rd-sample created Now, wait until `redis-standalone` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get rd -n demo NAME VERSION STATUS AGE rd-sample 6.2.14 Ready 88s -``` Now, we can connect to this database through redis-cli verify that the TLS is disabled. ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash - +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` root@rd-sample-0:/data# redis-cli 127.0.0.1:6379> config get tls-cert-file @@ -90,7 +90,6 @@ root@rd-sample-0:/data# redis-cli 2) "" 127.0.0.1:6379> exit root@rd-sample-0:/data# -``` We can verify from the above output that TLS is disabled for this database. @@ -101,23 +100,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 redis-ca \ +kubectl create secret tls redis-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/redis-ca created ``` +secret/redis-ca created Now, Let's create an `Issuer` using the `redis-ca` secret that we have just created. The `YAML` file looks like this: @@ -135,9 +134,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/issuer.yaml -issuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/issuer.yaml ``` +issuer.cert-manager.io/redis-ca-issuer created ### Create RedisOpsRequest @@ -177,27 +176,28 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-add-tls.yaml -redisopsrequest.ops.kubedb.com/rd-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-add-tls.yaml ``` +redisopsrequest.ops.kubedb.com/rd-add-tls created #### Verify TLS Enabled Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-add-tls ReconfigureTLS Successful 9m -``` We can see from the above output that the `RedisOpsRequest` 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 rd-sample-client-cert +kubectl describe secret -n demo rd-sample-client-cert +``` Name: rd-sample-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -220,25 +220,24 @@ Data ca.crt: 1147 bytes tls.crt: 1127 bytes tls.key: 1679 bytes -``` Now, Lets exec into a redis container and find out the username to connect in a redis shell, ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash - +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` root@rd-sample-0:/data# ls /certs ca.crt client.crt client.key server.crt server.key root@rd-sample-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs/client.key" --cacert "/certs/ca.crt" config get tls-cert-file 1) "tls-cert-file" 2) "/certs/server.crt -``` Now, we can connect using tls-certs to connect to the redis and write some data ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` # Trying to connect without tls certificates root@rd-sample-0:/data# redis-cli 127.0.0.1:6379> @@ -252,7 +251,6 @@ root@rd-sample-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> exit -``` ## Rotate Certificate @@ -285,20 +283,20 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-rotate.yaml -redisopsrequest.ops.kubedb.com/rd-ops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-rotate.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-ops-rotate ReconfigureTLS Successful 5m5s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. @@ -309,23 +307,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 redis-new-ca \ +kubectl create secret tls redis-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/redis-new-ca created ``` +secret/redis-new-ca created Now, Let's create a new `Issuer` using the `redis-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -343,9 +341,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/new-issuer.yaml -issuer.cert-manager.io/rd-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/new-issuer.yaml ``` +issuer.cert-manager.io/rd-new-issuer created ### Create RedisOpsRequest @@ -377,20 +375,20 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-change-issuer.yaml -redisopsrequest.ops.kubedb.com/rd-change-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-change-issuer.yaml ``` +redisopsrequest.ops.kubedb.com/rd-change-issuer created #### Verify Issuer is changed successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-change-issuer ReconfigureTLS Successful 4m65s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. @@ -425,27 +423,28 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-remove.yaml -redisopsrequest.ops.kubedb.com/rd-ops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure-tls/rd-ops-remove.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-remove created #### Verify TLS Removed Successfully Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CRO, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rd-ops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, Lets exec into the database primary node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- bash +kubectl exec -it -n demo rd-sample-0 -c redis -- bash +``` # root@rd-sample-0:/data# redis-cli @@ -454,7 +453,6 @@ root@rd-sample-0:/data# redis-cli 2) "" 127.0.0.1:6379> exit root@rd-sample-0:/data# -``` So, we can see from the above that, output that tls is disabled successfully. @@ -463,22 +461,28 @@ So, we can see from the above that, output that tls is disabled successfully. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo redis/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redis/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-sample patched -$ kubectl delete redis -n demo rd-sample +```bash +kubectl delete redis -n demo rd-sample +``` redis.kubedb.com/rd-sample deleted -$ kubectl delete issuer -n demo redis-ca-issuer rd-new-issuer +```bash +kubectl delete issuer -n demo redis-ca-issuer rd-new-issuer +``` issuer.cert-manager.io "redis-ca-issuer" deleted issuer.cert-manager.io "rd-new-issuer" deleted -$ kubectl delete redisopsrequest -n demo rd-add-tls rd-ops-remove rd-ops-rotate rd-change-issuer +```bash +kubectl delete redisopsrequest -n demo rd-add-tls rd-ops-remove rd-ops-rotate rd-change-issuer +``` redisopsrequest.ops.kubedb.com "rd-add-tls" deleted redisopsrequest.ops.kubedb.com "rd-ops-remove" deleted redisopsrequest.ops.kubedb.com "rd-ops-rotate" deleted redisopsrequest.ops.kubedb.com "rd-change-issuer" deleted -``` ## Next Steps diff --git a/docs/guides/redis/reconfigure/redis.md b/docs/guides/redis/reconfigure/redis.md index 739a5032ec..5d26593a5d 100644 --- a/docs/guides/redis/reconfigure/redis.md +++ b/docs/guides/redis/reconfigure/redis.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -55,9 +55,9 @@ Here, `maxclients` is set to `500`, whereas the default value is `10000`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rd-custom-config --from-file=./redis.conf -secret/rd-custom-config created +kubectl create secret generic -n demo rd-custom-config --from-file=./redis.conf ``` +secret/rd-custom-config created In this section, we are going to create a Redis object specifying `spec.configuration.secretName` field to apply this custom configuration. Below is the YAML of the `Redis` CR that we are going to create, @@ -84,36 +84,38 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/sample-redis-config.yaml -redis.kubedb.com/sample-redis created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/sample-redis-config.yaml ``` +redis.kubedb.com/sample-redis created Now, wait until `sample-redis` has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE sample-redis 6.2.14 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a redis instance, ```bash -$ kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.username}' | base64 -d +``` default -$ kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.password}' | base64 -d -0PI1tYTyzp;YaXOh +```bash +kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.password}' | base64 -d ``` +0PI1tYTyzp;YaXOh Now let's connect to a redis instance and run a redis internal command to check the configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +``` maxclients 500 -``` As we can see from the configuration of running redis, the value of `maxclients` has been set to `500`. @@ -131,9 +133,9 @@ maxclients 2000 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./redis.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./redis.conf ``` +secret/new-custom-config created #### Create RedisOpsRequest @@ -163,9 +165,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-reconfigure.yaml -redisopsrequest.ops.kubedb.com/rdops-reconfigure created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-reconfigure.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-reconfigure created #### Verify the new configuration is working @@ -174,16 +176,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-reconfigure Reconfigure Successful 1m -``` We can see from the above output that the `RedisOpsRequest` has succeeded. If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe redisopsrequest -n demo rdops-reconfigure +kubectl describe redisopsrequest -n demo rdops-reconfigure +``` Name: rdops-reconfigure Namespace: demo Labels: @@ -245,17 +248,15 @@ Events: Normal ResumeDatabase 88s KubeDB Ops-manager Operator Resuming Redis demo/sample-redis Normal ResumeDatabase 88s KubeDB Ops-manager Operator Successfully resumed Redis demo/sample-redis Normal Successful 88s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` Now let's connect to a redis instance and run a redis internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +``` maxclients 2000 -``` - As we can see from the configuration of running redis, the value of `maxclients` has been changed from `500` to `2000`. So the reconfiguration of the database is successful. @@ -292,9 +293,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-apply-reconfig.yaml -redisopsrequest.ops.kubedb.com/rdops-apply-reconfig created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-apply-reconfig.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-apply-reconfig created #### Verify the new configuration is working @@ -303,16 +304,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-apply-reconfig Reconfigure Successful 38s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe redisopsrequest -n demo rdops-apply-reconfig +kubectl describe redisopsrequest -n demo rdops-apply-reconfig +``` Name: rdops-apply-reconfig Namespace: demo Labels: @@ -373,15 +375,14 @@ Events: Normal ResumeDatabase 14s KubeDB Ops-manager Operator Resuming Redis demo/sample-redis Normal ResumeDatabase 14s KubeDB Ops-manager Operator Successfully resumed Redis demo/sample-redis Normal Successful 14s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` Now let's connect to a redis instance and run a redis internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- redis-cli config get maxclients +``` maxclients 3000 -``` As we can see from the configuration of running redis, the value of `maxclients` has been changed from `2000` to `3000`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/redis/reconfigure/valkey.md b/docs/guides/redis/reconfigure/valkey.md index d78d948f3c..3660f24033 100644 --- a/docs/guides/redis/reconfigure/valkey.md +++ b/docs/guides/redis/reconfigure/valkey.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -55,9 +55,9 @@ Here, `maxclients` is set to `500`, whereas the default value is `10000`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo rd-custom-config --from-file=./valkey.conf -secret/rd-custom-config created +kubectl create secret generic -n demo rd-custom-config --from-file=./valkey.conf ``` +secret/rd-custom-config created In this section, we are going to create a Redis object specifying `spec.configuration.secretName` field to apply this custom configuration. Below is the YAML of the `Redis` CR that we are going to create, @@ -84,36 +84,38 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/sample-redis-config.yaml -redis.kubedb.com/sample-redis created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/sample-redis-config.yaml ``` +redis.kubedb.com/sample-redis created Now, wait until `sample-redis` has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE sample-redis valkey-8.1.1 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. First we need to get the username and password to connect to a Valkey instance, ```bash -$ kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.username}' | base64 -d +``` default -$ kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.password}' | base64 -d -0PI1tYTyzp;YaXOh +```bash +kubectl get secrets -n demo sample-redis-auth -o jsonpath='{.data.password}' | base64 -d ``` +0PI1tYTyzp;YaXOh Now let's connect to a Valkey instance and run a Valkey internal command to check the configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +``` maxclients 500 -``` As we can see from the configuration of running Valkey, the value of `maxclients` has been set to `500`. @@ -131,9 +133,9 @@ maxclients 2000 Then, we will create a new secret with this configuration file. ```bash -$ kubectl create secret generic -n demo new-custom-config --from-file=./valkey.conf -secret/new-custom-config created +kubectl create secret generic -n demo new-custom-config --from-file=./valkey.conf ``` +secret/new-custom-config created #### Create RedisOpsRequest @@ -164,9 +166,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-reconfigure.yaml -redisopsrequest.ops.kubedb.com/rdops-reconfigure created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-reconfigure.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-reconfigure created #### Verify the new configuration is working @@ -175,16 +177,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-reconfigure Reconfigure Successful 1m -``` We can see from the above output that the `RedisOpsRequest` has succeeded. If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe redisopsrequest -n demo rdops-reconfigure +kubectl describe redisopsrequest -n demo rdops-reconfigure +``` Name: rdops-reconfigure Namespace: demo Labels: @@ -246,17 +249,15 @@ Events: Normal ResumeDatabase 88s KubeDB Ops-manager Operator Resuming Redis demo/sample-redis Normal ResumeDatabase 88s KubeDB Ops-manager Operator Successfully resumed Redis demo/sample-redis Normal Successful 88s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` Now let's connect to a Valkey instance and run a Valkey internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +``` maxclients 2000 -``` - As we can see from the configuration of running Valkey, the value of `maxclients` has been changed from `500` to `2000`. So the reconfiguration of the database is successful. @@ -293,9 +294,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-apply-reconfig.yaml -redisopsrequest.ops.kubedb.com/rdops-apply-reconfig created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/reconfigure/rdops-apply-reconfig.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-apply-reconfig created #### Verify the new configuration is working @@ -304,16 +305,17 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE rdops-apply-reconfig Reconfigure Successful 38s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe redisopsrequest -n demo rdops-apply-reconfig +kubectl describe redisopsrequest -n demo rdops-apply-reconfig +``` Name: rdops-apply-reconfig Namespace: demo Labels: @@ -374,15 +376,14 @@ Events: Normal ResumeDatabase 14s KubeDB Ops-manager Operator Resuming Redis demo/sample-redis Normal ResumeDatabase 14s KubeDB Ops-manager Operator Successfully resumed Redis demo/sample-redis Normal Successful 14s KubeDB Ops-manager Operator Successfully Reconfigured Database -``` Now let's connect to a Valkey instance and run a Valkey internal command to check the new configuration we have provided. ```bash -$ kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +kubectl exec -n demo sample-redis-0 -- valkey-cli config get maxclients +``` maxclients 3000 -``` As we can see from the configuration of running Valkey, the value of `maxclients` has been changed from `2000` to `3000`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/redis/restart/restart.md b/docs/guides/redis/restart/restart.md index ed1e5624f6..eee5041e35 100644 --- a/docs/guides/redis/restart/restart.md +++ b/docs/guides/redis/restart/restart.md @@ -25,9 +25,9 @@ KubeDB supports restarting a Redis/Valkey database via a `RedisOpsRequest`. Rest - To keep things isolated, this tutorial uses a namespace called `demo`. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The YAML files used in this tutorial are stored in the [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in the GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -60,14 +60,15 @@ spec: Let’s create the `Redis` custom resource (CR) shown above: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/restart/redis.yaml -redis.kubedb.com/redis-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/restart/redis.yaml ``` +redis.kubedb.com/redis-cluster created Once the Redis cluster is created, you can check the pods created: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=redis-cluster -w +kubectl get pods -n demo -l app.kubernetes.io/instance=redis-cluster -w +``` NAME READY STATUS RESTARTS AGE redis-cluster-shard0-0 1/1 Running 0 19h redis-cluster-shard0-1 1/1 Running 0 19h @@ -75,7 +76,6 @@ redis-cluster-shard1-0 1/1 Running 0 19h redis-cluster-shard1-1 1/1 Running 0 19h redis-cluster-shard2-0 1/1 Running 0 19h redis-cluster-shard2-1 1/1 Running 0 19h -``` ## Apply Restart OpsRequest @@ -101,9 +101,9 @@ spec: Let’s create the `RedisOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/restart/restart.yaml -RedisOpsRequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/restart/restart.yaml ``` +RedisOpsRequest.ops.kubedb.com/restart created ### Restart Process for Redis Cluster @@ -118,11 +118,14 @@ This ensures high availability and minimal disruption during the restart. You can check the status of the `RedisOpsRequest` to confirm the restart operation: ```bash -$ kubectl get rdops -n demo +kubectl get rdops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 6m51s -$ kubectl get rdops -n demo restart -o yaml +```bash +kubectl get rdops -n demo restart -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: RedisOpsRequest metadata: @@ -223,16 +226,20 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning Up To clean up the Kubernetes resources created in this tutorial, run: ```bash -$ kubectl delete rdops -n demo restart -$ kubectl delete redis -n demo redis-cluster -$ kubectl delete ns demo +kubectl delete rdops -n demo restart +``` + +```bash +kubectl delete redis -n demo redis-cluster +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/redis/rotateauth/rotateauth.md b/docs/guides/redis/rotateauth/rotateauth.md index c4f8c53fb0..f8310c060c 100644 --- a/docs/guides/redis/rotateauth/rotateauth.md +++ b/docs/guides/redis/rotateauth/rotateauth.md @@ -26,21 +26,23 @@ section_menu_id: guides - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 4h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create namespace demo + kubectl create namespace demo + ``` namespace/demo created - $ kubectl get namespaces + ```bash + kubectl get namespaces + ``` NAME STATUS AGE demo Active 10s - ``` > Note: The yaml files used in this tutorial are stored in [docs/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -70,17 +72,17 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1.yaml -redis.kubedb.com/redis-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/quickstart/demo-v1.yaml ``` +redis.kubedb.com/redis-quickstart created Now, wait until redis-quickstart has status Ready. i.e, -```shell -$ kubectl get rd -n demo -w +```bash +kubectl get rd -n demo -w +``` NAME VERSION STATUS AGE redis-quickstart 6.2.14 Ready 74m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the Secret. @@ -117,19 +119,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Redis. Let's create the `RedisOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rotate-auth/Redis-rotate-auth-generated.yaml -redisopsrequest.ops.kubedb.com/rdops-rotate-auth-generated created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rotate-auth/Redis-rotate-auth-generated.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-rotate-auth-generated created Let's wait for `RedisOpsrequest` to be `Successful`. Run the following command to watch `RedisOpsrequest` CRO -```shell - $ kubectl get rdops -n demo -w + ```bash + kubectl get rdops -n demo -w + ``` NAME TYPE STATUS AGE rdops-rotate-auth-generated RotateAuth Successful 45s -``` If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Redisopsrequest -n demo rdops-rotate-auth-generated +```bash +kubectl describe Redisopsrequest -n demo rdops-rotate-auth-generated +``` Name: rdops-rotate-auth-generated Namespace: demo Labels: @@ -214,37 +217,44 @@ Events: Normal ResumeDatabase 3m27s KubeDB Ops-manager Operator Resuming Redis demo/redis-quickstart Normal ResumeDatabase 3m27s KubeDB Ops-manager Operator Successfully resumed Redis demo/redis-quickstart Normal Successful 3m27s KubeDB Ops-manager Operator Succesfully Rotated Auth for Redis - -``` **Verify Auth is rotated** -```shell -$ kubectl get rd -n demo redis-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get rd -n demo redis-quickstart -ojson | jq .spec.authSecret.name +``` "redis-quickstart-auth" -$ kubectl get secret -n demo redis-quickstart-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo redis-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` default⏎ -$ kubectl get secret -n demo redis-quickstart-auth -o jsonpath='{.data.password}' | base64 -d -jGPx0DDKaOb6hWAb⏎ + +```bash +kubectl get secret -n demo redis-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` +jGPx0DDKaOb6hWAb⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo redis-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo redis-quickstart-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` default⏎ -$ kubectl get secret -n demo redis-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -nAiZo)pGW1f!se*2⏎ + +```bash +kubectl get secret -n demo redis-quickstart-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +nAiZo)pGW1f!se*2⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, -```shell -$ kubectl create secret generic redis-quickstart-user-auth -n demo \ +```bash +kubectl create secret generic redis-quickstart-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=admin \ --from-literal=password=Redis-secret - secret/redis-quickstart-user-auth created ``` + secret/redis-quickstart-user-auth created Now create a `RedisOpsRequest` with `RotateAuth` type. Below is the YAML of the `RedisOpsRequest` that we are going to create, ```shell @@ -272,21 +282,22 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rotate-auth/rotate-auth-user.yaml -redisopsrequest.ops.kubedb.com/rdops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rotate-auth/rotate-auth-user.yaml ``` +redisopsrequest.ops.kubedb.com/rdops-rotate-auth-user created Let’s wait for `RedisOpsRequest` to be Successful. Run the following command to watch `RedisOpsRequest` CRO: -```shell -$ kubectl get rdops -n demo -w +```bash +kubectl get rdops -n demo -w +``` NAME TYPE STATUS AGE rdops-rotate-auth-generated RotateAuth Successful 6m39s rdops-rotate-auth-user RotateAuth Successful 46s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. If we describe the `RedisOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Redisopsrequest -n demo rdops-rotate-auth-user +```bash +kubectl describe Redisopsrequest -n demo rdops-rotate-auth-user +``` Name: rdops-rotate-auth-user Namespace: demo Labels: @@ -374,24 +385,31 @@ Events: Normal ResumeDatabase 69s KubeDB Ops-manager Operator Resuming Redis demo/redis-quickstart Normal ResumeDatabase 69s KubeDB Ops-manager Operator Successfully resumed Redis demo/redis-quickstart Normal Successful 69s KubeDB Ops-manager Operator Succesfully Rotated Auth for Redis - -``` **Verify auth is rotate** -```shell -$ kubectl get rd -n demo redis-quickstart -ojson | jq .spec.authSecret.name +```bash +kubectl get rd -n demo redis-quickstart -ojson | jq .spec.authSecret.name +``` "redis-quickstart-user-auth" -$kubectl get secret -n demo redis-quickstart-user-auth -o=jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo redis-quickstart-user-auth -o=jsonpath='{.data.username}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo redis-quickstart-user-auth -o=jsonpath='{.data.password}' | base64 -d -Redis-secret⏎ + +```bash +kubectl get secret -n demo redis-quickstart-user-auth -o=jsonpath='{.data.password}' | base64 -d ``` +Redis-secret⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo redis-quickstart-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo redis-quickstart-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` default⏎ -$ kubectl get secret -n demo redis-quickstart-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -jGPx0DDKaOb6hWAb⏎ + +```bash +kubectl get secret -n demo redis-quickstart-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +jGPx0DDKaOb6hWAb⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -400,14 +418,20 @@ The above output shows that the password has been changed successfully. The prev To clean up the Kubernetes resources you can delete the CRD or namespace. Or, you can delete one by one resource by their name by this tutorial, run: -```shell -$ kubectl delete Redisopsrequest rdops-rotate-auth-generated rdops-rotate-auth-user -n demo +```bash +kubectl delete Redisopsrequest rdops-rotate-auth-generated rdops-rotate-auth-user -n demo +``` Redisopsrequest.ops.kubedb.com "rdops-rotate-auth-generated" "rdops-rotate-auth-user" deleted -$ kubectl delete secret -n demo redis-quickstart-user-auth + +```bash +kubectl delete secret -n demo redis-quickstart-user-auth +``` secret "redis-quickstart-user-auth" deleted -$ kubectl delete secret -n demo redis-quickstart-auth -secret "redis-quickstart-auth" deleted + +```bash +kubectl delete secret -n demo redis-quickstart-auth ``` +secret "redis-quickstart-auth" deleted ## Next Steps diff --git a/docs/guides/redis/scaling/horizontal-scaling/cluster.md b/docs/guides/redis/scaling/horizontal-scaling/cluster.md index 8ee2c959a0..66510335b5 100644 --- a/docs/guides/redis/scaling/horizontal-scaling/cluster.md +++ b/docs/guides/redis/scaling/horizontal-scaling/cluster.md @@ -31,9 +31,9 @@ This guide will give an overview on how KubeDB Ops-manager operator scales up or To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -75,37 +75,42 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/rd-cluster.yaml -redis.kubedb.com/redis-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/rd-cluster.yaml ``` +redis.kubedb.com/redis-cluster created Now, wait until `rd-cluster` has status `Ready`. i.e. , ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE redis-cluster 6.2.14 Ready 7m -``` Let's check the number of shards and replicas this database has from the Redis object ```bash -$ kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.shards' +kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.shards' +``` 3 -$ kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.replicas' -2 + +```bash +kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.replicas' ``` +2 Now let's connect to redis-cluster using `redis-cli` and verify master and replica count of the cluster ```bash -$ kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +``` 914e68b97816a9aae0ee90e68b918a096baf479b 10.244.0.159:6379@16379 myself,master - 0 1675770134000 1 connected 0-5460 a70923f477d7b37ce3c0beb7ed891f6501ac48ef 10.244.0.165:6379@16379 master - 0 1675770134111 3 connected 10923-16383 94ee446e08494f1c5c826e03151dd1889585140e 10.244.0.162:6379@16379 master - 0 1675770134813 2 connected 5461-10922 -$ kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l -3 +```bash +kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l ``` +3 We can see from above output that there are 3 masters and each master has 2 replicas. So, total 6 replicas in the cluster. Each master and its two replicas belongs to a shard. @@ -144,9 +149,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-cluster.yaml -redisopsrequest.ops.kubedb.com/redisops-horizontal created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-cluster.yaml ``` +redisopsrequest.ops.kubedb.com/redisops-horizontal created #### Verify Redis Cluster resources updated successfully @@ -155,31 +160,36 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas a Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo redisops-horizontal +watch kubectl get redisopsrequest -n demo redisops-horizontal +``` NAME TYPE STATUS AGE redisops-horizontal HorizontalScaling Successful 6m11s -``` Now, we are going to verify if the number of shards and replicas the redis cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.shards' +kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.shards' +``` 4 -$ kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.replicas' -1 + +```bash +kubectl get redis -n demo redis-cluster -o json | jq '.spec.cluster.replicas' ``` +1 Now let's connect to redis-cluster using `redis-cli` and verify master and replica count of the cluster ```bash -$ kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +``` 94a9278454d934d4b5058d3e49b4bca14ff88975 10.244.0.176:6379@16379 master - 0 1675770403000 6 connected 0-1364 5461-6826 10923-12287 914e68b97816a9aae0ee90e68b918a096baf479b 10.244.0.159:6379@16379 myself,master - 0 1675770403000 1 connected 1365-5460 a70923f477d7b37ce3c0beb7ed891f6501ac48ef 10.244.0.165:6379@16379 master - 0 1675770404571 3 connected 12288-16383 94ee446e08494f1c5c826e03151dd1889585140e 10.244.0.162:6379@16379 master - 0 1675770403667 2 connected 6827-10922 -$ kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l -4 +```bash +kubectl exec -it -n demo redis-cluster-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l ``` +4 The above output verifies that we have successfully scaled up the shards and scaled down the replicas of the Redis cluster database. The slots in redis shard is also distributed among 4 master. @@ -189,13 +199,16 @@ is also distributed among 4 master. To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-cluster patched -$ kubectl delete -n demo redis redis-cluster +```bash +kubectl delete -n demo redis redis-cluster +``` redis.kubedb.com "redis-cluster" deleted -$ kubectl delete -n demo redisopsrequest redisops-horizontal -redisopsrequest.ops.kubedb.com "redisops-horizontal " deleted -``` \ No newline at end of file +```bash +kubectl delete -n demo redisopsrequest redisops-horizontal +``` +redisopsrequest.ops.kubedb.com "redisops-horizontal " deleted \ No newline at end of file diff --git a/docs/guides/redis/scaling/horizontal-scaling/external-connection.md b/docs/guides/redis/scaling/horizontal-scaling/external-connection.md index 3456411cd7..519d825faa 100644 --- a/docs/guides/redis/scaling/horizontal-scaling/external-connection.md +++ b/docs/guides/redis/scaling/horizontal-scaling/external-connection.md @@ -40,22 +40,27 @@ Deploy `Redis/Valkey` cluster as shown in [External Connection Exposer](/docs/gu After it gets `Ready` check the number of shards and replicas this database has from the Redis object ```bash -$ kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.shards' +kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.shards' +``` 3 -$ kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.replicas' -2 + +```bash +kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.replicas' ``` +2 Now let's connect to redis-cluster using `redis-cli` and verify master and replica count of the cluster ```bash -$ kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +``` fc7c635c745b8c74c4422300e945eadb4251add6 10.2.0.87:10050@10056,rd0-0.kubedb.appscode myself,master - 0 1754481552000 1 connected 0-5460 e45749edaf324b980bbf5148644d500d6842ff5c 10.2.0.87:10054@10060,rd0-0.kubedb.appscode master - 0 1754481555065 3 connected 10923-16383 673060b3b589f06fe6a12e6f47ea8910042b6be6 10.2.0.87:10052@10058,rd0-0.kubedb.appscode master - 0 1754481555000 2 connected 5461-10922 -$ kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l -6 +```bash +kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l ``` +6 We can see from above output that there are 3 masters and each master has 2 replicas. So, total 6 replicas in the cluster. Each master and its two replicas belongs to a shard. @@ -107,9 +112,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-cluster.yaml -redisopsrequest.ops.kubedb.com/redisops-horizontal-external created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-cluster.yaml ``` +redisopsrequest.ops.kubedb.com/redisops-horizontal-external created #### Verify Redis Cluster resources updated successfully @@ -120,40 +125,45 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas a Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo redisops-horizontal-external +watch kubectl get redisopsrequest -n demo redisops-horizontal-external +``` NAME TYPE STATUS AGE redisops-horizontal-external HorizontalScaling Successful 3m8s -``` Now, we are going to verify if the number of shards and replicas the redis cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.shards' +kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.shards' +``` 4 -$ kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.replicas' -3 + +```bash +kubectl get redis -n demo redis-announce -o json | jq '.spec.cluster.replicas' ``` +3 Let's wait for the new `Announce` opsRequest to be created and Successful ```bash -$ watch kubectl get rdops -n demo +watch kubectl get rdops -n demo +``` NAME TYPE STATUS AGE rd-at86h7 Announce Successful 2m redisops-horizontal-external HorizontalScaling Successful 4m -``` Now let's connect to redis-announce using `redis-cli` and verify master and replica count of the cluster ```bash -$ kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep master +``` fc7c635c745b8c74c4422300e945eadb4251add6 10.2.0.87:10050@10056,rd0-0.kubedb.appscode myself,master - 0 1754484135000 1 connected 1365-5460 039d9b38874ee6dca807836646bbdc8b25f544d5 10.2.0.87:10065@10071,rd0-0.kubedb.appscode master - 0 1754484137945 4 connected 0-1364 5461-6826 10923-12287 e45749edaf324b980bbf5148644d500d6842ff5c 10.2.0.87:10054@10060,rd0-0.kubedb.appscode master - 0 1754484137000 3 connected 12288-16383 673060b3b589f06fe6a12e6f47ea8910042b6be6 10.2.0.87:10052@10058,rd0-0.kubedb.appscode master - 0 1754484136539 2 connected 6827-10922 -$ kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l -12 +```bash +kubectl exec -it -n demo redis-announce-shard0-0 -c redis -- redis-cli -c cluster nodes | grep slave | wc -l ``` +12 The above output verifies that we have successfully scaled up the shards and scaled down the replicas of the Redis cluster database. The slots in redis shard is also distributed among 4 master. @@ -163,14 +173,17 @@ is also distributed among 4 master. To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo rd/redis-announce -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-announce -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-announce patched -$ kubectl delete -n demo redis redis-announce +```bash +kubectl delete -n demo redis redis-announce +``` redis.kubedb.com "redis-announce" deleted -$ kubectl delete -n demo redisopsrequest redisops-horizontal-external rd-at86h7 +```bash +kubectl delete -n demo redisopsrequest redisops-horizontal-external rd-at86h7 +``` redisopsrequest.ops.kubedb.com "redisops-horizontal-external" deleted -redisopsrequest.ops.kubedb.com "rd-at86h7" deleted -``` \ No newline at end of file +redisopsrequest.ops.kubedb.com "rd-at86h7" deleted \ No newline at end of file diff --git a/docs/guides/redis/scaling/horizontal-scaling/sentinel.md b/docs/guides/redis/scaling/horizontal-scaling/sentinel.md index 661fc7ce24..76a08c1f7d 100644 --- a/docs/guides/redis/scaling/horizontal-scaling/sentinel.md +++ b/docs/guides/redis/scaling/horizontal-scaling/sentinel.md @@ -31,9 +31,9 @@ This guide will give an overview on how KubeDB Ops-manager operator scales up or To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -68,24 +68,24 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/sentinel.yaml -redissentinel.kubedb.com/sen-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/sentinel.yaml ``` +redissentinel.kubedb.com/sen-sample created Now, wait until `sen-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-sample 6.2.14 Ready 5m20s -``` Let's check the number of replicas this sentinel has from the RedisSentinel object ```bash -$ kubectl get redissentinel -n demo sen-sample -o json | jq '.spec.replicas' -5 +kubectl get redissentinel -n demo sen-sample -o json | jq '.spec.replicas' ``` +5 ### Deploy Redis : @@ -118,26 +118,27 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/rd-sentinel.yaml -redis.kubedb.com/rd-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/rd-sentinel.yaml ``` +redis.kubedb.com/rd-sample created Now, wait until `rd-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE rd-sample 6.2.14 Ready 2m11s -``` Let's check the Pod containers resources, ```bash -$ kubectl get redis -n demo rd-sample -o json | jq '.spec.replicas' -3 +kubectl get redis -n demo rd-sample -o json | jq '.spec.replicas' ``` +3 Now let's connect to redis with redis-cli to check the replication configuration ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- redis-cli info replication +kubectl exec -it -n demo rd-sample-0 -c redis -- redis-cli info replication +``` # Replication role:master connected_slaves:2 @@ -152,7 +153,6 @@ repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:35492 -``` Additionally, the sentinel monitoring can be checked with following command : ```bash @@ -192,9 +192,9 @@ Here, Let's create the `RedisSentinelOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-sentinel.yaml -redissentinelopsrequest.ops.kubedb.com/sen-ops-horizontal created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling/horizontal-sentinel.yaml ``` +redissentinelopsrequest.ops.kubedb.com/sen-ops-horizontal created #### Verify RedisSentinel replicas updated successfully : @@ -203,20 +203,20 @@ If everything goes well, `KubeDB` Enterprise operator will scale down the replic Let's wait for `RedisSentinelOpsRequest` to be `Successful`. Run the following command to watch `RedisSentinelOpsRequest` CR, ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE sen-ops-horizontal HorizontalScaling Successful 5m27s -``` We can see from the above output that the `RedisSentinelOpsRequest` has succeeded. Let's check the number of replicas this database has from the RedisSentinel object ```bash -$ kubectl get redissentinel -n demo sen-sample -o json | jq '.spec.replicas' -3 +kubectl get redissentinel -n demo sen-sample -o json | jq '.spec.replicas' ``` +3 The above output verifies that we have successfully scaled up the resources of the sentinel instance. ### Horizontal Scale Redis @@ -250,9 +250,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling//horizontal-redis-sentinel.yaml -redisopsrequest.ops.kubedb.com/rd-ops-horizontal created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/horizontal-scaling//horizontal-redis-sentinel.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-horizontal created #### Verify Redis resources updated successfully : @@ -261,22 +261,23 @@ If everything goes well, `KubeDB` Enterprise operator will scale up the replicas Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` NAME TYPE STATUS AGE rd-ops-horizontal HorizontalScaling Successful 4m4s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify if the number of replicas the redis sentinel has updated to meet up the desired state, Let's check, ```bash -$ kubectl get redis -n demo rd-sample -o json | jq '.spec.replicas' -5 +kubectl get redis -n demo rd-sample -o json | jq '.spec.replicas' ``` +5 Now let's connect to redis with redis-cli to check the replication configuration ```bash -$ kubectl exec -it -n demo rd-sample-0 -c redis -- redis-cli info replication +kubectl exec -it -n demo rd-sample-0 -c redis -- redis-cli info replication +``` # Replication role:master connected_slaves:4 @@ -293,7 +294,6 @@ repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1 repl_backlog_histlen:325651 -``` The above output verifies that we have successfully scaled up the resources of the redis database. There are 1 master and 4 connected slaves. So, the Ops Request scaled up the replicas to 5. @@ -307,24 +307,34 @@ kubectl exec -it -n demo sen-sample-0 -c redissentinel -- redis-cli -p 26379 sen To clean up the Kubernetes resources created by this tutorial, run: -```bash # Delete Redis and RedisOpsRequest -$ kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-sample patched -$ kubectl delete -n demo redis rd-sample +```bash +kubectl delete -n demo redis rd-sample +``` redis.kubedb.com "rd-sample" deleted -$ kubectl delete -n demo redisopsrequest rd-ops-horizontal +```bash +kubectl delete -n demo redisopsrequest rd-ops-horizontal +``` redisopsrequest.ops.kubedb.com "rd-ops-horizontal" deleted # Delete RedisSentinel and RedisSentinelOpsRequest -$ kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-sample patched -$ kubectl delete -n demo redissentinel sen-sample +```bash +kubectl delete -n demo redissentinel sen-sample +``` redissentinel.kubedb.com "sen-sample" deleted -$ kubectl delete -n demo redissentinelopsrequests sen-ops-horizontal -redissentinelopsrequest.ops.kubedb.com "sen-ops-horizontal" deleted +```bash +kubectl delete -n demo redissentinelopsrequests sen-ops-horizontal ``` +redissentinelopsrequest.ops.kubedb.com "sen-ops-horizontal" deleted diff --git a/docs/guides/redis/scaling/vertical-scaling/cluster.md b/docs/guides/redis/scaling/vertical-scaling/cluster.md index 83cc5c5fe2..eb55b4fdc3 100644 --- a/docs/guides/redis/scaling/vertical-scaling/cluster.md +++ b/docs/guides/redis/scaling/vertical-scaling/cluster.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -82,22 +82,23 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-cluster.yaml -redis.kubedb.com/redis-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-cluster.yaml ``` +redis.kubedb.com/redis-cluster created Now, wait until `rd-cluster` has status `Ready`. i.e. , ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE redis-cluster 7.0.14 Ready 7m -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "100Mi" @@ -108,7 +109,9 @@ $ kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[ } } -$ kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "100Mi" @@ -118,7 +121,6 @@ $ kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[ "memory": "100Mi" } } -``` We can see from the above output that there are some default resources set by the operator for pods across all shards. And the scheduler will choose the best suitable node to place the container of the Pod. @@ -163,9 +165,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-cluster.yaml -redisopsrequest.ops.kubedb.com/redisops-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-cluster.yaml ``` +redisopsrequest.ops.kubedb.com/redisops-vertical created #### Verify Redis Cluster resources updated successfully @@ -174,17 +176,18 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo redisops-vertical +watch kubectl get redisopsrequest -n demo redisops-vertical +``` NAME TYPE STATUS AGE redisops-vertical VerticalScaling Successful 6m11s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the Pod yaml whether the resources of the cluster database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -195,7 +198,10 @@ $ kubectl get pod -n demo redis-cluster-shard0-0 -o json | jq '.spec.containers[ "memory": "300Mi" } } -$ kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -206,7 +212,6 @@ $ kubectl get pod -n demo redis-cluster-shard1-1 -o json | jq '.spec.containers[ "memory": "300Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the Redis cluster database. @@ -215,13 +220,16 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this turorial, run: ```bash - -$ kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-cluster patched -$ kubectl delete -n demo redis redis-cluster +```bash +kubectl delete -n demo redis redis-cluster +``` redis.kubedb.com "redis-cluster" deleted -$ kubectl delete -n demo redisopsrequest redisops-vertical -redisopsrequest.ops.kubedb.com "redisops-vertical " deleted -``` \ No newline at end of file +```bash +kubectl delete -n demo redisopsrequest redisops-vertical +``` +redisopsrequest.ops.kubedb.com "redisops-vertical " deleted \ No newline at end of file diff --git a/docs/guides/redis/scaling/vertical-scaling/sentinel.md b/docs/guides/redis/scaling/vertical-scaling/sentinel.md index 1efbc79930..518bf57802 100644 --- a/docs/guides/redis/scaling/vertical-scaling/sentinel.md +++ b/docs/guides/redis/scaling/vertical-scaling/sentinel.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to perform vert To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -76,21 +76,22 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/sentinel.yaml -redissentinel.kubedb.com/sen-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/sentinel.yaml ``` +redissentinel.kubedb.com/sen-sample created Now, wait until `sen-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-sample 6.2.14 Ready 5m20s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "100Mi" @@ -100,7 +101,6 @@ $ kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resource "memory": "100Mi" } } -``` ### Deploy Redis : @@ -141,20 +141,21 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-sentinel.yaml -redis.kubedb.com/rd-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-sentinel.yaml ``` +redis.kubedb.com/rd-sample created Now, wait until `rd-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE rd-sample 6.2.14 Ready 2m11s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "100Mi" @@ -164,7 +165,6 @@ $ kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources "memory": "100Mi" } } -``` We are now ready to apply the `RedisSentinelOpsRequest` CR to vertical scale on sentinel and `RedisOpsRequest` CR to vertical scale database. @@ -206,9 +206,9 @@ Here, Let's create the `RedisSentinelOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-sentinel.yaml -redissentinelopsrequest.ops.kubedb.com/sen-ops-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-sentinel.yaml ``` +redissentinelopsrequest.ops.kubedb.com/sen-ops-vertical created #### Verify RedisSentinel resources updated successfully : @@ -217,18 +217,19 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisSentinelOpsRequest` to be `Successful`. Run the following command to watch `RedisSentinelOpsRequest` CR, ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE sen-ops-vertical VerticalScaling Successful 5m27s -``` We can see from the above output that the `RedisSentinelOpsRequest` has succeeded. Now, we are going to verify from the Pod yaml whether the resources of the sentinel has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -239,7 +240,6 @@ $ kubectl get pod -n demo sen-sample-0 -o json | jq '.spec.containers[].resource "memory": "300Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the sentinel instance. ### Vertical Scale Redis @@ -280,9 +280,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-redis-sentinel.yaml -redisopsrequest.ops.kubedb.com/rd-ops-vertical created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-redis-sentinel.yaml ``` +redisopsrequest.ops.kubedb.com/rd-ops-vertical created #### Verify Redis resources updated successfully : @@ -291,16 +291,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` NAME TYPE STATUS AGE rd-ops-vertical VerticalScaling Successful 4m4s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources' +``` {} { "limits": { @@ -312,31 +313,40 @@ $ kubectl get pod -n demo rd-sample-0 -o json | jq '.spec.containers[].resources "memory": "300Mi" } } -``` The above output verifies that we have successfully scaled up the resources of the redis database. ## Cleaning Up To clean up the Kubernetes resources created by this tutorial, run: -```bash # Delete Redis and RedisOpsRequest -$ kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-sample patched -$ kubectl delete -n demo redis rd-sample +```bash +kubectl delete -n demo redis rd-sample +``` redis.kubedb.com "rd-sample" deleted -$ kubectl delete -n demo redisopsrequest rd-ops-vertical +```bash +kubectl delete -n demo redisopsrequest rd-ops-vertical +``` redisopsrequest.ops.kubedb.com "rd-ops-vertical" deleted # Delete RedisSentinel and RedisSentinelOpsRequest -$ kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-sample patched -$ kubectl delete -n demo redissentinel sen-sample +```bash +kubectl delete -n demo redissentinel sen-sample +``` redissentinel.kubedb.com "sen-sample" deleted -$ kubectl delete -n demo redissentinelopsrequests sen-ops-vertical -redissentinelopsrequest.ops.kubedb.com "sen-ops-vertical" deleted +```bash +kubectl delete -n demo redissentinelopsrequests sen-ops-vertical ``` +redissentinelopsrequest.ops.kubedb.com "sen-ops-vertical" deleted diff --git a/docs/guides/redis/scaling/vertical-scaling/standalone.md b/docs/guides/redis/scaling/vertical-scaling/standalone.md index 0157241bc6..2ddfe4aedd 100644 --- a/docs/guides/redis/scaling/vertical-scaling/standalone.md +++ b/docs/guides/redis/scaling/vertical-scaling/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -77,22 +77,23 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-standalone.yaml -redis.kubedb.com/redis-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/rd-standalone.yaml ``` +redis.kubedb.com/redis-quickstart created Now, wait until `rd-quickstart` has status `Ready`. i.e. , ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE redis-quickstart 6.2.14 Ready 2m30s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "100Mi" @@ -102,7 +103,6 @@ $ kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].re "memory": "100Mi" } } -``` We can see from the above output that there are some default resources set by the operator. And the scheduler will choose the best suitable node to place the container of the Pod. @@ -146,9 +146,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-standalone.yaml -redisopsrequest.ops.kubedb.com/redisopsstandalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/scaling/vertical-scaling/vertical-standalone.yaml ``` +redisopsrequest.ops.kubedb.com/redisopsstandalone created #### Verify Redis Standalone resources updated successfully @@ -157,16 +157,17 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo redisopsstandalone +watch kubectl get redisopsrequest -n demo redisopsstandalone +``` NAME TYPE STATUS AGE redisopsstandalone VerticalScaling Successful 26s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the Pod yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "500m", @@ -178,8 +179,6 @@ $ kubectl get pod -n demo redis-quickstart-0 -o json | jq '.spec.containers[].re } } -``` - The above output verifies that we have successfully scaled up the resources of the Redis standalone database. ## Cleaning up @@ -187,13 +186,16 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this turorial, run: ```bash - -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-quickstart patched -$ kubectl delete -n demo redis redis-quickstart +```bash +kubectl delete -n demo redis redis-quickstart +``` redis.kubedb.com "redis-quickstart" deleted -$ kubectl delete redisopsrequest -n demo redisopsstandalone -redisopsrequest.ops.kubedb.com "redisopsstandalone" deleted -``` \ No newline at end of file +```bash +kubectl delete redisopsrequest -n demo redisopsstandalone +``` +redisopsrequest.ops.kubedb.com "redisopsstandalone" deleted \ No newline at end of file diff --git a/docs/guides/redis/sentinel/redis-sentinel.md b/docs/guides/redis/sentinel/redis-sentinel.md index 0eefce58c6..d76de748d6 100644 --- a/docs/guides/redis/sentinel/redis-sentinel.md +++ b/docs/guides/redis/sentinel/redis-sentinel.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -61,9 +61,9 @@ spec: deletionPolicy: WipeOut ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/sentinel.yaml -redissentinel.kubedb.com/sen-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/sentinel.yaml ``` +redissentinel.kubedb.com/sen-demo created Here, - `spec.replicas` denotes the number of replica nodes @@ -102,9 +102,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/redis.yaml -redis.kubedb.com/rd-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/redis.yaml ``` +redis.kubedb.com/rd-demo created Here, @@ -115,21 +115,27 @@ Here, KubeDB operator watches for `Redis` objects using Kubernetes API. When a `Redis` object is created, KubeDB operator will create a new PetSet and a Service with the matching Redis object name. KubeDB operator will also create a governing service for PetSets named `kubedb`, if one is not already present. ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-demo 6.2.14 Ready 2m39 -$ kubectl get redis -n demo +```bash +kubectl get redis -n demo +``` NAME VERSION STATUS AGE rd-demo 6.2.14 Ready 2m41s -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME READY AGE rd-demo 3/3 86s sen-demo 3/3 12m - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-rd-demo-0 Bound pvc-830fb301-512a-4de9-a110-c0ce032fabca 1Gi RWO standard 99s data-rd-demo-1 Bound pvc-0bc06618-a7ef-42ef-b2a0-4e5563d68df7 1Gi RWO standard 93s @@ -138,8 +144,9 @@ data-sen-demo-0 Bound pvc-c55d804e-67e1-431c-92a6-67bdde14f59c 1Gi data-sen-demo-1 Bound pvc-171e7d75-c423-4c7f-aabd-42ce50cd0ff4 1Gi RWO standard 12m data-sen-demo-2 Bound pvc-2886e192-845b-4b44-89e0-20c2af64ec47 1Gi RWO standard 12m - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-0bc06618-a7ef-42ef-b2a0-4e5563d68df7 1Gi RWO Delete Bound demo/data-rd-demo-1 standard 111s pvc-171e7d75-c423-4c7f-aabd-42ce50cd0ff4 1Gi RWO Delete Bound demo/data-sen-demo-1 standard 13m @@ -148,21 +155,21 @@ pvc-830fb301-512a-4de9-a110-c0ce032fabca 1Gi RWO Delete pvc-99aebc54-c016-4376-a3a3-25f882ae86e7 1Gi RWO Delete Bound demo/data-rd-demo-2 standard 104s pvc-c55d804e-67e1-431c-92a6-67bdde14f59c 1Gi RWO Delete Bound demo/data-sen-demo-0 standard 13m - -$ kubectl get svc -n demo +```bash +kubectl get svc -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rd-demo ClusterIP 10.96.165.208 6379/TCP 2m40s rd-demo-pods ClusterIP None 6379/TCP 2m40s rd-demo-standby ClusterIP 10.96.193.56 6379/TCP 2m40s sen-demo ClusterIP 10.96.249.99 26379/TCP 14m sen-demo-pods ClusterIP None 26379/TCP 14m -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. `status.phase` section is similar for `Redis` object and `RedisSentinel` object. Run the following command to see the modified `RedisSentinel` object: ```bash -$ kubectl get redissentinel -n demo sen-demo -o yaml +kubectl get redissentinel -n demo sen-demo -o yaml ``` ```yaml apiVersion: kubedb.com/v1 @@ -257,16 +264,16 @@ status: - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo rd-demo-auth -o jsonpath='{.data.username}' | base64 -d - default + kubectl get secrets -n demo rd-demo-auth -o jsonpath='{.data.username}' | base64 -d ``` + default - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo rd-demo-auth -o jsonpath='{.data.password}' | base64 -d - 5VjZ7iYaoo8YRp!p + kubectl get secrets -n demo rd-demo-auth -o jsonpath='{.data.password}' | base64 -d ``` + 5VjZ7iYaoo8YRp!p Now, you can connect to this redis database using the service using the credentials. ### Connect to Sentinel @@ -277,29 +284,32 @@ Now, you can connect to this redis database using the service using the credenti - Username: Run following command to get _username_, ```bash - $ kubectl get secrets -n demo sen-demo-auth -o jsonpath='{.data.username}' | base64 -d - root + kubectl get secrets -n demo sen-demo-auth -o jsonpath='{.data.username}' | base64 -d ``` + root - Password: Run the following command to get _password_, ```bash - $ kubectl get secrets -n demo sen-demo-auth -o jsonpath='{.data.password}' | base64 -d - Gw_sd;~Vrsj9kJSL + kubectl get secrets -n demo sen-demo-auth -o jsonpath='{.data.password}' | base64 -d ``` + Gw_sd;~Vrsj9kJSL Now, you can connect to this sentinel using the service using the credentials. ## Check Replication Scenario -```bash # first list the redis pods list -$ kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep rd-demo +```bash +kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep rd-demo +``` rd-demo-0 ---------- 10.244.0.70:6379 rd-demo-1 ---------- 10.244.0.72:6379 rd-demo-2 ---------- 10.244.0.74:6379 # enter into any pod's container named redis -$ kubectl exec -it -n demo rd-demo-0 -c redis -- bash +```bash +kubectl exec -it -n demo rd-demo-0 -c redis -- bash +``` /data # # now inside this container, see which role of this pod @@ -316,7 +326,6 @@ second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset -``` So, the node rd-demo-0 is master, and it has two connected slaves. If a replica node is being exec, it will show which master it is connected to. ## Check Sentinel Monitoring @@ -325,13 +334,16 @@ A sentinel can monitor multiple masters. Sentinel stores information about maste operation when master fail to respond. Sentinel pings master recurrently after a certain period a time. ```bash -$ kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep sen-demo +kubectl get pods --all-namespaces -o jsonpath='{range.items[*]}{.metadata.name} ---------- {.status.podIP}:6379{"\\n"}{end}' | grep sen-demo +``` sen-demo-0 ---------- 10.244.0.46:6379 sen-demo-1 ---------- 10.244.0.48:6379 sen-demo-2 ---------- 10.244.0.50:6379 -# enter into Sentinel pod's container named redissentinel -$ kubectl exec -it -n demo sen-demo-0 -c redissentinel -- bash +# enter into Sentinel pod's container named redissentinel +```bash +kubectl exec -it -n demo sen-demo-0 -c redissentinel -- bash +``` # now inside this container, see the masters information which this sentinels monitors /data # redis-cli -p 26379 sentinel masters 1) 1) "name" @@ -374,7 +386,6 @@ $ kubectl exec -it -n demo sen-demo-0 -c redissentinel -- bash 38) "5000" 39) "parallel-syncs" 40) "1" -``` It can be seen that the master `rd-demo-0.rd-demo-pods.demo.svc` has two slaves as we deployed Redis with three replicas, and it has two other sentinel instances monitoring it as we have deployed RedisSentinel instance with three replicas as well. @@ -385,10 +396,10 @@ Now, you can connect to this database through [redis-cli](https://redis.io/topic > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash - # connect to any node -$ kubectl exec -it rd-demo-0 -n demo -c redis -- bash +```bash +kubectl exec -it rd-demo-0 -n demo -c redis -- bash +``` /data # # now ensure that you are connected to the 1st pod @@ -408,7 +419,6 @@ OK 10.244.0.145:6379> set apps code (error) READONLY You can't write against a read only replica. 10.244.0.145:6379> exit -``` ## Automatic Failover @@ -418,10 +428,10 @@ as the new replica of the new master. > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # connect to any node and get the master nodes info -$ kubectl exec -it rd-demo-0 -n demo -c redis -- bash - +```bash +kubectl exec -it rd-demo-0 -n demo -c redis -- bash +``` # Check role of the first pod which has IP 10.244.0.70 /data # redis-cli -h 10.244.0.70 info replication | grep role role:master @@ -430,8 +440,9 @@ role:master /data # redis-cli -h 10.244.0.70 debug sleep 120 OK -$ kubectl exec -it rd-demo-0 -n demo -c redis -- bash - +```bash +kubectl exec -it rd-demo-0 -n demo -c redis -- bash +``` # Check role of the first pod which has IP 10.244.0.70 /data # redis-cli -h 10.244.0.70 info replication | grep role role:slave @@ -441,7 +452,6 @@ role:slave role:master /data # exit -``` Notice that 110.244.0.72 is the new master and 10.244.0.70 has become the replica of 10.244.0.72. @@ -451,21 +461,25 @@ First set termination policy to `WipeOut` all the things created by KubeDB opera to clean what you created in this tutorial. ```bash -$ kubectl patch -n demo rd/rd-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/rd-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-demo patched -$ kubectl delete rd rd-demo -n demo -redis.kubedb.com "rd-demo" deleted +```bash +kubectl delete rd rd-demo -n demo ``` +redis.kubedb.com "rd-demo" deleted Now delete the RedisSentinel instance similarly. ```bash -$ kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-demo patched -$ kubectl delete redissentinel sen-demo -n demo -redis.kubedb.com "sen-demo" deleted +```bash +kubectl delete redissentinel sen-demo -n demo ``` +redis.kubedb.com "sen-demo" deleted ## Next Steps diff --git a/docs/guides/redis/sentinel/replacesentinel/replace-sentinel.md b/docs/guides/redis/sentinel/replacesentinel/replace-sentinel.md index 2c5d1414ea..f0a8aac29f 100644 --- a/docs/guides/redis/sentinel/replacesentinel/replace-sentinel.md +++ b/docs/guides/redis/sentinel/replacesentinel/replace-sentinel.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to replace Sent To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -65,17 +65,17 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/sentinel.yaml -redissentinel.kubedb.com/sen-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/sentinel.yaml ``` +redissentinel.kubedb.com/sen-demo created Now, wait until `sen-dmo` has status `Ready`. i.e. , ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-demo 6.2.14 Ready 96s -``` ### Deploy Redis in Sentinel Mode In this section, we are going to deploy a Redis database in Sentinel Mode. @@ -106,9 +106,9 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/redis.yaml -redis.kubedb.com/rd-demo created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/redis.yaml ``` +redis.kubedb.com/rd-demo created Now, wait until `rd-demo` has status `Ready`. i.e. , @@ -119,7 +119,8 @@ rd-demo 6.2.14 Ready 67s Lets exec into a sentinel pod, and make sure sentinel monitors redis master ```bash -$ kubectl exec -it -n demo sen-demo-0 -c redissentinel -- bash +kubectl exec -it -n demo sen-demo-0 -c redissentinel -- bash +``` root@sen-demo-0:/data# redis-cli -p 26379 sentinel masters 1) 1) "name" 2) "demo/rd-demo" @@ -163,7 +164,6 @@ root@sen-demo-0:/data# redis-cli -p 26379 sentinel masters 40) "1" root@sen-demo-0:/data# exit exit -``` ### Replace Sentinel @@ -190,18 +190,18 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/new-sentinel.yaml -redissentinel.kubedb.com/new-sentinel created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/new-sentinel.yaml ``` +redissentinel.kubedb.com/new-sentinel created Now, wait until `new-sentinel` has status `Ready`. i.e. , ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE new-sentinel 6.2.14 Ready 60s sen-demo 6.2.14 Ready 11m -``` Here, we are going to replace `sen-demo` with `new-sentinel` @@ -237,9 +237,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/replace-sentinel.yaml -redisopsrequest.ops.kubedb.com/replace-sentinel created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/sentinel/replace-sentinel.yaml ``` +redisopsrequest.ops.kubedb.com/replace-sentinel created #### Verify Replacement @@ -248,10 +248,10 @@ If everything goes well, `KubeDB` Enterprise operator will update the sentinel o Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` NAME TYPE STATUS AGE replace-sentinel ReplaceSentinel Successful 2m34s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. @@ -260,7 +260,8 @@ Lets exec into one of the new-sentinel pod and verify if it is following the mas database if it exists. ```bash -$ kubectl exec -it -n demo new-sentinel-0 -c redissentinel -- bash +kubectl exec -it -n demo new-sentinel-0 -c redissentinel -- bash +``` root@new-sentinel-0:/data# redis-cli -p 26379 sentinel masters 1) 1) "name" 2) "demo/rd-demo" @@ -304,7 +305,6 @@ root@new-sentinel-0:/data# redis-cli -p 26379 sentinel masters 40) "1" root@new-sentinel-0:/data# exit exit -``` The above output verifies that we have successfully replaced sentinel of Redis database. @@ -314,30 +314,40 @@ First set termination policy to `WipeOut` all the things created by KubeDB opera to clean what you created in this tutorial. ```bash -$ kubectl patch -n demo rd/rd-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/rd-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-demo patched -$ kubectl delete rd rd-demo -n demo +```bash +kubectl delete rd rd-demo -n demo +``` redis.kubedb.com "rd-demo" deleted -$ kubectl delete -n demo redisopsrequest replace-sentinel -redisopsrequest.ops.kubedb.com "replace-sentinel" deleted +```bash +kubectl delete -n demo redisopsrequest replace-sentinel ``` +redisopsrequest.ops.kubedb.com "replace-sentinel" deleted Now delete the RedisSentinel instance similarly. ```bash -$ kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redissentinel/sen-demo -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-demo patched -$ kubectl delete redissentinel sen-demo -n demo +```bash +kubectl delete redissentinel sen-demo -n demo +``` redis.kubedb.com "sen-demo" deleted -$ kubectl patch -n demo redissentinel/new-sentinel -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/new-sentinel -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/new-sentinel patched -$ kubectl delete redissentinel new-sentinel -n demo -redis.kubedb.com "new-sentinel" deleted +```bash +kubectl delete redissentinel new-sentinel -n demo ``` +redis.kubedb.com "new-sentinel" deleted ## Next Steps diff --git a/docs/guides/redis/tls/cluster.md b/docs/guides/redis/tls/cluster.md index 00ddf9547d..e40c6d82e3 100644 --- a/docs/guides/redis/tls/cluster.md +++ b/docs/guides/redis/tls/cluster.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Redis. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,9 +79,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml -issuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml ``` +issuer.cert-manager.io/redis-ca-issuer created ## TLS/SSL encryption in Redis Cluster @@ -116,25 +116,26 @@ spec: ### Deploy Redis Cluster ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-cluster-ssl.yaml -redis.kubedb.com/rd-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-cluster-ssl.yaml ``` +redis.kubedb.com/rd-tls created Now, wait until `rd-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get redis -n demo NAME VERSION STATUS AGE rd-tls 6.2.14 Ready 2m14s -``` ### Verify TLS/SSL in Redis Cluster 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 rd-tls-client-cert +kubectl describe secret -n demo rd-tls-client-cert +``` Name: rd-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -157,13 +158,13 @@ Data ca.crt: 1147 bytes tls.crt: 1127 bytes tls.key: 1679 bytes -``` Now, we can connect using tls-certs as root to connect to the redis and write some data ```bash -$ kubectl exec -it -n demo rd-tls-shard0-0 -c redis -- bash +kubectl exec -it -n demo rd-tls-shard0-0 -c redis -- bash +``` # Trying to connect without tls certificates root@rd-tls-0:/data# redis-cli 127.0.0.1:6379> @@ -177,22 +178,25 @@ root@rd-tls-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs/cl 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> exit -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-tls patched -$ kubectl delete -n demo redis rd-tls +```bash +kubectl delete -n demo redis rd-tls +``` redis.kubedb.com "rd-tls" deleted -$ kubectl delete issuer -n demo redis-ca-issuer -issuer.cert-manager.io "redis-ca-issuer" deleted +```bash +kubectl delete issuer -n demo redis-ca-issuer ``` +issuer.cert-manager.io "redis-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/redis/tls/sentinel.md b/docs/guides/redis/tls/sentinel.md index fc6f5a7667..7fcf6c38be 100644 --- a/docs/guides/redis/tls/sentinel.md +++ b/docs/guides/redis/tls/sentinel.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Redis. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -63,7 +63,7 @@ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.c - Now create a ca-secret using the certificate files you have just generated. The secret should be created in `cert-manager` namespace to create the `ClusterIssuer`. ```bash -$ kubectl create secret tls redis-ca \ +kubectl create secret tls redis-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=cert-manager @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/clusterissuer.yaml -clusterissuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/clusterissuer.yaml ``` +clusterissuer.cert-manager.io/redis-ca-issuer created ## TLS/SSL encryption in Sentinel @@ -117,25 +117,26 @@ spec: ### Deploy Redis in Sentinel Mode ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/sentinel-ssl.yaml -redissentinel.kubedb.com/sen-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/sentinel-ssl.yaml ``` +redissentinel.kubedb.com/sen-tls created Now, wait until `sen-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get redissentinel -n demo +watch kubectl get redissentinel -n demo +``` Every 2.0s: kubectl get redis -n demo NAME VERSION STATUS AGE sen-tls 6.2.14 Ready 111s -``` ### Verify TLS/SSL in Redis in Sentinel Mode 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 sen-tls-client-cert +kubectl describe secret -n demo sen-tls-client-cert +``` Name: sen-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -158,7 +159,6 @@ Data ca.crt: 1147 bytes tls.crt: 1127 bytes tls.key: 1675 bytes -``` ## TLS/SSL encryption in Redis in Sentinel Mode @@ -193,25 +193,26 @@ spec: ### Deploy Redis in Sentinel Mode ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-sentinel.yaml -redis.kubedb.com/rd-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-sentinel.yaml ``` +redis.kubedb.com/rd-tls created Now, wait until `rd-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get redis -n demo NAME VERSION STATUS AGE rd-tls 6.2.14 Ready 2m14s -``` ### Verify TLS/SSL in Redis in Sentinel Mode 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 rd-tls-client-cert +kubectl describe secret -n demo rd-tls-client-cert +``` Name: rd-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -234,14 +235,13 @@ Data tls.key: 1679 bytes ca.crt: 1147 bytes tls.crt: 1127 bytes -``` Now, we can connect using tls-certs connect to the redis and write some data ```bash -$ kubectl exec -it -n demo rd-tls-0 -c redis -- bash - +kubectl exec -it -n demo rd-tls-0 -c redis -- bash +``` # Trying to connect without tls certificates root@rd-tls-0:/data# redis-cli 127.0.0.1:6379> @@ -255,28 +255,35 @@ root@rd-tls-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs/cl 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> exit -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-tls patched -$ kubectl delete -n demo redis rd-tls +```bash +kubectl delete -n demo redis rd-tls +``` redis.kubedb.com "rd-tls" deleted -$ kubectl patch -n demo redissentinel/sen-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/sen-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-tls patched -$ kubectl delete -n demo redissentinel sen-tls +```bash +kubectl delete -n demo redissentinel sen-tls +``` redissentinel.kubedb.com "sen-tls" deleted -$ kubectl delete clusterissuer redis-ca-issuer -clusterissuer.cert-manager.io "redis-ca-issuer" deleted +```bash +kubectl delete clusterissuer redis-ca-issuer ``` +clusterissuer.cert-manager.io "redis-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/redis/tls/standalone.md b/docs/guides/redis/tls/standalone.md index 0767f25f92..e8fb5cb401 100644 --- a/docs/guides/redis/tls/standalone.md +++ b/docs/guides/redis/tls/standalone.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Redis. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/redis](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/redis) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -79,9 +79,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml -issuer.cert-manager.io/redis-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/issuer.yaml ``` +issuer.cert-manager.io/redis-ca-issuer created ## TLS/SSL encryption in Redis Standalone @@ -112,25 +112,26 @@ spec: ### Deploy Redis Standalone ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-standalone-ssl.yaml -redis.kubedb.com/rd-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/tls/rd-standalone-ssl.yaml ``` +redis.kubedb.com/rd-tls created Now, wait until `rd-tls` has status `Ready`. i.e, ```bash -$ watch kubectl get rd -n demo +watch kubectl get rd -n demo +``` Every 2.0s: kubectl get redis -n demo NAME VERSION STATUS AGE rd-tls 6.2.14 Ready 14s -``` ### Verify TLS/SSL in Redis Standalone 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 rd-tls-client-cert +kubectl describe secret -n demo rd-tls-client-cert +``` Name: rd-tls-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -153,13 +154,12 @@ Data ca.crt: 1147 bytes tls.crt: 1127 bytes tls.key: 1675 bytes -``` Now, we can connect using tls certs to connect to the redis and write some data ```bash -$ kubectl exec -it -n demo rd-tls-0 -c redis -- bash - +kubectl exec -it -n demo rd-tls-0 -c redis -- bash +``` # Trying to connect without tls certificates root@rd-tls-0:/data# redis-cli 127.0.0.1:6379> @@ -173,22 +173,25 @@ root@rd-tls-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs/cl 127.0.0.1:6379> set hello world OK 127.0.0.1:6379> exit -``` ## Cleaning up To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo redis/rd-tls -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-tls patched -$ kubectl delete -n demo redis rd-tls +```bash +kubectl delete -n demo redis rd-tls +``` redis.kubedb.com "rd-tls" deleted -$ kubectl delete issuer -n demo redis-ca-issuer -issuer.cert-manager.io "redis-ca-issuer" deleted +```bash +kubectl delete issuer -n demo redis-ca-issuer ``` +issuer.cert-manager.io "redis-ca-issuer" deleted ## Next Steps diff --git a/docs/guides/redis/update-version/cluster.md b/docs/guides/redis/update-version/cluster.md index 10eb33ca89..6fff7e99c2 100644 --- a/docs/guides/redis/update-version/cluster.md +++ b/docs/guides/redis/update-version/cluster.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -71,17 +71,17 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-cluster.yaml -redis.kubedb.com/redis-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-cluster.yaml ``` +redis.kubedb.com/redis-cluster created Now, wait until `redis-cluster` created has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-cluster 6.0.20 Ready 88s -``` We are now ready to apply the `RedisOpsRequest` CR to update this database. @@ -116,9 +116,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-version.yaml -redisopsrequest.ops.kubedb.com/update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-version.yaml ``` +redisopsrequest.ops.kubedb.com/update-version created #### Verify Redis version updated successfully : @@ -127,26 +127,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE update-version UpdateVersion Successful 4m6s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify whether the `Redis` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get redis -n demo redis-cluster -o=jsonpath='{.spec.version}{"\n"}' +kubectl get redis -n demo redis-cluster -o=jsonpath='{.spec.version}{"\n"}' +``` 7.0.14 -$ kubectl get petset -n demo redis-cluster-shard0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo redis-cluster-shard0 -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 -$ kubectl get pods -n demo redis-cluster-shard1-1 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 +```bash +kubectl get pods -n demo redis-cluster-shard1-1 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 You can see from above, our `Redis` cluster database has been updated with the new version. So, the update process is successfully completed. @@ -157,12 +161,16 @@ You can see from above, our `Redis` cluster database has been updated with the n To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-quickstart patched -$ kubectl delete -n demo redis redis-cluster +```bash +kubectl delete -n demo redis redis-cluster +``` redis.kubedb.com "redis-cluster" deleted -$ kubectl delete -n demo redisopsrequest update-version -redisopsrequest.ops.kubedb.com "update-version" deleted +```bash +kubectl delete -n demo redisopsrequest update-version ``` +redisopsrequest.ops.kubedb.com "update-version" deleted diff --git a/docs/guides/redis/update-version/sentinel.md b/docs/guides/redis/update-version/sentinel.md index de1e90ead0..b15c63b549 100644 --- a/docs/guides/redis/update-version/sentinel.md +++ b/docs/guides/redis/update-version/sentinel.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -68,17 +68,17 @@ spec: Let's create the `RedisSentinel` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/sentinel.yaml -redissentinel.kubedb.com/sen-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/sentinel.yaml ``` +redissentinel.kubedb.com/sen-sample created Now, wait until `sen-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redissentinel -n demo +kubectl get redissentinel -n demo +``` NAME VERSION STATUS AGE sen-sample 6.2.14 Ready 5m20s -``` ### Deploy Redis : @@ -111,17 +111,17 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-sentinel.yaml -redis.kubedb.com/rd-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-sentinel.yaml ``` +redis.kubedb.com/rd-sample created Now, wait until `rd-sample` created has status `Ready`. i.e, ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE rd-sample 6.2.14 Ready 2m11s -``` We are now ready to apply the `RedisSentinelOpsRequest` CR to update the sentinel version and `RedisOpsRequest` CR to update the database version. @@ -156,9 +156,9 @@ Here, Let's create the `RedisSentinelOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-sentinel.yaml -redissentinelopsrequest.ops.kubedb.com/update-sen-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-sentinel.yaml ``` +redissentinelopsrequest.ops.kubedb.com/update-sen-version created #### Verify RedisSentinel version updated successfully : @@ -167,26 +167,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisSentinelOpsRequest` to be `Successful`. Run the following command to watch `RedisSentinelOpsRequest` CR, ```bash -$ watch kubectl get redissentinelopsrequest -n demo +watch kubectl get redissentinelopsrequest -n demo +``` Every 2.0s: kubectl get redissentinelopsrequest -n demo NAME TYPE STATUS AGE update-sen-version UpdateVersion Successful 3m30s -``` We can see from the above output that the `RedisSentinelOpsRequest` has succeeded. Now, we are going to verify whether the `RedisSentinel` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get redissentinel -n demo sen-sample -o=jsonpath='{.spec.version}{"\n"}' +kubectl get redissentinel -n demo sen-sample -o=jsonpath='{.spec.version}{"\n"}' +``` 7.0.14 -$ kubectl get petset -n demo sen-sample -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo sen-sample -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 -$ kubectl get pods -n demo sen-sample-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 +```bash +kubectl get pods -n demo sen-sample-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 You can see from above, our `RedisSentinel` sen-demo has been updated with the new version. So, the UpdateVersion process is successfully completed. ### Update Redis Version @@ -220,9 +224,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-redis-sentinel.yaml -redisopsrequest.ops.kubedb.com/update-rd-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-redis-sentinel.yaml ``` +redisopsrequest.ops.kubedb.com/update-rd-version created #### Verify Redis version updated successfully : @@ -231,26 +235,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE update-rd-version UpdateVersion Successful 5m40s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify whether the `Redis` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get redis -n demo rd-sample -o=jsonpath='{.spec.version}{"\n"}' +kubectl get redis -n demo rd-sample -o=jsonpath='{.spec.version}{"\n"}' +``` 7.0.4 -$ kubectl get petset -n demo rd-sample -o=jsonpath='{.spec.template.spec.containers[1].image}{"\n"}' +```bash +kubectl get petset -n demo rd-sample -o=jsonpath='{.spec.template.spec.containers[1].image}{"\n"}' +``` redis:7.0.4@sha256:091a7b5de688f283b30a4942280b64cf822bbdab0abfb2d2ce6db989f2d3c3f4 -$ kubectl get pods -n demo rd-sample-0 -o=jsonpath='{.spec.containers[1].image}{"\n"}' -redis:7.0.4@sha256:091a7b5de688f283b30a4942280b64cf822bbdab0abfb2d2ce6db989f2d3c3f4 +```bash +kubectl get pods -n demo rd-sample-0 -o=jsonpath='{.spec.containers[1].image}{"\n"}' ``` +redis:7.0.4@sha256:091a7b5de688f283b30a4942280b64cf822bbdab0abfb2d2ce6db989f2d3c3f4 You can see from above, our `Redis` standalone database has been updated with the new version. So, the UpdateVersion process is successfully completed. @@ -260,24 +268,34 @@ You can see from above, our `Redis` standalone database has been updated with th To clean up the Kubernetes resources created by this tutorial, run: -```bash # Delete Redis and RedisOpsRequest -$ kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo rd/rd-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/rd-sample patched -$ kubectl delete -n demo redis rd-sample +```bash +kubectl delete -n demo redis rd-sample +``` redis.kubedb.com "rd-sample" deleted -$ kubectl delete -n demo redisopsrequest update-rd-version +```bash +kubectl delete -n demo redisopsrequest update-rd-version +``` redisopsrequest.ops.kubedb.com "update-rd-version" deleted # Delete RedisSentinel and RedisSentinelOpsRequest -$ kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +```bash +kubectl patch -n demo redissentinel/sen-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redissentinel.kubedb.com/sen-sample patched -$ kubectl delete -n demo redissentinel sen-sample +```bash +kubectl delete -n demo redissentinel sen-sample +``` redissentinel.kubedb.com "sen-sample" deleted -$ kubectl delete -n demo redissentinelopsrequests update-sen-version -redissentinelopsrequest.ops.kubedb.com "update-sen-version" deleted +```bash +kubectl delete -n demo redissentinelopsrequests update-sen-version ``` +redissentinelopsrequest.ops.kubedb.com "update-sen-version" deleted diff --git a/docs/guides/redis/update-version/standalone.md b/docs/guides/redis/update-version/standalone.md index 7fbe45637f..5d65b17a2d 100644 --- a/docs/guides/redis/update-version/standalone.md +++ b/docs/guides/redis/update-version/standalone.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/redis](/docs/examples/redis) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -65,17 +65,17 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-standalone.yaml -redis.kubedb.com/redis-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/rd-standalone.yaml ``` +redis.kubedb.com/redis-quickstart created Now, wait until `redis-quickstart` created has status `Ready`. i.e, ```bash -$ kubectl get rd -n demo +kubectl get rd -n demo +``` NAME VERSION STATUS AGE redis-quickstart 6.2.14 Ready 5m14s -``` We are now ready to apply the `RedisOpsRequest` CR to update this database. @@ -110,9 +110,9 @@ Here, Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-standalone.yaml -redisopsrequest.ops.kubedb.com/update-standalone created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/update-version/update-standalone.yaml ``` +redisopsrequest.ops.kubedb.com/update-standalone created #### Verify Redis version updated successfully : @@ -121,26 +121,30 @@ If everything goes well, `KubeDB` Enterprise operator will update the image of ` Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ watch kubectl get redisopsrequest -n demo +watch kubectl get redisopsrequest -n demo +``` Every 2.0s: kubectl get redisopsrequest -n demo NAME TYPE STATUS AGE update-standalone UpdateVersion Successful 3m45s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify whether the `Redis` and the related `PetSets` their `Pods` have the new version image. Let's check, ```bash -$ kubectl get redis -n demo redis-quickstart -o=jsonpath='{.spec.version}{"\n"}' +kubectl get redis -n demo redis-quickstart -o=jsonpath='{.spec.version}{"\n"}' +``` 7.0.14 -$ kubectl get petset -n demo redis-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo redis-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 -$ kubectl get pods -n demo redis-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 +```bash +kubectl get pods -n demo redis-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +redis:7.0.14@sha256:dfeb5451fce377ab47c5bb6b6826592eea534279354bbfc3890c0b5e9b57c763 > If you are a current `Redis` user and want to switch to `Valkey`, just make sure that both `Redis` and `Valkey` versions are 7.\*.\* @@ -151,12 +155,16 @@ You can see from above, our `Redis` standalone database has been updated with th To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/redis-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/redis-quickstart patched -$ kubectl delete -n demo redis redis-quickstart +```bash +kubectl delete -n demo redis redis-quickstart +``` redis.kubedb.com "redis-quickstart" deleted -$ kubectl delete -n demo redisopsrequest update-standalone -redisopsrequest.ops.kubedb.com "update-standalone" deleted +```bash +kubectl delete -n demo redisopsrequest update-standalone ``` +redisopsrequest.ops.kubedb.com "update-standalone" deleted diff --git a/docs/guides/redis/virtual_secret/guide.md b/docs/guides/redis/virtual_secret/guide.md index 243b54a9d1..862edeb099 100644 --- a/docs/guides/redis/virtual_secret/guide.md +++ b/docs/guides/redis/virtual_secret/guide.md @@ -46,19 +46,28 @@ Before you begin, ensure you have the following prerequisites in place: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## How to use Virtual Secrets ### Install Virtual Secrets Server First, install the virtual-secret-server which is a custom api server for the `secrets.virtual-secrets.dev` resource. ```bash -$ helm repo add appscode https://charts.appscode.com/stable/ -$ helm repo update -$ helm search repo appscode/virtual-secrets-server --version=v2025.3.14 -$ helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ +helm repo add appscode https://charts.appscode.com/stable/ +``` + +```bash +helm repo update +``` + +```bash +helm search repo appscode/virtual-secrets-server --version=v2025.3.14 +``` + +```bash +helm upgrade -i virtual-secrets-server appscode/virtual-secrets-server \ --version=v2025.3.14 -n kubevault --create-namespace ``` @@ -69,28 +78,30 @@ read, list, delete and delete in a kv secret engine named `virtual-secrets.dev` Now let’s configure the vault server with following commands: -```shell # enable kv secret engine in the path virtual-secrets.dev -$ vault secrets enable -path=virtual-secrets.dev -version=2 kv +```bash +vault secrets enable -path=virtual-secrets.dev -version=2 kv +``` Success! Enabled the kv secrets engine at: virtual-secrets.dev/ - # creates a policy with the permission to create, update, read, list and delete -$ vault policy write virtual-secrets-policy - <}}/docs/examples/vault/secretstore.yaml -secretstore.config.virtual-secrets.dev/vault configured +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretstore.yaml ``` +secretstore.config.virtual-secrets.dev/vault configured Here, - `spec.vault` - section describes the connection information for vault. @@ -152,8 +163,9 @@ virtual-secret Opaque 2 2d19h We can also get the whole definition of the `Secret`, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +```bash +kubectl get secrets.virtual-secrets.dev -n demo virtual-secret -oyaml +``` apiVersion: virtual-secrets.dev/v1alpha1 data: password: dmlydHVhbC1zZWNyZXQ= @@ -171,7 +183,6 @@ metadata: uid: f4bc8051-65e9-405d-847a-ecfa4fcab182 secretStoreName: vault type: Opaque -``` We can see that this `Secret`actually behaves identical of the core `Secret`. But the data is not stored in the `etcd` and it is way more secure than using the native `k8s Secret`. @@ -180,15 +191,22 @@ We can see that this `Secret`actually behaves identical of the core `Secret`. Bu We will connect to the Vault by using Vault CLI. Therefore, we need to export the necessary environment variables and port-forward the service. In one terminal port-forward the vault server service, -```shell -$ kubectl port-forward -n demo service/vault 8200 +```bash +kubectl port-forward -n demo service/vault 8200 +``` Forwarding from 127.0.0.1:8200 -> 8200 Forwarding from [::1]:8200 -> 8200 +```bash +export VAULT_ADDR=http://127.0.0.1:8200 +``` + +```bash +export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) +``` + +```bash +vault kv get virtual-secrets.dev/demo/virtual-secret ``` -```shell -$ export VAULT_ADDR=http://127.0.0.1:8200 -$ export VAULT_TOKEN=(kubectl vault root-token get vaultserver vault -n demo --value-only) -$ vault kv get virtual-secrets.dev/demo/virtual-secret ================ Secret Path ================ virtual-secrets.dev/data/demo/virtual-secret @@ -206,7 +224,6 @@ Key Value --- ----- password virtual-secret username default -``` We can see that the secret data is stored in the `virtual-secrets.dev/demo/virtual-secret` path where, - `virtual-secret.dev` is the secret engine name. @@ -221,22 +238,30 @@ data from virtual secrets and uses the `Secrets Store CSI Driver` to mount those Let’s go ahead and install `Secrets Store CSI Driver` and `secrets-store-csi-driver-provider-virtual-secrets` into our cluster, -```shell -$ helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts -$ helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +```bash +helm repo add secrets-store-csi-driver https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts +``` -$ helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 -$ helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 +```bash +helm install csi-secrets-store secrets-store-csi-driver/secrets-store-csi-driver --namespace kube-system +``` + +```bash +helm search repo appscode/secrets-store-csi-driver-provider-virtual-secrets --version=v2025.3.14 +``` + +```bash +helm upgrade -i secrets-store-csi-driver-provider-virtual-secrets appscode/secrets-store-csi-driver-provider-virtual-secrets -n kube-system --create-namespace --version=v2025.3.14 ``` If both of them are deployed we should see two new pods in the `kube-system` namespace. -```shell -$ kubectl get pods -n kube-system +```bash +kubectl get pods -n kube-system +``` NAME READY STATUS RESTARTS AGE csi-secrets-store-secrets-store-csi-driver-rvpvm 3/3 Running 0 61s secrets-store-csi-driver-provider-virtual-secrets-m78gv 1/1 Running 0 34s -``` The `Secrets Store CSI Driver` uses a custom resource named `SecretProviderClass` to mount the secret. Let’s go ahead and create that, ```yaml @@ -259,10 +284,10 @@ Here, > **Note:** -We can also call the mount subresource of the virtual secret to create the SecretProviderClass for us. -The namespace and the name of SecretProviderClass should be same as the Virtual Secret it is being used for. Let’s create the SecretProviderClass, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml -secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/vault/secretProviderClass.yaml ``` +secretproviderclass.secrets-store.csi.x-k8s.io/virtual-secret created ### Use Virtual Secrets with Redis Virtual Secrets is integrated with KubeDB from the v2025.3.24 and it can be used to store KubeDB’s database credential. Now, the support has been added for `Redis`. @@ -302,27 +327,28 @@ Here, We can now apply the redis custom resource, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rd_vs.yaml +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/rd_vs.yaml +``` redis.kubedb.com/rd created -``` Now, wait until `rd` has status `Ready`. i.e. , -```shell -$ kubectl get rd -n demo +```bash +kubectl get rd -n demo +``` NAME VERSION STATUS AGE rd 8.2.2 Ready 18h -``` Now, lets go ahead and check what secret it is using, -```shell -$ kubectl get secrets.virtual-secrets.dev -n demo +```bash +kubectl get secrets.virtual-secrets.dev -n demo +``` NAME TYPE DATA AGE virtual-secret Opaque 2 1d -``` We can see that the Redis user password is stored in the vault server as named `virtual-secret` . Now let’s go ahead and connect to the database using the password to check whether it is working or not. ```bash -$ kubectl exec -it rd-shard0-0 -n demo -c redis -- bash +kubectl exec -it rd-shard0-0 -n demo -c redis -- bash +``` redis@rd-shard0-0:/data$ redis-cli -a virtual-secret Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. 127.0.0.1:6379> set hello world @@ -332,22 +358,35 @@ OK 127.0.0.1:6379> exit redis@rd-shard0-0:/data$ exit exit - -``` We can see that we are able to connect to the database and create a database and a table successfully. ## Cleanup To clean up the resources created in this guide, run the following commands: ```bash -$ kubectl delete rd -n demo rd +kubectl delete rd -n demo rd +``` redis.kubedb.com "rd" deleted -$ kubectl delete secretproviderclass -n demo virtual-secret -$ kubectl delete ns demo -$ helm uninstall virtual-secrets-server -n kubevault -$ helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system -$ helm uninstall csi-secrets-store -n kube-system + +```bash +kubectl delete secretproviderclass -n demo virtual-secret +``` + +```bash +kubectl delete ns demo +``` + +```bash +helm uninstall virtual-secrets-server -n kubevault +``` + +```bash +helm uninstall secrets-store-csi-driver-provider-virtual-secrets -n kube-system +``` + +```bash +helm uninstall csi-secrets-store -n kube-system ``` If you want to uninstall the `KubeVault`, run: ```bash -$ helm uninstall kubevault --namespace kubevault +helm uninstall kubevault --namespace kubevault ``` diff --git a/docs/guides/redis/volume-expansion/volume-expansion.md b/docs/guides/redis/volume-expansion/volume-expansion.md index 21c2f24011..497432ba6b 100644 --- a/docs/guides/redis/volume-expansion/volume-expansion.md +++ b/docs/guides/redis/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to expand the v To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of Redis @@ -45,13 +45,12 @@ Here, we are going to deploy a `Redis` cluster using a supported version by `Ku At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 69s topolvm-provisioner topolvm.cybozu.com Delete WaitForFirstConsumer true 37s -``` - We can see from the output the `topolvm-provisioner` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We will use this storage class. You can install topolvm from [here](https://github.com/topolvm/topolvm). Now, we are going to deploy a `Redis` database with in `Cluster` Mode version `8.2.2`. @@ -86,25 +85,28 @@ spec: Let's create the `Redis` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/volume-expansion/sample-redis.yaml -redis.kubedb.com/sample-redis created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/volume-expansion/sample-redis.yaml ``` +redis.kubedb.com/sample-redis created Now, wait until `sample-redis` has status `Ready`. i.e, ```bash -$ kubectl get redis -n demo +kubectl get redis -n demo +``` NAME VERSION STATUS AGE sample-redis 6.2.14 Ready 5m4s -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-redis-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-redis-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-032f1355-1720-4d85-b1e5-b86427bc4662 1Gi RWO Delete Bound demo/data-sample-redis-shard0-1 topolvm-provisioner 2m49s pvc-207ac9aa-2ba2-432b-ac00-8cc1cd46e20a 1Gi RWO Delete Bound demo/data-sample-redis-shard2-0 topolvm-provisioner 2m49s @@ -112,7 +114,6 @@ pvc-20c946e4-4812-4dfc-a76e-4629bcd385dc 1Gi RWO Delete pvc-69158d05-c715-4dd5-afee-2f5d196ba1f9 1Gi RWO Delete Bound demo/data-sample-redis-shard1-0 topolvm-provisioner 2m53s pvc-aee29446-eff0-430e-95ff-ae853e73a244 1Gi RWO Delete Bound demo/data-sample-redis-shard1-1 topolvm-provisioner 2m41s pvc-d37fbdf9-90bd-4b5e-b3b2-7e40156c13a8 1Gi RWO Delete Bound demo/data-sample-redis-shard0-0 topolvm-provisioner 2m56s -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -157,9 +158,9 @@ are deleted and PVC is updated. Then the database Pods are recreated with update Let's create the `RedisOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/volume-expansion/online-vol-expansion.yaml -redisopsrequest.ops.kubedb.com/rd-online-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/redis/volume-expansion/online-vol-expansion.yaml ``` +redisopsrequest.ops.kubedb.com/rd-online-volume-expansion created #### Verify Redis volume expanded successfully @@ -168,23 +169,28 @@ If everything goes well, `KubeDB` Enterprise operator will update the volume siz Let's wait for `RedisOpsRequest` to be `Successful`. Run the following command to watch `RedisOpsRequest` CR, ```bash -$ kubectl get redisopsrequest -n demo +kubectl get redisopsrequest -n demo +``` NAME TYPE STATUS AGE rd-online-volume-expansion VolumeExpansion Successful 96s -``` We can see from the above output that the `RedisOpsRequest` has succeeded. Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-redis-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-redis-shard0 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get petset -n demo sample-redis-shard1 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo sample-redis-shard1 -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-032f1355-1720-4d85-b1e5-b86427bc4662 2Gi RWO Delete Bound demo/data-sample-redis-shard0-1 topolvm-provisioner 7m9s pvc-207ac9aa-2ba2-432b-ac00-8cc1cd46e20a 2Gi RWO Delete Bound demo/data-sample-redis-shard2-0 topolvm-provisioner 7m9s @@ -192,7 +198,6 @@ pvc-20c946e4-4812-4dfc-a76e-4629bcd385dc 2Gi RWO Delete pvc-69158d05-c715-4dd5-afee-2f5d196ba1f9 2Gi RWO Delete Bound demo/data-sample-redis-shard1-0 topolvm-provisioner 7m3s pvc-aee29446-eff0-430e-95ff-ae853e73a244 2Gi RWO Delete Bound demo/data-sample-redis-shard1-1 topolvm-provisioner 7m1s pvc-d37fbdf9-90bd-4b5e-b3b2-7e40156c13a8 2Gi RWO Delete Bound demo/data-sample-redis-shard0-0 topolvm-provisioner 7m6s -``` The above output verifies that we have successfully expanded the volume of the Redis database. @@ -208,17 +213,24 @@ in standalone or sentinel mode. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete redis -n demo sample-redis -$ kubectl delete redisopsrequest -n demo rd-online-volume-expansion +kubectl delete redis -n demo sample-redis +``` + +```bash +kubectl delete redisopsrequest -n demo rd-online-volume-expansion ``` ```bash -$ kubectl patch -n demo rd/sample-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo rd/sample-redis -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` redis.kubedb.com/sample-redis patched -$ kubectl delete -n demo redis sample-redis +```bash +kubectl delete -n demo redis sample-redis +``` redis.kubedb.com "sample-redis" deleted -$ kubectl delete -n demo redisopsrequest rd-online-volume-expansion -redisopsrequest.ops.kubedb.com "rd-online-volume-expansion" deleted +```bash +kubectl delete -n demo redisopsrequest rd-online-volume-expansion ``` +redisopsrequest.ops.kubedb.com "rd-online-volume-expansion" deleted diff --git a/docs/guides/singlestore/autoscaler/compute/cluster.md b/docs/guides/singlestore/autoscaler/compute/cluster.md index 828925eebe..f7af93ed4e 100644 --- a/docs/guides/singlestore/autoscaler/compute/cluster.md +++ b/docs/guides/singlestore/autoscaler/compute/cluster.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/singlestore](/docs/examples/singlestore) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -46,11 +46,11 @@ Here, we are going to deploy a `SingleStore` Cluster using a supported version b We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created #### Deploy SingleStore Cluster @@ -115,9 +115,9 @@ spec: Let's create the `SingleStore` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/compute/sdb-cluster.yaml -singlestore.kubedb.com/sdb-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/compute/sdb-cluster.yaml ``` +singlestore.kubedb.com/sdb-cluster created Now, wait until `sdb-sample` has status `Ready`. i.e, @@ -212,16 +212,17 @@ Here, Let's create the `SinglestoreAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaler/compute/sdb-cluster-autoscaler.yaml -singlestoreautoscaler.autoscaling.kubedb.com/sdb-cluster-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaler/compute/sdb-cluster-autoscaler.yaml ``` +singlestoreautoscaler.autoscaling.kubedb.com/sdb-cluster-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `singlestoreautoscaler` resource is created successfully, ```bash -$ kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +``` Name: sdb-cluster-autoscaler Namespace: demo Labels: @@ -347,7 +348,6 @@ Status: Memory: 6Gi Vpa Name: sdb-sample-aggregator Events: -``` So, the `singlestoreautoscaler` resource is created successfully. you can see in the `Status.VPAs.Recommendation` section, that recommendation has been generated for our database. Our autoscaler operator continuously watches the recommendation generated and creates an `singlestoreopsrequest` based on the recommendations, if the database pods resources are needed to scaled up or down. @@ -355,24 +355,25 @@ you can see in the `Status.VPAs.Recommendation` section, that recommendation has Let's watch the `singlestoreopsrequest` in the demo namespace to see if any `singlestoreopsrequest` object is created. After some time you'll see that a `singlestoreopsrequest` will be created based on the recommendation. ```bash -$ watch kubectl get singlestoreopsrequest -n demo +watch kubectl get singlestoreopsrequest -n demo +``` Every 2.0s: kubectl get singlestoreopsrequest -n demo NAME TYPE STATUS AGE sdbops-sdb-sample-aggregator-c0u141 VerticalScaling Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-sdb-sample-aggregator-c0u141 VerticalScaling Successful 3m2s -``` We can see from the above output that the `SinglestoreOpsRequest` has succeeded. If we describe the `SinglestoreOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-aggregator-c0u141 +kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-aggregator-c0u141 +``` Name: sdbops-sdb-sample-aggregator-c0u141 Namespace: demo Labels: app.kubernetes.io/component=database @@ -484,7 +485,6 @@ Events: Normal RestartPods 24m KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting Normal Successful -``` Now, we are going to verify from the Pod, and the singlestore yaml whether the resources of the topology database has updated to meet up the desired state, Let's check, diff --git a/docs/guides/singlestore/autoscaler/storage/cluster.md b/docs/guides/singlestore/autoscaler/storage/cluster.md index c2deb4bbb1..dbff7c2f31 100644 --- a/docs/guides/singlestore/autoscaler/storage/cluster.md +++ b/docs/guides/singlestore/autoscaler/storage/cluster.md @@ -37,9 +37,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a Singl To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/singlestore](/docs/examples/singlestore) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -48,21 +48,21 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) kubernetes.io/gce-pd Delete Immediate true 2m49s -``` #### Create SingleStore License Secret We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created #### Deploy SingleStore Cluster @@ -127,9 +127,9 @@ spec: Let's create the `SingleStore` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-cluster.yaml -singlestore.kubedb.com/sdb-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-cluster.yaml ``` +singlestore.kubedb.com/sdb-cluster created Now, wait until `sdb-sample` has status `Ready`. i.e, @@ -143,16 +143,17 @@ singlestore.kubedb.com/sdb-sample kubedb.com/v1alpha2 8.9.3 Ready 4m35 Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sdb-sample-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sdb-sample-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "10Gi" -$ kubectl get pv -n demo | grep 'leaf' +```bash +kubectl get pv -n demo | grep 'leaf' +``` pvc-5cf8638e365544dd 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-0 linode-block-storage-retain 50s pvc-a99e7adb282a4f9c 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-2 linode-block-storage-retain 60s pvc-da8e9e5162a748df 10Gi RWO Retain Bound demo/data-sdb-sample-leaf-1 linode-block-storage-retain 70s -``` - You can see the petset of leaf has 10GB storage, and the capacity of all the persistent volume is also 10GB. We are now ready to apply the `SingleStoreAutoscaler` CRO to set up storage autoscaling for this cluster. @@ -195,21 +196,23 @@ Let's create the `SinglestoreAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml -singlestoreautoscaler.autoscaling.kubedb.com/sdb-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/autoscaling/storage/sdb-storage-autoscaler.yaml ``` +singlestoreautoscaler.autoscaling.kubedb.com/sdb-storage-autoscaler created #### Storage Autoscaling is set up successfully Let's check that the `singlestoreautoscaler` resource is created successfully, ```bash -$ kubectl get singlestoreautoscaler -n demo +kubectl get singlestoreautoscaler -n demo +``` NAME AGE sdb-cluster-autoscaler 2m5s - -$ kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +```bash +kubectl describe singlestoreautoscaler -n demo sdb-cluster-autoscaler +``` Name: sdb-cluster-autoscaler Namespace: demo Labels: @@ -245,9 +248,6 @@ Spec: Usage Threshold: 30 Events: - -``` - So, the `singlestoreautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up the persistent volume to exceed the `usageThreshold` creating new database with partitions 6 to see if storage autoscaling is working or not. @@ -255,13 +255,16 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the cluster pod and fill the cluster volume using the following commands: ```bash -$ kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-sample-leaf-0 /]$ df -h var/lib/memsql Filesystem Size Used Avail Use% Mounted on /dev/disk/by-id/scsi-0Linode_Volume_pvcc50e0d73d07349f9 9.8G 1.4G 8.4G 15% /var/lib/memsql -$ kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +```bash +kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-sample-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -276,41 +279,41 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. singlestore> create database demo partitions 6; Query OK, 1 row affected (3.78 sec) -$ kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +```bash +kubectl exec -it -n demo sdb-sample-leaf-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-sample-leaf-0 /]$ df -h var/lib/memsql Filesystem Size Used Avail Use% Mounted on /dev/disk/by-id/scsi-0Linode_Volume_pvcc50e0d73d07349f9 9.8G 3.2G 6.7G 33% /var/lib/memsql -``` - So, from the above output we can see that the storage usage is 33%, which exceeded the `usageThreshold` 30%. Let's watch the `singlestoreopsrequest` in the demo namespace to see if any `singlestoreopsrequest` object is created. After some time you'll see that a `singlestoreopsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ watch kubectl get singlestoreopsrequest -n demo +watch kubectl get singlestoreopsrequest -n demo +``` Every 2.0s: kubectl get singlestoreopsrequest -n demo ashraful: Wed Sep 11 13:39:25 2024 NAME TYPE STATUS AGE sdbops-sdb-sample-th2r62 VolumeExpansion Progressing 10s -``` Let's wait for the ops request to become successful. ```bash -$ watch kubectl get singlestoreopsrequest -n demo +watch kubectl get singlestoreopsrequest -n demo +``` Every 2.0s: kubectl get singlestoreopsrequest -n demo ashraful: Wed Sep 11 13:41:12 2024 NAME TYPE STATUS AGE sdbops-sdb-sample-th2r62 VolumeExpansion Successful 2m31s -``` - We can see from the above output that the `SinglestoreOpsRequest` has succeeded. If we describe the `SinglestoreOpsRequest` we will get an overview of the steps that were followed to expand the volume of the cluster. ```bash -$ kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-th2r62 +kubectl describe singlestoreopsrequest -n demo sdbops-sdb-sample-th2r62 +``` Name: sdbops-sdb-sample-th2r62 Namespace: demo Labels: app.kubernetes.io/component=database @@ -441,7 +444,6 @@ Events: Normal ReadyPetSets 4m55s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 4m27s KubeDB Ops-manager Operator Resuming Singlestore database: demo/sdb-sample Normal Successful 4m27s KubeDB Ops-manager Operator Successfully resumed Singlestore database: demo/sdb-sample for SinglestoreOpsRequest: sdbops-sdb-sample-th2r62 -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the combined cluster has expanded to meet the desired state, Let's check, diff --git a/docs/guides/singlestore/backup/kubestash/application-level/index.md b/docs/guides/singlestore/backup/kubestash/application-level/index.md index 62422b4253..7956d9b02d 100644 --- a/docs/guides/singlestore/backup/kubestash/application-level/index.md +++ b/docs/guides/singlestore/backup/kubestash/application-level/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/singlestore/backup/kubestash/application-level/examples](/docs/guides/singlestore/backup/kubestash/application-level/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -55,11 +55,11 @@ This section will demonstrate how to take application-level backup of a `SingleS We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Deploy Sample SingleStore Database @@ -138,34 +138,35 @@ Here, Create the above `SingleStore` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/sample-singlestore.yaml -singlestore.kubedb.com/sample-singlestore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/sample-singlestore.yaml ``` +singlestore.kubedb.com/sample-singlestore created KubeDB will deploy a SingleStore database according to the above specification. It will also create the necessary Secrets and Services to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get singlestores.kubedb.com -n demo +kubectl get singlestores.kubedb.com -n demo +``` NAME VERSION STATUS AGE sample-singlestore 8.9.3 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-singlestore +kubectl get secret -n demo -l=app.kubernetes.io/instance=sample-singlestore +``` NAME TYPE DATA AGE sample-singlestore-auth kubernetes.io/basic-auth 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-singlestore +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-singlestore +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-singlestore ClusterIP 10.128.230.168 3306/TCP,8081/TCP 5m10s sample-singlestore-pods ClusterIP None 3306/TCP 5m10s -``` - Here, we have to use service `sample-singlestore` and secret `sample-singlestore-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/singlestore/concepts/appbinding.md) CR that holds the necessary information to connect with the database. **Verify AppBinding:** @@ -173,15 +174,15 @@ Here, we have to use service `sample-singlestore` and secret `sample-singlestore Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sample-singlestore 9m24s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-singlestore -o yaml +kubectl get appbindings -n demo sample-singlestore -o yaml ``` ```yaml @@ -251,29 +252,30 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, we are going to exec into the any aggregator pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-singlestore" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-singlestore" +``` NAME READY STATUS RESTARTS AGE sample-singlestore-aggregator-0 2/2 Running 0 15m sample-singlestore-aggregator-1 2/2 Running 0 15m sample-singlestore-leaf-0 2/2 Running 0 15m sample-singlestore-leaf-1 2/2 Running 0 15m sample-singlestore-leaf-2 2/2 Running 0 15m -``` And copy the username and password of the `root` user to access into `memsql` shell. ```bash -$ kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.password}'| base64 -d xEJv73q3w_m1~H.G⏎ -``` Now, Lets exec into the any aggregator `Pod` to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-singlestore-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +kubectl exec -it -n demo sample-singlestore-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) singlestore-client: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -331,8 +333,6 @@ singlestore> SELECT * FROM playground.equipment; singlestore> exit Bye -``` - Now, we are ready to backup the database. ### Prepare Backend @@ -344,13 +344,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -379,9 +385,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -412,9 +418,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -427,8 +433,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -484,27 +493,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-singlestore-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-singlestore-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-singlestore-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-singlestore-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/singlestore` directory. @@ -515,10 +524,10 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-singlestore-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** @@ -527,11 +536,10 @@ KubeStash triggers an instant backup as soon as the `BackupConfiguration` is rea Run the following command to watch `BackupSession` CR, ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-singlestore-backup-frequent-backup-1724065200 BackupConfiguration sample-singlestore-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -540,18 +548,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-singlestore-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-singlestore-repo +kubectl get repository -n demo gcs-singlestore-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-singlestore-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-demo-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-demo-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-singlestore-repo-sample-singlestore-backup-frequent-backup-1725359100 sample-singlestore-backup frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -564,7 +572,7 @@ gcs-singlestore-repo-sample-singlestore-backup-frequent-backup-1725359100 samp If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-singlestore-repo-sample-singlestore-backup-frequent-backup-1725359100 -oyaml +kubectl get snapshots -n demo gcs-singlestore-repo-sample-singlestore-backup-frequent-backup-1725359100 -oyaml ``` ```yaml @@ -668,9 +676,9 @@ For this tutorial, we will restore the database in a separate namespace called ` First, create the namespace by running the following command: ```bash -$ kubectl create ns dev -namespace/dev created +kubectl create ns dev ``` +namespace/dev created #### Create RestoreSession: @@ -711,19 +719,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-singlestore-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/application-level/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-singlestore-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. #### Verify Restored SingleStore Manifest: @@ -731,10 +739,10 @@ The `Succeeded` phase means that the restore process has been completed successf In this section, we will verify whether the desired `SingleStore` database manifest has been successfully applied to the cluster. ```bash -$ kubectl get singlestores.kubedb.com -n dev +kubectl get singlestores.kubedb.com -n dev +``` NAME VERSION STATUS AGE sample-singlestore 8.9.3 Ready 39m -``` The output confirms that the `SingleStore` database has been successfully created with the same configuration as it had at the time of backup. @@ -745,37 +753,38 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get sdb -n dev sample-singlestore +kubectl get sdb -n dev sample-singlestore +``` NAME VERSION STATUS AGE sample-singlestore 8.9.3 Ready 4m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-singlestore" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-singlestore" +``` NAME READY STATUS RESTARTS AGE sample-singlestore-aggregator-0 2/2 Running 0 15m sample-singlestore-aggregator-1 2/2 Running 0 15m sample-singlestore-leaf-0 2/2 Running 0 15m sample-singlestore-leaf-1 2/2 Running 0 15m sample-singlestore-leaf-2 2/2 Running 0 15m -``` And copy the username and password of the `root` user to access into `mysql` shell. ```bash -$ kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ kubectl get secret -n demo sample-singlestore-auth -o jsonpath='{.data.password}'| base64 -d xEJv73q3w_m1~H.G⏎ -``` Now, Lets exec into the any aggregator `Pod` to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sample-singlestore-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +kubectl exec -it -n demo sample-singlestore-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) singlestore-client: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -824,8 +833,6 @@ singlestore> SELECT * FROM playground.equipment; singlestore> exit Bye -``` - So, from the above output, we can see that the `playground` database and the `equipment` table we have created earlier in the original database and now, they are restored successfully. ## Cleanup diff --git a/docs/guides/singlestore/backup/kubestash/auto-backup/index.md b/docs/guides/singlestore/backup/kubestash/auto-backup/index.md index d462a212d8..50d1d2545a 100644 --- a/docs/guides/singlestore/backup/kubestash/auto-backup/index.md +++ b/docs/guides/singlestore/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ### Prepare Backend @@ -51,13 +51,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -86,9 +92,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created **Create RetentionPolicy:** @@ -117,9 +123,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -128,11 +134,14 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created ## Auto-backup with default configurations @@ -192,9 +201,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/singlestore-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/singlestore-default-backup-blueprint created Now, we are ready to backup our `SingleStore` databases using few annotations. @@ -203,11 +212,11 @@ Now, we are ready to backup our `SingleStore` databases using few annotations. We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created **Create Database** @@ -278,24 +287,24 @@ Here, Let's create the `SingleStore` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/sample-singlestore.yaml -singlestore.kubedb.com/sample-singlestore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/sample-singlestore.yaml ``` +singlestore.kubedb.com/sample-singlestore created **Verify BackupConfiguration** If everything is set up correctly, KubeStash will create a `BackupConfiguration` for our SingleStore instance in the demo namespace. The phase of this `BackupConfiguration` should be Ready. You can verify the `BackupConfiguration` object by running the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-singlestore Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-singlestore -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-singlestore -o yaml ``` ```yaml @@ -360,11 +369,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-singlestore-frequent-backup-1724236500 BackupConfiguration appbinding-sample-singlestore Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -373,18 +381,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-sample-singlestore-frequent-backup-1724236500 default-blueprint frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -398,7 +406,7 @@ default-blueprint-appbinding-sample-singlestore-frequent-backup-1724236500 def If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-sample-singlestore-frequent-backup-1724236500 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-sample-singlestore-frequent-backup-1724236500 -oyaml ``` ```yaml @@ -535,9 +543,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/singlestore-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/singlestore-customize-backup-blueprint created Now, we are ready to backup our `SingleStore` databases using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -611,24 +619,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `SingleStore` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/sample-singlestore-2.yaml -singlestore.kubedb.com/sample-singlestore-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/auto-backup/examples/sample-singlestore-2.yaml ``` +singlestore.kubedb.com/sample-singlestore-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our SingleStore in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-singlestore-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-singlestore-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-singlestore-2 -o yaml ``` ```yaml @@ -693,11 +701,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-singlestore-2-frequent-backup-1725007200 BackupConfiguration appbinding-sample-singlestore-2 Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -706,18 +713,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-sample-singlestore-2-frequent-backup-1725007200 customize-blueprint frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -731,7 +738,7 @@ customize-blueprint-appbinding-sample-singlestore-2-frequent-backup-1725007200 If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-sample-singlestore-2-frequent-backup-1725007200 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-sample-singlestore-2-frequent-backup-1725007200 -oyaml ``` ```yaml diff --git a/docs/guides/singlestore/backup/kubestash/logical/index.md b/docs/guides/singlestore/backup/kubestash/logical/index.md index 0e4515ef8c..c7fa007834 100644 --- a/docs/guides/singlestore/backup/kubestash/logical/index.md +++ b/docs/guides/singlestore/backup/kubestash/logical/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/singlestore/backup/kubestash/logical/examples](/docs/guides/singlestore/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -55,11 +55,11 @@ This section will demonstrate how to backup a `SingleStore` database. Here, we a We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Deploy Sample SingleStore Database @@ -138,34 +138,35 @@ Here, Create the above `SingleStore` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/sdb-sample.yaml -singlestore.kubedb.com/sdb-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/sdb-sample.yaml ``` +singlestore.kubedb.com/sdb-sample created KubeDB will deploy a SingleStore database according to the above specification. It will also create the necessary `Secrets` and `Services` to access the database. Let's check if the database is ready to use, ```bash -$ kubectl get singlestores.kubedb.com -n demo +kubectl get singlestores.kubedb.com -n demo +``` NAME VERSION STATUS AGE sdb-sample 8.9.3 Ready 4m22s -``` The database is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this database using the following commands, ```bash -$ kubectl get secret -n demo -l=app.kubernetes.io/instance=sdb-sample +kubectl get secret -n demo -l=app.kubernetes.io/instance=sdb-sample +``` NAME TYPE DATA AGE sdb-sample-auth kubernetes.io/basic-auth 2 4m58s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sdb-sample +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sdb-sample +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sdb-sample ClusterIP 10.128.230.168 3306/TCP,8081/TCP 5m10s sdb-sample-pods ClusterIP None 3306/TCP 5m10s -``` - Here, we have to use service `sdb-sample` and secret `sdb-sample-auth` to connect with the database. `KubeDB` creates an [AppBinding](/docs/guides/mysql/concepts/appbinding/index.md) CR that holds the necessary information to connect with the database. **Verify AppBinding:** @@ -173,15 +174,15 @@ Here, we have to use service `sdb-sample` and secret `sdb-sample-auth` to connec Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME AGE sdb-sample 9m24s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sdb-sample -o yaml +kubectl get appbindings -n demo sdb-sample -o yaml ``` ```yaml @@ -251,29 +252,30 @@ KubeStash uses the `AppBinding` CR to connect with the target database. It requi Now, we are going to exec into the any aggregator pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sdb-sample" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sdb-sample" +``` NAME READY STATUS RESTARTS AGE sdb-sample-aggregator-0 2/2 Running 0 15m sdb-sample-aggregator-1 2/2 Running 0 15m sdb-sample-leaf-0 2/2 Running 0 15m sdb-sample-leaf-1 2/2 Running 0 15m sdb-sample-leaf-2 2/2 Running 0 15m -``` And copy the username and password of the `root` user to access into `memsql` shell. ```bash -$ kubectl get secret -n demo sdb-sample-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo sdb-sample-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ kubectl get secret -n demo sdb-sample-auth -o jsonpath='{.data.password}'| base64 -d xEJv73q3w_m1~H.G⏎ -``` Now, Lets exec into the any aggregator `Pod` to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo sdb-sample-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +kubectl exec -it -n demo sdb-sample-aggregator-0 -- singlestore --user=root --password=xEJv73q3w_m1~H.G +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) singlestore-client: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -331,8 +333,6 @@ singlestore> SELECT * FROM playground.equipment; singlestore> exit Bye -``` - Now, we are ready to backup the database. ### Prepare Backend @@ -344,13 +344,19 @@ We are going to store our backed up data into a GCS bucket. We have to create a Let's create a secret called `gcs-secret` with access credentials to our desired GCS bucket, ```bash -$ echo -n '' > GOOGLE_PROJECT_ID -$ cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY -$ kubectl create secret generic -n demo gcs-secret \ +echo -n '' > GOOGLE_PROJECT_ID +``` + +```bash +cat /path/to/downloaded-sa-key.json > GOOGLE_SERVICE_ACCOUNT_JSON_KEY +``` + +```bash +kubectl create secret generic -n demo gcs-secret \ --from-file=./GOOGLE_PROJECT_ID \ --from-file=./GOOGLE_SERVICE_ACCOUNT_JSON_KEY -secret/gcs-secret created ``` +secret/gcs-secret created **Create BackupStorage:** @@ -379,9 +385,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/gcs-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/gcs-storage created Now, we are ready to backup our database to our desired backend. @@ -412,9 +418,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -427,8 +433,11 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -482,27 +491,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-sdb-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-sdb-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-sdb-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-sdb-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the GCS bucket, we will see the `Repository` YAML stored in the `demo/singlestore` directory. @@ -513,21 +522,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-sdb-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w - +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-sdb-backup-frequent-backup-1724065200 BackupConfiguration sdb-sample-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -536,18 +544,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-sdb-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo gcs-sdb-repo +kubectl get repository -n demo gcs-sdb-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE gcs-sdb-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-demo-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=gcs-demo-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE gcs-sdb-repo-sample-sdb-backup-frequent-backup-1724065200 sample-sdb-backup frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -560,7 +568,7 @@ gcs-sdb-repo-sample-sdb-backup-frequent-backup-1724065200 sample-sdb-backup If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo gcs-sdb-repo-sample-sdb-backup-frequent-backup-1724065200 -oyaml +kubectl get snapshots -n demo gcs-sdb-repo-sample-sdb-backup-frequent-backup-1724065200 -oyaml ``` ```yaml @@ -697,17 +705,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/restored-singlestore.yaml -singlestore.kubedb.com/restored-singlestore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/restored-singlestore.yaml ``` +singlestore.kubedb.com/restored-singlestore created If you check the database status, you will see it is stuck in `Provisioning` state. ```bash -$ kubectl get singlestore -n demo restored-singlestore +kubectl get singlestore -n demo restored-singlestore +``` NAME VERSION STATUS AGE restored-singlestore 8.9.3 Provisioning 61s -``` #### Create RestoreSession: @@ -748,19 +756,19 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-singlestore-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-singlestore-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Sep 20 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-restore gcs-demo-repo Succeeded 3s 53s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -772,37 +780,38 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into `Ready` state by the following command, ```bash -$ kubectl get singlestore -n demo restored-singlestore +kubectl get singlestore -n demo restored-singlestore +``` NAME VERSION STATUS AGE restored-singlestore 8.9.3 Ready 34m -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-singlestore" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-singlestore" +``` NAME READY STATUS RESTARTS AGE restored-singlestore-aggregator-0 2/2 Running 0 34m restored-singlestore-aggregator-1 2/2 Running 0 34m restored-singlestore-leaf-0 2/2 Running 0 34m restored-singlestore-leaf-1 2/2 Running 0 34m restored-singlestore-leaf-2 2/2 Running 0 34m -``` And then copy the user name and password of the `root` user to access into `memsql` shell. ```bash -$ kubectl get secret -n demo restored-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +kubectl get secret -n demo restored-singlestore-auth -o jsonpath='{.data.username}'| base64 -d +``` root⏎ kubectl get secret -n demo restored-singlestore-auth -o jsonpath='{.data.password}'| base64 -d QMm1hi0T*7QFz_yh⏎ -``` Now, Lets exec into the any aggregator `Pod` to enter into `mysql` shell and create a database and a table, ```bash -$ kubectl exec -it -n demo restored-singlestore-aggregator-0 -- singlestore --user=root --password=QMm1hi0T*7QFz_yh +kubectl exec -it -n demo restored-singlestore-aggregator-0 -- singlestore --user=root --password=QMm1hi0T*7QFz_yh +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) singlestore-client: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. @@ -851,8 +860,6 @@ singlestore> SELECT * FROM playground.equipment; singlestore> exit Bye -``` - So, from the above output, we can see that the `playground` database and the `equipment` table we have created earlier in the original database and now, they are restored successfully. ## Cleanup diff --git a/docs/guides/singlestore/clustering/singlestore-clustering/index.md b/docs/guides/singlestore/clustering/singlestore-clustering/index.md index 446d55c5ad..7f6f5351b4 100644 --- a/docs/guides/singlestore/clustering/singlestore-clustering/index.md +++ b/docs/guides/singlestore/clustering/singlestore-clustering/index.md @@ -29,9 +29,9 @@ Before proceeding: - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/singlestore](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/clustering/singlestore-clustering/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,11 +40,11 @@ Before proceeding: We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Create a SingleStore database @@ -107,9 +107,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/clustering/singlestore-clustering/examples/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Here, - `spec.version` is the name of the SinglestoreVersion CRD where the docker images are specified. In this tutorial, a SingleStore `8.9.3` database is going to be created. @@ -124,7 +124,8 @@ Here, KubeDB operator watches for `Singlestore` objects using Kubernetes api. When a `Singlestore` object is created, KubeDB operator will create new PetSet and Service with the matching SingleStore object name. KubeDB operator will also create a governing service for PetSets, if one is not already present. ```bash -$ kubectl get petset,pvc,pv,svc -n demo +kubectl get petset,pvc,pv,svc -n demo +``` NAME AGE petset.apps.k8s.appscode.com/sample-sdb-aggregator 16m petset.apps.k8s.appscode.com/sample-sdb-leaf 16m @@ -143,9 +144,6 @@ NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) service/sample-sdb ClusterIP 10.128.15.230 3306/TCP,8081/TCP 16m service/sample-sdb-pods ClusterIP None 3306/TCP 16m - -``` - KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified Singlestore object: ```yaml @@ -362,17 +360,24 @@ If you want to use an existing secret please specify that when creating the Sing Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `sample-sdb-auth` secret holds username and password ```bash -$ kubectl get pod -n demo sample-sdb-aggregator-0 -oyaml | grep podIP +kubectl get pod -n demo sample-sdb-aggregator-0 -oyaml | grep podIP +``` podIP: 10.244.0.14 -$ kubectl get secrets -n demo sample-sdb-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secrets -n demo sample-sdb-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sample-sdb-auth -o jsonpath='{.data.password}' | base64 -d - J0h_BUdJB8mDO31u + +```bash +kubectl get secrets -n demo sample-sdb-auth -o jsonpath='{.data.password}' | base64 -d ``` + J0h_BUdJB8mDO31u we will exec into the pod `sample-sdb-aggregator-0` and connect to the database using username and password ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulting container name to singlestore. Use 'kubectl describe pod/sample-sdb-aggregator-0 -n demo' to see all of the containers in this pod. @@ -425,16 +430,15 @@ singlestore> SELECT * FROM playground.equipment; singlestore> exit Bye -``` You can also connect with database management tools like [singlestore-studio](https://docs.singlestore.com/db/v8.5/reference/singlestore-tools-reference/singlestore-studio/) You can simply access to SingleStore studio by forwarding the Primary service port to any of your localhost port. Or, Accessing through ExternalP's 8081 port is also an option. ```bash -$ kubectl port-forward -n demo service/sample-sdb 8081 +kubectl port-forward -n demo service/sample-sdb 8081 +``` Forwarding from 127.0.0.1:8081 -> 8081 Forwarding from [::1]:8081 -> 8081 -``` Lets, open your browser and go to the http://localhost:8081 or with TLS https://localhost:8081 then click on `Add or Create Cluster` option. Then choose `Add Existing Cluster` and click on `next` and you will get an interface like that below: diff --git a/docs/guides/singlestore/concepts/singlestore.md b/docs/guides/singlestore/concepts/singlestore.md index fc302f8738..a8054c30af 100644 --- a/docs/guides/singlestore/concepts/singlestore.md +++ b/docs/guides/singlestore/concepts/singlestore.md @@ -211,11 +211,11 @@ Secrets provided by users are not managed by KubeDB, and therefore, won't be mod Example: ```bash -$ kubectl create secret generic sdb-cred -n demo \ +kubectl create secret generic sdb-cred -n demo \ --from-literal=user=root \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "sdb-cred" created ``` +secret "sdb-cred" created ```yaml apiVersion: v1 diff --git a/docs/guides/singlestore/configuration/config-file/index.md b/docs/guides/singlestore/configuration/config-file/index.md index 9be5457ea0..6a8a7a5d3b 100644 --- a/docs/guides/singlestore/configuration/config-file/index.md +++ b/docs/guides/singlestore/configuration/config-file/index.md @@ -25,13 +25,15 @@ KubeDB supports providing custom configuration for SingleStore. This tutorial wi - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo + kubectl create ns demo + ``` namespace/demo created - - $ kubectl get ns demo + + ```bash + kubectl get ns demo + ``` NAME STATUS AGE demo Active 5s - ``` > Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/configuration/config-file/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/configuration/config-file/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,11 +50,11 @@ In this tutorial, we will configure [max_connections](https://docs.singlestore.c We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Custom Configuration @@ -74,9 +76,9 @@ read_buffer_size = 122880 Now, create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf -configmap/sdb-configuration created +kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf ``` +configmap/sdb-configuration created Verify the secret has the configuration file. @@ -100,9 +102,9 @@ type: Opaque Now, create SingleStore crd specifying `spec.topology.aggregator.configSecret` and `spec.topology.leaf.configSecret` field. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml -singlestore.kubedb.com/custom-sdb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/config-file/yamls/sdb-custom.yaml ``` +singlestore.kubedb.com/custom-sdb created Below is the YAML for the SingleStore crd we just created. @@ -171,28 +173,30 @@ Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, serv Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE custom-sdb-aggregator-0 2/2 Running 0 94s custom-sdb-aggregator-1 2/2 Running 0 88s custom-sdb-leaf-0 2/2 Running 0 91s custom-sdb-leaf-1 2/2 Running 0 86s -$ kubectl get sdb -n demo +```bash +kubectl get sdb -n demo +``` NAME TYPE VERSION STATUS AGE custom-sdb kubedb.com/v1alpha2 8.9.3 Ready 4m29s -``` - We can see the database is in ready phase so it can accept conncetion. Now, we will check if the database has started with the custom configuration we have provided. > Read the comment written for the following commands. They contain the instructions and explanations of the commands. -```bash # Connceting to the database -$ kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +```bash +kubectl exec -it -n demo custom-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@custom-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -228,8 +232,6 @@ singlestore> show variables like 'read_buffer_size'; singlestore> exit Bye - -``` ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/singlestore/configuration/podtemplating/index.md b/docs/guides/singlestore/configuration/podtemplating/index.md index e73597a5ad..b9577cafce 100644 --- a/docs/guides/singlestore/configuration/podtemplating/index.md +++ b/docs/guides/singlestore/configuration/podtemplating/index.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for SingleStore via [PodTemplate] - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/configuration/podtemplating/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -63,11 +63,11 @@ Read about the fields in details in [PodTemplate concept](/docs/guides/singlesto We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## CRD Configuration @@ -134,26 +134,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml -singlestore.kubedb.com/sdb-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-misc-config.yaml ``` +singlestore.kubedb.com/sdb-misc-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-misc-config-aggregator-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo +kubectl get pod -n demo +``` NAME READY STATUS RESTARTS AGE sdb-misc-config-aggregator-0 2/2 Running 0 4m51s sdb-misc-config-leaf-0 2/2 Running 0 4m48s sdb-misc-config-leaf-1 2/2 Running 0 4m30s -``` Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl exec -it -n demo sdb-misc-config-aggregator-0 -- bash +kubectl exec -it -n demo sdb-misc-config-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-misc-config-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -187,8 +188,6 @@ singlestore> SHOW VARIABLES LIKE 'char%'; singlestore> exit Bye -``` - Here we can see the character_set_server value is utf8mb4. ## Custom Sidecar Containers @@ -214,9 +213,9 @@ data: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml -configmap/nginx-config-map created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/nginx-config-map.yaml ``` +configmap/nginx-config-map created Now we will deploy our singlestore with custom sidecar container. Here is the yaml of singlestore, @@ -298,26 +297,27 @@ Here, - Volumes: A volume is defined to link the ConfigMap nginx-config-map to the Nginx configuration directory. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml -singlestore.kubedb.com/sdb-custom-sidecar created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-custom-sidecar.yaml ``` +singlestore.kubedb.com/sdb-custom-sidecar created Now, wait a few minutes. KubeDB operator will create necessary petset, services, secret etc. If everything goes well, we will see the pods has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE sdb-custom-sidecar-aggregator-0 3/3 Running 0 3m17s sdb-custom-sidecar-leaf-0 2/2 Running 0 3m14s sdb-custom-sidecar-leaf-1 2/2 Running 0 2m59s -``` Now check the logs of sidecar container, ```bash -$ kubectl logs -f -n demo sdb-custom-sidecar-aggregator-0 -c sidecar +kubectl logs -f -n demo sdb-custom-sidecar-aggregator-0 -c sidecar +``` /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh @@ -344,7 +344,6 @@ $ kubectl logs -f -n demo sdb-custom-sidecar-aggregator-0 -c sidecar 2024/10/29 07:43:11 [notice] 1#1: start worker process 30 2024/10/29 07:43:11 [notice] 1#1: start worker process 31 2024/10/29 07:43:11 [notice] 1#1: start worker process 32 -``` So, we have successfully deploy sidecar container in KubeDB manage SingleStore. ## Using Node Selector @@ -352,31 +351,32 @@ So, we have successfully deploy sidecar container in KubeDB manage SingleStore. Here in this example we will use [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/) to schedule our singlestore 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 +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 +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 + ```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" +kubectl describe node "lke212553-307295-5541798e0000" +``` Name: lke212553-307295-5541798e0000 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -392,7 +392,6 @@ Labels: beta.kubernetes.io/arch=amd64 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 singlestore with this new label as nodeSelector. Below is the yaml we are going to apply: @@ -422,24 +421,24 @@ spec: storageType: Durable ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml -singlestore.kubedb.com/sdb-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-node-selector.yaml ``` +singlestore.kubedb.com/sdb-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 `sdb-node-selector-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE sdb-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 sdb-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo sdb-node-selector-0 -o wide +kubectl get pods -n demo sdb-node-selector-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sdb-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 @@ -447,28 +446,33 @@ We can successfully verify that our pod was scheduled to our desired node. Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our singlestore 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 +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 +kubectl taint nodes lke212553-307295-339173d10000 key1=node1:NoSchedule +``` node/lke212553-307295-339173d10000 tainted -$ kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +```bash +kubectl taint nodes lke212553-307295-5541798e0000 key1=node2:NoSchedule +``` node/lke212553-307295-5541798e0000 tainted -$ kubectl taint nodes lke212553-307295-5b53c5520000 key1=node3:NoSchedule -node/lke212553-307295-5b53c5520000 tainted +```bash +kubectl taint nodes lke212553-307295-5b53c5520000 key1=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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` lke212553-307295-339173d10000 [ { @@ -493,7 +497,6 @@ lke212553-307295-5b53c5520000 "value": "node3" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a singlestore without proper tolerations. Here is the yaml of singlestore we are going to createc ```yaml apiVersion: kubedb.com/v1alpha2 @@ -517,20 +520,21 @@ spec: version: 8.9.3 ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml -singlestore.kubedb.com/sdb-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-without-tolerations.yaml ``` +singlestore.kubedb.com/sdb-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 `sdb-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE sdb-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 sdb-without-tolerations-0 +kubectl describe pods -n demo sdb-without-tolerations-0 +``` Name: sdb-without-tolerations-0 Namespace: demo Priority: 0 @@ -639,7 +643,6 @@ Events: 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 singlestore. Here is the yaml we are going to apply, @@ -673,24 +676,24 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml -singlestore.kubedb.com/sdb-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/configuration/podtemplating/yamls/sdb-with-tolerations.yaml ``` +singlestore.kubedb.com/sdb-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 `sdb-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pods -n demo +kubectl get pods -n demo +``` NAME READY STATUS RESTARTS AGE sdb-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 sdb-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pods -n demo sdb-with-tolerations-0 -o wide +kubectl get pods -n demo sdb-with-tolerations-0 -o wide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES sdb-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 diff --git a/docs/guides/singlestore/initialization/using-script/index.md b/docs/guides/singlestore/initialization/using-script/index.md index 6f8ecfa9c7..28d6167dc0 100644 --- a/docs/guides/singlestore/initialization/using-script/index.md +++ b/docs/guides/singlestore/initialization/using-script/index.md @@ -26,9 +26,9 @@ In this tutorial we will use .sql script stored in GitHub repository [kubedb/sin - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare Initialization Scripts @@ -41,21 +41,21 @@ At first, we will create a ConfigMap from `init.sql` file. Then, we will provide Let's create a ConfigMap with initialization script, ```bash -$ kubectl create configmap -n demo sdb-init-script \ +kubectl create configmap -n demo sdb-init-script \ --from-literal=init.sql="$(curl -fsSL https://github.com/kubedb/singlestore-init-scripts/raw/master/init.sql)" -configmap/sdb-init-script created ``` +configmap/sdb-init-script created ## Create SingleStore License Secret We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Create a SingleStore database with Init-Script @@ -122,9 +122,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/Initialization/demo-1.yaml -singlestore.kubedb.com/singlestore-init-script created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/singlestore/Initialization/demo-1.yaml ``` +singlestore.kubedb.com/singlestore-init-script created Here, @@ -343,9 +343,10 @@ KubeDB operator sets the `status.phase` to `Ready` once the database is successf Now, we will connect to this database and check the data inserted by the initlization script. -```bash # Connecting to the database -$ kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +```bash +kubectl exec -it -n demo sdb-sample-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-sample-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -393,16 +394,16 @@ singlestore> select * from kubedb_write_check; singlestore> exit Bye - -``` - ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo sdb-sample +kubectl delete sdb -n demo sdb-sample +``` singlestore.kubedb.com "sdb-sample" deleted -$ kubectl delete ns demo -namespace "demo" deleted + +```bash +kubectl delete ns demo ``` +namespace "demo" deleted diff --git a/docs/guides/singlestore/monitoring/builtin-prometheus/index.md b/docs/guides/singlestore/monitoring/builtin-prometheus/index.md index bf678678a1..c58add0095 100644 --- a/docs/guides/singlestore/monitoring/builtin-prometheus/index.md +++ b/docs/guides/singlestore/monitoring/builtin-prometheus/index.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor SingleStore database using builtin [P - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/monitoring/builtin-prometheus/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -107,35 +109,33 @@ Here, Let's create the SingleStore crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml -singlestore.kubedb.com/builtin-prom-sdb created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/builtin-prom-singlestore.yaml ``` +singlestore.kubedb.com/builtin-prom-sdb created Now, wait for the database to go into `Running` state. ```bash -$ watch -n 3 kubectl get singlestore -n demo builtin-prom-sdb - +watch -n 3 kubectl get singlestore -n demo builtin-prom-sdb +``` NAME TYPE VERSION STATUS AGE builtin-prom-sdb kubedb.com/v1alpha2 8.9.3 Ready 9m5s -``` - KubeDB will create a separate stats service with name `{SingleStore crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-sdb" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=builtin-prom-sdb" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-sdb ClusterIP 10.128.102.243 3306/TCP,8081/TCP 14m builtin-prom-sdb-pods ClusterIP None 3306/TCP 14m builtin-prom-sdb-stats ClusterIP 10.128.218.225 9104/TCP 14m -``` - Here, `builtin-prom-sdb-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-sdb-stats +kubectl describe svc -n demo builtin-prom-sdb-stats +``` Name: builtin-prom-sdb-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -158,7 +158,6 @@ TargetPort: metrics/TCP Endpoints: 10.2.1.142:9104,10.2.1.143:9104 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -322,20 +321,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/builtin-prometheus/yamls/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -346,9 +345,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -357,18 +356,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-sdb-stats` service as one of the targets. diff --git a/docs/guides/singlestore/monitoring/prometheus-operator/index.md b/docs/guides/singlestore/monitoring/prometheus-operator/index.md index b1d68a6c04..6b984e3355 100644 --- a/docs/guides/singlestore/monitoring/prometheus-operator/index.md +++ b/docs/guides/singlestore/monitoring/prometheus-operator/index.md @@ -32,9 +32,9 @@ The following diagram shows how KubeDB Provisioner operator monitor `SingleStore - To keep database resources isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster: ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -49,10 +49,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION REPLICAS AGE default prometheus 1 2m19s -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -103,20 +103,20 @@ KubeDB creates a `ServiceMonitor` in database namespace `demo`. We need to add l Let's add label `prometheus: prometheus` to `demo` namespace, ```bash -$ kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' -namespace/demo patched +kubectl patch namespace demo -p '{"metadata":{"labels": {"prometheus":"prometheus"}}}' ``` +namespace/demo patched ## Create SingleStore License Secret We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Deploy SingleStore with Monitoring Enabled @@ -196,31 +196,28 @@ Here, Let's create the SingleStore object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml -singlestore.kubedb.com/prom-operator-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/monitoring/prometheus-operator/yamls/prom-operator-singlestore.yaml ``` +singlestore.kubedb.com/prom-operator-sdb created Now, wait for the database to go into `Running` state. ```bash -$ watch -n 3 kubectl get singlestore -n demo prom-operator-sdb - +watch -n 3 kubectl get singlestore -n demo prom-operator-sdb +``` NAME TYPE VERSION STATUS AGE prom-operator-sdb kubedb.com/v1alpha2 8.9.3 Ready 10m -``` - KubeDB will create a separate stats service with name `{SingleStore crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=prom-operator-sdb" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=prom-operator-sdb" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prom-operator-sdb ClusterIP 10.128.249.124 3306/TCP,8081/TCP 12m prom-operator-sdb-pods ClusterIP None 3306/TCP 12m prom-operator-sdb-stats ClusterIP 10.128.25.236 9104/TCP 12m -``` - Here, `prom-operator-sdb-stats` service has been created for monitoring purpose. Let's describe this stats service. @@ -254,12 +251,11 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these informati KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `prom-operator-sdb-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE prom-operator-sdb-stats 32m -``` - Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of SingleStore crd. ```yaml @@ -313,20 +309,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n default -l=app=prometheus +kubectl get pod -n default -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 121m -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n default prometheus-prometheus-0 9090 +kubectl port-forward -n default prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `prom-operator-sdb-stats` service as one of the targets. diff --git a/docs/guides/singlestore/quickstart/quickstart.md b/docs/guides/singlestore/quickstart/quickstart.md index c15d4cc996..67300c079a 100644 --- a/docs/guides/singlestore/quickstart/quickstart.md +++ b/docs/guides/singlestore/quickstart/quickstart.md @@ -30,24 +30,25 @@ This tutorial will show you how to use KubeDB to run a SingleStore database. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 6h22m - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Find Available SingleStoreVersion When you have installed KubeDB, it has created `SinglestoreVersion` crd for all supported SingleStore versions. Check it by using the `kubectl get singlestoreversions` command. You can also use `sdbv` shorthand instead of `singlestoreversions`. -```bash - $ kubectl get singlestoreversions.catalog.kubedb.com + ```bash + kubectl get singlestoreversions.catalog.kubedb.com + ``` NAME VERSION DB_IMAGE DEPRECATED AGE 8.1.32 8.1.32 ghcr.io/appscode-images/singlestore-node:alma-8.1.32-e3d3cde6da 2d1h 8.5.30 8.5.30 ghcr.io/appscode-images/singlestore-node:alma-8.5.30-4f46ab16a5 2d1h @@ -55,17 +56,16 @@ NAME VERSION DB_IMAGE 8.7.10 8.7.10 ghcr.io/appscode-images/singlestore-node:alma-8.7.10-95e2357384 2d1h 8.7.21 8.7.21 ghcr.io/appscode-images/singlestore-node:alma-8.7.21-f0b8de04d5 2d1h 8.9.3 8.9.3 ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a 2d1h -``` ## Create SingleStore License Secret We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Create a SingleStore database @@ -135,9 +135,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/quickstart/yamls/quickstart.yaml -singlestore.kubedb.com/sdb-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/quickstart/yamls/quickstart.yaml ``` +singlestore.kubedb.com/sdb-quickstart created Here, - `spec.version` is the name of the SinglestoreVersion CRD where the docker images are specified. In this tutorial, a SingleStore `8.9.3` database is going to be created. @@ -152,27 +152,35 @@ Here, KubeDB operator watches for `Singlestore` objects using Kubernetes api. When a `Singlestore` object is created, KubeDB operator will create new PetSet and Service with the matching SingleStore object name. KubeDB operator will also create a governing service for PetSets, if one is not already present. ```bash -$ kubectl get petset -n demo +kubectl get petset -n demo +``` NAME READY AGE sdb-quickstart-leaf 2/2 33s sdb-quickstart-aggregator 1/1 37s -$ kubectl get pvc -n demo + +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-sdb-quickstart-leaf-0 Bound pvc-4f45c51b-47d4-4254-8275-782bf3588667 10Gi RWO standard 42s data-sdb-quickstart-leaf-1 Bound pvc-769e68f4-80a9-4e3e-b2bc-e974534b9dee 10Gi RWO standard 35s data-sdb-quickstart-aggregator-0 Bound pvc-75057e3d-e1d7-4770-905b-6049f2edbcde 1Gi RWO standard 46s -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-4f45c51b-47d4-4254-8275-782bf3588667 10Gi RWO Delete Bound demo/data-sdb-quickstart-leaf-0 standard 87s pvc-75057e3d-e1d7-4770-905b-6049f2edbcde 1Gi RWO Delete Bound demo/data-sdb-quickstart-aggregator-0 standard 91s pvc-769e68f4-80a9-4e3e-b2bc-e974534b9dee 10Gi RWO Delete Bound demo/data-sdb-quickstart-leaf-1 standard 80s -$ kubectl get service -n demo + +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sdb-quickstart LoadBalancer 10.96.27.144 192.10.25.36 3306:32076/TCP,8081:30910/TCP 2m1s sdb-quickstart-pods ClusterIP None 3306/TCP 2m1s -``` - KubeDB operator sets the `status.phase` to `Running` once the database is successfully created. Run the following command to see the modified Singlestore object: ```yaml @@ -404,17 +412,24 @@ If you want to use an existing secret please specify that when creating the Sing Now, we need `username` and `password` to connect to this database from `kubectl exec` command. In this example `sdb-quickstart-auth` secret holds username and password ```bash -$ kubectl get pod -n demo sdb-quickstart-aggregator-0 -oyaml | grep podIP +kubectl get pod -n demo sdb-quickstart-aggregator-0 -oyaml | grep podIP +``` podIP: 10.244.0.14 -$ kubectl get secrets -n demo sdb-quickstart-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secrets -n demo sdb-quickstart-auth -o jsonpath='{.data.username}' | base64 -d +``` root -$ kubectl get secrets -n demo sdb-quickstart-auth -o jsonpath='{.data.password}' | base64 -d - J0h_BUdJB8mDO31u + +```bash +kubectl get secrets -n demo sdb-quickstart-auth -o jsonpath='{.data.password}' | base64 -d ``` + J0h_BUdJB8mDO31u we will exec into the pod `sdb-quickstart-aggregator-0` and connect to the database using username and password ```bash -$ kubectl exec -it -n demo sdb-quickstart-aggregator-0 -- bash +kubectl exec -it -n demo sdb-quickstart-aggregator-0 -- bash +``` Defaulting container name to singlestore. Use 'kubectl describe pod/sdb-quickstart-aggregator-0 -n demo' to see all of the containers in this pod. @@ -442,17 +457,15 @@ $ kubectl exec -it -n demo sdb-quickstart-aggregator-0 -- bash | singlestore_health | +--------------------+ 4 rows in set (0.00 sec) - -``` You can also connect with database management tools like [singlestore-studio](https://docs.singlestore.com/db/v8.5/reference/singlestore-tools-reference/singlestore-studio/) You can simply access to SingleStore studio by forwarding the Primary service port to any of your localhost port. Or, Accessing through ExternalP's 8081 port is also an option. ```bash -$ kubectl port-forward -n demo service/sdb-quickstart 8081 +kubectl port-forward -n demo service/sdb-quickstart 8081 +``` Forwarding from 127.0.0.1:8081 -> 8081 Forwarding from [::1]:8081 -> 8081 -``` Lets, open your browser and go to the http://localhost:8081 or with TLS https://localhost:8081 then click on `Add or Create Cluster` option. Then choose `Add Existing Cluster` and click on `next` and you will get an interface like that below: @@ -475,9 +488,9 @@ This field is used to regulate the deletion process of the related resources whe When `deletionPolicy` is set to `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete sdb sdb-quickstart -n demo -The Singlestore "sdb-quickstart" is invalid: spec.deletionPolicy: Invalid value: "sdb-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" +kubectl delete sdb sdb-quickstart -n demo ``` +The Singlestore "sdb-quickstart" is invalid: spec.deletionPolicy: Invalid value: "sdb-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl patch -n demo sdb sdb-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"` to set `spec.deletionPolicy` to `Halt` (which deletes the singlestore object and keeps PVC, snapshots, Secrets intact) or remove this field (which default to `Delete`). Then you will be able to delete/halt the database. @@ -492,14 +505,15 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele At first, run `kubectl patch -n demo sdb sdb-quickstart -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge"`. Then delete the singlestore object, ```bash -$ kubectl delete sdb sdb-quickstart -n demo -singlestore.kubedb.com "sdb-quickstart" deleted +kubectl delete sdb sdb-quickstart -n demo ``` +singlestore.kubedb.com "sdb-quickstart" deleted Now, run the following command to get all singlestore resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/sdb-quickstart-auth kubernetes.io/basic-auth 2 3m35s @@ -508,8 +522,6 @@ persistentvolumeclaim/data-sdb-quickstart-leaf-0 Bound pvc-389 persistentvolumeclaim/data-sdb-quickstart-leaf-1 Bound pvc-8dfbf04e-41a8-4cdd-ba14-7ad42d8701bb 1Gi RWO standard 3m11s persistentvolumeclaim/data-sdb-quickstart-aggregator-0 Bound pvc-c4f7d255-7307-4455-b195-70c71b81706f 1Gi RWO standard 3m29s -``` - From the above output, you can see that all singlestore resources(`PetSet`, `Service`, etc.) are deleted except `PVC` and `Secret`. You can recreate your singlestore again using this resources. >You can also set the `deletionPolicy` to `Halt`(deprecated). It's behavior same as `halt` and right now `Halt` is replaced by `Halt`. @@ -523,19 +535,18 @@ When the [DeletionPolicy](/docs/guides/mysql/concepts/database/index.md#specdele Suppose, we have a database with `deletionPolicy` set to `Delete`. Now, are going to delete the database using the following command: ```bash -$ kubectl delete sdb sdb-quickstart -n demo -singlestore.kubedb.com "sdb-quickstart" deleted +kubectl delete sdb sdb-quickstart -n demo ``` +singlestore.kubedb.com "sdb-quickstart" deleted Now, run the following command to get all singlestore resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo +kubectl get petset,svc,secret,pvc -n demo +``` NAME TYPE DATA AGE secret/sdb-quickstart-auth kubernetes.io/basic-auth 2 17m -``` - From the above output, you can see that all singlestore resources(`PetSet`, `Service`, `PVCs` etc.) are deleted except `Secret`. >If you don't set the deletionPolicy then the kubeDB set the DeletionPolicy to Delete by-default. @@ -554,9 +565,9 @@ singlestore.kubedb.com "singlestore-quickstart" deleted Now, run the following command to get all singlestore resources in `demo` namespaces, ```bash -$ kubectl get petset,svc,secret,pvc -n demo -No resources found in demo namespace. +kubectl get petset,svc,secret,pvc -n demo ``` +No resources found in demo namespace. From the above output, you can see that all singlestore resources are deleted. There is no option to recreate/reinitialize your database if `deletionPolicy` is set to `Delete`. diff --git a/docs/guides/singlestore/reconfigure-tls/cluster/index.md b/docs/guides/singlestore/reconfigure-tls/cluster/index.md index 2a0be6e9b2..9476d1db7a 100644 --- a/docs/guides/singlestore/reconfigure-tls/cluster/index.md +++ b/docs/guides/singlestore/reconfigure-tls/cluster/index.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created ## Add TLS to a SingleStore Cluster @@ -41,11 +41,11 @@ Here, We are going to create a SingleStore database without TLS and then reconfi We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Deploy SingleStore without TLS @@ -109,21 +109,21 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Now, wait until `sample-sdb` has status `Ready`. i.e, ```bash -$ kubectl get sdb -n demo +kubectl get sdb -n demo +``` NAME TYPE VERSION STATUS AGE sample-sdb kubedb.com/v1alpha2 8.9.3 Ready 38m -``` - ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -166,7 +166,6 @@ singlestore> show variables like '%ssl%'; | ssl_last_successful_reload_time | | +---------------------------------+------------+ 21 rows in set (0.00 sec) -``` We can verify from the above output that TLS is disabled for this database. @@ -177,12 +176,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -252,22 +251,20 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-add-tls created - +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-add-tls.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE singlestoreopsrequest.ops.kubedb.com/sdbops-add-tls ReconfigureTLS Successful 2m45s -``` - We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to connect to the database for verifying the `SingleStore` server has configured with TLS/SSL encryption. @@ -275,7 +272,8 @@ Now, we are going to connect to the database for verifying the `SingleStore` ser Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ ls etc/memsql/certs/ ca.crt client.crt client.key server.crt server.key @@ -321,7 +319,6 @@ singlestore> show variables like '%ssl%'; | ssl_last_successful_reload_time | | +---------------------------------+------------------------------+ 21 rows in set (0.00 sec) -``` We can see from the above output that, `have_ssl` is set to `ture`. So, database TLS is enabled successfully to this database. @@ -330,13 +327,12 @@ We can see from the above output that, `have_ssl` is set to `ture`. So, 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 exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jan 6 06:56:55 2025 GMT -``` - So, the certificate will expire on this time `Jan 6 06:56:55 2025 GMT`. ### Create SingleStoreOpsRequest @@ -366,31 +362,29 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-rotate-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-rotate-tls.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-rotate-tls created #### Verify Certificate Rotated Successfully Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-rotate-tls ReconfigureTLS Successful 4m14s -``` - We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Jan 6 07:15:47 2025 GMT -``` - As we can see from the above output, the certificate has been rotated successfully. ## Update Certificate @@ -398,8 +392,9 @@ As we can see from the above output, the certificate has been rotated successful Now, we are going to update the server certificate. - Let's describe the server certificate `sample-sdb-server-cert` -```bash - $ kubectl describe certificate -n demo sample-sdb-server-cert + ```bash + kubectl describe certificate -n demo sample-sdb-server-cert + ``` Name: sample-sdb-server-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -473,8 +468,6 @@ Events: Normal Issuing 5m7s (x23 over 23m) cert-manager-certificates-issuing The certificate has been successfully issued Normal Requested 5m7s (x13 over 7m6s) cert-manager-certificates-request-manager (combined from similar events): Created new CertificateRequest resource "sample-sdb-server-cert-qn8g9" -``` - We want to add `subject` and `emailAddresses` in the spec of server sertificate. ### Create SingleStoreOpsRequest @@ -512,34 +505,31 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-update-tls created - +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-update-tls.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-update-tls created #### Verify certificate is updated successfully Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-update-tls ReconfigureTLS Successful 3m24s - -``` - We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, Let's exec into a database node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ openssl x509 -in /etc/memsql/certs/server.crt -inform PEM -subject -email -nameopt RFC2253 -noout subject=CN=sample-sdb,O=kubedb:server kubedb@appscode.com -``` We can see from the above output that, the subject name and email address match with the new ca certificate that we have created. So, the issuer is changed successfully. @@ -574,26 +564,27 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-remove-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure-tls/cluster/examples/sdbops-remove-tls.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-remove-tls created #### Verify TLS Removed Successfully Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CRO, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-remove-tls ReconfigureTLS Successful 27m -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. If we describe the `SingleStoreOpsRequest` we will get an overview of the steps that were followed. Now, Let's exec into the database and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ ls etc/memsql/ memsql_exporter.cnf memsqlctl.hcl @@ -642,7 +633,6 @@ singlestore> show variables like '%ssl%'; singlestore> exit Bye -``` So, we can see from the above that, output that tls is disabled successfully. @@ -651,8 +641,17 @@ So, we can see from the above that, output that tls is disabled successfully. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo --all -$ kubectl delete issuer -n demo --all -$ kubectl delete singlestoreopsrequest -n demo --all -$ kubectl delete ns demo +kubectl delete sdb -n demo --all +``` + +```bash +kubectl delete issuer -n demo --all +``` + +```bash +kubectl delete singlestoreopsrequest -n demo --all +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md b/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md index 18c6f995d6..2463a1c11b 100644 --- a/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md +++ b/docs/guides/singlestore/reconfigure/reconfigure-steps/index.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created Now, we are going to deploy a `SingleStore` Cluster using a supported version by `KubeDB` operator. Then we are going to apply `SingleStoreOpsRequest` to reconfigure its configuration. @@ -41,11 +41,11 @@ Now, we are going to deploy a `SingleStore` Cluster using a supported version b We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Deploy SingleStore @@ -64,9 +64,9 @@ Here, `max_connections` is set to `250`, whereas the default value is `100000`. Now, we will create a secret with this configuration file. ```bash -$ kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf -secret/sdb-configuration created +kubectl create secret generic -n demo sdb-configuration --from-file=./sdb-config.cnf ``` +secret/sdb-configuration created In this section, we are going to create a SingleStore object specifying `spec.topology.aggreagtor.configSecret` field to apply this custom configuration. Below is the YAML of the `SingleStore` CR that we are going to create, @@ -134,13 +134,12 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/reconfigure/reconfigure-steps/yamls/custom-sdb.yaml +``` singlestore.kubedb.com/custom-sdb created Now, wait until `custom-sdb` has status `Ready`. i.e, - -```bash $ kubectl get pod -n demo NAME READY STATUS RESTARTS AGE custom-sdb-aggregator-0 2/2 Running 0 94s diff --git a/docs/guides/singlestore/restart/restart.md b/docs/guides/singlestore/restart/restart.md index a51478b298..5dab1a55c4 100644 --- a/docs/guides/singlestore/restart/restart.md +++ b/docs/guides/singlestore/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the SingleStore database via a SingleStoreOpsRequest. - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/restart/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -36,11 +36,11 @@ KubeDB supports restarting the SingleStore database via a SingleStoreOpsRequest. We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ## Deploy SingleStore @@ -104,9 +104,9 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/sdb-sample.yaml -singlestore.kubedb.com/sdb-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/sdb-sample.yaml ``` +singlestore.kubedb.com/sdb-sample created **Wait for the database to be ready:** Now, wait for `SingleStore` going on `Ready` state @@ -143,18 +143,21 @@ spec: Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/restart-ops.yaml -singlestoreopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/restart/yamls/restart-ops.yaml ``` +singlestoreopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will restart the pods sequentially by their cardinal suffix. -```shell -$ kubectl get singlestoreopsrequest -n demo +```bash +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 10m -$ kubectl get singlestoreopsrequest -n demo restart -oyaml +```bash +kubectl get singlestoreopsrequest -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: SinglestoreOpsRequest metadata: @@ -246,7 +249,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md index 2e12655e88..4d3e85dd15 100644 --- a/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md +++ b/docs/guides/singlestore/scaling/horizontal-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to scale the cl To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Horizontal Scaling on Cluster @@ -44,11 +44,11 @@ Here, we are going to deploy a `SingleStore` cluster using a supported version We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Deploy SingleStore Cluster @@ -113,34 +113,37 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Now, wait until `sample-sdb` has status `Ready`. i.e, ```bash -$ kubectl get singlestore -n demo +kubectl get singlestore -n demo +``` NAME TYPE VERSION STATUS AGE sample-sdb kubedb.com/v1alpha2 8.9.3 Ready 86s -``` Let's check the number of `aggreagtor replicas` and `leaf replicas` this database has from the SingleStore object, number of pods the `aggregator-petset` and `leaf-petset` have, ```bash -$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.aggregator.replicas' +kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.aggregator.replicas' +``` 1 -$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' + +```bash +kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +``` 2 -$ kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.replicas}{"\n"}' +```bash +kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.replicas}{"\n"}' +``` 1 kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' 2 - -``` - We can see from both command that the database has 1 `aggregator replicas` and 2 `leaf replicas` in the cluster. Also, we can verify the replicas of the from an internal memsqlctl command by execing into a replica. @@ -148,7 +151,8 @@ Also, we can verify the replicas of the from an internal memsqlctl command by ex Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster +---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ @@ -159,9 +163,6 @@ Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, | Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | +---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ - -``` - We can see from the above output that the cluster has 1 aggregator node and 2 leaf nodes. We are now ready to apply the `SingleStoreOpsRequest` CR to scale this database. @@ -197,9 +198,9 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-upscale.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-up created #### Verify Cluster replicas scaled up successfully @@ -207,26 +208,29 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, -```bash - $ kubectl get singlestoreopsrequest -n demo + ```bash + kubectl get singlestoreopsrequest -n demo + ``` NAME TYPE STATUS AGE sdbops-scale-horizontal-up HorizontalScaling Successful 74s -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify the number of `leaf replicas` this database has from the SingleStore object, number of pods the `leaf petset` have, ```bash -$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' -3 -$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' +kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +``` 3 +```bash +kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' ``` +3 Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster +---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ @@ -238,8 +242,6 @@ Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, | Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | +---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ -``` - From all the above outputs we can see that the `leaf replicas` of the cluster is `3`. That means we have successfully scaled up the `leaf replicas` of the SingleStore Cluster. ### Scale Down Replicas @@ -273,9 +275,9 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/horizontal-scaling/cluster/example/sdbops-downscale.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-scale-horizontal-down created #### Verify Cluster replicas scaled down successfully @@ -284,24 +286,27 @@ If everything goes well, `KubeDB` Enterprise operator will update the replicas o Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-scale-horizontal-down HorizontalScaling Successful 63s -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify the number of `leaf replicas` this database has from the SingleStore object, number of pods the `leaf petset` have, ```bash -$ kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' -2 -$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' +kubectl get sdb -n demo sample-sdb -o json | jq '.spec.topology.leaf.replicas' +``` 2 +```bash +kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.replicas}{"\n"}' ``` +2 Now let's connect to a singlestore instance and run a memsqlctl internal command to check the number of replicas, ```bash -$ kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +kubectl exec -it -n demo sample-sdb-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) bash: mesqlctl: command not found [memsql@sample-sdb-aggregator-0 /]$ memsqlctl show-cluster @@ -313,8 +318,6 @@ bash: mesqlctl: command not found | Aggregator (Leader) | sample-sdb-aggregator-0.sample-sdb-pods.demo.svc | 3306 | | null | null | online | 1 | null | 1 | 1 | +---------------------+--------------------------------------------------+------+--------------------+-----------+-----------+--------+--------------------+------------------------------+--------+-------------------+ -``` - From all the above outputs we can see that the `leaf replicas` of the cluster is `2`. That means we have successfully scaled down the `leaf replicas` of the SingleStore database. ## Cleaning Up @@ -322,6 +325,9 @@ From all the above outputs we can see that the `leaf replicas` of the cluster is To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo sample-sdb -$ kubectl delete singlestoreopsrequest -n demo sdbops-scale-horizontal-up sdbops-scale-horizontal-down +kubectl delete sdb -n demo sample-sdb +``` + +```bash +kubectl delete singlestoreopsrequest -n demo sdbops-scale-horizontal-up sdbops-scale-horizontal-down ``` \ No newline at end of file diff --git a/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md b/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md index c63c51427e..750316c6b0 100644 --- a/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md +++ b/docs/guides/singlestore/scaling/vertical-scaling/cluster/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Enterprise operator to update the r To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Apply Vertical Scaling on Cluster @@ -44,11 +44,11 @@ Here, we are going to deploy a `SingleStore` cluster using a supported version We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Deploy SingleStore Cluster @@ -113,22 +113,23 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Now, wait until `sample-sdb` has status `Ready`. i.e, ```bash -$ kubectl get sdb -n demo +kubectl get sdb -n demo +``` NAME TYPE VERSION STATUS AGE sample-sdb kubedb.com/v1alpha2 8.9.3 Ready 101s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "600m", @@ -140,8 +141,6 @@ $ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers } } -``` - We are now ready to apply the `SingleStoreOpsRequest` CR to update the resources of this database. ### Vertical Scaling @@ -182,9 +181,9 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml -singlestoreopsrequest.ops.kubedb.com/sdbops-vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/scaling/vertical-scaling/cluster/example/sdbops-vscale.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdbops-vscale created #### Verify SingleStore Cluster resources updated successfully @@ -193,15 +192,16 @@ If everything goes well, `KubeDB` Enterprise operator will update the resources Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdbops-vscale VerticalScaling Successful 7m30s -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify from one of the Pod yaml whether the resources of the database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "700m", @@ -213,8 +213,6 @@ $ kubectl get pod -n demo sample-sdb-aggregator-0 -o json | jq '.spec.containers } } -``` - The above output verifies that we have successfully scaled up the resources of the SingleStore database. ## Cleaning Up @@ -222,6 +220,9 @@ The above output verifies that we have successfully scaled up the resources of t To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo sample-sdb -$ kubectl delete singlestoreopsrequest -n demo sdbops-vscale +kubectl delete sdb -n demo sample-sdb +``` + +```bash +kubectl delete singlestoreopsrequest -n demo sdbops-vscale ``` \ No newline at end of file diff --git a/docs/guides/singlestore/tls/configure/index.md b/docs/guides/singlestore/tls/configure/index.md index ced12d34ae..a32ac3e2c6 100644 --- a/docs/guides/singlestore/tls/configure/index.md +++ b/docs/guides/singlestore/tls/configure/index.md @@ -27,9 +27,9 @@ section_menu_id: guides - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/singlestore/tls/configure/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,11 +42,11 @@ As pre-requisite, at first, we are going to create an Issuer/ClusterIssuer. This We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Create Issuer/ClusterIssuer @@ -55,12 +55,12 @@ Now, we are going to create an example `Issuer` that will be used throughout the - Start off by generating our ca-certificates using openssl, ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=memsql/O=kubedb" +``` Generating a RSA private key ...........................................................................+++++ ........................................................................................................+++++ writing new private key to './ca.key' -``` - create a secret using the certificate files we have just generated, @@ -175,23 +175,23 @@ You can found more details from [here](/docs/guides/singlestore/concepts/singles Let’s create the `SingleStore` cr we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml -singlestore.kubedb.com/sdb-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/tls/configure/examples/tls-cluster.yaml ``` +singlestore.kubedb.com/sdb-tls created **Wait for the database to be ready:** Now, wait for `SingleStore` going on `Running` state and also wait for `PetSet` and its pod to be created and going to `Running` state, ```bash -$ kubectl get sdb,petset -n demo +kubectl get sdb,petset -n demo +``` NAME TYPE VERSION STATUS AGE singlestore.kubedb.com/sdb-tls kubedb.com/v1alpha2 8.9.3 Ready 3m57s NAME AGE petset.apps.k8s.appscode.com/sdb-tls-aggregator 3m53s petset.apps.k8s.appscode.com/sdb-tls-leaf 3m50s -``` **Verify tls-secrets created successfully:** @@ -202,11 +202,11 @@ All tls-secret are created by `KubeDB` Ops Manager. Default tls-secret name form Let's check the tls-secrets have created, ```bash -$ kubectl get secret -n demo | grep sdb-tls +kubectl get secret -n demo | grep sdb-tls +``` sdb-tls-client-cert kubernetes.io/tls 3 5m41s sdb-tls-auth kubernetes.io/basic-auth 2 5m41s sdb-tls-server-cert kubernetes.io/tls -``` **Verify SingleStore configured with TLS/SSL:** @@ -215,7 +215,8 @@ Now, we are going to connect to the database for verifying the `SingleStore` ser Let's exec into the pod to verify TLS/SSL configuration, ```bash -$ kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-tls-aggregator-0 /]$ ls etc/memsql/certs @@ -265,8 +266,6 @@ singlestore> show variables like '%ssl%'; singlestore> exit Bye -``` - The above output shows that the `SingleStore` server is configured to TLS/SSL. You can also see that the `.crt` and `.key` files are stored in `/etc/mysql/certs/` directory for client and server respectively. **Verify secure connection for SSL required user:** @@ -276,7 +275,8 @@ Now, you can create an SSL required user that will be used to connect to the dat Let's connect to the database server with a secure connection, ```bash -$ kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +kubectl exec -it -n demo sdb-tls-aggregator-0 -- bash +``` Defaulted container "singlestore" out of: singlestore, singlestore-coordinator, singlestore-init (init) [memsql@sdb-tls-aggregator-0 /]$ memsql -uroot -p$ROOT_PASSWORD singlestore-client: [Warning] Using a password on the command line interface can be insecure. @@ -319,8 +319,6 @@ Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. singlestore> exit; Bye -``` - From the above output, you can see that only using client certificate we can access the database securely, otherwise, it shows "Access denied". Our client certificate is stored in `/etc/memsql/certs/` directory. ## Cleaning up @@ -328,8 +326,11 @@ From the above output, you can see that only using client certificate we can acc To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb demo sdb-tls +kubectl delete sdb demo sdb-tls +``` singlestore.kubedb.com "sdb-tls" deleted -$ kubectl delete ns demo -namespace "demo" deleted -``` \ No newline at end of file + +```bash +kubectl delete ns demo +``` +namespace "demo" deleted \ No newline at end of file diff --git a/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md b/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md index 96f84e651b..8e969b2c26 100644 --- a/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md +++ b/docs/guides/singlestore/update-version/sdb update-version opsrequest/index.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Prepare SingleStore Cluster @@ -42,11 +42,11 @@ namespace/demo created We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created Now, we are going to deploy a `SingleStore` cluster database with version `8.7.21`. @@ -114,17 +114,17 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Now, wait until `sample-sdb` created has status `Ready`. i.e, ```bash -$ kubectl get sdb -n demo +kubectl get sdb -n demo +``` NAME TYPE VERSION STATUS AGE sample-sdb kubedb.com/v1alpha2 8.7.21 Ready 4m37s -``` We are now ready to apply the `SingleStoreOpsRequest` CR to update this database. @@ -159,9 +159,9 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sdbops-update.yaml -singlestoreopsrequest.ops.kubedb.com/sdb-update-patch created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/update-version/cluster/examples/sdbops-update.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdb-update-patch created #### Verify SingleStore version updated successfully @@ -170,31 +170,39 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, ```bash -$ kubectl get sdbops -n demo +kubectl get sdbops -n demo +``` NAME TYPE STATUS AGE sdb-update-patch UpdateVersion Successful 3m46s -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. Now, we are going to verify whether the `SingleStore` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get sdb -n demo sample-sdb -o=jsonpath='{.spec.version}{"\n"}' +kubectl get sdb -n demo sample-sdb -o=jsonpath='{.spec.version}{"\n"}' +``` 8.9.3 -$ kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo sample-sdb-aggregator -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a -$ kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo sample-sdb-leaf -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a -$ kubectl get pods -n demo sample-sdb-aggregator-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +```bash +kubectl get pods -n demo sample-sdb-aggregator-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a -$ kubectl get pods -n demo sample-sdb-leaf-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a +```bash +kubectl get pods -n demo sample-sdb-leaf-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/singlestore-node:alma-8.9.3-bfa36a984a You can see from above, our `SingleStore` cluster database has been updated with the new version. So, the update process is successfully completed. @@ -203,6 +211,9 @@ You can see from above, our `SingleStore` cluster database has been updated with To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo sample-sdb -$ kubectl delete singlestoreopsrequest -n demo sdb-update-patch +kubectl delete sdb -n demo sample-sdb +``` + +```bash +kubectl delete singlestoreopsrequest -n demo sdb-update-patch ``` \ No newline at end of file diff --git a/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md index 51efda08dd..9241fdce4b 100644 --- a/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md +++ b/docs/guides/singlestore/volume-expansion/sdb volume-expansion opsrequest/index.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Expand Volume of SingleStore @@ -45,23 +45,23 @@ Here, we are going to deploy a `SingleStore` cluster using a supported version We need SingleStore License to create SingleStore Database. So, Ensure that you have acquired a license and then simply pass the license by secret. ```bash -$ kubectl create secret generic -n demo license-secret \ +kubectl create secret generic -n demo license-secret \ --from-literal=username=license \ --from-literal=password='your-license-set-here' -secret/license-secret created ``` +secret/license-secret created ### Prepare SingleStore Database At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageClass +kubectl get storageClass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 6d2h standard (default) driver.standard.io Delete Immediate true 3d21h standard-static driver.standard.io Delete Immediate true 42m -``` Here, we will use `standard` storageClass for this tuitorial. @@ -130,37 +130,38 @@ spec: Let's create the `SingleStore` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sample-sdb.yaml -singlestore.kubedb.com/sample-sdb created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sample-sdb.yaml ``` +singlestore.kubedb.com/sample-sdb created Now, wait until `sample-sdb` has status `Ready`. i.e, ```bash -$ kubectl get sdb -n demo +kubectl get sdb -n demo +``` NAME TYPE VERSION STATUS AGE sample-sdb kubedb.com/v1alpha2 8.9.3 Ready 4m25s -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +```bash +kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "10Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-41cb892c-99fc-4211-a8c2-4e6f8a16c661 10Gi RWO Delete Bound demo/data-sample-sdb-leaf-0 standard 90s pvc-6e241724-6577-408e-b8de-9569d7d785c4 10Gi RWO Delete Bound demo/data-sample-sdb-leaf-1 standard 75s pvc-95ecc525-540b-4496-bf14-bfac901d73c4 1Gi RWO Delete Bound demo/data-sample-sdb-aggregator-0 standard 94s - -``` - You can see the `aggregator` petset has 1GB storage, and the capacity of all the `aggregator` persistent volumes are also 1GB. You can see the `leaf` petset has 10GB storage, and the capacity of all the `leaf` persistent volumes are also 10GB. @@ -203,9 +204,9 @@ Here, Let's create the `SingleStoreOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sdb-offline-volume-expansion.yaml -singlestoreopsrequest.ops.kubedb.com/sdb-offline-vol-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/singlestore/volume-expansion/volume-expansion/example/sdb-offline-volume-expansion.yaml ``` +singlestoreopsrequest.ops.kubedb.com/sdb-offline-vol-expansion created #### Verify SingleStore volume expanded successfully @@ -214,15 +215,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `SingleStoreOpsRequest` to be `Successful`. Run the following command to watch `SingleStoreOpsRequest` CR, ```bash -$ kubectl get singlestoreopsrequest -n demo +kubectl get singlestoreopsrequest -n demo +``` NAME TYPE STATUS AGE sdb-offline-vol-expansion VolumeExpansion Successful 13m -``` We can see from the above output that the `SingleStoreOpsRequest` has succeeded. If we describe the `SingleStoreOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe sdbops -n demo sdb-offline-vol-expansion +kubectl describe sdbops -n demo sdb-offline-vol-expansion +``` Name: sdb-offline-vol-expansion Namespace: demo Labels: @@ -450,24 +452,25 @@ Events: Normal Starting 8m49s KubeDB Ops-manager Operator Resuming Singlestore database: demo/sample-sdb Normal Successful 8m49s KubeDB Ops-manager Operator Successfully resumed Singlestore database: demo/sample-sdb for SinglestoreOpsRequest: sdb-offline-vol-expansion - -``` - Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo sample-sdb-aggregator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' -"11Gi" +```bash +kubectl get petset -n demo sample-sdb-leaf -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` +"11Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-0a4b35e6-988e-4088-ae41-852ad82c5800 2Gi RWO Delete Bound demo/data-sample-sdb-aggregator-0 standard 22m pvc-f6df5743-2bb1-4705-a2f7-be6cf7cdd7f1 11Gi RWO Delete Bound demo/data-sample-sdb-leaf-0 standard 22m pvc-f8fee59d-74dc-46ac-9973-ff1701a6837b 11Gi RWO Delete Bound demo/data-sample-sdb-leaf-1 standard 19m -``` The above output verifies that we have successfully expanded the volume of the SingleStore database. @@ -476,6 +479,9 @@ The above output verifies that we have successfully expanded the volume of the S To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sdb -n demo sample-sdb -$ kubectl delete singlestoreopsrequest -n demo sdb-offline-volume-expansion +kubectl delete sdb -n demo sample-sdb +``` + +```bash +kubectl delete singlestoreopsrequest -n demo sdb-offline-volume-expansion ``` diff --git a/docs/guides/solr/autoscaler/compute/combined.md b/docs/guides/solr/autoscaler/compute/combined.md index e6128b20fb..3fc2c982de 100644 --- a/docs/guides/solr/autoscaler/compute/combined.md +++ b/docs/guides/solr/autoscaler/compute/combined.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/examples/solr/autoscaler) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -70,23 +70,23 @@ spec: Let's create the `Solr` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscalers/combined.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscalers/combined.yaml ``` +solr.kubedb.com/solr-combined created Now, wait until `es-combined` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.6.1 Ready 83s -``` - Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -96,12 +96,12 @@ $ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resou "memory": "2Gi" } } -``` Let's check the Solr resources, ```bash -$ kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "solr") | .resources' +kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "solr") | .resources' +``` { "limits": { "memory": "2Gi" @@ -112,8 +112,6 @@ $ kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.co } } -``` - You can see from the above outputs that the resources are the same as the ones we have assigned while deploying the Solr. We are now ready to apply the `SolrAutoscaler` CRO to set up autoscaling for this database. @@ -169,20 +167,23 @@ Here, Let's create the `SolrAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/compute/combined-scaler.yaml -solrautoscaler.autoscaling.kubedb.com/sl-node-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/compute/combined-scaler.yaml ``` +solrautoscaler.autoscaling.kubedb.com/sl-node-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `Solrautoscaler` resource is created successfully, ```bash -$ kubectl get solrautoscaler -n demo +kubectl get solrautoscaler -n demo +``` NAME AGE sl-node-autoscaler 100s -$ kubectl describe solrautoscaler -n demo sl-node-autoscaler +```bash +kubectl describe solrautoscaler -n demo sl-node-autoscaler +``` Name: sl-node-autoscaler Namespace: demo Labels: @@ -275,7 +276,6 @@ Status: Memory: 3Gi Vpa Name: solr-combined Events: -``` So, the `Solrautoscaler` resource is created successfully. @@ -284,23 +284,24 @@ you can see in the `Status.VPAs.Recommendation section`, that recommendation has Let's watch the `solropsrequest` in the demo namespace to see if any `solropsrequest` object is created. After some time you'll see that an `Solropsrequest` will be created based on the recommendation. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-combined-04xbzd VerticalScaling Progressing 2m24s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-combined-04xbzd VerticalScaling Successful 2m24s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe slops -n demo slops-solr-combined-04xbzd +kubectl describe slops -n demo slops-solr-combined-04xbzd +``` Name: slops-solr-combined-04xbzd Namespace: demo Labels: app.kubernetes.io/component=database @@ -404,12 +405,12 @@ Events: Normal RestartPods 2m47s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 2m47s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 2m47s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: slops-solr-combined-04xbzd -``` Now, we are going to verify from the Pod, and the Solr YAML whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -420,7 +421,9 @@ $ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resou } } -$ kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "solr") | .resources' +```bash +kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.containers[] | select(.name == "solr") | .resources' +``` { "limits": { "memory": "2Gi" @@ -431,8 +434,6 @@ $ kubectl get solr -n demo solr-combined -o json | jq '.spec.podTemplate.spec.co } } -``` - The above output verifies that we have successfully auto-scaled the resources of the Solr standalone database. ## Cleaning Up @@ -440,7 +441,13 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete sl -n demo solr-combined -$ kubectl delete solrautoscaler -n demo sl-node-autoscaler -$ kubectl delete ns demo +kubectl delete sl -n demo solr-combined +``` + +```bash +kubectl delete solrautoscaler -n demo sl-node-autoscaler +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/solr/autoscaler/compute/topology.md b/docs/guides/solr/autoscaler/compute/topology.md index 87a972210b..6d4b01a3ea 100644 --- a/docs/guides/solr/autoscaler/compute/topology.md +++ b/docs/guides/solr/autoscaler/compute/topology.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` to autoscale compute resources i.e. To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/examples/solr/autoscaler/compute) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -90,22 +90,23 @@ spec: Let's create the `Solr` CRD we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/topology.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/topology.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 82s -``` Let's check an data node containers resources, ```bash -$ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -115,12 +116,12 @@ $ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].r "memory": "2Gi" } } -``` Let's check the Solr CR for the data node resources, ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTemplate.spec.containers[0].resources' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTemplate.spec.containers[0].resources' +``` { "limits": { "memory": "2Gi" @@ -130,7 +131,6 @@ $ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTem "memory": "2Gi" } } -``` You can see from the above outputs that the resources are the same as the ones we have assigned while deploying the Solr. @@ -185,20 +185,23 @@ Here, Let's create the `SolrAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/compute/topology-scaler.yaml -solrautoscaler.autoscaling.kubedb.com/sl-data-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/compute/topology-scaler.yaml ``` +solrautoscaler.autoscaling.kubedb.com/sl-data-autoscaler created #### Verify Autoscaling is set up successfully Let's check that the `Solrautoscaler` resource is created successfully, ```bash -$ kubectl get solrautoscaler -n demo +kubectl get solrautoscaler -n demo +``` NAME AGE sl-data-autoscaler 94s -$ kubectl describe solrautoscaler -n demo sl-data-autoscaler +```bash +kubectl describe solrautoscaler -n demo sl-data-autoscaler +``` Name: sl-data-autoscaler Namespace: demo Labels: @@ -301,8 +304,6 @@ Status: Vpa Name: solr-cluster-overseer Events: -``` - So, the `solrautoscaler` resource is created successfully. @@ -311,23 +312,24 @@ As you can see from the output the vpa has generated a recommendation for the da Let's watch the `solropsrequest` in the demo namespace to see if any `solropsrequest` object is created. After some time you'll see that an `Solropsrequest` will be created based on the recommendation. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-cluster-data-n3vjgi VerticalScaling Progressing 2m7s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-cluster-data-n3vjgi VerticalScaling Successful 2m38s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe slops -n demo slops-solr-cluster-data-n3vjgi +kubectl describe slops -n demo slops-solr-cluster-data-n3vjgi +``` Name: slops-solr-cluster-data-n3vjgi Namespace: demo Labels: app.kubernetes.io/component=database @@ -443,12 +445,12 @@ Events: Normal RestartPods 32s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 32s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 32s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-solr-cluster-data-n3vjgi -``` Now, we are going to verify from the Pod, and the Solr YAML whether the resources of the data node of the cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2560Mi" @@ -459,7 +461,9 @@ $ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].r } } -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTemplate.spec.containers[0].resources' +```bash +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTemplate.spec.containers[0].resources' +``` { "limits": { "memory": "2560Mi" @@ -470,8 +474,6 @@ $ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.podTem } } -``` - The above output verifies that we have successfully auto-scaled the resources of the Solr topology cluster. ## Cleaning Up @@ -479,7 +481,13 @@ The above output verifies that we have successfully auto-scaled the resources of To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete solr -n demo solr-cluster -$ kubectl delete solrautoscaler -n demo sl-data-autoscaler -$ kubectl delete ns demo +kubectl delete solr -n demo solr-cluster +``` + +```bash +kubectl delete solrautoscaler -n demo sl-data-autoscaler +``` + +```bash +kubectl delete ns demo ``` \ No newline at end of file diff --git a/docs/guides/solr/autoscaler/storage/combined.md b/docs/guides/solr/autoscaler/storage/combined.md index 8dd45be855..9b3a6e5a87 100644 --- a/docs/guides/solr/autoscaler/storage/combined.md +++ b/docs/guides/solr/autoscaler/storage/combined.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of an Solr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/examples/solr/autoscaler/storage) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -46,12 +46,12 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get sc +kubectl get sc +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 11d longhorn (default) driver.longhorn.io Delete Immediate true 7d21h longhorn-static driver.longhorn.io Delete Immediate true 7d21h -``` We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. Now, we are going to deploy a `Solr` combined cluster using a supported version by the `KubeDB` operator. Then we are going to apply `SolrAutoscaler` to set up autoscaling. @@ -84,35 +84,35 @@ spec: Let's create the `Solr` CRD we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/combined-scaler.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/combined-scaler.yaml ``` +solr.kubedb.com/solr-combined created Now, wait until `solr-combined` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.6.1 Ready 17m -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1Gi" } } - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-ceee299c-5c50-4f5c-83d5-97e2423bf286 7332Mi RWO Delete Bound demo/solr-combined-data-solr-combined-1 longhorn 19m pvc-d9c2f7c1-7c27-48bd-a87e-cb1935cc2e61 7332Mi RWO Delete Bound demo/solr-combined-data-solr-combined-0 longhorn 19m -``` You can see the PetSet has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -153,21 +153,23 @@ Here, Let's create the `SolrAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/combined-scaler.yaml -solrautoscaler.autoscaling.kubedb.com/sl-storage-autoscaler-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/combined-scaler.yaml ``` +solrautoscaler.autoscaling.kubedb.com/sl-storage-autoscaler-combined created #### Storage Autoscaling is set up successfully Let's check that the `Solrautoscaler` resource is created successfully, ```bash -$ kubectl get solrautoscaler -n demo +kubectl get solrautoscaler -n demo +``` NAME AGE sl-storage-autoscaler-combined 20m - -$ kubectl describe solrautoscaler -n demo sl-storage-autoscaler-combined +```bash +kubectl describe solrautoscaler -n demo sl-storage-autoscaler-combined +``` Name: sl-storage-autoscaler-combined Namespace: demo Labels: @@ -209,7 +211,6 @@ Status: Status: True Type: CreateOpsRequest Events: -``` So, the `solrautoscaler` resource is created successfully. @@ -218,7 +219,8 @@ Now, for this demo, we are going to manually fill up the persistent volume to ex Let's exec into the database pod and fill the database volume using the following commands: ```bash -$ kubectl exec -it -n demo solr-combined-0 -- bash +kubectl exec -it -n demo solr-combined-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-combined-0:/opt/solr-9.6.1$ df -h /var/solr/data Filesystem Size Used Avail Use% Mounted on @@ -232,30 +234,30 @@ Filesystem Size Used Avail Use% Mo [root@es-combined-0 Solr]# df -h /usr/share/Solr/data Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-d9c2f7c1-7c27-48bd-a87e-cb1935cc2e61 7.1G 601M 6.5G 63% /var/solr/data -``` So, from the above output, we can see that the storage usage is 64%, which exceeded the `usageThreshold` 60%. Let's watch the `solropsrequest` in the demo namespace to see if any `solropsrequest` object is created. After some time you'll see that a `Solropsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-combined-gzqvx7 VolumeExpansion Progressing 9m42s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get esops -n demo +kubectl get esops -n demo +``` NAME TYPE STATUS AGE slops-solr-combined-gzqvx7 VolumeExpansion Successful 19m -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe slops -n demo slops-solr-combined-gzqvx7 +kubectl describe slops -n demo slops-solr-combined-gzqvx7 +``` Name: slops-solr-combined-gzqvx7 Namespace: demo Labels: app.kubernetes.io/component=database @@ -380,24 +382,24 @@ Status: Type: Successful Observed Generation: 1 Phase: Successful -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the combined cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "7687602176" } } - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-ceee299c-5c50-4f5c-83d5-97e2423bf286 7332Mi RWO Delete Bound demo/solr-combined-data-solr-combined-1 longhorn 26m pvc-d9c2f7c1-7c27-48bd-a87e-cb1935cc2e61 7332Mi RWO Delete Bound demo/solr-combined-data-solr-combined-0 longhorn -``` The above output verifies that we have successfully autoscaler the volume of the Solr combined cluster. @@ -406,6 +408,9 @@ The above output verifies that we have successfully autoscaler the volume of the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete solr -n demo solr-combined -$ kubectl delete solrautoscaler -n demo sl-storage-autoscaler-combined +kubectl delete solr -n demo solr-combined +``` + +```bash +kubectl delete solrautoscaler -n demo sl-storage-autoscaler-combined ``` diff --git a/docs/guides/solr/autoscaler/storage/topology.md b/docs/guides/solr/autoscaler/storage/topology.md index 2471a219ed..65f70c4bd5 100644 --- a/docs/guides/solr/autoscaler/storage/topology.md +++ b/docs/guides/solr/autoscaler/storage/topology.md @@ -35,9 +35,9 @@ This guide will show you how to use `KubeDB` to autoscale the storage of a solr To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in this [directory](/docs/examples/solr/autoscaler/storage) of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -46,14 +46,13 @@ namespace/demo created At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get sc +kubectl get sc +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 11d longhorn (default) driver.longhorn.io Delete Immediate true 7d22h longhorn-static driver.longhorn.io Delete Immediate true 7d22h -``` - We can see from the output the `longhorn` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. You can install topolvm from [here](https://github.com/topolvm/topolvm) Now, we are going to deploy a `Solr` topology cluster using a supported version by the `KubeDB` operator. Then we are going to apply `SolrAutoscaler` to set up autoscaling. @@ -106,37 +105,37 @@ spec: Let's create the `Solr` CRO we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/topology.yaml -Solr.kubedb.com/es-topology created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/topology.yaml ``` +Solr.kubedb.com/es-topology created Now, wait until `solr-cluster` has status `Ready`. i.e, -```bash - $ kubectl get sl -n demo + ```bash + kubectl get sl -n demo + ``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.6.1 Ready 83s -``` - Let's check volume size from the data petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "1Gi" } } -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-24431af2-8df5-4ad2-a6cd-795dcbdc6355 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-coordinator-0 longhorn 2m15s pvc-5e3430da-545c-4234-a891-3385b100401d 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-overseer-0 longhorn 2m17s pvc-aa75a15f-94cd-475a-a7ad-498023830020 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-data-0 longhorn 2m19s -``` - You can see that the data PetSet has 1GB storage, and the capacity of all the persistent volume is also 1GB. We are now ready to apply the `SolrAutoscaler` CRO to set up storage autoscaling for the data nodes. @@ -178,20 +177,23 @@ Here, Let's create the `SolrAutoscaler` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/topology-scaler.yaml -solrautoscaler.autoscaling.kubedb.com/sl-storage-autoscaler-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/autoscaler/storage/topology-scaler.yaml ``` +solrautoscaler.autoscaling.kubedb.com/sl-storage-autoscaler-topology created #### Storage Autoscaling is set up successfully Let's check that the `solrautoscaler` resource is created successfully, ```bash -$ kubectl get solrautoscaler -n demo +kubectl get solrautoscaler -n demo +``` NAME AGE sl-storage-autoscaler-topology 70s -$ kubectl describe solrautoscaler -n demo sl-storage-autoscaler-topology +```bash +kubectl describe solrautoscaler -n demo sl-storage-autoscaler-topology +``` Name: sl-storage-autoscaler-topology Namespace: demo Labels: @@ -226,17 +228,15 @@ Spec: Usage Threshold: 60 Events: - -``` - So, the `solrautoscaler` resource is created successfully. Now, for this demo, we are going to manually fill up one of the persistent volume to exceed the `usageThreshold` using `dd` command to see if storage autoscaling is working or not. Let's exec into the data nodes and fill the database volume using the following commands: -```bash - $ kubectl exec -it -n demo solr-cluster-data-0 -- bash + ```bash + kubectl exec -it -n demo solr-cluster-data-0 -- bash + ``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-combined-0:/opt/solr-9.6.1$ df -h /var/solr/data Filesystem Size Used Avail Use% Mounted on @@ -249,30 +249,29 @@ solr@solr-cluster-data-0:/opt/solr-9.6.1$ df -h /var/solr/data Filesystem Size Used Avail Use% Mounted on /dev/longhorn/pvc-aa75a15f-94cd-475a-a7ad-498023830020 974M 601M 358M 63% /var/solr/data -``` - So, from the above output we can see that the storage usage is 69%, which exceeded the `usageThreshold` 60%. Let's watch the `solropsrequest` in the demo namespace to see if any `solropsrequest` object is created. After some time you'll see that an `solropsrequest` of type `VolumeExpansion` will be created based on the `scalingThreshold`. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-cluster-0s6kgw VolumeExpansion Progressing 95s -``` Let's wait for the opsRequest to become successful. ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-solr-cluster-0s6kgw VolumeExpansion Successful 2m58s -``` We can see from the above output that the `solrOpsRequest` has succeeded. If we describe the `solrOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe slops -n demo slops-solr-cluster-0s6kgw +kubectl describe slops -n demo slops-solr-cluster-0s6kgw +``` Name: slops-solr-cluster-0s6kgw Namespace: demo Labels: app.kubernetes.io/component=database @@ -407,31 +406,32 @@ Events: Warning delete petset; ConditionStatus:True 3m31s KubeDB Ops-manager Operator delete petset; ConditionStatus:True Warning get petset; ConditionStatus:True 3m26s KubeDB Ops-manager Operator get petset; ConditionStatus:True -``` - Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the data nodes of the cluster has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources' +``` { "requests": { "storage": "2041405440" } } - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE solr-cluster-data-solr-cluster-coordinator-0 Bound pvc-24431af2-8df5-4ad2-a6cd-795dcbdc6355 1Gi RWO longhorn 18m solr-cluster-data-solr-cluster-data-0 Bound pvc-aa75a15f-94cd-475a-a7ad-498023830020 1948Mi RWO longhorn 18m solr-cluster-data-solr-cluster-overseer-0 Bound pvc-5e3430da-545c-4234-a891-3385b100401d 1Gi RWO longhorn 18m -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-24431af2-8df5-4ad2-a6cd-795dcbdc6355 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-coordinator-0 longhorn 18m pvc-5e3430da-545c-4234-a891-3385b100401d 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-overseer-0 longhorn 18m pvc-aa75a15f-94cd-475a-a7ad-498023830020 1948Mi RWO Delete Bound demo/solr-cluster-data-solr-cluster-data-0 longhorn 18m -``` The above output verifies that we have successfully autoscaler the volume of the data nodes of this Solr topology cluster. @@ -440,6 +440,9 @@ The above output verifies that we have successfully autoscaler the volume of the To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete Solr -n demo solr-cluster -$ kubectl delete solrautoscaler -n demo sl-storage-autoscaler-topology +kubectl delete Solr -n demo solr-cluster +``` + +```bash +kubectl delete solrautoscaler -n demo sl-storage-autoscaler-topology ``` diff --git a/docs/guides/solr/clustering/combined_cluster.md b/docs/guides/solr/clustering/combined_cluster.md index 021498831a..20ffee9b4a 100644 --- a/docs/guides/solr/clustering/combined_cluster.md +++ b/docs/guides/solr/clustering/combined_cluster.md @@ -25,13 +25,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/solr/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -78,17 +80,17 @@ Here, Let's create the ZooKeeper CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml -zooKeeper.kubedb.com/zoo-com created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml ``` +zooKeeper.kubedb.com/zoo-com created The ZooKeeper's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get ZooKeeper -n demo -w +kubectl get ZooKeeper -n demo -w +``` NAME TYPE VERSION STATUS AGE zoo-com kubedb.com/v1alpha2 3.7.2 Ready 13m -``` Here, we are going to create a standalone (ie. `replicas: 1`) Solr cluster. We will use the Solr image provided by the Solr (`9.8.0`) for this demo. To learn more about Solr CR, visit [here](/docs/guides/solr/concepts/solr.md). ```yaml @@ -117,24 +119,24 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/combined-standalone.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/combined-standalone.yaml ``` +solr.kubedb.com/solr-combined created Watch the bootstrap progress: ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.6.1 Ready 3h37m -``` - Hence the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +``` NAME READY STATUS RESTARTS AGE pod/solr-combined-0 1/1 Running 0 75s @@ -157,7 +159,6 @@ secret/solr-combined-zk-digest-readonly kubernetes.io/basic-auth 2 78s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/solr-combined-data-solr-combined-0 Bound pvc-c073b8b8-9005-41c5-ac21-bd060a5214a1 1Gi RWO standard 75s -``` - `PetSet` - a PetSet(Appscode manages customized petset) named after the Solr instance. In topology mode, the operator creates 3 PetSets with name `{Solr-Name}-{Sufix}`. - `Services` - 2 services are generated for each Solr database. @@ -179,10 +180,10 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `8983` to local machine: ```bash -$ kubectl port-forward -n demo svc/solr-combined 8983 +kubectl port-forward -n demo svc/solr-combined 8983 +``` Forwarding from 127.0.0.1:8983 -> 8983 Forwarding from [::1]:8983 -> 8983 -``` Now, our Solr cluster is accessible at `localhost:8983`. @@ -192,21 +193,22 @@ Now, our Solr cluster is accessible at `localhost:8983`. - Username: ```bash - $ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d + kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d + ``` admin - ``` - Password: ```bash - $ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d - Xy3ZjyU)~(9IO8_n + kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d ``` + Xy3ZjyU)~(9IO8_n Now let's check the health of our Solr database. ```bash -$ curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +``` { "responseHeader":{ "status":0, @@ -248,7 +250,6 @@ $ curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/co "live_nodes":["solr-combined-0.solr-combined-pods.demo:8983_solr"] } } -``` ## Create Multi-Node Combined Solr Cluster @@ -280,24 +281,24 @@ spec: Let's deploy the above example by the following command: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/combined-multinode.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/combined-multinode.yaml ``` +solr.kubedb.com/solr-combined created Watch the bootstrap progress: ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.6.1 Ready 3h37m -``` - Hence the cluster is ready to use. Let's check the k8s resources created by the operator on the deployment of Elasticsearch CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +``` NAME READY STATUS RESTARTS AGE pod/solr-combined-0 1/1 Running 0 75s pod/solr-combined-1 1/1 Running 0 66s @@ -322,7 +323,6 @@ secret/solr-combined-zk-digest-readonly kubernetes.io/basic-auth 2 78s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/solr-combined-data-solr-combined-0 Bound pvc-c073b8b8-9005-41c5-ac21-bd060a5214a1 1Gi RWO standard 75s persistentvolumeclaim/solr-combined-data-solr-combined-1 Bound pvc-69b509b1-5e42-4b7e-a64e-1b8e15b25bc7 1Gi RWO standard 66s -``` @@ -331,12 +331,16 @@ persistentvolumeclaim/solr-combined-data-solr-combined-1 Bound pvc-69b509b1 To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` solr.kubedb.com/solr-combined patched -$ kubectl delete -n demo sl/solr-combined +```bash +kubectl delete -n demo sl/solr-combined +``` solr.kubedb.com "solr-combined" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted diff --git a/docs/guides/solr/clustering/topology_cluster.md b/docs/guides/solr/clustering/topology_cluster.md index 6917e94201..3f78819322 100644 --- a/docs/guides/solr/clustering/topology_cluster.md +++ b/docs/guides/solr/clustering/topology_cluster.md @@ -23,13 +23,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 7s -``` > Note: YAML files used in this tutorial are stored in [here](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls) in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -38,10 +40,10 @@ demo Active 7s We will have to provide `StorageClass` in Solr CR specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 1h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -124,22 +126,23 @@ Here, Let's deploy the above example by the following command: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/topology.yaml -solr.kubedb.com/solr-cluster created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/topology.yaml ``` +solr.kubedb.com/solr-cluster created KubeDB will create the necessary resources to deploy the Solr cluster according to the above specification. Let’s wait until the database to be ready to use, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 3d2h -``` Here, Solr is in `Ready` state. It means the database is ready to accept connections. Describe the Solr object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ kubectl describe sl -n demo solr-cluster +kubectl describe sl -n demo solr-cluster +``` Name: solr-cluster Namespace: demo Labels: @@ -388,7 +391,6 @@ Status: Type: Provisioned Phase: Ready Events: -``` - Here, in `Status.Conditions` - `Conditions.Status` is `True` for the `Condition.Type:ProvisioningStarted` which means database provisioning has been started successfully. - `Conditions.Status` is `True` for the `Condition.Type:ReplicaReady` which specifies all replicas are ready in the cluster. @@ -401,7 +403,8 @@ Events: Let's check the Kubernetes resources created by the operator on the deployment of Solr CRO: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-cluster' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-cluster' +``` NAME READY STATUS RESTARTS AGE pod/solr-cluster-coordinator-0 1/1 Running 0 3d2h pod/solr-cluster-data-0 1/1 Running 0 3d2h @@ -427,7 +430,6 @@ persistentvolumeclaim/solr-cluster-data-solr-cluster-coordinator-0 Bound pv persistentvolumeclaim/solr-cluster-data-solr-cluster-data-0 Bound pvc-6c7c1f9d-68cd-4ed6-b151-6d1b88dccbe0 1Gi RWO standard 3d2h persistentvolumeclaim/solr-cluster-data-solr-cluster-data-1 Bound pvc-6c7d1f9d-68cd-4ed6-b151-6d1b88dccbe0 1Gi RWO standard 3d2h persistentvolumeclaim/solr-cluster-data-solr-cluster-overseer-0 Bound pvc-106da684-7414-44a7-97e1-f13b65834c36 1Gi RWO standard 3d2h -``` - `PetSet` - 3 PetSets are created for 3 types Solr nodes. The PetSets are named after the Solr instance with given suffix: `{Solr-Name}-{Sufix}`. - `Services` - 3 services are generated for each Solr database. @@ -447,17 +449,17 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio KubeDB will create few Services to connect with the database. Let’s check the Services by following command, ```bash -$ kubectl get svc -n demo -l 'app.kubernetes.io/instance=solr-cluster' +kubectl get svc -n demo -l 'app.kubernetes.io/instance=solr-cluster' +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE solr-cluster ClusterIP 10.43.2.22 8983/TCP 3d2h solr-cluster-pods ClusterIP None 8983/TCP 3d2h -``` Here, we are going to use `solr-cluster` Service to connect with the database. Now, let’s port-forward the `es-cluster` Service to the port `9200` to local machine: ```bash -$ kubectl port-forward -n demo svc/solr-cluster 8983 -Forwarding from 127.0.0.1:8983 -> 8983 +kubectl port-forward -n demo svc/solr-cluster 8983 ``` +Forwarding from 127.0.0.1:8983 -> 8983 Now, our Solr cluster is accessible at `localhost:8983`. #### Export the Credentials @@ -465,14 +467,14 @@ Now, our Solr cluster is accessible at `localhost:8983`. KubeDB also create some Secrets for the database. Let’s check which Secrets have been created by KubeDB for our `es-cluster`. ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE solr-cluster-auth kubernetes.io/basic-auth 2 10d solr-cluster-auth-config Opaque 1 10d solr-cluster-config Opaque 1 3d2h solr-cluster-zk-digest kubernetes.io/basic-auth 2 10d solr-cluster-zk-digest-readonly kubernetes.io/basic-auth 2 10d -``` Now, we can connect to the database with `solr-cluster-auth` which contains the admin level credentials to connect with the database. ### Accessing Database Through CLI @@ -480,17 +482,21 @@ Now, we can connect to the database with `solr-cluster-auth` which contains the To access the database through CLI, we have to get the credentials to access. Let’s export the credentials as environment variable to our current shell : ```bash -$ kubectl get secret -n demo solr-cluster-auth -o jsonpath='{.data.username}' | base64 -d +kubectl get secret -n demo solr-cluster-auth -o jsonpath='{.data.username}' | base64 -d +``` elastic -$ kubectl get secret -n demo solr-cluster-auth -o jsonpath='{.data.password}' | base64 -d -tS$k!2IBI.ASI7FJ + +```bash +kubectl get secret -n demo solr-cluster-auth -o jsonpath='{.data.password}' | base64 -d ``` +tS$k!2IBI.ASI7FJ Now, let's check the health of our Solr cluster -```bash # curl -XGET -k -u 'username:password' https://localhost:9200/_cluster/health?pretty" -$ curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +```bash +curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +``` { "responseHeader":{ "status":0, @@ -536,14 +542,13 @@ $ curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admi } } -``` - ## Insert Sample Data Now, we are going to insert some data into Solr. ```bash -$ curl -XPOST -k -u "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=CREATE&name=book&numShards=2&replicationFactor=2&wt=xml" +curl -XPOST -k -u "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=CREATE&name=book&numShards=2&replicationFactor=2&wt=xml" +``` @@ -581,11 +586,11 @@ $ curl -XPOST -k -u "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/c book_shard1_replica_n2 -``` Now, let’s verify that the index have been created successfully. ```bash -$ curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=LIST" +curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admin/collections?action=LIST" +``` { "responseHeader":{ "status":0, @@ -593,11 +598,11 @@ $ curl -XGET -k --user "admin:7eONFVgU9BS50eiB" "http://localhost:8983/solr/admi }, "collections":["book","kubedb-system"] } -``` Also, let’s verify the data in the indexes: ```bash -$ curl -X POST -u "admin:7eONFVgU9BS50eiB" http://localhost:8983/solr/book/select -H 'Content-Type: application/json' -d ' +curl -X POST -u "admin:7eONFVgU9BS50eiB" http://localhost:8983/solr/book/select -H 'Content-Type: application/json' -d ' +``` { "query": "*:*", "limit": 10, @@ -624,20 +629,22 @@ $ curl -X POST -u "admin:7eONFVgU9BS50eiB" http://localhost:8983/solr/book/sele } } -``` - ## Cleaning Up To cleanup the k8s resources created by this tutorial, run: ```bash -$ kubectl patch -n demo solr solr-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo solr solr-cluster -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` -$ kubectl delete Solr -n demo solr-cluster +```bash +kubectl delete Solr -n demo solr-cluster +``` # Delete namespace -$ kubectl delete namespace demo +```bash +kubectl delete namespace demo ``` ## Next Steps diff --git a/docs/guides/solr/concepts/solr.md b/docs/guides/solr/concepts/solr.md index e88057bc86..552934aaff 100644 --- a/docs/guides/solr/concepts/solr.md +++ b/docs/guides/solr/concepts/solr.md @@ -135,11 +135,11 @@ AuthSecret contains a `username` key and a `password` key which contains the `us Example: ```bash -$ kubectl create secret generic solr-cluster-admin0-cred -n demo \ +kubectl create secret generic solr-cluster-admin0-cred -n demo \ --from-literal=username=admin \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "solr-cluster-admin-cred" created ``` +secret "solr-cluster-admin-cred" created ```yaml apiVersion: v1 diff --git a/docs/guides/solr/configuration/config-file.md b/docs/guides/solr/configuration/config-file.md index 7a566e5fb4..27611b1674 100644 --- a/docs/guides/solr/configuration/config-file.md +++ b/docs/guides/solr/configuration/config-file.md @@ -29,9 +29,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -75,9 +75,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/configuration/sl-custom-config.yaml -secret/sl-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/configuration/sl-custom-config.yaml ``` +secret/sl-custom-config created In this section, we are going to create a Solr object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Solr` CR that we are going to create, @@ -107,23 +107,24 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/configuration/solr.yaml -solr.kubedb.com/solr created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/configuration/solr.yaml ``` +solr.kubedb.com/solr created Now, wait until `solr` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr kubedb.com/v1alpha2 9.6.1 Ready 10m -``` Now, we will check if the Solr has started with the custom configuration we have provided. Exec into the Solr pod and execute the following commands to see the configurations: ```bash -$ kubectl exec -it -n demo solr-0 -- bash +kubectl exec -it -n demo solr-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml @@ -158,8 +159,6 @@ solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml -``` - ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: diff --git a/docs/guides/solr/configuration/custom-pod-template.md b/docs/guides/solr/configuration/custom-pod-template.md index 0c74948efa..80a7f2fc4b 100644 --- a/docs/guides/solr/configuration/custom-pod-template.md +++ b/docs/guides/solr/configuration/custom-pod-template.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Solr via [PodTemplate](/docs/ - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/guides/solr/configuration/podtemplating/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/Solr/configuration/podtemplating/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -136,26 +136,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/configuration/sl-custom-podtemplate.yaml -Solr.kubedb.com/solr-misc-config created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/configuration/sl-custom-podtemplate.yaml ``` +Solr.kubedb.com/solr-misc-config created Now, wait a few minutes. KubeDB operator will create necessary PVC, petset, services, secret etc. If everything goes well, we will see that a pod with the name `sdb-misc-config-aggregator-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-misc-config +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-misc-config +``` NAME READY STATUS RESTARTS AGE solr-misc-config-coordinator-0 1/1 Running 0 3m30s solr-misc-config-data-0 1/1 Running 0 3m35s solr-misc-config-overseer-0 1/1 Running 0 3m33s -``` Now, we will check if the database has started with the custom configuration we have provided. ```bash -$ kubectl get pod -n demo solr-misc-config-coordinator-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-misc-config-coordinator-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "900m", @@ -167,7 +168,9 @@ $ kubectl get pod -n demo solr-misc-config-coordinator-0 -o json | jq '.spec.con } } -$ kubectl get pod -n demo solr-misc-config-data-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo solr-misc-config-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "900m", @@ -179,7 +182,9 @@ $ kubectl get pod -n demo solr-misc-config-data-0 -o json | jq '.spec.containers } } -$ kubectl get pod -n demo solr-misc-config-overseer-0 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo solr-misc-config-overseer-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "900m", @@ -191,15 +196,14 @@ $ kubectl get pod -n demo solr-misc-config-overseer-0 -o json | jq '.spec.contai } } -``` - ## 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 Solr 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 +kubectl get nodes +``` NAME STATUS ROLES AGE VERSION gke-pritam-default-pool-c682fe6e-59x3 Ready 110m v1.30.5-gke.1443001 gke-pritam-default-pool-c682fe6e-rbtx Ready 110m v1.30.5-gke.1443001 @@ -210,21 +214,21 @@ gke-pritam-default-pool-cc96ce9b-vbpc Ready 110m v1.30.5-gke.144 gke-pritam-default-pool-dadbf4db-5fv5 Ready 110m v1.30.5-gke.1443001 gke-pritam-default-pool-dadbf4db-5vkv Ready 110m v1.30.5-gke.1443001 gke-pritam-default-pool-dadbf4db-p039 Ready 110m v1.30.5-gke.1443001 -``` As you see, we have nine nodes in the cluster. Let’s say we want pods to schedule to nodes with key `topology.gke.io/zone` and value `us-central1-b` ```bash -$ kubectl get nodes -n demo -l topology.gke.io/zone=us-central1-b +kubectl get nodes -n demo -l topology.gke.io/zone=us-central1-b +``` NAME STATUS ROLES AGE VERSION gke-pritam-default-pool-c682fe6e-59x3 Ready 118m v1.30.5-gke.1443001 gke-pritam-default-pool-c682fe6e-rbtx Ready 118m v1.30.5-gke.1443001 gke-pritam-default-pool-c682fe6e-spdb Ready 118m v1.30.5-gke.1443001 -``` As you see, the gke-pritam-default-pool-c682fe6e-59x3 now has a new label topology.gke.io/zone=us-central1-b. To see all labels attached to the node, you can also run: ```bash -$ kubectl describe nodes gke-pritam-default-pool-c682fe6e-59x3 +kubectl describe nodes gke-pritam-default-pool-c682fe6e-59x3 +``` Name: gke-pritam-default-pool-c682fe6e-59x3 Roles: Labels: beta.kubernetes.io/arch=amd64 @@ -252,7 +256,6 @@ Labels: beta.kubernetes.io/arch=amd64 topology.gke.io/zone=us-central1-b topology.kubernetes.io/region=us-central1 topology.kubernetes.io/zone=us-central1-b -``` Now let's create a Solr with this new label as nodeSelector. Below is the yaml we are going to apply: ```yaml @@ -280,26 +283,26 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/configuration/sl-custom-nodeselector.yaml -solr.kubedb.com/solr-node-selector created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/configuration/sl-custom-nodeselector.yaml ``` +solr.kubedb.com/solr-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 `sdb-node-selector-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-custom-nodeselector +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-custom-nodeselector +``` NAME READY STATUS RESTARTS AGE solr-custom-nodeselector-0 1/1 Running 0 3m18s solr-custom-nodeselector-1 1/1 Running 0 2m54s -``` As we see the pod is running, you can verify that by running `kubectl get pods -n demo sdb-node-selector-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-custom-nodeselector -owide +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-custom-nodeselector -owide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES solr-custom-nodeselector-0 1/1 Running 0 3m52s 10.12.7.7 gke-pritam-default-pool-c682fe6e-spdb solr-custom-nodeselector-1 1/1 Running 0 3m28s 10.12.8.9 gke-pritam-default-pool-c682fe6e-59x3 -``` We can successfully verify that our pod was scheduled to our desired node. ## Using Taints and Tolerations @@ -307,7 +310,8 @@ We can successfully verify that our pod was scheduled to our desired node. Here in this example we will use [Taints and Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to schedule our Solr 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 +kubectl get nodes +``` NAME STATUS ROLES AGE VERSION gke-pritam-default-pool-c682fe6e-59x3 Ready 123m v1.30.5-gke.1443001 gke-pritam-default-pool-c682fe6e-rbtx Ready 123m v1.30.5-gke.1443001 @@ -318,33 +322,57 @@ gke-pritam-default-pool-cc96ce9b-vbpc Ready 123m v1.30.5-gke.144 gke-pritam-default-pool-dadbf4db-5fv5 Ready 123m v1.30.5-gke.1443001 gke-pritam-default-pool-dadbf4db-5vkv Ready 123m v1.30.5-gke.1443001 gke-pritam-default-pool-dadbf4db-p039 Ready 123m v1.30.5-gke.1443001 -``` As you see, we have nine nodes in the cluster Next, we are going to taint these nodes. ```bash -$ kubectl taint nodes gke-pritam-default-pool-c682fe6e-59x3 key1=node1:NoSchedule +kubectl taint nodes gke-pritam-default-pool-c682fe6e-59x3 key1=node1:NoSchedule +``` node/gke-pritam-default-pool-c682fe6e-59x3 tainted -$ kubectl taint nodes gke-pritam-default-pool-c682fe6e-rbtx key1=node2:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-c682fe6e-rbtx key1=node2:NoSchedule +``` node/gke-pritam-default-pool-c682fe6e-rbtx tainted -$ kubectl taint nodes gke-pritam-default-pool-c682fe6e-spdb key1=node3:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-c682fe6e-spdb key1=node3:NoSchedule +``` node/gke-pritam-default-pool-c682fe6e-spdb tainted -$ kubectl taint nodes gke-pritam-default-pool-cc96ce9b-049h key1=node4:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-cc96ce9b-049h key1=node4:NoSchedule +``` node/gke-pritam-default-pool-cc96ce9b-049h tainted -$ kubectl taint nodes gke-pritam-default-pool-cc96ce9b-b8p8 key1=node5:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-cc96ce9b-b8p8 key1=node5:NoSchedule +``` node/gke-pritam-default-pool-cc96ce9b-b8p8 tainted -$ kubectl taint nodes gke-pritam-default-pool-cc96ce9b-vbpc key1=node6:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-cc96ce9b-vbpc key1=node6:NoSchedule +``` node/gke-pritam-default-pool-cc96ce9b-vbpc tainted -$ kubectl taint nodes gke-pritam-default-pool-dadbf4db-5fv5 key1=node7:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-dadbf4db-5fv5 key1=node7:NoSchedule +``` node/gke-pritam-default-pool-dadbf4db-5fv5 tainted -$ kubectl taint nodes gke-pritam-default-pool-dadbf4db-5vkv key1=node8:NoSchedule + +```bash +kubectl taint nodes gke-pritam-default-pool-dadbf4db-5vkv key1=node8:NoSchedule +``` node/gke-pritam-default-pool-dadbf4db-5vkv tainted -$ kubectl taint nodes gke-pritam-default-pool-dadbf4db-p039 key1=node9:NoSchedule -node/gke-pritam-default-pool-dadbf4db-p039 tainted + +```bash +kubectl taint nodes gke-pritam-default-pool-dadbf4db-p039 key1=node9:NoSchedule ``` +node/gke-pritam-default-pool-dadbf4db-p039 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' +kubectl get nodes -o json | jq -r '.items[] | select(.spec.taints != null) | .metadata.name, .spec.taints' +``` gke-pritam-default-pool-c682fe6e-59x3 [ { @@ -417,7 +445,6 @@ gke-pritam-default-pool-dadbf4db-p039 "value": "node9" } ] -``` We can see that our taints were successfully assigned. Now let's try to create a Solr without proper tolerations. Here is the yaml of Solr we are going to createc ```yaml apiVersion: kubedb.com/v1alpha2 @@ -439,20 +466,21 @@ spec: storage: 1Gi ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/configuration/solr-without-tolerations.yaml -solr.kubedb.com/solr-without-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/configuration/solr-without-tolerations.yaml ``` +solr.kubedb.com/solr-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 `sdb-without-tolerations-0` has been created and running. Check that the petset's pod is running or not, ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-without-toleration +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-without-toleration +``` NAME READY STATUS RESTARTS AGE solr-without-toleration-0 0/1 Pending 0 64s -``` Here we can see that the pod is not running. So let's describe the pod, ```bash -$ kubectl describe pod -n demo solr-without-toleration-0 +kubectl describe pod -n demo solr-without-toleration-0 +``` Name: solr-without-toleration-0 Namespace: demo Priority: 0 @@ -594,7 +622,6 @@ Events: ---- ------ ---- ---- ------- Normal NotTriggerScaleUp 106s cluster-autoscaler pod didn't trigger scale-up: Warning FailedScheduling 104s (x2 over 106s) default-scheduler 0/9 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}, 1 node(s) had untolerated taint {key1: node4}, 1 node(s) had untolerated taint {key1: node5}, 1 node(s) had untolerated taint {key1: node6}, 1 node(s) had untolerated taint {key1: node7}, 1 node(s) had untolerated taint {key1: node8}, 1 node(s) had untolerated taint {key1: node9}. preemption: 0/9 nodes are available: 9 Preemption is not helpful for scheduling. -``` 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 Solr. Here is the yaml we are going to apply, @@ -630,26 +657,26 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/Solr/configuration/solr-with-tolerations.yaml -solr.kubedb.com/solr-with-tolerations created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/Solr/configuration/solr-with-tolerations.yaml ``` +solr.kubedb.com/solr-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 `sdb-with-tolerations-0` has been created. Check that the petset's pod is running ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-with-toleration +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-with-toleration +``` NAME READY STATUS RESTARTS AGE solr-with-toleration-0 1/1 Running 0 2m12s solr-with-toleration-1 1/1 Running 0 80s -``` As we see the pod is running, you can verify that by running `kubectl get pods -n demo sdb-with-tolerations-0 -o wide` and looking at the “NODE” to which the Pod was assigned. ```bash -$ kubectl get pod -n demo -l app.kubernetes.io/instance=solr-with-toleration -owide +kubectl get pod -n demo -l app.kubernetes.io/instance=solr-with-toleration -owide +``` NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES solr-with-toleration-0 1/1 Running 0 2m37s 10.12.3.7 gke-pritam-default-pool-dadbf4db-5fv5 solr-with-toleration-1 1/1 Running 0 105s 10.12.5.5 gke-pritam-default-pool-dadbf4db-5vkv -``` We can successfully verify that our pod was scheduled to the node which it has tolerations. ## Cleaning up diff --git a/docs/guides/solr/failover/overview.md b/docs/guides/solr/failover/overview.md index 2323a93f6d..6fb36d5abd 100644 --- a/docs/guides/solr/failover/overview.md +++ b/docs/guides/solr/failover/overview.md @@ -45,16 +45,17 @@ remain highly available, even in the face of failures. - To keep things isolated, this tutorial uses a separate namespace called 'demo' throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Find Available Solr Versions When you have installed KubeDB, it has created `SolrVersion` CR for all supported Solr versions. Check available versions by: ```bash -$ kubectl get solrversions + kubectl get solrversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 8.11.4 8.11.4 ghcr.io/appscode-images/solr:8.11.4 27d 9.4.1 9.4.1 ghcr.io/appscode-images/solr:9.4.1 27d @@ -62,8 +63,6 @@ NAME VERSION DB_IMAGE DEPRECATED AGE 9.7.0 9.7.0 ghcr.io/appscode-images/solr:9.7.0 27d 9.8.0 9.8.0 ghcr.io/appscode-images/solr:9.8.0 27d -``` - ## Deploy a Highly Available Solr Cluster The KubeDB operator implements a Solr CRD to define the specification of a Solr database. @@ -99,19 +98,18 @@ We have to apply zookeeper first and wait till atleast pods are running to make Let's create the ZooKeeper CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml -zooKeeper.kubedb.com/zoo-com created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml ``` +zooKeeper.kubedb.com/zoo-com created The ZooKeeper's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get zookeeper -n demo -w +kubectl get zookeeper -n demo -w +``` NAME TYPE VERSION STATUS AGE zoo-com kubedb.com/v1alpha2 3.8.3 Ready 4d -``` - Then we can deploy solr in our cluster. The Solr instance used for this tutorial: @@ -141,14 +139,15 @@ spec: Apply the manifest: ```bash -$ kubectl apply -f solr-ha.yaml -solr.kubedb.com/solr-ha created +kubectl apply -f solr-ha.yaml ``` +solr.kubedb.com/solr-ha created Monitor the status: ```bash -$ kubectl get solr,pods -n demo +kubectl get solr,pods -n demo +``` NAME TYPE VERSION STATUS AGE solr.kubedb.com/solr-ha kubedb.com/v1alpha2 9.4.1 Ready 4d @@ -160,12 +159,11 @@ pod/zoo-com-0 1/1 Running 2 (103m ago) 4d pod/zoo-com-1 1/1 Running 2 (103m ago) 4d pod/zoo-com-2 1/1 Running 2 (103m ago) 4d -``` - Let's create a collection and add some data to test failover scenarios: ```bash -$ kubectl exec -it -n demo solr-ha-0 -- bash +kubectl exec -it -n demo solr-ha-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-ha-0:/opt/solr-9.4.1$ alias solr_curl='curl -u admin:c4d0IeGGDO**1h9y' solr@solr-ha-0:/opt/solr-9.4.1$ solr_curl "http://localhost:8983/solr/admin/collections?action=CREATE&name=sattriyam&numShards=1&replicationFactor=1&wt=json" @@ -192,13 +190,11 @@ solr@solr-ha-0:/opt/solr-9.4.1$ solr_curl "http://localhost:8983/solr/admin/col }, "collections":["kubedb-system","sattriyam"] }solr@solr-ha-0:/opt/solr-9.4.1$ - - -``` If we check another pod, we can see the collection there as well: ```bash -$ kubectl exec -it -n demo solr-ha-1 -- bash +kubectl exec -it -n demo solr-ha-1 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-ha-1:/opt/solr-9.4.1$ alias solr_curl='curl -u admin:c4d0IeGGDO**1h9y' @@ -249,8 +245,6 @@ solr@solr-ha-1:/opt/solr-9.4.1$ solr_curl "http://localhost:8983/solr/admin/col "_version_":1845866210893234177 }] } - -``` 📌 Note: Because every Solr node is both readable and writable, data created in one pod is automatically replicated to other pods that host replicas of the same shard. If any pod is deleted or fails, there will be no data loss as long as other replicas are available, since the data is stored in persistent @@ -285,14 +279,14 @@ When a Solr node fails: Let's simulate by deleting a pod: ```bash -$ kubectl delete pod -n demo solr-ha-0 -pod "solr-ha-0" deleted +kubectl delete pod -n demo solr-ha-0 ``` +pod "solr-ha-0" deleted Watch the recovery: ```bash -$ watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" +watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" ``` ```shell solr-ha-0 @@ -311,7 +305,8 @@ During this process: Let's verify the collection is still accessible: ```bash -$ $ kubectl exec -it -n demo solr-ha-1 -- bash +kubectl exec -it -n demo solr-ha-1 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-ha-1:/opt/solr-9.4.1$ alias solr_curl='curl -u admin:c4d0IeGGDO**1h9y' @@ -362,7 +357,6 @@ solr@solr-ha-1:/opt/solr-9.4.1$ solr_curl "http://localhost:8983/solr/admin/col "_version_":1845866210893234177 }] } -``` ### Scenario 2: Multiple Node Failure @@ -373,14 +367,14 @@ Even with multiple node failures, Solr remains available as long as: Let's simulate multiple failures: ```bash -$ kubectl delete pod -n demo solr-ha-0 solr-ha-1 +kubectl delete pod -n demo solr-ha-0 solr-ha-1 +``` pod "solr-ha-0" deleted pod "solr-ha-1" deleted -``` Watch the recovery: ```bash -$ watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" +watch -n 2 "kubectl get pods -n demo -o jsonpath='{range .items[*]}{.metadata.name} {.metadata.labels.kubedb\\.com/role}{\"\\n\"}{end}'" ``` ```shell solr-ha-0 @@ -396,7 +390,7 @@ zoo-com-2 In case all nodes fail: ```bash -$ kubectl delete pod -n demo solr-ha-0 solr-ha-1 solr-ha-2 +kubectl delete pod -n demo solr-ha-0 solr-ha-1 solr-ha-2 ``` The cluster will recover automatically, but full availability requires: @@ -408,7 +402,10 @@ The cluster will recover automatically, but full availability requires: ## Cleanup ```bash -$ kubectl delete solr -n demo solr-ha -$ kubectl delete ns demo +kubectl delete solr -n demo solr-ha +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/solr/monitoring/prometheus-builtin.md b/docs/guides/solr/monitoring/prometheus-builtin.md index 2ad40a690e..93496ab356 100644 --- a/docs/guides/solr/monitoring/prometheus-builtin.md +++ b/docs/guides/solr/monitoring/prometheus-builtin.md @@ -33,12 +33,14 @@ This tutorial will show you how to monitor Solr database using builtin [Promethe - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/elasticsearch) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -80,32 +82,33 @@ Here, Let's create the Elasticsearch crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/monitoring/solr-builtin.yaml -solr.kubedb.com/builtin-prom-sl created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/monitoring/solr-builtin.yaml ``` +solr.kubedb.com/builtin-prom-sl created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE builtin-prom-sl kubedb.com/v1alpha2 9.6.1 Ready 59m -``` KubeDB will create a separate stats service with name `{Solr crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo -l 'app.kubernetes.io/instance=builtin-prom-sl' +kubectl get svc -n demo -l 'app.kubernetes.io/instance=builtin-prom-sl' +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE builtin-prom-sl ClusterIP 10.96.94.160 8983/TCP 59m builtin-prom-sl-pods ClusterIP None 8983/TCP 59m builtin-prom-sl-stats ClusterIP 10.96.157.93 9854/TCP 59m -``` Here, `builtin-prom-sl-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo builtin-prom-sl-stats +kubectl describe svc -n demo builtin-prom-sl-stats +``` Name: builtin-prom-sl-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -128,7 +131,6 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.54:9854,10.244.0.56:9854 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -292,20 +294,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/builtin-prometheus/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -316,9 +318,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -327,18 +329,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-8568c86d86-95zhn 1/1 Running 0 77s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-8568c86d86-95zhn` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +kubectl port-forward -n monitoring prometheus-8568c86d86-95zhn 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `builtin-prom-es-stats` service as one of the targets. @@ -355,14 +357,29 @@ Now, you can view the collected metrics and create a graph from homepage of this To cleanup the Kubernetes resources created by this tutorial, run following commands ```bash -$ kubectl delete -n demo es/builtin-prom-es +kubectl delete -n demo es/builtin-prom-es +``` + +```bash +kubectl delete -n monitoring deployment.apps/prometheus +``` + +```bash +kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete -n monitoring deployment.apps/prometheus +```bash +kubectl delete -n monitoring serviceaccount/prometheus +``` -$ kubectl delete -n monitoring clusterrole.rbac.authorization.k8s.io/prometheus -$ kubectl delete -n monitoring serviceaccount/prometheus -$ kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +```bash +kubectl delete -n monitoring clusterrolebinding.rbac.authorization.k8s.io/prometheus +``` -$ kubectl delete ns demo -$ kubectl delete ns monitoring +```bash +kubectl delete ns demo +``` + +```bash +kubectl delete ns monitoring ``` \ No newline at end of file diff --git a/docs/guides/solr/monitoring/prometheus-operator.md b/docs/guides/solr/monitoring/prometheus-operator.md index f6e7f0ba9e..3fe978d5d6 100644 --- a/docs/guides/solr/monitoring/prometheus-operator.md +++ b/docs/guides/solr/monitoring/prometheus-operator.md @@ -28,13 +28,15 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. -```bash - $ kubectl create ns monitoring + ```bash + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -49,17 +51,18 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus -A +kubectl get prometheus -A +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 11d -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. Now, let's view the YAML of the available Prometheus server `prometheus` in `monitoring` namespace. ```bash -$ kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +kubectl get prometheus -n monitoring prometheus-kube-prometheus-prometheus -oyaml +``` apiVersion: monitoring.coreos.com/v1 kind: Prometheus metadata: @@ -164,7 +167,6 @@ status: shards: 1 unavailableReplicas: 0 updatedReplicas: 1 -``` Notice the `spec.serviceMonitorSelector` section. Here, `release: prometheus` label is used to select `ServiceMonitor` crd. So, we are going to use this label in `spec.monitor.prometheus.labels` field of Solr crd. @@ -217,34 +219,35 @@ Here, Let's create the Elasticsearch object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/monitoring/solr-operator.yaml -solr.kubedb.com/operator-prom-sl created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/monitoring/solr-operator.yaml ``` +solr.kubedb.com/operator-prom-sl created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE operator-prom-sl kubedb.com/v1alpha2 9.6.1 Ready 104m -``` KubeDB will create a separate stats service with name `{Solr crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo -l 'app.kubernetes.io/instance=operator-prom-sl' +kubectl get svc -n demo -l 'app.kubernetes.io/instance=operator-prom-sl' +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE operator-prom-sl ClusterIP 10.96.76.207 8983/TCP 122m operator-prom-sl-pods ClusterIP None 8983/TCP 122m operator-prom-sl-stats ClusterIP 10.96.192.50 9854/TCP 122m -``` Here, `operator-prom-sl-stats` service has been created for monitoring purpose. Let's describe this stats service. ```bash -$ kubectl describe svc -n demo operator-prom-sl-stats +kubectl describe svc -n demo operator-prom-sl-stats +``` Name: operator-prom-sl-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -264,22 +267,22 @@ TargetPort: metrics/TCP Endpoints: 10.244.0.37:9854,10.244.0.39:9854 Session Affinity: None Events: -``` Notice the `Labels` and `Port` fields. `ServiceMonitor` will use these information to target its endpoints. KubeDB will also create a `ServiceMonitor` crd in `monitoring` namespace that select the endpoints of `coreos-prom-es-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE operator-prom-sl-stats 125m -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of Elasticsearch crd. ```bash -$ kubectl get servicemonitor -n demo operator-prom-sl-stats -oyaml +kubectl get servicemonitor -n demo operator-prom-sl-stats -oyaml +``` apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -318,7 +321,6 @@ spec: app.kubernetes.io/managed-by: kubedb.com app.kubernetes.io/name: solrs.kubedb.com kubedb.com/role: stats -``` Notice that the `ServiceMonitor` has label `release: prometheus` that we had specified in Solr crd. @@ -329,22 +331,22 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=release=prometheus +kubectl get pod -n monitoring -l=release=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-kube-prometheus-operator-6c8698f59d-cljvq 1/1 Running 12 (4h11m ago) 12d prometheus-kube-state-metrics-5548456c74-ksh5n 1/1 Running 13 (4h10m ago) 12d prometheus-prometheus-node-exporter-n5ht8 1/1 Running 9 (4h11m ago) 12d -``` Prometheus server is listening to port `9090` of `prometheus-kube-prometheus-operator-6c8698f59d-cljvq` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-kube-prometheus-operator-6c8698f59d-cljvq 9090 +kubectl port-forward -n monitoring prometheus-kube-prometheus-operator-6c8698f59d-cljvq 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `prom-http` endpoint of `operator-prom-sl-stats` service as one of the targets. diff --git a/docs/guides/solr/quickstart/overview/index.md b/docs/guides/solr/quickstart/overview/index.md index af589b82e5..fe1f06c1de 100644 --- a/docs/guides/solr/quickstart/overview/index.md +++ b/docs/guides/solr/quickstart/overview/index.md @@ -29,13 +29,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [docs/guides/solr/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -46,10 +48,10 @@ demo Active 9s We will have to provide `StorageClass` in Solr CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -58,11 +60,11 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named `SolrVersions`. The installation process comes with a set of tested SolrVersion objects. Let's check available SolrVersions by, ```bash -$ kubectl get solrversion +kubectl get solrversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 8.11.2 8.11.2 ghcr.io/appscode-images/solr:8.11.2 9d 9.4.1 9.4.1 ghcr.io/appscode-images/solr:9.4.1 9d -``` Notice the `DEPRECATED` column. Here, `true` means that this SolrVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated SolrVersion. @@ -115,17 +117,17 @@ Here, Let's create the ZooKeeper CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml -zooKeeper.kubedb.com/zoo-com created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml ``` +zooKeeper.kubedb.com/zoo-com created The ZooKeeper's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get zookeeper -n demo -w +kubectl get zookeeper -n demo -w +``` NAME TYPE VERSION STATUS AGE zoo-com kubedb.com/v1alpha2 3.7.2 Ready 13m -``` Then we can deploy solr in our cluster. @@ -166,23 +168,24 @@ Here, Let's create the Solr CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml -solr.kubedb.com/solr-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml ``` +solr.kubedb.com/solr-combined created The Solr's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get Solr -n demo -w +kubectl get Solr -n demo -w +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.4.1 Ready 17m -``` Describe the Solr object to observe the progress if something goes wrong or the status is not changing for a long period of time: ```bash -$ Name: solr-combined +Name: solr-combined +``` Namespace: demo Labels: Annotations: @@ -310,14 +313,14 @@ Status: Type: DatabaseReadAccess Phase: Ready Events: -``` ### KubeDB Operator Generated Resources On deployment of a Solr CR, the operator creates the following resources: ```bash -$ kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +kubectl get all,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +``` NAME READY STATUS RESTARTS AGE pod/solr-combined-0 1/1 Running 0 3m40s pod/solr-combined-1 1/1 Running 0 3m33s @@ -345,7 +348,6 @@ NAME STATUS VOLUME persistentvolumeclaim/solr-combined-data-solr-combined-0 Bound pvc-6dc5573b-b59f-4ad7-beed-7438400ff500 1Gi RWO standard 3m40s persistentvolumeclaim/solr-combined-data-solr-combined-1 Bound pvc-1649cba5-b5e1-421b-aa73-ab6a4be0d637 1Gi RWO standard 3m33s persistentvolumeclaim/solr-combined-data-solr-combined-2 Bound pvc-dcb8c9e2-e64b-4a53-8b46-5c30301bb905 1Gi RWO standard 3m26s -``` - `PetSet` - a PetSet(Appscode manages customized petset) named after the Solr instance. In topology mode, the operator creates 3 PetSets with name `{Solr-Name}-{Sufix}`. - `Services` - 2 services are generated for each Solr database. @@ -367,10 +369,10 @@ We will use [port forwarding](https://kubernetes.io/docs/tasks/access-applicatio Let's port-forward the port `8983` to local machine: ```bash -$ kubectl port-forward -n demo svc/solr-combined 8983 +kubectl port-forward -n demo svc/solr-combined 8983 +``` Forwarding from 127.0.0.1:8983 -> 8983 Forwarding from [::1]:8983 -> 8983 -``` Now, our Solr cluster is accessible at `localhost:8983`. @@ -380,21 +382,22 @@ Now, our Solr cluster is accessible at `localhost:8983`. - Username: ```bash - $ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d + kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d + ``` admin - ``` - Password: ```bash - $ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d - Xy3ZjyU)~(9IO8_n + kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d ``` + Xy3ZjyU)~(9IO8_n Now let's check the health of our Solr database. ```bash -$ curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/collections?action=CLUSTERSTATUS" +``` { "responseHeader":{ "status":0, @@ -436,7 +439,6 @@ $ curl -XGET -k -u 'admin:Xy3ZjyU)~(9IO8_n' "http://localhost:8983/solr/admin/co "live_nodes":["solr-combined-2.solr-combined-pods.demo:8983_solr","solr-combined-1.solr-combined-pods.demo:8983_solr","solr-combined-0.solr-combined-pods.demo:8983_solr"] } } -``` From the health information above, we can see that health of our collections in Solr cluster's status is `green` which means the cluster is healthy. @@ -447,21 +449,22 @@ KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or lat To halt the database, we have to set `spec.deletionPolicy:` to `Halt` by updating it, ```bash -$ kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" -solr.kubedb.com/solr-combined patched +kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"Halt"}}' --type="merge" ``` +solr.kubedb.com/solr-combined patched Now, if you delete the Solr object, the KubeDB operator will delete every resource created for this Solr CR, but leaves the auth secrets, and PVCs. ```bash -$ kubectl delete solr -n demo solr-combined -solr.kubedb.com "solr-combined" deleted + kubectl delete solr -n demo solr-combined ``` +solr.kubedb.com "solr-combined" deleted Check resources: ```bash -$ kubectl get all,petset,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +kubectl get all,petset,secret,pvc -n demo -l 'app.kubernetes.io/instance=solr-combined' +``` NAME TYPE DATA AGE secret/solr-combined-admin-cred kubernetes.io/basic-auth 2 9d secret/solr-combined-auth-config Opaque 1 9d @@ -473,8 +476,6 @@ persistentvolumeclaim/solr-combined-data-solr-combined-0 Bound pvc-6dc5573b persistentvolumeclaim/solr-combined-data-solr-combined-1 Bound pvc-1649cba5-b5e1-421b-aa73-ab6a4be0d637 1Gi RWO standard 24m persistentvolumeclaim/solr-combined-data-solr-combined-2 Bound pvc-dcb8c9e2-e64b-4a53-8b46-5c30301bb905 1Gi RWO standard 23m -``` - ## Resume Solr Say, the Solr CR was deleted with `spec.deletionPolicy` to `Halt` and you want to re-create the Solr cluster using the existing auth secrets and the PVCs. @@ -482,24 +483,28 @@ Say, the Solr CR was deleted with `spec.deletionPolicy` to `Halt` and you want t You can do it by simpily re-deploying the original Solr object: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml -solr.kubedb.com/solr-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml ``` +solr.kubedb.com/solr-combined created ## Cleaning up To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo solr solr-combined -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` solr.kubedb.com/solr-combined patched -$ kubectl delete -n demo sl/solr-combined +```bash +kubectl delete -n demo sl/solr-combined +``` solr.kubedb.com "solr-combined" deleted -$ kubectl delete namespace demo -namespace "demo" deleted +```bash + kubectl delete namespace demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/solr/reconfigure-tls/solr.md b/docs/guides/solr/reconfigure-tls/solr.md index 4a895c9a08..d76a6bdcd1 100644 --- a/docs/guides/solr/reconfigure-tls/solr.md +++ b/docs/guides/solr/reconfigure-tls/solr.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. **add, remove, update and rotation** of TLS/SSL - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -86,24 +86,24 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/topology.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/clustering/yamls/topology.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.6.1 Ready 148m -``` Now, we can exec one Solr broker pod and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo solr-cluster-data-0 -- env | grep SSL -Defaulted container "solr" out of: solr, init-solr (init) +kubectl exec -it -n demo solr-cluster-data-0 -- env | grep SSL ``` +Defaulted container "solr" out of: solr, init-solr (init) We can verify from the above output that TLS is disabled for this cluster. @@ -114,23 +114,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca /O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca /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 solr-ca \ +kubectl create secret tls solr-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/solr-ca created ``` +secret/solr-ca created Now, Let's create an `Issuer` using the `Solr-ca` secret that we have just created. The `YAML` file looks like this: @@ -148,9 +148,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml -issuer.cert-manager.io/solr-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml ``` +issuer.cert-manager.io/solr-ca-issuer created ### Create SolrOpsRequest @@ -195,24 +195,25 @@ Let's create the `SolrOpsRequest` CR we have shown above, > **Note:** For combined Solr, you just need to refer solr combined object in `databaseRef` field. To learn more about combined solr, please visit [here](/docs/guides/solr/clustering/combined_cluster.md). ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/add-tls.yaml -Solropsrequest.ops.kubedb.com/slops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/add-tls.yaml ``` +Solropsrequest.ops.kubedb.com/slops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CRO, ```bash -$ kubectl get Solropsrequest -n demo +kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE slops-add-tls ReconfigureTLS Successful 4m36s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe slops -n demo slops-add-tls +kubectl describe slops -n demo slops-add-tls +``` Name: slops-add-tls Namespace: demo Labels: @@ -328,12 +329,12 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Let's exec into a Solr broker pod and verify the configuration that the TLS is enabled. -```bash - $ kubectl exec -it -n demo solr-cluster-data-0 -- env | grep -i ssl + ```bash + kubectl exec -it -n demo solr-cluster-data-0 -- env | grep -i ssl + ``` Defaulted container "solr" out of: solr, init-solr (init) JAVA_OPTS= -Djavax.net.ssl.trustStore=/var/solr/etc/truststore.p12 -Djavax.net.ssl.trustStorePassword=Ni5tEgfjahzS53D3 -Djavax.net.ssl.keyStore=/var/solr/etc/keystore.p12 -Djavax.net.ssl.keyStorePassword=Ni5tEgfjahzS53D3 -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.trustStoreType=PKCS12 SOLR_SSL_KEY_STORE_PASSWORD=Ni5tEgfjahzS53D3 @@ -343,7 +344,6 @@ SOLR_SSL_WANT_CLIENT_AUTH=false SOLR_SSL_ENABLED=true SOLR_SSL_TRUST_STORE_PASSWORD=Ni5tEgfjahzS53D3 SOLR_SSL_NEED_CLIENT_AUTH=false -``` We can see from the above output that, keystore location is `/var/solr/etc/keystore.p12` which means that TLS is enabled. @@ -352,13 +352,12 @@ We can see from the above output that, keystore location is `/var/solr/etc/keyst Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ $ kubectl exec -it -n demo solr-cluster-data-0 -- keytool -list -v -keystore /var/solr/etc/keystore.p12 -storepass Ni5tEgfjahzS53D3 | grep -E 'Valid from|Alias name' +kubectl exec -it -n demo solr-cluster-data-0 -- keytool -list -v -keystore /var/solr/etc/keystore.p12 -storepass Ni5tEgfjahzS53D3 | grep -E 'Valid from|Alias name' +``` Alias name: 1 Valid from: Mon Nov 04 09:05:23 UTC 2024 until: Sun Feb 02 09:05:23 UTC 2025 Valid from: Thu Aug 15 05:59:09 UTC 2024 until: Fri Aug 15 05:59:09 UTC 2025 -``` - So, the certificate will expire on this time `Sun Feb 02 09:05:23 UTC 2025`. ### Create SolrOpsRequest @@ -388,24 +387,25 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/rotate-tls.yaml -Solropsrequest.ops.kubedb.com/slops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/rotate-tls.yaml ``` +Solropsrequest.ops.kubedb.com/slops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CRO, ```bash -$ kubectl get slops -n demo slops-rotate +kubectl get slops -n demo slops-rotate +``` NAME TYPE STATUS AGE slops-rotate ReconfigureTLS Successful 32m -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe slops -n demo slops-rotate +kubectl describe slops -n demo slops-rotate +``` Name: slops-rotate Namespace: demo Labels: @@ -539,17 +539,16 @@ Events: Normal RestartNodes 30m KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 30m KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 30m KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: rotate-tls -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo solr-cluster-data-0 -- keytool -list -v -keystore /var/solr/etc/keystore.p12 -storepass Ni5tEgfjahzS53D3 | grep -E 'Valid from|Alias name' +kubectl exec -it -n demo solr-cluster-data-0 -- keytool -list -v -keystore /var/solr/etc/keystore.p12 -storepass Ni5tEgfjahzS53D3 | grep -E 'Valid from|Alias name' +``` Defaulted container "solr" out of: solr, init-solr (init) Alias name: 1 Valid from: Mon Nov 04 12:23:07 UTC 2024 until: Sun Feb 02 12:23:07 UTC 2025 Valid from: Thu Aug 15 05:59:09 UTC 2024 until: Fri Aug 15 05:59:09 UTC 2025 -``` As we can see from the above output, the certificate has been rotated successfully. @@ -560,23 +559,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated /O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 Solr-new-ca \ +kubectl create secret tls Solr-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/solr-new-ca created ``` +secret/solr-new-ca created Now, Let's create a new `Issuer` using the `mongo-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -594,9 +593,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/sl-new-issuer.yaml -issuer.cert-manager.io/sl-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/sl-new-issuer.yaml ``` +issuer.cert-manager.io/sl-new-issuer created ### Create SolrOpsRequest @@ -628,24 +627,25 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/reconfigure-tls/sl-update-issuer.yaml -solrpsrequest.ops.kubedb.com/slops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/reconfigure-tls/sl-update-issuer.yaml ``` +solrpsrequest.ops.kubedb.com/slops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CRO, ```bash -$ kubectl get solropsrequests -n demo slops-update-issuer +kubectl get solropsrequests -n demo slops-update-issuer +``` NAME TYPE STATUS AGE slops-update-issuer ReconfigureTLS Successful 8m6s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe slops -n demo slops-update-issuer +kubectl describe slops -n demo slops-update-issuer +``` Name: slops-update-issuer Namespace: demo Labels: @@ -782,19 +782,17 @@ Events: Normal RestartNodes 59s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 59s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 59s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-update-issuer -``` Now, Let's exec into a Solr node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo solr-cluster-data-0 -- bash +kubectl exec -it -n demo solr-cluster-data-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-cluster-data-0:/opt/solr-9.6.1$ keytool -list -v -keystore /var/solr/etc/keystore.p12 -storepass Ni5tEgfjahzS53D3 | grep 'Issuer' Issuer: O=kubedb-updated, CN="ca-updated " Issuer: O=kubedb-updated, CN="ca-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 @@ -828,24 +826,25 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/remove-tls.yaml -solropsrequest.ops.kubedb.com/slops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure-tls/remove-tls.yaml ``` +solropsrequest.ops.kubedb.com/slops-remove created #### Verify TLS Removed Successfully Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CRO, ```bash -$ kubectl get solropsrequest -n demo slops-remove +kubectl get solropsrequest -n demo slops-remove +``` NAME TYPE STATUS AGE slops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe slops -n demo slops-remove +kubectl describe slops -n demo slops-remove +``` Name: slops-remove Namespace: demo Labels: @@ -944,14 +943,13 @@ Events: Normal RestartNodes 3m20s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 3m20s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 3m20s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-remove -``` Now, Let's exec into one of the broker node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo solr-cluster-data-0 -- env | grep -i ssl -Defaulted container "solr" out of: solr, init-solr (init) +kubectl exec -it -n demo solr-cluster-data-0 -- env | grep -i ssl ``` +Defaulted container "solr" out of: solr, init-solr (init) So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/solr/reconfigure/solr.md b/docs/guides/solr/reconfigure/solr.md index 9b8233418d..b02101a4d0 100644 --- a/docs/guides/solr/reconfigure/solr.md +++ b/docs/guides/solr/reconfigure/solr.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -77,9 +77,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-custom-config.yaml -secret/sl-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-custom-config.yaml ``` +secret/sl-custom-config created In this section, we are going to create a Solr object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `Solr` CR that we are going to create, @@ -109,23 +109,24 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/reconfigure/solr.yaml -solr.kubedb.com/solr created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/reconfigure/solr.yaml ``` +solr.kubedb.com/solr created Now, wait until `solr` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr kubedb.com/v1alpha2 9.6.1 Ready 10m -``` Now, we will check if the Solr has started with the custom configuration we have provided. Exec into the Solr pod and execute the following commands to see the configurations: ```bash -$ kubectl exec -it -n demo solr-0 -- bash +kubectl exec -it -n demo solr-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml @@ -159,8 +160,6 @@ solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml - -``` Here, we can see that our given configuration is applied to the Solr cluster. `maxBooleanClauses` is set to `2024`. ### Reconfigure using new config secret @@ -198,9 +197,9 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/new-sl-custom-config.yaml -secret/new-sl-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/new-sl-custom-config.yaml ``` +secret/new-sl-custom-config created #### Create SolrOpsRequest @@ -231,9 +230,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-reconfigure-custom-config.yaml -solropsrequest.ops.kubedb.com/sl-reconfigure-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-reconfigure-custom-config.yaml ``` +solropsrequest.ops.kubedb.com/sl-reconfigure-custom-config created #### Verify the new configuration is working @@ -242,15 +241,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE sl-reconfigure-custom-config Reconfigure Successful 5m24s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe slops -n demo sl-reconfigure-custom-config +kubectl describe slops -n demo sl-reconfigure-custom-config +``` Name: sl-reconfigure-custom-config Namespace: demo Labels: @@ -339,12 +339,12 @@ Events: Normal Starting 3m31s KubeDB Ops-manager Operator Resuming Solr database: demo/solr Normal Successful 3m31s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr for SolrOpsRequest: sl-reconfigure-custom-config Normal RestartNodes 3m31s KubeDB Ops-manager Operator Successfully restarted all nodes -``` Now let's exec one of the instance and cat solr.xml file to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo solr-0 -- bash +kubectl exec -it -n demo solr-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml @@ -378,7 +378,6 @@ solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml -``` As we can see from the configuration of ready Solr, the value of `log.retention.hours` has been changed from `2024` to `2030`. So the reconfiguration of the cluster is successful. @@ -426,9 +425,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-reconfigure-apply-config.yaml -Solropsrequest.ops.kubedb.com/sl-reconfigure-apply-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/reconfigure/sl-reconfigure-apply-config.yaml ``` +Solropsrequest.ops.kubedb.com/sl-reconfigure-apply-config created #### Verify the new configuration is working @@ -437,15 +436,16 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE sl-reconfigure-custom-config Reconfigure Successful 2m22s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to reconfigure the cluster. ```bash -$ kubectl describe slops -n demo sl-reconfigure-custom-config +kubectl describe slops -n demo sl-reconfigure-custom-config +``` Name: sl-reconfigure-custom-config Namespace: demo Labels: @@ -549,12 +549,12 @@ Events: Normal RestartNodes 52s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 52s KubeDB Ops-manager Operator Resuming Solr database: demo/solr Normal Successful 52s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr for SolrOpsRequest: sl-reconfigure-custom-config -``` Now let's exec into one of the instance and cat `solr.xml` file to check the new configuration we have provided. ```bash -$ kubectl exec -it -n demo solr-0 -- bash +kubectl exec -it -n demo solr-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml @@ -588,7 +588,6 @@ solr@solr-0:/opt/solr-9.6.1$ cat /var/solr/solr.xml -``` As we can see from the configuration of ready Solr, the value of `maxBooleanClauses` has been changed from `2030` to `2024`. So the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/solr/restart/restart.md b/docs/guides/solr/restart/restart.md index 01d6e92953..3e84d93c9b 100644 --- a/docs/guides/solr/restart/restart.md +++ b/docs/guides/solr/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the Solr database via a `SolrOpsRequest`. Restarting - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -81,9 +81,9 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Sslr/restart/solr-cluster.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Sslr/restart/solr-cluster.yaml ``` +solr.kubedb.com/solr-cluster created ## Apply Restart opsRequest @@ -109,20 +109,21 @@ spec: Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/restart/ops.yaml -solropsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/restart/ops.yaml ``` +solropsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will first restart the controller pods, then broker of the referenced Solr. -```shell -$ kubectl get slops -n demo +```bash +kubectl get slops -n demo +``` NAME TYPE STATUS AGE restart Restart Successful 2m34s -```` ```bash -$ kubectl get slops -n demo restart -oyaml +kubectl get slops -n demo restart -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: SolrOpsRequest metadata: @@ -197,7 +198,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Cleaning up diff --git a/docs/guides/solr/rotateauth/rotateauth.md b/docs/guides/solr/rotateauth/rotateauth.md index 459f368afb..b4fcae4002 100644 --- a/docs/guides/solr/rotateauth/rotateauth.md +++ b/docs/guides/solr/rotateauth/rotateauth.md @@ -30,13 +30,15 @@ Now, install the KubeDB operator in your cluster following the steps [here](/doc To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create namespace demo +kubectl create namespace demo +``` namespace/demo created -$ kubectl get namespace +```bash +kubectl get namespace +``` NAME STATUS AGE demo Active 9s -``` > Note: YAML files used in this tutorial are stored in [docs/guides/solr/quickstart/overview/yamls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,10 +49,10 @@ demo Active 9s We will have to provide `StorageClass` in Solr CRD specification. Check available `StorageClass` in your cluster using the following command, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 14h -``` Here, we have `standard` StorageClass in our cluster from [Local Path Provisioner](https://github.com/rancher/local-path-provisioner). @@ -59,7 +61,8 @@ Here, we have `standard` StorageClass in our cluster from [Local Path Provisione When you install the KubeDB operator, it registers a CRD named `SolrVersions`. The installation process comes with a set of tested SolrVersion objects. Let's check available SolrVersions by, ```bash -$ kubectl get solrversion +kubectl get solrversion +``` NAME VERSION DB_IMAGE DEPRECATED AGE 8.11.2 8.11.2 ghcr.io/appscode-images/solr:8.11.2 true 12d 8.11.4 8.11.4 ghcr.io/appscode-images/solr:8.11.4 12d @@ -68,8 +71,6 @@ NAME VERSION DB_IMAGE DEPRECATED AGE 9.7.0 9.7.0 ghcr.io/appscode-images/solr:9.7.0 12d 9.8.0 9.8.0 ghcr.io/appscode-images/solr:9.8.0 12d -``` - Notice the `DEPRECATED` column. Here, `true` means that this SolrVersion is deprecated for the current KubeDB version. KubeDB will not work for deprecated SolrVersion. In this tutorial, we will use `9.8.0 ` SolrVersion CR to create a Solr cluster. @@ -109,17 +110,17 @@ spec: Let's create the ZooKeeper CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml -zooKeeper.kubedb.com/zoo-com created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/zookeeper/zookeeper.yaml ``` +zooKeeper.kubedb.com/zoo-com created The ZooKeeper's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get zookeeper -n demo -w +kubectl get zookeeper -n demo -w +``` NAME TYPE VERSION STATUS AGE zoo-com kubedb.com/v1alpha2 3.7.2 Ready 13m -``` Then we can deploy solr in our cluster. @@ -150,17 +151,17 @@ spec: Let's create the Solr CR that is shown above: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml -solr.kubedb.com/solr-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/solr/quickstart/overview/yamls/solr/solr.yaml ``` +solr.kubedb.com/solr-combined created The Solr's `STATUS` will go from `Provisioning` to `Ready` state within few minutes. Once the `STATUS` is `Ready`, you are ready to use the database. ```bash -$ kubectl get Solr -n demo -w +kubectl get Solr -n demo -w +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.8.0 Ready 17m -``` ## Verify authentication The user can verify whether they are authorized by executing a query directly in the database. To do this, the user needs `username` and `password` in order to connect to the database using the `kubectl exec` command. Below is an example showing how to retrieve the credentials from the secret. @@ -198,19 +199,20 @@ Here, - `spec.type` specifies that we are performing `RotateAuth` on Solr. Let's create the `SolrOpsRequest` CR we have shown above, -```shell - $ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/rotate-auth/rotate-auth.yaml + ```bash + kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/rotate-auth/rotate-auth.yaml + ``` solropsrequest.ops.kubedb.com/solrops-rotate-auth-generated created -``` Let's wait for `SolrOpsrequest` to be `Successful`. Run the following command to watch `SolrOpsrequest` CRO -```shell - $ kubectl get Solropsrequest -n demo + ```bash + kubectl get Solropsrequest -n demo + ``` NAME TYPE STATUS AGE solrops-rotate-auth-generated RotateAuth Successful 2m3s -``` If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Solropsrequest -n demo solrops-rotate-auth-generated +```bash +kubectl describe Solropsrequest -n demo solrops-rotate-auth-generated +``` Name: solrops-rotate-auth-generated Namespace: demo Labels: @@ -303,37 +305,44 @@ Events: Normal RestartNodes 5m20s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 5m20s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 5m20s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: solrops-rotate-auth-generated - -``` **Verify Auth is rotated** -```shell -$ kubectl get solr -n demo solr-combined -ojson | jq .spec.authSecret.name +```bash + kubectl get solr -n demo solr-combined -ojson | jq .spec.authSecret.name +``` "solr-combined-auth" -$ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.username}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d -dt(MVdBeBDlEy~Cp⏎ + +```bash +kubectl get secret -n demo solr-combined-auth -o jsonpath='{.data.password}' | base64 -d ``` +dt(MVdBeBDlEy~Cp⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo solr-combined-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo solr-combined-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` admin⏎ -$ kubectl get secret -n demo solr-combined-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -QtnsJluRRjaaWWec⏎ + +```bash +kubectl get secret -n demo solr-combined-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +QtnsJluRRjaaWWec⏎ The above output shows that the password has been changed successfully. The previous username & password is stored for rollback purpose. #### 2. Using user created credentials At first, we need to create a secret with kubernetes.io/basic-auth type using custom username and password. Below is the command to create a secret with kubernetes.io/basic-auth type, -```shell -$ kubectl create secret generic solr-combined-user-auth -n demo \ +```bash +kubectl create secret generic solr-combined-user-auth -n demo \ --type=kubernetes.io/basic-auth \ --from-literal=username=admin \ --from-literal=password=Solr-secret - secret/solr-combined-user-auth created ``` + secret/solr-combined-user-auth created Now create a `SolrOpsRequest` with `RotateAuth` type. Below is the YAML of the `SolrOpsRequest` that we are going to create, ```shell @@ -361,21 +370,22 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, -```shell -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/rotate-auth/rotateauthuser.yaml -solropsrequest.ops.kubedb.com/solrops-rotate-auth-user created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/rotate-auth/rotateauthuser.yaml ``` +solropsrequest.ops.kubedb.com/solrops-rotate-auth-user created Let’s wait for `SolrOpsRequest` to be Successful. Run the following command to watch `SolrOpsRequest` CRO: -```shell -$ kubectl get Solropsrequest -n demo +```bash +kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE solrops-rotate-auth-generated RotateAuth Successful 13m solrops-rotate-auth-user RotateAuth Successful 2m3s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed. -```shell -$ kubectl describe Solropsrequest -n demo solrops-rotate-auth-user +```bash +kubectl describe Solropsrequest -n demo solrops-rotate-auth-user +``` Name: solrops-rotate-auth-user Namespace: demo Labels: @@ -470,24 +480,31 @@ Events: Normal RestartNodes 11m KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 11m KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 11m KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: solrops-rotate-auth-user - -``` **Verify auth is rotate** -```shell -$ kubectl get solr -n demo solr-combined -ojson | jq .spec.authSecret.name +```bash + kubectl get solr -n demo solr-combined -ojson | jq .spec.authSecret.name +``` "solr-combined-user-auth" -$ kubectl get secret -n demo solr-combined-user-auth -o jsonpath='{.data.username}' | base64 -d + +```bash +kubectl get secret -n demo solr-combined-user-auth -o jsonpath='{.data.username}' | base64 -d +``` solr⏎ -$ kubectl get secret -n demo solr-combined-user-auth -o jsonpath='{.data.password}' | base64 -d -Solr-secret⏎ + +```bash +kubectl get secret -n demo solr-combined-user-auth -o jsonpath='{.data.password}' | base64 -d ``` +Solr-secret⏎ Also, there will be two more new keys in the secret that stores the previous credentials. The keys are `username.prev` and `password.prev`. You can find the secret and its data by running the following command: -```shell -$ kubectl get secret -n demo solr-combined-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +```bash +kubectl get secret -n demo solr-combined-user-auth -o go-template='{{ index .data "username.prev" }}' | base64 -d +``` Solr -$ kubectl get secret -n demo solr-combined-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d -dt(MVdBeBDlEy~Cp⏎ + +```bash +kubectl get secret -n demo solr-combined-user-auth -o go-template='{{ index .data "password.prev" }}' | base64 -d ``` +dt(MVdBeBDlEy~Cp⏎ The above output shows that the password has been changed successfully. The previous username & password is stored in the secret for rollback purpose. @@ -495,13 +512,24 @@ The above output shows that the password has been changed successfully. The prev To cleanup the Kubernetes resources created by this tutorial, run: -```shell -$ kubectl delete Solropsrequest solrops-rotate-auth-generated solrops-rotate-auth-user -n demo -$ kubectl delete secret -n demo solr-combined-user-auth -$ kubectl delete secret -n demo solr-combined-auth -$ kubectl delete solr -n demo solr-combined -$ kubectl delete ns demo +```bash +kubectl delete Solropsrequest solrops-rotate-auth-generated solrops-rotate-auth-user -n demo +``` + +```bash +kubectl delete secret -n demo solr-combined-user-auth +``` +```bash +kubectl delete secret -n demo solr-combined-auth +``` + +```bash +kubectl delete solr -n demo solr-combined +``` + +```bash +kubectl delete ns demo ``` ## Next Steps diff --git a/docs/guides/solr/scaling/horizontal-scaling/combined.md b/docs/guides/solr/scaling/horizontal-scaling/combined.md index 62f2ca2ac5..d092debb0a 100644 --- a/docs/guides/solr/scaling/horizontal-scaling/combined.md +++ b/docs/guides/solr/scaling/horizontal-scaling/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the S To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -72,27 +72,29 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/combined/solr.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/combined/solr.yaml ``` +solr.kubedb.com/solr-combined created Now, wait until `solr-combined` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.4.1 Ready 65m -``` Let's check the number of replicas has from Solr object, number of pods the petset have, ```bash -$ kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' -2 -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' +``` 2 +```bash +kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' ``` +2 We can see from both command that the cluster has 2 replicas. @@ -133,9 +135,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/combined/scaling.yaml -Solropsrequest.ops.kubedb.com/kfops-hscale-up-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/combined/scaling.yaml ``` +Solropsrequest.ops.kubedb.com/kfops-hscale-up-combined created #### Verify Combined cluster replicas scaled up successfully @@ -144,15 +146,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ watch kubectl get Solropsrequest -n demo +watch kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE slops-hscale-up-combined HorizontalScaling Successful 106s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-hscale-up-combined +kubectl describe slops -n demo slops-hscale-up-combined +``` Name: slops-hscale-up-combined Namespace: demo Labels: @@ -218,16 +221,18 @@ Events: Normal HorizontalScaleCombinedNode 31s KubeDB Ops-manager Operator ScaleUp solr-combined nodes Normal Starting 31s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 31s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: slops-hscale-up-combined -``` Now, we are going to verify the number of replicas this cluster has from the Solr object, number of pods the petset have, ```bash -$ kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' -4 -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' +``` 4 + +```bash +kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' ``` +4 ### Scale Down Replicas @@ -260,9 +265,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal-scaling/solr-hscale-down-combined.yaml -solropsrequest.ops.kubedb.com/slops-hscale-down-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal-scaling/solr-hscale-down-combined.yaml ``` +solropsrequest.ops.kubedb.com/slops-hscale-down-combined created #### Verify Combined cluster replicas scaled down successfully @@ -271,15 +276,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ watch kubectl get Solropsrequest -n demo +watch kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE slops-hscale-down-combined HorizontalScaling Successful 2m32s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-hscale-down-combined +kubectl describe slops -n demo slops-hscale-down-combined +``` Name: slops-hscale-down-combined Namespace: demo Labels: @@ -372,16 +378,18 @@ Events: Normal HorizontalScaleCombinedNode 6m9s KubeDB Ops-manager Operator ScaleDown solr-combined nodes Normal Starting 6m9s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 6m9s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: slops-hscale-down-combined -``` Now, we are going to verify the number of replicas this cluster has from the Solr object, number of pods the petset have, ```bash -$ kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' -2 -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-combined -o json | jq '.spec.replicas' +``` 2 + +```bash +kubectl get petset -n demo solr-combined -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that the replicas of the combined cluster is `2`. That means we have successfully scaled down the replicas of the Solr combined cluster. diff --git a/docs/guides/solr/scaling/horizontal-scaling/topology.md b/docs/guides/solr/scaling/horizontal-scaling/topology.md index 36d8903578..a63e2c2316 100644 --- a/docs/guides/solr/scaling/horizontal-scaling/topology.md +++ b/docs/guides/solr/scaling/horizontal-scaling/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the S To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -90,48 +90,55 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/topology/solr.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/topology/solr.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 90m -``` Let's check the number of replicas has from Solr object, number of pods the petset have, **Data Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' -1 -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' +``` 1 + +```bash +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' ``` +1 **Overseer Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' -1 -$ kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' +``` 1 +```bash +kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' ``` +1 **Coordinator Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' -1 -$ kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' +``` 1 +```bash +kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' ``` +1 We can see from commands that the cluster has 3 replicas for data, overseer, coordinator. @@ -173,9 +180,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/topology/slops-hscale-up-topology.yaml -solropsrequest.ops.kubedb.com/slops-hscale-up-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/horizontal/topology/slops-hscale-up-topology.yaml ``` +solropsrequest.ops.kubedb.com/slops-hscale-up-topology created > **Note:** If you want to scale down only broker or controller, you can specify the desired replicas for only broker or controller in the `SolrOpsRequest` CR. You can specify one at a time. If you want to scale broker only, no node will need restart to apply the changes. But if you want to scale controller, all nodes will need restart to apply the changes. @@ -186,15 +193,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ watch kubectl get Solropsrequest -n demo +watch kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE slops-hscale-up-topology HorizontalScaling Successful 106s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-hscale-up-topology +kubectl describe slops -n demo slops-hscale-up-topology +``` Name: slops-hscale-up-topology Namespace: demo Labels: @@ -268,32 +276,40 @@ Events: Normal HorizontalScaleOverseerNode 6m16s KubeDB Ops-manager Operator ScaleUp solr-cluster-overseer nodes Normal Starting 6m16s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 6m16s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-hscale-up-topolog -``` Now, we are going to verify the number of replicas this cluster has from the Solr object, number of pods the petset have, **Broker Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' -2 -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' -2 +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' ``` +2 ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' -2 -$ kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' +``` 2 + +```bash +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' ``` +2 ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' +kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' +``` 2 -$ kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' + +```bash +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' +``` 2 + +```bash +kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' ``` +2 From all the above outputs we can see that all data, overseer, coordinator of the topology Solr is `2`. That means we have successfully scaled up the replicas of the Solr topology cluster. @@ -332,9 +348,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/scaling/horizontal-scaling/Solr-hscale-down-topology.yaml -solropsrequest.ops.kubedb.com/slops-hscale-down-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/scaling/horizontal-scaling/Solr-hscale-down-topology.yaml ``` +solropsrequest.ops.kubedb.com/slops-hscale-down-topology created #### Verify Topology cluster replicas scaled down successfully @@ -343,15 +359,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ watch kubectl get solropsrequest -n demo +watch kubectl get solropsrequest -n demo +``` NAME TYPE STATUS AGE slops-hscale-down-topology HorizontalScaling Successful 2m32s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-hscale-down-topology +kubectl describe slops -n demo slops-hscale-down-topology +``` Name: slops-hscale-down-topology Namespace: demo Labels: @@ -451,7 +468,6 @@ Events: Normal HorizontalScaleOverseerNode 13s KubeDB Ops-manager Operator ScaleDown solr-cluster-overseer nodes Normal Starting 13s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 13s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-hscale-down-topology -``` Now, we are going to verify the number of replicas this cluster has from the Solr object, number of pods the petset have, @@ -460,31 +476,38 @@ Let's check the number of replicas has from Solr object, number of pods the pets **Data Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' -1 -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.data.replicas' +``` 1 + +```bash +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.replicas' ``` +1 **Overseer Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' -1 -$ kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.overseer.replicas' +``` 1 +```bash +kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.replicas' ``` +1 **Coordinator Replicas** ```bash -$ kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' -1 -$ kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' +kubectl get solr -n demo solr-cluster -o json | jq '.spec.topology.coordinator.replicas' +``` 1 +```bash +kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.replicas' ``` +1 ## Cleaning Up diff --git a/docs/guides/solr/scaling/vertical-scaling/combined.md b/docs/guides/solr/scaling/vertical-scaling/combined.md index c40655c074..1035f055ef 100644 --- a/docs/guides/solr/scaling/vertical-scaling/combined.md +++ b/docs/guides/solr/scaling/vertical-scaling/combined.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -73,22 +73,23 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/combined/solr.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/combined/solr.yaml ``` +solr.kubedb.com/solr-combined created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.4.1 Ready 63m -``` Let's check the Pod containers resources for `data`, `overseer` and `coordinator` of the solr Combined cluster. Run the following command to get the resources of the `broker` and `controller` containers of the Solr Combined cluster ```bash -$ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -99,7 +100,9 @@ $ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resou } } -$ kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resources' +```bash +kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -109,7 +112,6 @@ $ kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resou "memory": "2Gi" } } -``` This is the default resources of the Solr Combined cluster set by the `KubeDB` operator. @@ -153,9 +155,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/combined/scaling.yaml -solropsrequest.ops.kubedb.com/slops-slops-vscale-combined-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/combined/scaling.yaml ``` +solropsrequest.ops.kubedb.com/slops-slops-vscale-combined-combined created #### Verify Solr Combined cluster resources updated successfully @@ -164,15 +166,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-slops-vscale-combined-combined VerticalScaling Successful 3m9s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-vscale-combined +kubectl describe slops -n demo slops-vscale-combined +``` Name: slops-vscale-combined Namespace: demo Labels: @@ -266,11 +269,11 @@ Events: Normal RestartPods 35s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 35s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 35s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: slops-vscale-combined -``` Now, we are going to verify from one of the Pod yaml whether the resources of the Combined cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -281,7 +284,10 @@ $ kubectl get pod -n demo solr-combined-0 -o json | jq '.spec.containers[].resou "memory": "2560Mi" } } -$ kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -293,8 +299,6 @@ $ kubectl get pod -n demo solr-combined-1 -o json | jq '.spec.containers[].resou } } -``` - The above output verifies that we have successfully scaled up the resources of the Solr Combined cluster. ## Cleaning Up diff --git a/docs/guides/solr/scaling/vertical-scaling/topology.md b/docs/guides/solr/scaling/vertical-scaling/topology.md index a85c9b63b5..9c99c02ca2 100644 --- a/docs/guides/solr/scaling/vertical-scaling/topology.md +++ b/docs/guides/solr/scaling/vertical-scaling/topology.md @@ -31,9 +31,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -90,22 +90,23 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/topology/solr.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/topology/solr.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 63m -``` Let's check the Pod containers resources for `data`, `overseer` and `coordinator` of the solr topology cluster. Run the following command to get the resources of the `broker` and `controller` containers of the Solr topology cluster ```bash -$ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -115,10 +116,10 @@ $ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].r "memory": "2Gi" } } -``` ```bash -$ kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -128,10 +129,10 @@ $ kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers "memory": "2Gi" } } -``` ```bash -$ kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "2Gi" @@ -141,7 +142,6 @@ $ kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.contain "memory": "2Gi" } } -``` This is the default resources of the Solr topology cluster set by the `KubeDB` operator. We are now ready to apply the `SolrOpsRequest` CR to update the resources of this database. @@ -200,9 +200,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/topology/scaling.yaml -solropsrequest.ops.kubedb.com/slops-slops-vscale-topology-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/scaling/vertical/topology/scaling.yaml ``` +solropsrequest.ops.kubedb.com/slops-slops-vscale-topology-topology created #### Verify Solr Topology cluster resources updated successfully @@ -211,15 +211,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE slops-vscale-topology VerticalScaling Successful 3m9s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to scale the cluster. ```bash -$ kubectl describe slops -n demo slops-vscale-topology +kubectl describe slops -n demo slops-vscale-topology +``` Name: slops-vscale-topology Namespace: demo Labels: @@ -339,11 +340,11 @@ Events: Normal RestartPods 80s KubeDB Ops-manager Operator Successfully Restarted Pods With Resources Normal Starting 80s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 80s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: slops-vscale-topology -``` Now, we are going to verify from one of the Pod yaml whether the resources of the topology cluster has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -354,7 +355,10 @@ $ kubectl get pod -n demo solr-cluster-coordinator-0 -o json | jq '.spec.contain "memory": "2560Mi" } } -$ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -365,7 +369,10 @@ $ kubectl get pod -n demo solr-cluster-data-0 -o json | jq '.spec.containers[].r "memory": "2560Mi" } } -$ kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers[].resources' + +```bash +kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -377,8 +384,6 @@ $ kubectl get pod -n demo solr-cluster-overseer-0 -o json | jq '.spec.containers } } -``` - The above output verifies that we have successfully scaled up the resources of the Solr topology cluster. ## Cleaning Up diff --git a/docs/guides/solr/tls/combined.md b/docs/guides/solr/tls/combined.md index 8017369be7..7e59e70439 100644 --- a/docs/guides/solr/tls/combined.md +++ b/docs/guides/solr/tls/combined.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for `Solr`. This tutorial will show - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml -issuer.cert-manager.io/solr-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml ``` +issuer.cert-manager.io/solr-ca-issuer created ## TLS/SSL encryption in Solr Combined @@ -130,22 +130,23 @@ spec: ### Deploy Solr Combined with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/solr-combined.yaml -solr.kubedb.com/solr-combined created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/solr-combined.yaml ``` +solr.kubedb.com/solr-combined created Now, wait until `solr-combined created` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.4.1 Ready 2m31s -``` ### Verify TLS/SSL in Solr Combined ```bash -$ kubectl describe secret solr-combined-client-cert -n demo +kubectl describe secret solr-combined-client-cert -n demo +``` Name: solr-combined-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -172,12 +173,12 @@ ca.crt: 1147 bytes keystore.p12: 3511 bytes tls.crt: 1497 bytes tls.key: 1679 bytes -``` Now, Let's exec into a solr data pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo solr-combined-data-0 -- bash +kubectl exec -it -n demo solr-combined-data-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-combined-data-0:/opt/solr-9.4.1$ env | grep -i SSL JAVA_OPTS= -Djavax.net.ssl.trustStore=/var/solr/etc/truststore.p12 -Djavax.net.ssl.trustStorePassword=QyHKB(dYoT1MQYMu -Djavax.net.ssl.keyStore=/var/solr/etc/keystore.p12 -Djavax.net.ssl.keyStorePassword=QyHKB(dYoT1MQYMu -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.trustStoreType=PKCS12 @@ -189,8 +190,6 @@ SOLR_SSL_TRUST_STORE=/var/solr/etc/truststore.p12 SOLR_SSL_KEY_STORE=/var/solr/etc/keystore.p12 SOLR_SSL_NEED_CLIENT_AUTH=false -``` - We can see from the above output that, keystore location is `/var/solr/etc` which means that TLS is enabled. ```bash diff --git a/docs/guides/solr/tls/topology.md b/docs/guides/solr/tls/topology.md index 059fc4ad7e..e8443b0f3a 100644 --- a/docs/guides/solr/tls/topology.md +++ b/docs/guides/solr/tls/topology.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for Solr. This tutorial will show y - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -84,9 +84,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml -issuer.cert-manager.io/solr-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/sl-issuer.yaml ``` +issuer.cert-manager.io/solr-ca-issuer created ## TLS/SSL encryption in Solr Topology Cluster @@ -148,22 +148,23 @@ spec: ### Deploy Solr Topology Cluster with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/solr-topology.yaml -Solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/tls/solr-topology.yaml ``` +Solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster created` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 2m31s -``` ### Verify TLS/SSL in Solr Topology Cluster ```bash -$ kubectl describe secret solr-cluster-client-cert -n demo +kubectl describe secret solr-cluster-client-cert -n demo +``` Name: solr-cluster-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -190,12 +191,12 @@ ca.crt: 1147 bytes keystore.p12: 3511 bytes tls.crt: 1497 bytes tls.key: 1679 bytes -``` Now, Let's exec into a solr data pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo solr-cluster-data-0 -- bash +kubectl exec -it -n demo solr-cluster-data-0 -- bash +``` Defaulted container "solr" out of: solr, init-solr (init) solr@solr-cluster-data-0:/opt/solr-9.4.1$ env | grep -i SSL JAVA_OPTS= -Djavax.net.ssl.trustStore=/var/solr/etc/truststore.p12 -Djavax.net.ssl.trustStorePassword=QyHKB(dYoT1MQYMu -Djavax.net.ssl.keyStore=/var/solr/etc/keystore.p12 -Djavax.net.ssl.keyStorePassword=QyHKB(dYoT1MQYMu -Djavax.net.ssl.keyStoreType=PKCS12 -Djavax.net.ssl.trustStoreType=PKCS12 @@ -207,8 +208,6 @@ SOLR_SSL_TRUST_STORE=/var/solr/etc/truststore.p12 SOLR_SSL_KEY_STORE=/var/solr/etc/keystore.p12 SOLR_SSL_NEED_CLIENT_AUTH=false -``` - We can see from the above output that, keystore location is `/var/solr/etc` which means that TLS is enabled. ```bash diff --git a/docs/guides/solr/update-version/update-version.md b/docs/guides/solr/update-version/update-version.md index f35c7e1e42..858c9f6469 100644 --- a/docs/guides/solr/update-version/update-version.md +++ b/docs/guides/solr/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/Solr](/docs/examples/solr) directory of [kubedb/docs](https://github.com/kube/docs) repository. @@ -85,21 +85,21 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/update-version/solr.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/update-version/solr.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` created has status `Ready`. i.e, ```bash -$ kubectl get kf -n demo -w +kubectl get kf -n demo -w +``` NAME TYPE VERSION STATUS AGE Solr-prod kubedb.com/v1 3.5.2 Provisioning 0s Solr-prod kubedb.com/v1 3.5.2 Provisioning 55s . . Solr-prod kubedb.com/v1 3.5.2 Ready 119s -``` We are now ready to apply the `SolrOpsRequest` CR to update. @@ -136,9 +136,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/update-version/update-version-ops.yaml -solropsrequest.ops.kubedb.com/solr-update-version created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/Solr/update-version/update-version-ops.yaml ``` +solropsrequest.ops.kubedb.com/solr-update-version created #### Verify Solr version updated successfully @@ -147,15 +147,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get Solropsrequest -n demo +kubectl get Solropsrequest -n demo +``` NAME TYPE STATUS AGE solr-update-version UpdateVersion Successful 2m6s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl get slops -n demo solr-update-version -oyaml +kubectl get slops -n demo solr-update-version -oyaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: SolrOpsRequest metadata: @@ -239,18 +240,16 @@ status: observedGeneration: 1 phase: Successful 61s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/Solr-prod for SolrOpsRequest: Solr-update-version -``` Now, we are going to verify whether the `Solr` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get sl -n demo solr-cluster -o=jsonpath='{.spec.version}{"\n"}' +kubectl get sl -n demo solr-cluster -o=jsonpath='{.spec.version}{"\n"}' +``` 9.6.1 ~/y/s/ops (main|✚23…) $ kubectl get petset -n demo Solr-cluster-data -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' ghcr.io/appscode-images/daily/solr:9.6.1_20241024@sha256:0996340eff1e59bcac49eb8f96c28f0a3efb061f0e91b2053bfb7dade860c0e4 -``` - You can see from above, our `Solr` has been updated with the new version. So, the updateVersion process is successfully completed. ## Cleaning up diff --git a/docs/guides/solr/volume-expansion/combined.md b/docs/guides/solr/volume-expansion/combined.md index 22f322d612..c1918a53ae 100644 --- a/docs/guides/solr/volume-expansion/combined.md +++ b/docs/guides/solr/volume-expansion/combined.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Solr` combined using a supported version by `Kub At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get sc +kubectl get sc +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 24d -``` We can see from the output the `local-path` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -84,29 +84,31 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/combined.yaml -Solr.kubedb.com/Solr-dev created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/combined.yaml ``` +Solr.kubedb.com/Solr-dev created Now, wait until `Solr-dev` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-combined kubedb.com/v1alpha2 9.4.1 Ready 23m -``` Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-02cddba5-1d6a-4f1b-91b2-a7e55857b6b7 1Gi RWO Delete Bound demo/solr-combined-data-solr-combined-1 standard 23m pvc-61b8f97a-a588-4125-99f3-604f6a70d560 1Gi RWO Delete Bound demo/solr-combined-data-solr-combined-0 standard 24m -``` You can see the petset has 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -145,9 +147,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/solr-volume-expansion-combined.yaml -solropsrequest.ops.kubedb.com/sl-volume-exp-combined created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/solr-volume-expansion-combined.yaml ``` +solropsrequest.ops.kubedb.com/sl-volume-exp-combined created #### Verify Solr Combined volume expanded successfully @@ -156,15 +158,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get slops -n demo +kubectl get slops -n demo +``` NAME TYPE STATUS AGE sl-volume-exp-topology VolumeExpansion Successful 3m -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe slops -n demo sl-volume-exp-topology +kubectl describe slops -n demo sl-volume-exp-topology +``` Name: sl-volume-exp-topology Namespace: demo Labels: @@ -326,18 +329,20 @@ Events: Normal ReadyPetSets 56s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 56s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-combined Normal Successful 56s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-combined for SolrOpsRequest: sl-volume-exp-topology -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo solr-combined -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "11Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-02cddba5-1d6a-4f1b-91b2-a7e55857b6b7 11Gi RWO Delete Bound demo/solr-combined-data-solr-combined-1 standard 33m pvc-61b8f97a-a588-4125-99f3-604f6a70d560 11Gi RWO Delete Bound demo/solr-combined-data-solr-combined-0 standard 33m -``` The above output verifies that we have successfully expanded the volume of the Solr. diff --git a/docs/guides/solr/volume-expansion/topology.md b/docs/guides/solr/volume-expansion/topology.md index b504e530fb..1a977258d3 100644 --- a/docs/guides/solr/volume-expansion/topology.md +++ b/docs/guides/solr/volume-expansion/topology.md @@ -33,9 +33,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/Solr](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/Solr) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -48,10 +48,10 @@ Here, we are going to deploy a `Solr` topology using a supported version by `Kub At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get sc +kubectl get sc +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 24d -``` We can see from the output the `local-path` storage class has `ALLOWVOLUMEEXPANSION` field as false. So, this storage class supports volume expansion. We can use it. @@ -101,34 +101,42 @@ spec: Let's create the `Solr` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/topology.yaml -solr.kubedb.com/solr-cluster created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/topology.yaml ``` +solr.kubedb.com/solr-cluster created Now, wait until `solr-cluster` has status `Ready`. i.e, ```bash -$ kubectl get sl -n demo +kubectl get sl -n demo +``` NAME TYPE VERSION STATUS AGE solr-cluster kubedb.com/v1alpha2 9.4.1 Ready 41m -``` - Let's check volume size from petset, and from the persistent volume, ```bash -$ kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-31538e3e-2d02-4ca0-9b76-5da7c63cea70 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-data-0 standard 44m pvc-8c5b14ab-3da4-4492-abf4-edd7faa265ef 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-overseer-0 standard 44m pvc-95522f35-52bd-4978-b66f-1979cec34982 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-coordinator-0 standard 44m -``` You can see the petsets have 1GB storage, and the capacity of all the persistent volumes are also 1GB. @@ -173,9 +181,9 @@ Here, Let's create the `SolrOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/solr-volume-expansion-topology.yaml -solropsrequest.ops.kubedb.com/sl-volume-exp-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/solr/volume-expansion/solr-volume-expansion-topology.yaml ``` +solropsrequest.ops.kubedb.com/sl-volume-exp-topology created #### Verify Solr Topology volume expanded successfully @@ -184,15 +192,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `SolrOpsRequest` to be `Successful`. Run the following command to watch `SolrOpsRequest` CR, ```bash -$ kubectl get solropsrequest -n demo +kubectl get solropsrequest -n demo +``` NAME TYPE STATUS AGE sl-volume-exp-topology VolumeExpansion Successful 3m1s -``` We can see from the above output that the `SolrOpsRequest` has succeeded. If we describe the `SolrOpsRequest` we will get an overview of the steps that were followed to expand the volume of Solr. ```bash -$ kubectl describe slops -n demo sl-volume-exp-topology +kubectl describe slops -n demo sl-volume-exp-topology +``` Name: sl-volume-exp-topology Namespace: demo Labels: @@ -379,23 +388,31 @@ Events: Normal ReadyPetSets 19s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 19s KubeDB Ops-manager Operator Resuming Solr database: demo/solr-cluster Normal Successful 19s KubeDB Ops-manager Operator Successfully resumed Solr database: demo/solr-cluster for SolrOpsRequest: sl-volume-exp-topology -``` Now, we are going to verify from the `Petset`, and the `Persistent Volumes` whether the volume of the database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo solr-cluster-data -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "11Gi" -$ kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo solr-cluster-overseer -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "11Gi" -$ kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' + +```bash +kubectl get petset -n demo solr-cluster-coordinator -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo + +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-31538e3e-2d02-4ca0-9b76-5da7c63cea70 11Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-data-0 standard 52m pvc-8c5b14ab-3da4-4492-abf4-edd7faa265ef 11Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-overseer-0 standard 52m pvc-95522f35-52bd-4978-b66f-1979cec34982 1Gi RWO Delete Bound demo/solr-cluster-data-solr-cluster-coordinator-0 standard 52m -``` The above output verifies that we have successfully expanded the volume of the Solr. diff --git a/docs/guides/weaviate/autoscaler/compute/compute-autoscale.md b/docs/guides/weaviate/autoscaler/compute/compute-autoscale.md index 00381152c7..5f735ff335 100644 --- a/docs/guides/weaviate/autoscaler/compute/compute-autoscale.md +++ b/docs/guides/weaviate/autoscaler/compute/compute-autoscale.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` to auto-scale the compute resources To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Autoscaling of Database @@ -78,9 +78,9 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`. Then check the current container resources: ```bash -$ kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' -{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} +kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' ``` +{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} ### Create WeaviateAutoscaler @@ -123,16 +123,17 @@ Here, Let's create the `WeaviateAutoscaler`: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/autoscaler/compute/weaviate-compute-autoscaler.yaml -weaviateautoscaler.autoscaling.kubedb.com/weaviate-sample-autoscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/autoscaler/compute/weaviate-compute-autoscaler.yaml ``` +weaviateautoscaler.autoscaling.kubedb.com/weaviate-sample-autoscale created ### Verify Autoscaling Let's describe the `WeaviateAutoscaler`. Because the initial resources (`500m`/`1Gi`) are below the `minAllowed` floor (`600m`/`1.2Gi`), the autoscaler quickly produces a recommendation: ```bash -$ kubectl describe weaviateautoscaler -n demo weaviate-sample-autoscale +kubectl describe weaviateautoscaler -n demo weaviate-sample-autoscale +``` ... Status: Vpas: @@ -151,27 +152,26 @@ Status: Upper Bound: Cpu: 1 Memory: 2Gi -``` After the `podLifeTimeThreshold` passes, the autoscaler operator creates a `WeaviateOpsRequest` of type `VerticalScaling`: ```bash -$ kubectl get weaviateopsrequest -n demo +kubectl get weaviateopsrequest -n demo +``` NAME TYPE STATUS AGE wvops-weaviate-sample-0oyvzl VerticalScaling Successful 119s -``` ```bash -$ kubectl get weaviateopsrequest -n demo wvops-weaviate-sample-0oyvzl -o jsonpath='{.spec.verticalScaling}' -{"node":{"resources":{"limits":{"cpu":"600m","memory":"1288490188"},"requests":{"cpu":"600m","memory":"1288490188"}}}} +kubectl get weaviateopsrequest -n demo wvops-weaviate-sample-0oyvzl -o jsonpath='{.spec.verticalScaling}' ``` +{"node":{"resources":{"limits":{"cpu":"600m","memory":"1288490188"},"requests":{"cpu":"600m","memory":"1288490188"}}}} Once the ops request completes, verify the updated resources on the pods: ```bash -$ kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' -{"limits":{"cpu":"600m","memory":"1288490188"},"requests":{"cpu":"600m","memory":"1288490188"}} +kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' ``` +{"limits":{"cpu":"600m","memory":"1288490188"},"requests":{"cpu":"600m","memory":"1288490188"}} The compute resources of the Weaviate database have been autoscaled up to the `minAllowed` floor (`600m` CPU / `1.2Gi` memory). When the actual usage grows, the autoscaler will continue to recommend higher resources (up to `maxAllowed`). @@ -180,7 +180,13 @@ The compute resources of the Weaviate database have been autoscaled up to the `m To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateautoscaler -n demo weaviate-sample-autoscale -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateautoscaler -n demo weaviate-sample-autoscale +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/autoscaler/storage/storage-autoscale.md b/docs/guides/weaviate/autoscaler/storage/storage-autoscale.md index 80cf22d0c0..8b6bae1d3d 100644 --- a/docs/guides/weaviate/autoscaler/storage/storage-autoscale.md +++ b/docs/guides/weaviate/autoscaler/storage/storage-autoscale.md @@ -34,9 +34,9 @@ This guide will show you how to use `KubeDB` to auto-scale the storage of a Weav To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created ## Storage Autoscaling of Database @@ -69,12 +69,12 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`. Then check the current storage: ```bash -$ kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +``` NAME SIZE data-weaviate-sample-0 1Gi data-weaviate-sample-1 1Gi data-weaviate-sample-2 1Gi -``` ### Create WeaviateAutoscaler @@ -112,16 +112,17 @@ Here, Let's create the `WeaviateAutoscaler`: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/autoscaler/storage/weaviate-storage-autoscaler.yaml -weaviateautoscaler.autoscaling.kubedb.com/weaviate-storage-autoscaler created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/autoscaler/storage/weaviate-storage-autoscaler.yaml ``` +weaviateautoscaler.autoscaling.kubedb.com/weaviate-storage-autoscaler created ### Verify Autoscaler is Set Up Let's describe the `WeaviateAutoscaler` to confirm it is configured and watching the volumes: ```bash -$ kubectl describe weaviateautoscaler -n demo weaviate-storage-autoscaler +kubectl describe weaviateautoscaler -n demo weaviate-storage-autoscaler +``` Name: weaviate-storage-autoscaler Namespace: demo API Version: autoscaling.kubedb.com/v1alpha1 @@ -146,7 +147,6 @@ Spec: Trigger: On Usage Threshold: 20 Events: -``` The autoscaler is now watching the PVC usage of the Weaviate pods. @@ -154,30 +154,30 @@ The autoscaler is now watching the PVC usage of the Weaviate pods. When a volume's used space crosses the `usageThreshold` (20%), the autoscaler operator creates a `WeaviateOpsRequest` of type `VolumeExpansion` that grows the volume by `scalingThreshold` (50%). For example, after writing enough data to fill more than 20% of a `1Gi` volume: -```bash # usage on each node's data volume crosses 20% -$ kubectl exec -n demo weaviate-sample-0 -c weaviate -- df -h /var/lib/weaviate +```bash +kubectl exec -n demo weaviate-sample-0 -c weaviate -- df -h /var/lib/weaviate +``` Filesystem Size Used Available Use% Mounted on /dev/longhorn/pvc-... 973.4M 401.7M 555.7M 42% /var/lib/weaviate -``` the autoscaler creates a `VolumeExpansion` ops request: ```bash -$ kubectl get weaviateopsrequest -n demo +kubectl get weaviateopsrequest -n demo +``` NAME TYPE STATUS AGE wvops-weaviate-sample-xxxxxx VolumeExpansion Successful 3m -``` and the PVCs are expanded (here, from `1Gi` to `1.5Gi` — a 50% increase): ```bash -$ kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SIZE:.status.capacity.storage +``` NAME SIZE data-weaviate-sample-0 1531584Ki data-weaviate-sample-1 1531584Ki data-weaviate-sample-2 1531584Ki -``` > **Note:** The auto-trigger relies on the `volume_used_percentage` metric being available through KubeDB's metrics API. If that metric is not exposed in your cluster, the autoscaler will stay configured and watching but will not generate an ops request. The underlying `VolumeExpansion` mechanism it uses is the same one demonstrated step-by-step in the [Volume Expansion](/docs/guides/weaviate/volume-expansion/volume-expansion.md) guide. @@ -186,7 +186,13 @@ data-weaviate-sample-2 1531584Ki To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateautoscaler -n demo weaviate-storage-autoscaler -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateautoscaler -n demo weaviate-storage-autoscaler +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/concepts/catalog.md b/docs/guides/weaviate/concepts/catalog.md index b8395d82bb..8c3592bfac 100644 --- a/docs/guides/weaviate/concepts/catalog.md +++ b/docs/guides/weaviate/concepts/catalog.md @@ -54,10 +54,10 @@ spec: ## List available versions ```bash -$ kubectl get weaviateversions +kubectl get weaviateversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.33.1 1.33.1 ghcr.io/appscode-images/weaviate:1.33.1 34h -``` ## Next Steps diff --git a/docs/guides/weaviate/configuration/using-config-file.md b/docs/guides/weaviate/configuration/using-config-file.md index 0e55ded794..9e2972ddfe 100644 --- a/docs/guides/weaviate/configuration/using-config-file.md +++ b/docs/guides/weaviate/configuration/using-config-file.md @@ -25,9 +25,9 @@ KubeDB supports providing custom configuration for Weaviate. This tutorial will - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/configuration](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/configuration) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -82,9 +82,9 @@ type: Opaque Let's create the `Secret`: ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/weaviate-custom-config-secret.yaml -secret/weaviate-custom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/weaviate-custom-config-secret.yaml ``` +secret/weaviate-custom-config created Now, create the `Weaviate` CR specifying the `spec.configuration.secretName` field: @@ -111,28 +111,31 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/cus-conf.yaml -weaviate.kubedb.com/weaviate-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/cus-conf.yaml ``` +weaviate.kubedb.com/weaviate-sample created Now, wait a few minutes. KubeDB operator will create the necessary PVC, PetSet, services, and secrets. Let's check the status: ```bash -$ kubectl get weaviate -n demo +kubectl get weaviate -n demo +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 66s -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 65s weaviate-sample-1 1/1 Running 0 50s weaviate-sample-2 1/1 Running 0 38s -``` Now, let's verify that the custom configuration has been applied by checking the config file inside the pod: ```bash -$ kubectl exec -n demo weaviate-sample-0 -c weaviate -- cat /weaviate-config/conf.yaml/conf.yaml +kubectl exec -n demo weaviate-sample-0 -c weaviate -- cat /weaviate-config/conf.yaml/conf.yaml +``` authentication: anonymous_access: enabled: true @@ -150,7 +153,6 @@ persistence: data_path: /var/lib/weaviate query_defaults: limit: 400 -``` The output confirms the database is running with our custom `query_defaults.limit: 400` and `anonymous_access` settings. KubeDB has merged in the cluster-specific `cluster.hostname` and `persistence.data_path` values. @@ -186,17 +188,20 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/cus-inline-conf.yaml -weaviate.kubedb.com/weaviate-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/configuration/cus-inline-conf.yaml ``` +weaviate.kubedb.com/weaviate-sample created Wait until the cluster is `Ready`, then verify the inline configuration has been applied: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.configuration}' +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.configuration}' +``` {"inline":{"conf.yaml":"query_defaults:\n limit: 1000"}} -$ kubectl exec -n demo weaviate-sample-0 -c weaviate -- cat /weaviate-config/conf.yaml/conf.yaml +```bash +kubectl exec -n demo weaviate-sample-0 -c weaviate -- cat /weaviate-config/conf.yaml/conf.yaml +``` authorization: admin_list: enabled: false @@ -209,7 +214,6 @@ persistence: data_path: /var/lib/weaviate query_defaults: limit: 1000 -``` The output confirms the database is running with our inline `query_defaults.limit: 1000` setting. @@ -220,7 +224,13 @@ The output confirms the database is running with our inline `query_defaults.limi To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete secret -n demo weaviate-custom-config -$ kubectl delete ns demo +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete secret -n demo weaviate-custom-config +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/quickstart/quickstart.md b/docs/guides/weaviate/quickstart/quickstart.md index 5f1f787173..e768b3dcd2 100644 --- a/docs/guides/weaviate/quickstart/quickstart.md +++ b/docs/guides/weaviate/quickstart/quickstart.md @@ -25,9 +25,9 @@ This tutorial will show you how to use KubeDB to run a [Weaviate](https://weavia - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/quickstart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/quickstart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -36,12 +36,12 @@ namespace/demo created We will need to provide a `StorageClass` in the Weaviate CR specification. Check the available `StorageClass` in your cluster using the following command: ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 38h longhorn driver.longhorn.io Delete Immediate true 6m27s longhorn-static driver.longhorn.io Delete Immediate true 6m23s -``` Here, we have the `longhorn` StorageClass in our cluster. It supports volume expansion, which is required by some of the day-2 operations (such as Volume Expansion and Storage Autoscaling) shown in later guides. @@ -50,10 +50,10 @@ Here, we have the `longhorn` StorageClass in our cluster. It supports volume exp When you install KubeDB, it creates a `WeaviateVersion` CR for each supported Weaviate version. Let's check the available `WeaviateVersion`s: ```bash -$ kubectl get weaviateversions +kubectl get weaviateversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 1.33.1 1.33.1 ghcr.io/appscode-images/weaviate:1.33.1 34h -``` Notice the `DEPRECATED` column. `true` means that the `WeaviateVersion` is deprecated for the current KubeDB version and KubeDB will not work for that version. @@ -103,9 +103,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/quickstart/weaviate-sample.yaml -weaviate.kubedb.com/weaviate-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/quickstart/weaviate-sample.yaml ``` +weaviate.kubedb.com/weaviate-sample created Here, @@ -120,19 +120,20 @@ Here, Now, let's watch the progress of creating the `Weaviate` cluster: ```bash -$ kubectl get weaviate -n demo weaviate-sample -w +kubectl get weaviate -n demo weaviate-sample -w +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Provisioning 6s weaviate-sample kubedb.com/v1alpha2 1.33.1 Provisioning 2m weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 5m21s -``` ## Describe Weaviate Let's describe the `Weaviate` object to see its current state: ```bash -$ kubectl describe weaviate -n demo weaviate-sample +kubectl describe weaviate -n demo weaviate-sample +``` Name: weaviate-sample Namespace: demo Labels: @@ -225,34 +226,39 @@ Status: Type: Provisioned Phase: Ready Events: -``` ## Find Underlying Kubernetes Resources KubeDB operator creates a PetSet, PVCs, Services, and Secrets for the Weaviate database. Let's check them: ```bash -$ kubectl get petset -n demo weaviate-sample +kubectl get petset -n demo weaviate-sample +``` NAME AGE weaviate-sample 5m19s -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 62s weaviate-sample-1 1/1 Running 0 55s weaviate-sample-2 1/1 Running 0 44s -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-weaviate-sample-0 Bound pvc-b8b6d9e6-634f-4ead-b1fd-1bfe549976e4 1Gi RWO longhorn 5m18s data-weaviate-sample-1 Bound pvc-4e9329c0-8a3d-4402-919c-afa4fe2144c9 1Gi RWO longhorn 56s data-weaviate-sample-2 Bound pvc-a846947c-212f-4aea-92a7-c8f88ae7f463 1Gi RWO longhorn 45s -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE weaviate-sample ClusterIP 10.43.98.199 8080/TCP,50051/TCP,7102/TCP,7103/TCP,8300/TCP 5m23s weaviate-sample-pods ClusterIP None 8080/TCP,50051/TCP,7102/TCP,7103/TCP,8300/TCP 5m23s -``` KubeDB creates two services for a Weaviate cluster: @@ -266,7 +272,7 @@ The internal ports are: `8080` (HTTP REST), `50051` (gRPC), `8300` (raft consens KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created and is able to accept client connections. Run the following command to see the modified Weaviate object: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o yaml +kubectl get weaviate -n demo weaviate-sample -o yaml ``` ```yaml @@ -366,7 +372,7 @@ status: By default, KubeDB enables API-key authentication for the Weaviate cluster and stores the generated key in a Secret named `-auth`. Let's check it: ```bash -$ kubectl get secret -n demo weaviate-sample-auth -o yaml +kubectl get secret -n demo weaviate-sample-auth -o yaml ``` ```yaml apiVersion: v1 @@ -403,24 +409,27 @@ The Secret stores the standard Weaviate API-key environment variables: `AUTHENTI Now, let's connect to the Weaviate cluster using port forwarding. In one terminal, start the port-forward: ```bash -$ kubectl port-forward -n demo svc/weaviate-sample 8080:8080 -Forwarding from 127.0.0.1:8080 -> 8080 +kubectl port-forward -n demo svc/weaviate-sample 8080:8080 ``` +Forwarding from 127.0.0.1:8080 -> 8080 In another terminal, export the API key and call the REST API: ```bash -$ export WEAVIATE_API_KEY=$(kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d) +export WEAVIATE_API_KEY=$(kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d) +``` -$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/.well-known/ready \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/.well-known/ready \ -H "Authorization: Bearer $WEAVIATE_API_KEY" -200 ``` +200 Check the cluster nodes — all three should report `HEALTHY`: ```bash -$ curl -s http://localhost:8080/v1/nodes -H "Authorization: Bearer $WEAVIATE_API_KEY" | jq +curl -s http://localhost:8080/v1/nodes -H "Authorization: Bearer $WEAVIATE_API_KEY" | jq +``` { "nodes": [ {"name": "weaviate-sample-0", "status": "HEALTHY", "version": "1.33.1", "gitHash": "c87f308", "batchStats": {"queueLength": 0, "ratePerSecond": 0}, "shards": null}, @@ -428,20 +437,21 @@ $ curl -s http://localhost:8080/v1/nodes -H "Authorization: Bearer $WEAVIATE_API {"name": "weaviate-sample-2", "status": "HEALTHY", "version": "1.33.1", "gitHash": "c87f308", "batchStats": {"queueLength": 0, "ratePerSecond": 0}, "shards": null} ] } -``` Let's create a collection (class) and then read the schema back: ```bash -$ curl -s -X POST http://localhost:8080/v1/schema \ +curl -s -X POST http://localhost:8080/v1/schema \ -H "Authorization: Bearer $WEAVIATE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"class":"Article","vectorizer":"none"}' +``` {"class":"Article","invertedIndexConfig":{...},"multiTenancyConfig":{"enabled":false},...} -$ curl -s http://localhost:8080/v1/schema -H "Authorization: Bearer $WEAVIATE_API_KEY" | jq '.classes[].class' -"Article" +```bash +curl -s http://localhost:8080/v1/schema -H "Authorization: Bearer $WEAVIATE_API_KEY" | jq '.classes[].class' ``` +"Article" The collection was created and is served by the cluster. @@ -450,11 +460,13 @@ The collection was created and is served by the cluster. KubeDB creates an AppBinding CR that holds the necessary information to connect with the database. ```bash -$ kubectl get appbinding -n demo +kubectl get appbinding -n demo +``` NAME TYPE VERSION AGE weaviate-sample kubedb.com/weaviate 1.33.1 5m20s -$ kubectl get appbinding -n demo weaviate-sample -o yaml +```bash +kubectl get appbinding -n demo weaviate-sample -o yaml ``` ```yaml @@ -507,12 +519,14 @@ This field regulates the deletion process of the related resources when the `Wea When `deletionPolicy` is set to `DoNotTerminate`, KubeDB prevents deletion of the database using admission webhooks. If you try to delete it, you will get an error: ```bash -$ kubectl patch -n demo weaviate/weaviate-sample -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +kubectl patch -n demo weaviate/weaviate-sample -p '{"spec":{"deletionPolicy":"DoNotTerminate"}}' --type="merge" +``` weaviate.kubedb.com/weaviate-sample patched -$ kubectl delete weaviate -n demo weaviate-sample -The Weaviate "weaviate-sample" is invalid: spec.deletionPolicy: Invalid value: "weaviate-sample": Can not delete as deletionPolicy is set to "DoNotTerminate" +```bash +kubectl delete weaviate -n demo weaviate-sample ``` +The Weaviate "weaviate-sample" is invalid: spec.deletionPolicy: Invalid value: "weaviate-sample": Can not delete as deletionPolicy is set to "DoNotTerminate" **Halt:** @@ -527,9 +541,9 @@ When `deletionPolicy` is set to `Delete`, KubeDB deletes the `Weaviate` object, When `deletionPolicy` is set to `WipeOut`, KubeDB deletes all resources of this database (pods, PVCs, Secrets, snapshots, etc.). There is no option to recreate the database once deleted with this policy. ```bash -$ kubectl patch -n demo weaviate/weaviate-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" -weaviate.kubedb.com/weaviate-sample patched +kubectl patch -n demo weaviate/weaviate-sample -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" ``` +weaviate.kubedb.com/weaviate-sample patched > Be careful when using `WipeOut` — there is no way to recover the database after deletion. diff --git a/docs/guides/weaviate/reconfigure-tls/reconfigure-tls.md b/docs/guides/weaviate/reconfigure-tls/reconfigure-tls.md index 27710dc690..1ce8199d0e 100644 --- a/docs/guides/weaviate/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/weaviate/reconfigure-tls/reconfigure-tls.md @@ -31,9 +31,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to add TLS to a run To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/reconfigure-tls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,22 +42,24 @@ namespace/demo created Deploy a Weaviate cluster without TLS and wait for it to become `Ready`. The REST service is served over plain HTTP on port `8080`: ```bash -$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' -http=8080 grpc=50051 gossip=7102 data=7103 raft=8300 +kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' ``` +http=8080 grpc=50051 gossip=7102 data=7103 raft=8300 ## Create an Issuer Weaviate TLS is issued through cert-manager. First, create a CA secret and an `Issuer` named `weaviate-issuer` in the `demo` namespace: ```bash -$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout weaviate-ca.key -out weaviate-ca.crt -subj "/CN=weaviate-ca" +``` -$ kubectl create secret tls weaviate-ca \ +```bash +kubectl create secret tls weaviate-ca \ --cert=weaviate-ca.crt --key=weaviate-ca.key -n demo -secret/weaviate-ca created ``` +secret/weaviate-ca created ```yaml apiVersion: cert-manager.io/v1 @@ -71,13 +73,15 @@ spec: ``` ```bash -$ kubectl apply -f issuer.yaml +kubectl apply -f issuer.yaml +``` issuer.cert-manager.io/weaviate-issuer created -$ kubectl get issuer -n demo +```bash +kubectl get issuer -n demo +``` NAME READY AGE weaviate-issuer True 3s -``` ## Add TLS to the Cluster @@ -103,22 +107,23 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/add-tls.yaml -weaviateopsrequest.ops.kubedb.com/weaviate-add-tls created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/add-tls.yaml ``` +weaviateopsrequest.ops.kubedb.com/weaviate-add-tls created The Ops Manager issues the certificates and restarts the pods. ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-add-tls +kubectl get weaviateopsrequest -n demo weaviate-add-tls +``` NAME TYPE STATUS AGE weaviate-add-tls ReconfigureTLS Successful 2m -``` The `status.conditions` show the certificates being synced and the pods restarted: ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-add-tls -o yaml +kubectl get weaviateopsrequest -n demo weaviate-add-tls -o yaml +``` ... status: conditions: @@ -147,33 +152,45 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Verify that the REST service now serves HTTPS on port `8443` and the certificates were created: ```bash -$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' +kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' +``` https=8443 grpc=50051 gossip=7102 data=7103 raft=8300 -$ kubectl get certificate -n demo +```bash +kubectl get certificate -n demo +``` NAME READY SECRET AGE weaviate-sample-client-cert True weaviate-sample-client-cert 84s weaviate-sample-server-cert True weaviate-sample-server-cert 84s -``` The cluster requires client certificate authentication (mTLS) by default. You can connect like this: ```bash -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt +``` + +```bash +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt +``` + +```bash +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +``` + +```bash +kubectl port-forward -n demo svc/weaviate-sample 8443:8443 +``` -$ kubectl port-forward -n demo svc/weaviate-sample 8443:8443 # in another terminal -$ curl -s -o /dev/null -w "%{http_code}\n" --cacert ca.crt --cert client.crt --key client.key \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" --cacert ca.crt --cert client.crt --key client.key \ https://localhost:8443/v1/.well-known/ready -H "Authorization: Bearer " -200 ``` +200 ## Rotate Certificates @@ -195,35 +212,39 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/rotate-certificate.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/rotate-certificate.yaml +``` weaviateopsrequest.ops.kubedb.com/wvops-rotate created -$ kubectl get weaviateopsrequest -n demo wvops-rotate +```bash +kubectl get weaviateopsrequest -n demo wvops-rotate +``` NAME TYPE STATUS AGE wvops-rotate ReconfigureTLS Successful 2m -``` Verify that the server certificate has a newer validity window: ```bash -$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -dates +kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -dates +``` subject=CN=weaviate-sample notBefore=Jun 30 17:52:42 2026 GMT notAfter=Sep 28 17:52:42 2026 GMT -``` ## Update the Issuer You can switch the cluster to a different cert-manager issuer. First, create the new CA secret and the `weaviate-new-issuer`: ```bash -$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout weaviate-new-ca.key -out weaviate-new-ca.crt -subj "/CN=weaviate-new-ca" +``` -$ kubectl create secret tls weaviate-new-ca \ +```bash +kubectl create secret tls weaviate-new-ca \ --cert=weaviate-new-ca.crt --key=weaviate-new-ca.key -n demo -secret/weaviate-new-ca created ``` +secret/weaviate-new-ca created ```yaml apiVersion: cert-manager.io/v1 @@ -237,9 +258,9 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/weaviate-new-issuer.yaml -issuer.cert-manager.io/weaviate-new-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/weaviate-new-issuer.yaml ``` +issuer.cert-manager.io/weaviate-new-issuer created Now, create a `ReconfigureTLS` OpsRequest that points at the new issuer: @@ -261,23 +282,27 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/update-issuer.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/update-issuer.yaml +``` weaviateopsrequest.ops.kubedb.com/wvops-update-issuer created -$ kubectl get weaviateopsrequest -n demo wvops-update-issuer +```bash +kubectl get weaviateopsrequest -n demo wvops-update-issuer +``` NAME TYPE STATUS AGE wvops-update-issuer ReconfigureTLS Successful 2m -``` Verify that the server certificate is now signed by the new CA: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls.issuerRef.name}' +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls.issuerRef.name}' +``` weaviate-new-issuer -$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -issuer -issuer=CN=weaviate-new-ca +```bash +kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -issuer ``` +issuer=CN=weaviate-new-ca ## Remove TLS @@ -298,25 +323,31 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/remove-tls.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure-tls/remove-tls.yaml +``` weaviateopsrequest.ops.kubedb.com/wvops-remove created -$ kubectl get weaviateopsrequest -n demo wvops-remove +```bash +kubectl get weaviateopsrequest -n demo wvops-remove +``` NAME TYPE STATUS AGE wvops-remove ReconfigureTLS Successful 2m -``` Verify that the service is back to plain HTTP on port `8080`, the `spec.tls` field is cleared, and the certificate secrets are gone: ```bash -$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' +kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' +``` http=8080 grpc=50051 gossip=7102 data=7103 raft=8300 -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' +``` -$ kubectl get secret -n demo | grep weaviate-sample-.*cert -# (no cert secrets) +```bash +kubectl get secret -n demo | grep weaviate-sample-.*cert ``` +# (no cert secrets) TLS has been added, rotated, re-issued with a new CA, and finally removed — all without recreating the database. @@ -331,8 +362,17 @@ TLS has been added, rotated, re-issued with a new CA, and finally removed — al To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo weaviate-add-tls wvops-rotate wvops-update-issuer wvops-remove -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete issuer -n demo weaviate-issuer weaviate-new-issuer -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo weaviate-add-tls wvops-rotate wvops-update-issuer wvops-remove +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete issuer -n demo weaviate-issuer weaviate-new-issuer +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/reconfigure/reconfigure.md b/docs/guides/weaviate/reconfigure/reconfigure.md index 5ebf5cb1a0..449b5c99f4 100644 --- a/docs/guides/weaviate/reconfigure/reconfigure.md +++ b/docs/guides/weaviate/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to reconfigure a We To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/reconfigure](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -106,12 +106,14 @@ stringData: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/new-weaviate-config.yaml +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/new-weaviate-config.yaml +``` secret/new-weaviate-config created -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/minio-secret.yaml -secret/minio-secret created +```bash +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/minio-secret.yaml ``` +secret/minio-secret created ## Apply Reconfigure OpsRequest @@ -148,22 +150,23 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/reconfigure created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/reconfigure/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/reconfigure created The Ops Manager prepares the new configuration, updates the PetSet, and restarts the pods one by one. ```bash -$ kubectl get weaviateopsrequest -n demo reconfigure +kubectl get weaviateopsrequest -n demo reconfigure +``` NAME TYPE STATUS AGE reconfigure Reconfigure Successful 83s -``` Let's check the `status.conditions` of the `WeaviateOpsRequest`: ```bash -$ kubectl get weaviateopsrequest -n demo reconfigure -o yaml +kubectl get weaviateopsrequest -n demo reconfigure -o yaml +``` ... status: conditions: @@ -207,12 +210,12 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Now, let's verify that the new configuration has been applied to the `Weaviate` object: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.configuration}' | jq +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.configuration}' | jq +``` { "backupConfigSecret": { "name": "minio-secret" @@ -222,7 +225,6 @@ $ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.configuration }, "secretName": "new-weaviate-config" } -``` The reconfigure operation has been applied successfully. @@ -237,7 +239,13 @@ The reconfigure operation has been applied successfully. To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo reconfigure -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo reconfigure +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/restart/restart.md b/docs/guides/weaviate/restart/restart.md index b8f748f7b5..df3eae9557 100644 --- a/docs/guides/weaviate/restart/restart.md +++ b/docs/guides/weaviate/restart/restart.md @@ -29,9 +29,9 @@ KubeDB supports restarting the Weaviate database via a `WeaviateOpsRequest`. Res To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/restart](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/restart) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,17 +62,17 @@ spec: Let's create the `Weaviate` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/restart/weaviate.yaml -weaviate.kubedb.com/weaviate-sample created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/restart/weaviate.yaml ``` +weaviate.kubedb.com/weaviate-sample created Now, wait until `weaviate-sample` has status `Ready`: ```bash -$ kubectl get weaviate -n demo +kubectl get weaviate -n demo +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 5m -``` ## Apply Restart OpsRequest @@ -98,20 +98,21 @@ spec: Let's create the `WeaviateOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/restart/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/restart/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/restart created Now the Ops-manager operator will restart the Weaviate pods one by one, waiting for each pod to come back to `Running` state before proceeding to the next. ```bash -$ kubectl get weaviateopsrequest -n demo restart +kubectl get weaviateopsrequest -n demo restart +``` NAME TYPE STATUS AGE restart Restart Successful 92s -``` ```bash -$ kubectl get weaviateopsrequest -n demo restart -o yaml +kubectl get weaviateopsrequest -n demo restart -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: WeaviateOpsRequest metadata: @@ -195,7 +196,6 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Next Steps @@ -208,7 +208,13 @@ status: To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo restart -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo restart +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/rotate-auth/rotate-auth.md b/docs/guides/weaviate/rotate-auth/rotate-auth.md index 4e3493eb78..06a9c3af51 100644 --- a/docs/guides/weaviate/rotate-auth/rotate-auth.md +++ b/docs/guides/weaviate/rotate-auth/rotate-auth.md @@ -29,9 +29,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to rotate the API-k To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/rotate-auth](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/rotate-auth) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -40,19 +40,22 @@ namespace/demo created Deploy a Weaviate cluster and wait for it to become `Ready`. By default, KubeDB generates an API key and stores it in the `weaviate-sample-auth` Secret: ```bash -$ kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d -vzWSjiRGNNEZEytR +kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d ``` +vzWSjiRGNNEZEytR You can confirm this key works through a port-forward: ```bash -$ kubectl port-forward -n demo svc/weaviate-sample 8080:8080 +kubectl port-forward -n demo svc/weaviate-sample 8080:8080 +``` + # in another terminal -$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ -H "Authorization: Bearer vzWSjiRGNNEZEytR" -200 ``` +200 ## Rotate Auth with a User-provided Secret @@ -72,9 +75,9 @@ type: Opaque ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/rotate-auth/weaviate-rotate-auth.yaml -secret/weaviate-rotate-auth created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/rotate-auth/weaviate-rotate-auth.yaml ``` +secret/weaviate-rotate-auth created Now, create the `RotateAuth` OpsRequest referencing that Secret: @@ -100,22 +103,23 @@ spec: - `spec.authentication.secretRef.name` references the Secret holding the new API key. If you omit this field, the Ops Manager generates a brand-new random key instead. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/rotate-auth/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/weaviate-rotate-auth-generated created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/rotate-auth/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/weaviate-rotate-auth-generated created The Ops Manager updates the credentials and restarts the pods one by one. ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-rotate-auth-generated +kubectl get weaviateopsrequest -n demo weaviate-rotate-auth-generated +``` NAME TYPE STATUS AGE weaviate-rotate-auth-generated RotateAuth Successful 70s -``` Let's check the `status.conditions` of the `WeaviateOpsRequest`: ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-rotate-auth-generated -o yaml +kubectl get weaviateopsrequest -n demo weaviate-rotate-auth-generated -o yaml +``` ... status: conditions: @@ -159,36 +163,42 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Verify Authentication Rotated After the rotation, the `Weaviate` object now references the provided Secret, and the Ops Manager has enriched it with the previous key (under `*-PREV`), the enabled flag, and the bound user: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.authSecret}' +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.authSecret}' +``` {"activeFrom":"2026-06-30T17:47:20Z","apiGroup":"","externallyManaged":true,"kind":"","name":"weaviate-rotate-auth"} -$ kubectl get secret -n demo weaviate-rotate-auth -o go-template='{{ range $k, $v := .data }}{{ $k }}: {{ $v | base64decode }}{{ "\n" }}{{ end }}' +```bash +kubectl get secret -n demo weaviate-rotate-auth -o go-template='{{ range $k, $v := .data }}{{ $k }}: {{ $v | base64decode }}{{ "\n" }}{{ end }}' +``` AUTHENTICATION_APIKEY_ALLOWED_KEYS: U1UzvrTvnz5Mw9c4 AUTHENTICATION_APIKEY_ALLOWED_KEYS-PREV: vzWSjiRGNNEZEytR AUTHENTICATION_APIKEY_ENABLED: true AUTHENTICATION_APIKEY_USERS: admin -``` Let's confirm that the new key works and the old key is rejected: ```bash -$ kubectl port-forward -n demo svc/weaviate-sample 8080:8080 +kubectl port-forward -n demo svc/weaviate-sample 8080:8080 +``` + # in another terminal -$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ -H "Authorization: Bearer U1UzvrTvnz5Mw9c4" +``` 200 -$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/v1/schema \ -H "Authorization: Bearer vzWSjiRGNNEZEytR" -401 ``` +401 The new key returns `200` while the old key now returns `401` — the authentication has been rotated successfully. @@ -205,7 +215,13 @@ The new key returns `200` while the old key now returns `401` — the authentica To cleanup the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo weaviate-rotate-auth-generated -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo weaviate-rotate-auth-generated +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/weaviate/scaling/horizontal-scaling/horizontal-scaling.md index 136af37d87..41c79a51bb 100644 --- a/docs/guides/weaviate/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/weaviate/scaling/horizontal-scaling/horizontal-scaling.md @@ -29,9 +29,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to scale the number To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/scaling/horizontal-scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/scaling/horizontal-scaling) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -62,16 +62,18 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`: ```bash -$ kubectl get weaviate -n demo +kubectl get weaviate -n demo +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 5m -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 5m weaviate-sample-1 1/1 Running 0 5m weaviate-sample-2 1/1 Running 0 5m -``` ## Scale Up @@ -97,18 +99,21 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/horizontal-scaling/scale-up.yaml -weaviateopsrequest.ops.kubedb.com/weaviate-scale-up created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/horizontal-scaling/scale-up.yaml ``` +weaviateopsrequest.ops.kubedb.com/weaviate-scale-up created The Ops Manager adds the new nodes, waits for them to join and sync the schema, and rebalances the shard replicas. ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-scale-up +kubectl get weaviateopsrequest -n demo weaviate-scale-up +``` NAME TYPE STATUS AGE weaviate-scale-up HorizontalScaling Successful 3m -$ kubectl get weaviateopsrequest -n demo weaviate-scale-up -o yaml +```bash +kubectl get weaviateopsrequest -n demo weaviate-scale-up -o yaml +``` ... status: conditions: @@ -144,12 +149,12 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Verify the new node count: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 3m51s weaviate-sample-1 1/1 Running 0 3m11s @@ -157,9 +162,10 @@ weaviate-sample-2 1/1 Running 0 2m31s weaviate-sample-3 1/1 Running 0 56s weaviate-sample-4 1/1 Running 0 44s -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.replicas}' -5 +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.replicas}' ``` +5 ## Scale Down @@ -182,18 +188,21 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/horizontal-scaling/scale-down.yaml -weaviateopsrequest.ops.kubedb.com/weaviate-scale-down created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/horizontal-scaling/scale-down.yaml ``` +weaviateopsrequest.ops.kubedb.com/weaviate-scale-down created The Ops Manager moves the shards off the nodes that are going away before removing them. ```bash -$ kubectl get weaviateopsrequest -n demo weaviate-scale-down +kubectl get weaviateopsrequest -n demo weaviate-scale-down +``` NAME TYPE STATUS AGE weaviate-scale-down HorizontalScaling Successful 3m -$ kubectl get weaviateopsrequest -n demo weaviate-scale-down -o yaml +```bash +kubectl get weaviateopsrequest -n demo weaviate-scale-down -o yaml +``` ... status: conditions: @@ -233,19 +242,20 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Verify the node count again: ```bash -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 7m27s weaviate-sample-1 1/1 Running 0 6m47s -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.replicas}' -2 +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.replicas}' ``` +2 The cluster has been scaled horizontally — first up to `5` nodes, then back down to `2`. @@ -260,7 +270,13 @@ The cluster has been scaled horizontally — first up to `5` nodes, then back do To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo weaviate-scale-up weaviate-scale-down -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo weaviate-scale-up weaviate-scale-down +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/weaviate/scaling/vertical-scaling/vertical-scaling.md index c6dd5317c0..645d43efa9 100644 --- a/docs/guides/weaviate/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/weaviate/scaling/vertical-scaling/vertical-scaling.md @@ -29,9 +29,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to update the resou To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/scaling/vertical-scaling](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/scaling/vertical-scaling) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -73,20 +73,22 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/vertical-scaling/weaviate.yaml +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/vertical-scaling/weaviate.yaml +``` weaviate.kubedb.com/weaviate-sample created -$ kubectl get weaviate -n demo +```bash +kubectl get weaviate -n demo +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 5m -``` Let's check the current resources of one of the pods: ```bash -$ kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' -{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} +kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' ``` +{"limits":{"cpu":"500m","memory":"1Gi"},"requests":{"cpu":"500m","memory":"1Gi"}} ## Apply Vertical Scaling on the Weaviate Cluster @@ -122,22 +124,23 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/vertical-scaling/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/wvops-vertical-scale created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/scaling/vertical-scaling/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/wvops-vertical-scale created The Ops Manager will update the PetSet resources and restart the pods one by one to apply the new resources. ```bash -$ kubectl get weaviateopsrequest -n demo wvops-vertical-scale +kubectl get weaviateopsrequest -n demo wvops-vertical-scale +``` NAME TYPE STATUS AGE wvops-vertical-scale VerticalScaling Successful 2m -``` Let's look at the `status.conditions` of the `WeaviateOpsRequest`: ```bash -$ kubectl get weaviateopsrequest -n demo wvops-vertical-scale -o yaml +kubectl get weaviateopsrequest -n demo wvops-vertical-scale -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: WeaviateOpsRequest metadata: @@ -206,17 +209,18 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Now, let's verify the resources of the cluster have been updated: ```bash -$ kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' +kubectl get pod -n demo weaviate-sample-0 -o jsonpath='{.spec.containers[0].resources}' +``` {"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.podTemplate.spec.containers[0].resources}' -{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.podTemplate.spec.containers[0].resources}' ``` +{"limits":{"cpu":"1","memory":"2Gi"},"requests":{"cpu":"1","memory":"2Gi"}} The resources have been updated successfully. @@ -231,7 +235,13 @@ The resources have been updated successfully. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo wvops-vertical-scale -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo wvops-vertical-scale +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/storage-migration/storage-migration.md b/docs/guides/weaviate/storage-migration/storage-migration.md index b0c9f69cb2..df98035c34 100644 --- a/docs/guides/weaviate/storage-migration/storage-migration.md +++ b/docs/guides/weaviate/storage-migration/storage-migration.md @@ -25,11 +25,11 @@ This guide will show you how to use the `KubeDB` Ops Manager to migrate a Weavia - You need at least two `StorageClass`es in your cluster — the one the database currently runs on, and the one you want to migrate to. Verify with: ```bash - $ kubectl get storageclass + kubectl get storageclass + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 38h longhorn driver.longhorn.io Delete Immediate true 30m - ``` - You should be familiar with the following `KubeDB` concepts: - [Weaviate](/docs/guides/weaviate/concepts/weaviate.md) @@ -38,9 +38,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to migrate a Weavia To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/storage-migration](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/storage-migration) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -71,11 +71,11 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`. Then check the current StorageClass of the PVCs: ```bash -$ kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-weaviate-sample-0 longhorn 3Gi data-weaviate-sample-1 longhorn 3Gi -``` The cluster is currently running on the `longhorn` StorageClass. @@ -106,22 +106,23 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/storage-migration/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/storage-migration created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/storage-migration/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/storage-migration created For each node, the Ops Manager provisions a new PVC on the target StorageClass, runs a migrator job to copy the data, deletes the old PVC, and re-points the node at the new volume. ```bash -$ kubectl get weaviateopsrequest -n demo storage-migration +kubectl get weaviateopsrequest -n demo storage-migration +``` NAME TYPE STATUS AGE storage-migration StorageMigration Successful 6m -``` Let's look at the (abbreviated) `status.conditions` of the `WeaviateOpsRequest`: ```bash -$ kubectl get weaviateopsrequest -n demo storage-migration -o yaml +kubectl get weaviateopsrequest -n demo storage-migration -o yaml +``` ... status: conditions: @@ -156,21 +157,22 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` ## Verify the StorageClass Migrated Successfully Verify that the PVCs are now on the `local-path` StorageClass and the database is back to `Ready`: ```bash -$ kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +kubectl get pvc -n demo -o custom-columns=NAME:.metadata.name,SC:.spec.storageClassName,SIZE:.status.capacity.storage +``` NAME SC SIZE data-weaviate-sample-0 local-path 3Gi data-weaviate-sample-1 local-path 3Gi -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.storage.storageClassName}{" "}{.status.phase}' -local-path Ready +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.storage.storageClassName}{" "}{.status.phase}' ``` +local-path Ready The StorageClass has been migrated from `longhorn` to `local-path` successfully. @@ -185,7 +187,13 @@ The StorageClass has been migrated from `longhorn` to `local-path` successfully. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo storage-migration -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo storage-migration +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/tls/configure-tls.md b/docs/guides/weaviate/tls/configure-tls.md index 42236855ac..e3d76c554c 100644 --- a/docs/guides/weaviate/tls/configure-tls.md +++ b/docs/guides/weaviate/tls/configure-tls.md @@ -31,9 +31,9 @@ This tutorial will show you how to provision a Weaviate cluster with TLS enabled To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/tls](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/tls) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -42,13 +42,15 @@ namespace/demo created Weaviate TLS is issued through cert-manager. First, create a self-signed CA and a `Secret` that holds it: ```bash -$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout weaviate-ca.key -out weaviate-ca.crt -subj "/CN=weaviate-ca" +``` -$ kubectl create secret tls weaviate-ca \ +```bash +kubectl create secret tls weaviate-ca \ --cert=weaviate-ca.crt --key=weaviate-ca.key -n demo -secret/weaviate-ca created ``` +secret/weaviate-ca created Now, create an `Issuer` named `weaviate-issuer` that references this CA secret: @@ -64,13 +66,15 @@ spec: ``` ```bash -$ kubectl apply -f issuer.yaml +kubectl apply -f issuer.yaml +``` issuer.cert-manager.io/weaviate-issuer created -$ kubectl get issuer -n demo +```bash +kubectl get issuer -n demo +``` NAME READY AGE weaviate-issuer True 3s -``` ## Deploy Weaviate with TLS @@ -103,45 +107,50 @@ spec: ``` ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/tls/tls.yaml -weaviate.kubedb.com/weaviate-sample created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/tls/tls.yaml ``` +weaviate.kubedb.com/weaviate-sample created Wait until the cluster becomes `Ready`: ```bash -$ kubectl get weaviate -n demo +kubectl get weaviate -n demo +``` NAME TYPE VERSION STATUS AGE weaviate-sample kubedb.com/v1alpha2 1.33.1 Ready 73s -$ kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=weaviate-sample +``` NAME READY STATUS RESTARTS AGE weaviate-sample-0 1/1 Running 0 71s weaviate-sample-1 1/1 Running 0 59s weaviate-sample-2 1/1 Running 0 45s -``` ## Verify TLS Resources KubeDB created cert-manager `Certificate` resources and the corresponding TLS secrets (a `server` and a `client` certificate): ```bash -$ kubectl get certificate -n demo +kubectl get certificate -n demo +``` NAME READY SECRET AGE weaviate-sample-client-cert True weaviate-sample-client-cert 73s weaviate-sample-server-cert True weaviate-sample-server-cert 73s -$ kubectl get secret -n demo | grep weaviate-sample +```bash +kubectl get secret -n demo | grep weaviate-sample +``` weaviate-sample-auth Opaque 3 73s weaviate-sample-client-cert kubernetes.io/tls 4 73s weaviate-sample-d25c86 Opaque 1 73s weaviate-sample-server-cert kubernetes.io/tls 3 73s -``` The `spec.tls` block on the `Weaviate` object reflects the TLS configuration: ```bash -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' | jq +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' | jq +``` { "certificates": [ {"alias": "server", "secretName": "weaviate-sample-server-cert"}, @@ -154,51 +163,65 @@ $ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.tls}' | jq "name": "weaviate-issuer" } } -``` With TLS enabled, the REST service is served over HTTPS on port `8443` instead of plain HTTP on `8080`: ```bash -$ kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' -https=8443 grpc=50051 gossip=7102 data=7103 raft=8300 +kubectl get svc -n demo weaviate-sample -o jsonpath='{range .spec.ports[*]}{.name}={.port} {end}' ``` +https=8443 grpc=50051 gossip=7102 data=7103 raft=8300 You can inspect the issued server certificate: ```bash -$ kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -issuer -dates +kubectl get secret -n demo weaviate-sample-server-cert -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -subject -issuer -dates +``` subject=CN=weaviate-sample issuer=CN=weaviate-ca notBefore=Jun 30 18:07:40 2026 GMT notAfter=Sep 28 18:07:40 2026 GMT -``` ## Connect over TLS Because `clientAuth` is enabled, clients must present the client certificate. Extract the certificates from the `client` secret and connect through a port-forward: ```bash -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt -$ kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt +``` -$ export WEAVIATE_API_KEY=$(kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d) +```bash +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt +``` + +```bash +kubectl get secret -n demo weaviate-sample-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key +``` + +```bash +export WEAVIATE_API_KEY=$(kubectl get secret -n demo weaviate-sample-auth -o jsonpath='{.data.AUTHENTICATION_APIKEY_ALLOWED_KEYS}' | base64 -d) +``` + +```bash +kubectl port-forward -n demo svc/weaviate-sample 8443:8443 +``` -$ kubectl port-forward -n demo svc/weaviate-sample 8443:8443 # in another terminal -$ curl -s -o /dev/null -w "%{http_code}\n" \ +```bash +curl -s -o /dev/null -w "%{http_code}\n" \ --cacert ca.crt --cert client.crt --key client.key \ https://localhost:8443/v1/.well-known/ready \ -H "Authorization: Bearer $WEAVIATE_API_KEY" +``` 200 -$ curl -s --cacert ca.crt --cert client.crt --key client.key \ +```bash +curl -s --cacert ca.crt --cert client.crt --key client.key \ https://localhost:8443/v1/nodes \ -H "Authorization: Bearer $WEAVIATE_API_KEY" | jq '.nodes[] | {name, status}' +``` {"name": "weaviate-sample-0", "status": "HEALTHY"} {"name": "weaviate-sample-1", "status": "HEALTHY"} {"name": "weaviate-sample-2", "status": "HEALTHY"} -``` All three nodes are reachable over the TLS-encrypted, mutually-authenticated REST endpoint. @@ -213,8 +236,17 @@ All three nodes are reachable over the TLS-encrypted, mutually-authenticated RES To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete issuer -n demo weaviate-issuer -$ kubectl delete secret -n demo weaviate-ca -$ kubectl delete ns demo +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete issuer -n demo weaviate-issuer +``` + +```bash +kubectl delete secret -n demo weaviate-ca +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/weaviate/volume-expansion/volume-expansion.md b/docs/guides/weaviate/volume-expansion/volume-expansion.md index a2aa163c52..c381562bd4 100644 --- a/docs/guides/weaviate/volume-expansion/volume-expansion.md +++ b/docs/guides/weaviate/volume-expansion/volume-expansion.md @@ -25,11 +25,11 @@ This guide will show you how to use the `KubeDB` Ops Manager to expand the volum - You need a `StorageClass` that supports volume expansion. Verify with: ```bash - $ kubectl get storageclass + kubectl get storageclass + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 38h longhorn driver.longhorn.io Delete Immediate true 30m - ``` Here, the `longhorn` StorageClass has `ALLOWVOLUMEEXPANSION` set to `true`. @@ -40,9 +40,9 @@ This guide will show you how to use the `KubeDB` Ops Manager to expand the volum To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/weaviate/volume-expansion](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/weaviate/volume-expansion) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -73,12 +73,12 @@ spec: Let's create the `Weaviate` CR and wait for it to become `Ready`. Then check the PVCs: ```bash -$ kubectl get pvc -n demo +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-weaviate-sample-0 Bound pvc-b8b6d9e6-634f-4ead-b1fd-1bfe549976e4 1Gi RWO longhorn 5m data-weaviate-sample-1 Bound pvc-4e9329c0-8a3d-4402-919c-afa4fe2144c9 1Gi RWO longhorn 5m data-weaviate-sample-2 Bound pvc-a846947c-212f-4aea-92a7-c8f88ae7f463 1Gi RWO longhorn 5m -``` Each PVC has `1Gi` of storage. @@ -108,22 +108,23 @@ spec: Let's create the `WeaviateOpsRequest` CR: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/volume-expansion/ops-request.yaml -weaviateopsrequest.ops.kubedb.com/wv-volume-expansion-offline created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/weaviate/volume-expansion/ops-request.yaml ``` +weaviateopsrequest.ops.kubedb.com/wv-volume-expansion-offline created The Ops Manager will expand the PVCs and reconcile the cluster. ```bash -$ kubectl get weaviateopsrequest -n demo wv-volume-expansion-offline +kubectl get weaviateopsrequest -n demo wv-volume-expansion-offline +``` NAME TYPE STATUS AGE wv-volume-expansion-offline VolumeExpansion Successful 2m -``` Let's check the `status.conditions` of the `WeaviateOpsRequest`: ```bash -$ kubectl get weaviateopsrequest -n demo wv-volume-expansion-offline -o yaml +kubectl get weaviateopsrequest -n demo wv-volume-expansion-offline -o yaml +``` apiVersion: ops.kubedb.com/v1alpha1 kind: WeaviateOpsRequest metadata: @@ -181,20 +182,21 @@ status: type: Successful observedGeneration: 1 phase: Successful -``` Now, let's verify that the PVCs have been expanded to `3Gi`: ```bash -$ kubectl get pvc -n demo +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-weaviate-sample-0 Bound pvc-b8b6d9e6-634f-4ead-b1fd-1bfe549976e4 3Gi RWO longhorn 14m data-weaviate-sample-1 Bound pvc-4e9329c0-8a3d-4402-919c-afa4fe2144c9 3Gi RWO longhorn 10m data-weaviate-sample-2 Bound pvc-a846947c-212f-4aea-92a7-c8f88ae7f463 3Gi RWO longhorn 10m -$ kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.storage.resources.requests.storage}' -3Gi +```bash +kubectl get weaviate -n demo weaviate-sample -o jsonpath='{.spec.storage.resources.requests.storage}' ``` +3Gi The volume has been expanded successfully. @@ -209,7 +211,13 @@ The volume has been expanded successfully. To clean up the Kubernetes resources created by this tutorial, run: ```bash -$ kubectl delete weaviateopsrequest -n demo wv-volume-expansion-offline -$ kubectl delete weaviate -n demo weaviate-sample -$ kubectl delete ns demo +kubectl delete weaviateopsrequest -n demo wv-volume-expansion-offline +``` + +```bash +kubectl delete weaviate -n demo weaviate-sample +``` + +```bash +kubectl delete ns demo ``` diff --git a/docs/guides/zookeeper/backup/kubestash/auto-backup/index.md b/docs/guides/zookeeper/backup/kubestash/auto-backup/index.md index ad5cd85589..adc0433b10 100644 --- a/docs/guides/zookeeper/backup/kubestash/auto-backup/index.md +++ b/docs/guides/zookeeper/backup/kubestash/auto-backup/index.md @@ -38,9 +38,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/zookeeper/backup/kubestash/auto-backup/examples](/docs/guides/zookeeper/backup/kubestash/auto-backup/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -53,13 +53,19 @@ We are going to store our backed up data into a `s3` bucket. We have to create a Let's create a secret called `s3-secret` with access credentials to our desired s3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -89,9 +95,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our database to our desired backend. @@ -122,9 +128,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created **Create Secret:** @@ -133,8 +139,11 @@ We also need to create a secret with a `Restic` password for backup data encrypt Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD \ secret "encrypt-secret" created ``` @@ -197,9 +206,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml -backupblueprint.core.kubestash.com/zookeeper-default-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/default-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/zookeeper-default-backup-blueprint created Now, we are ready to backup our `ZooKeeper` using few annotations. @@ -239,24 +248,24 @@ Here, Let's create the `ZooKeeper` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/sample-zookeeper.yaml -zookeeper.kubedb.com/sample-zookeeper created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/sample-zookeeper.yaml ``` +zookeeper.kubedb.com/sample-zookeeper created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our ZooKeeper in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-zookeeper Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-zookeeper -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-zookeeper -o yaml ``` ```yaml @@ -364,10 +373,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-zookeeper-frequent-backup-1726735844 BackupConfiguration appbinding-sample-zookeeper Succeeded 23s 6m40s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -376,18 +385,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `default-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo default-blueprint +kubectl get repository -n demo default-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE default-blueprint true 1 1.559 KiB Ready 80s 7m32s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=default-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE default-blueprint-appbinding-samgres-frequent-backup-1726736101 default-blueprint frequent-backup 2024-09-19T08:55:01Z Delete Succeeded 7m48s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -400,7 +409,7 @@ default-blueprint-appbinding-samgres-frequent-backup-1726736101 default-bluepr If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo default-blueprint-appbinding-sameper-frequent-backup-1726736101 -oyaml +kubectl get snapshots -n demo default-blueprint-appbinding-sameper-frequent-backup-1726736101 -oyaml ``` ```yaml @@ -545,9 +554,9 @@ Here, Let's create the `BackupBlueprint` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml -backupblueprint.core.kubestash.com/zookeeper-customize-backup-blueprint created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/customize-backupblueprint.yaml ``` +backupblueprint.core.kubestash.com/zookeeper-customize-backup-blueprint created Now, we are ready to backup our `ZooKeeper` using few annotations. You can check available auto-backup annotations for a databases from [here](https://kubestash.com/docs/latest/concepts/crds/backupblueprint/). @@ -589,24 +598,24 @@ Notice the `metadata.annotations` field, where we have defined the annotations r Let's create the `ZooKeeper` we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/sample-zookeeper-2.yaml -zookeeper.kubedb.com/sample-zookeeper-2 created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/auto-backup/examples/sample-zookeeper-2.yaml ``` +zookeeper.kubedb.com/sample-zookeeper-2 created **Verify BackupConfiguration** If everything goes well, KubeStash should create a `BackupConfiguration` for our ZooKeeper in demo namespace and the phase of that `BackupConfiguration` should be `Ready`. Verify the `BackupConfiguration` object by the following command, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE appbinding-sample-zookeeper-2 Ready 2m50m -``` Now, let’s check the YAML of the `BackupConfiguration`. ```bash -$ kubectl get backupconfiguration -n demo appbinding-sample-zookeeper-2 -o yaml +kubectl get backupconfiguration -n demo appbinding-sample-zookeeper-2 -o yaml ``` ```yaml @@ -713,10 +722,10 @@ Notice the `spec.backends`, `spec.sessions` and `spec.target` sections, KubeStas KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE appbinding-sample-zookeeper-2-frequent-backup-1726742400 BackupConfiguration appbinding-sample-zookeeper-2 Succeeded 58s 112s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -725,18 +734,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `customize-blueprint` has been updated by the following command, ```bash -$ kubectl get repository -n demo customize-blueprint +kubectl get repository -n demo customize-blueprint +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE customize-blueprint true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +kubectl get snapshots -n demo -l=kubestash.com/repo-name=customize-blueprint +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE customize-blueprint-appbinding-ser-2-frequent-backup-1726742400 customize-blueprint frequent-backup 2024-09-19T10:40:01Z Delete Succeeded 6m19s -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubedb.com/db-version: ` @@ -750,7 +759,7 @@ customize-blueprint-appbinding-ser-2-frequent-backup-1726742400 customize-blue If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml +kubectl get snapshots -n demo customize-blueprint-appbinding-sql-2-frequent-backup-1725597000 -oyaml ``` ```yaml diff --git a/docs/guides/zookeeper/backup/kubestash/logical/index.md b/docs/guides/zookeeper/backup/kubestash/logical/index.md index f07333a7dc..cdfd22e8fa 100644 --- a/docs/guides/zookeeper/backup/kubestash/logical/index.md +++ b/docs/guides/zookeeper/backup/kubestash/logical/index.md @@ -39,9 +39,9 @@ You should be familiar with the following `KubeStash` concepts: To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/guides/zookeeper/backup/kubestash/logical/examples](/docs/guides/zookeeper/backup/kubestash/logical/examples) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -83,33 +83,35 @@ spec: Create the above `ZooKeeper` CR, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/sample-zookeeper.yaml -zookeeper.kubedb.com/sample-zookeeper created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/sample-zookeeper.yaml ``` +zookeeper.kubedb.com/sample-zookeeper created KubeDB will deploy a `ZooKeeper` according to the above specification. It will also create the necessary `Secrets` and `Services` to access. Let's check if the zookeeper is ready to use, ```bash -$ kubectl get zk -n demo sample-zookeeper +kubectl get zk -n demo sample-zookeeper +``` NAME VERSION STATUS AGE sample-zookeeper 3.9.1 Ready 5m1s -``` The zookeeper is `Ready`. Verify that KubeDB has created a `Secret` and a `Service` for this zookeeper using the following commands, ```bash -$ kubectl get secret -n demo +kubectl get secret -n demo +``` NAME TYPE DATA AGE sample-zookeeper-auth kubernetes.io/basic-auth 2 5m20s -$ kubectl get service -n demo -l=app.kubernetes.io/instance=sample-zookeeper +```bash +kubectl get service -n demo -l=app.kubernetes.io/instance=sample-zookeeper +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE sample-zookeeper ClusterIP 10.128.65.175 2181/TCP 5m55s sample-zookeeper-pods ClusterIP None 2181/TCP,2888/TCP,3888/TCP 5m55s sample-zookeeper-admin-server ClusterIP 10.128.163.169 8080/TCP 5m55s -``` Here, we have to use service `sample-zookeeper` and secret `sample-zookeeper-auth` to connect with the zookeeper. `KubeDB` creates an [AppBinding](/docs/guides/zookeeper/concepts/appbinding.md) CR that holds the necessary information to connect with the zookeeper. @@ -119,15 +121,15 @@ Here, we have to use service `sample-zookeeper` and secret `sample-zookeeper-aut Verify that the `AppBinding` has been created successfully using the following command, ```bash -$ kubectl get appbindings -n demo +kubectl get appbindings -n demo +``` NAME TYPE VERSION AGE sample-zookeeper kubedb.com/zookeeper 3.9.1 9m30s -``` Let's check the YAML of the above `AppBinding`, ```bash -$ kubectl get appbindings -n demo sample-zookeeper -o yaml +kubectl get appbindings -n demo sample-zookeeper -o yaml ``` ```yaml @@ -186,26 +188,30 @@ Here, Now, we are going to exec into one of the database pod and create some sample data. At first, find out the database `Pod` using the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-zookeeper" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=sample-zookeeper" +``` NAME READY STATUS RESTARTS AGE sample-zookeeper-0 2/2 Running 0 16m sample-zookeeper-1 2/2 Running 0 13m sample-zookeeper-2 2/2 Running 0 13m -``` Now, let’s exec into the pod and create a directory, ```bash -$ kubectl exec -it -n demo sample-zookeeper-0 -- sh - +kubectl exec -it -n demo sample-zookeeper-0 -- sh +``` Type "help" for help. # Check if Zookeeper server is running and healthy -$ echo ruok | nc localhost 2181 +```bash +echo ruok | nc localhost 2181 +``` imok # Create a znode named /hello-dir with the data "hello-message" -$ zkCli.sh create /hello-dir hello-messege +```bash +zkCli.sh create /hello-dir hello-messege +``` Connecting to localhost:2181 ... Connection Log Messeges @@ -214,7 +220,6 @@ Created /hello-dir # exit from the pod / $ exit -``` Now, we are ready to backup the data. @@ -227,13 +232,19 @@ We are going to store our backed up data into a `S3` bucket. We have to create a Let's create a secret called `s3-secret` with access credentials to our desired s3 bucket, ```bash -$ echo -n '' > AWS_ACCESS_KEY_ID -$ echo -n '' > AWS_SECRET_ACCESS_KEY -$ kubectl create secret generic -n demo s3-secret \ +echo -n '' > AWS_ACCESS_KEY_ID +``` + +```bash +echo -n '' > AWS_SECRET_ACCESS_KEY +``` + +```bash +kubectl create secret generic -n demo s3-secret \ --from-file=./AWS_ACCESS_KEY_ID \ --from-file=./AWS_SECRET_ACCESS_KEY -secret/s3-secret created ``` +secret/s3-secret created **Create BackupStorage:** @@ -263,9 +274,9 @@ spec: Let's create the BackupStorage we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/backupstorage.yaml -backupstorage.storage.kubestash.com/s3-storage created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/backupstorage.yaml ``` +backupstorage.storage.kubestash.com/s3-storage created Now, we are ready to backup our data to our desired backend. @@ -296,9 +307,9 @@ spec: Let’s create the above `RetentionPolicy`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/retentionpolicy.yaml -retentionpolicy.storage.kubestash.com/demo-retention created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/retentionpolicy.yaml ``` +retentionpolicy.storage.kubestash.com/demo-retention created ### Backup @@ -311,11 +322,14 @@ At first, we need to create a secret with a Restic password for backup data encr Let's create a secret called `encrypt-secret` with the Restic password, ```bash -$ echo -n 'changeit' > RESTIC_PASSWORD -$ kubectl create secret generic -n demo encrypt-secret \ +echo -n 'changeit' > RESTIC_PASSWORD +``` + +```bash +kubectl create secret generic -n demo encrypt-secret \ --from-file=./RESTIC_PASSWORD -secret "encrypt-secret" created ``` +secret "encrypt-secret" created Below is the YAML for `BackupConfiguration` CR to backup the `sample-zookeeper` that we have deployed earlier, @@ -364,27 +378,27 @@ spec: Let's create the `BackupConfiguration` CR that we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/backupconfiguration.yaml -backupconfiguration.core.kubestash.com/sample-zookeeper-backup created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/backupconfiguration.yaml ``` +backupconfiguration.core.kubestash.com/sample-zookeeper-backup created **Verify Backup Setup Successful** If everything goes well, the phase of the `BackupConfiguration` should be `Ready`. The `Ready` phase indicates that the backup setup is successful. Let's verify the `Phase` of the BackupConfiguration, ```bash -$ kubectl get backupconfiguration -n demo +kubectl get backupconfiguration -n demo +``` NAME PHASE PAUSED AGE sample-zookeeper-backup Ready 2m50s -``` Additionally, we can verify that the `Repository` specified in the `BackupConfiguration` has been created using the following command, ```bash -$ kubectl get repo -n demo +kubectl get repo -n demo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-zookeeper-repo 0 0 B Ready 3m -``` KubeStash keeps the backup for `Repository` YAMLs. If we navigate to the s3 bucket, we will see the `Repository` YAML stored in the `demo/zookeeper` directory. @@ -395,20 +409,20 @@ It will also create a `CronJob` with the schedule specified in `spec.sessions[*] Verify that the `CronJob` has been created using the following command, ```bash -$ kubectl get cronjob -n demo +kubectl get cronjob -n demo +``` NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE trigger-sample-zookeeper-backup-frequent-backup */5 * * * * 0 2m45s 3m25s -``` **Verify BackupSession:** KubeStash triggers an instant backup as soon as the `BackupConfiguration` is ready. After that, backups are scheduled according to the specified schedule. ```bash -$ kubectl get backupsession -n demo -w +kubectl get backupsession -n demo -w +``` NAME INVOKER-TYPE INVOKER-NAME PHASE DURATION AGE sample-zookeeper-backup-frequent-backup-1726572962 BackupConfiguration sample-zookeeper-backup Succeeded 7m22s -``` We can see from the above output that the backup session has succeeded. Now, we are going to verify whether the backed up data has been stored in the backend. @@ -417,18 +431,18 @@ We can see from the above output that the backup session has succeeded. Now, we Once a backup is complete, KubeStash will update the respective `Repository` CR to reflect the backup. Check that the repository `sample-zookeeper-backup` has been updated by the following command, ```bash -$ kubectl get repository -n demo s3-zookeeper-repo +kubectl get repository -n demo s3-zookeeper-repo +``` NAME INTEGRITY SNAPSHOT-COUNT SIZE PHASE LAST-SUCCESSFUL-BACKUP AGE s3-zookeeper-repo true 1 806 B Ready 8m27s 9m18s -``` At this moment we have one `Snapshot`. Run the following command to check the respective `Snapshot` which represents the state of a backup run for an application. ```bash -$ kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-zookeeper-repo +kubectl get snapshots -n demo -l=kubestash.com/repo-name=s3-zookeeper-repo +``` NAME REPOSITORY SESSION SNAPSHOT-TIME DELETION-POLICY PHASE AGE s3-zookeeper-repo-sample-zookeeper-backup-frequent-backup-1726572962 s3-zookeeper-repo frequent-backup 2024-01-23T13:10:54Z Delete Succeeded 16h -``` > Note: KubeStash creates a `Snapshot` with the following labels: > - `kubestash.com/app-ref-kind: ` @@ -441,7 +455,7 @@ s3-zookeeper-repo-sample-zookeeper-backup-frequent-backup-1726572962 s3-zookee If we check the YAML of the `Snapshot`, we can find the information about the backed up components of the Database. ```bash -$ kubectl get snapshots -n demo s3-zookeeper-repo-sample-zookeeper-backup-frequent-backup-1726572962 -oyaml +kubectl get snapshots -n demo s3-zookeeper-repo-sample-zookeeper-backup-frequent-backup-1726572962 -oyaml ``` ```yaml @@ -554,17 +568,17 @@ spec: Let's create the above database, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/restored-zookeeper.yaml -zookeeper.kubedb.com/restored-zookeeper created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/restored-zookeeper.yaml ``` +zookeeper.kubedb.com/restored-zookeeper created If you check the database status, you will see it is stuck in **`Provisioning`** state. ```bash -$ kubectl get zookeeper -n demo restored-zookeeper +kubectl get zookeeper -n demo restored-zookeeper +``` NAME VERSION STATUS AGE restored-zookeeper 3.9.1 Provisioning 61s -``` #### Create RestoreSession: @@ -605,18 +619,18 @@ Here, Let's create the RestoreSession CRD object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/restoresession.yaml -restoresession.core.kubestash.com/sample-zookeeper-restore created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/guides/zookeeper/backup/kubestash/logical/examples/restoresession.yaml ``` +restoresession.core.kubestash.com/sample-zookeeper-restore created Once, you have created the `RestoreSession` object, KubeStash will create restore Job. Run the following command to watch the phase of the `RestoreSession` object, ```bash -$ watch kubectl get restoresession -n demo +watch kubectl get restoresession -n demo +``` Every 2.0s: kubectl get restores... AppsCode-PC-03: Wed Aug 21 10:44:05 2024 NAME REPOSITORY FAILURE-POLICY PHASE DURATION AGE sample-zookeeper-restore s3-zookeeper-repo Succeeded 7s 116s -``` The `Succeeded` phase means that the restore process has been completed successfully. @@ -627,34 +641,38 @@ In this section, we are going to verify whether the desired data has been restor At first, check if the database has gone into **`Ready`** state by the following command, ```bash -$ kubectl get zookeeper -n demo restored-zookeeper +kubectl get zookeeper -n demo restored-zookeeper +``` NAME VERSION STATUS AGE restored-zookeeper 3.9.1 Ready 6m31s -``` Now, find out the database `Pod` by the following command, ```bash -$ kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-zookeeper" +kubectl get pods -n demo --selector="app.kubernetes.io/instance=restored-zookeeper" +``` NAME READY STATUS RESTARTS AGE restored-zookeeper-0 2/2 Running 0 6m7s restored-zookeeper-1 2/2 Running 0 6m1s restored-zookeeper-2 2/2 Running 0 5m55s -``` Now, lets exec one of the `Pod` and verify restored data. ```bash -$ kubectl exec -it -n demo restored-zookeeper-0 -- sh - +kubectl exec -it -n demo restored-zookeeper-0 -- sh +``` Type "help" for help. # Check if Zookeeper server is running and healthy -$ echo ruok | nc localhost 2181 +```bash +echo ruok | nc localhost 2181 +``` imok # List all znodes from the root directory -$ zkCli.sh ls / +```bash +zkCli.sh ls / +``` Connecting to localhost:2181 ... Connection Log Messeges @@ -662,7 +680,9 @@ Connection Log Messeges [hello-dir] # Verify the data stored in the /hello-dir znode -$ zkCli.sh get /hello-dir +```bash +zkCli.sh get /hello-dir +``` Connecting to localhost:2181 ... Connection Log Messeges @@ -671,7 +691,6 @@ hello-messege # exit from the pod / $ exit -``` So, from the above output, we can see the `demo` database we had created in the original database `sample-zookeeper` has been restored in the `restored-zookeeper`. diff --git a/docs/guides/zookeeper/concepts/zookeeper.md b/docs/guides/zookeeper/concepts/zookeeper.md index dee3c6030d..82a0a8e7dd 100644 --- a/docs/guides/zookeeper/concepts/zookeeper.md +++ b/docs/guides/zookeeper/concepts/zookeeper.md @@ -145,11 +145,11 @@ AuthSecret contains a `username` key and a `password` key which contains the `us Example: ```bash -$ kubectl create secret generic zk-auth -n demo \ +kubectl create secret generic zk-auth -n demo \ --from-literal=username=jhon-doe \ --from-literal=password=6q8u_2jMOW-OOZXk -secret "zk-auth" created ``` +secret "zk-auth" created ```yaml apiVersion: v1 diff --git a/docs/guides/zookeeper/monitoring/using-builtin-prometheus.md b/docs/guides/zookeeper/monitoring/using-builtin-prometheus.md index f7dda022e5..a354629485 100644 --- a/docs/guides/zookeeper/monitoring/using-builtin-prometheus.md +++ b/docs/guides/zookeeper/monitoring/using-builtin-prometheus.md @@ -29,12 +29,14 @@ This tutorial will show you how to monitor ZooKeeper database using builtin [Pro - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/zookeeper](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/zookeeper) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -75,33 +77,34 @@ Here, Let's create the ZooKeeper crd we have shown above. ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/builtin-prom-zk.yaml -zookeeper.kubedb.com/zookeeper-builtin-prom created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/builtin-prom-zk.yaml ``` +zookeeper.kubedb.com/zookeeper-builtin-prom created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zookeeper-builtin-prom 3.9.1 Ready 129m -``` KubeDB will create a separate stats service with name `{ZooKeeper crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=zookeeper-builtin-prom" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=zookeeper-builtin-prom" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE zookeeper-builtin-prom ClusterIP 10.43.115.171 2181/TCP 129m zookeeper-builtin-prom-admin-server ClusterIP 10.43.55.7 8080/TCP 129m zookeeper-builtin-prom-pods ClusterIP None 2181/TCP,2888/TCP,3888/TCP 129m zookeeper-builtin-prom-stats ClusterIP 10.43.211.84 7000/TCP 129m -``` Here, `zookeeper-builtin-prom-stats` service has been created for monitoring purpose. Let's describe the service. ```bash -$ kubectl describe svc -n demo zookeeper-builtin-prom-stats +kubectl describe svc -n demo zookeeper-builtin-prom-stats +``` Name: zookeeper-builtin-prom-stats Namespace: demo Labels: app.kubernetes.io/component=database @@ -124,7 +127,6 @@ TargetPort: metrics/TCP Endpoints: 10.42.0.124:7000,10.42.0.126:7000,10.42.0.128:7000 Session Affinity: None Events: -``` You can see that the service contains following annotations. @@ -288,20 +290,20 @@ data: Let's create above `ConfigMap`, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/prom-config.yaml -configmap/prometheus-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/prom-config.yaml ``` +configmap/prometheus-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -312,9 +314,9 @@ Now, we are ready to deploy Prometheus server. We are going to use following [de Let's deploy the Prometheus server. ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/deployment.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -323,18 +325,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-d64b668fb-vg746 1/1 Running 0 28s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-7bd56c6865-8dlpv` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-d64b668fb-vg746 9090 +kubectl port-forward -n monitoring prometheus-d64b668fb-vg746 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see the endpoint of `zookeeper-builtin-prom-stats` service as one of the targets. diff --git a/docs/guides/zookeeper/monitoring/using-prometheus-operator.md b/docs/guides/zookeeper/monitoring/using-prometheus-operator.md index c2475dbcea..50a7772d94 100644 --- a/docs/guides/zookeeper/monitoring/using-prometheus-operator.md +++ b/docs/guides/zookeeper/monitoring/using-prometheus-operator.md @@ -27,12 +27,14 @@ section_menu_id: guides - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy the prometheus operator helm chart. We are going to deploy database in `demo` namespace. ```bash - $ kubectl create ns monitoring + kubectl create ns monitoring + ``` namespace/monitoring created - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created @@ -45,10 +47,10 @@ We need to know the labels used to select `ServiceMonitor` by a `Prometheus` crd At first, let's find out the available Prometheus server in our cluster. ```bash -$ kubectl get prometheus --all-namespaces +kubectl get prometheus --all-namespaces +``` NAMESPACE NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE monitoring prometheus-kube-prometheus-prometheus v2.54.1 1 1 True True 22h -``` > If you don't have any Prometheus server running in your cluster, deploy one following the guide specified in **Before You Begin** section. @@ -203,28 +205,28 @@ Here, Let's create the ZooKeeper object that we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/prom-zk.yaml -zookeeper.kubedb.com/zookeeper created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/monitoring/prom-zk.yaml ``` +zookeeper.kubedb.com/zookeeper created Now, wait for the database to go into `Running` state. ```bash -$ kubectl get zk -n demo zookeeper +kubectl get zk -n demo zookeeper +``` NAME VERSION STATUS AGE zookeeper 3.9.1 Ready 34s -``` KubeDB will create a separate stats service with name `{ZooKeeper crd name}-stats` for monitoring purpose. ```bash -$ kubectl get svc -n demo --selector="app.kubernetes.io/instance=zookeeper" +kubectl get svc -n demo --selector="app.kubernetes.io/instance=zookeeper" +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE zookeeper ClusterIP 10.43.121.151 2181/TCP 26s zookeeper-admin-server ClusterIP 10.43.28.44 8080/TCP 26s zookeeper-pods ClusterIP None 2181/TCP,2888/TCP,3888/TCP 26s zookeeper-stats ClusterIP 10.43.19.32 7000/TCP 26s -``` Here, `zookeeper-stats` service has been created for monitoring purpose. @@ -258,10 +260,10 @@ Notice the `Labels` and `Port` fields. `ServiceMonitor` will use this informatio KubeDB will also create a `ServiceMonitor` crd in `demo` namespace that select the endpoints of `zookeeper-stats` service. Verify that the `ServiceMonitor` crd has been created. ```bash -$ kubectl get servicemonitor -n demo +kubectl get servicemonitor -n demo +``` NAME AGE zookeeper-stats 2m40s -``` Let's verify that the `ServiceMonitor` has the label that we had specified in `spec.monitor` section of ZooKeeper crd. @@ -316,20 +318,20 @@ Also notice that the `ServiceMonitor` has selector which match the labels we hav At first, let's find out the respective Prometheus pod for `prometheus` Prometheus server. ```bash -$ kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +kubectl get pod -n monitoring -l=app.kubernetes.io/name=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-kube-prometheus-prometheus-0 2/2 Running 1 22h -``` Prometheus server is listening to port `9090` of `prometheus-prometheus-kube-prometheus-prometheus-0` pod. We are going to use [port forwarding](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/) to access Prometheus dashboard. Run following command on a separate terminal to forward the port 9090 of `prometheus-prometheus-kube-prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `metrics` endpoint of `zookeeper-stats` service as one of the targets. diff --git a/docs/guides/zookeeper/quickstart/quickstart.md b/docs/guides/zookeeper/quickstart/quickstart.md index cf9bbad946..4d7b6aea9f 100644 --- a/docs/guides/zookeeper/quickstart/quickstart.md +++ b/docs/guides/zookeeper/quickstart/quickstart.md @@ -30,21 +30,23 @@ to install ZooKeeper CRDs. - [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) is required to run KubeDB. Check the available StorageClass in cluster. ```bash - $ kubectl get storageclasses + kubectl get storageclasses + ``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 20h - ``` - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. Run the following command to prepare your cluster for this tutorial: ```bash - $ kubectl create namespace demo + kubectl create namespace demo + ``` namespace/demo created - $ kubectl get namespaces + ```bash + kubectl get namespaces + ``` NAME STATUS AGE demo Active 10s - ``` > Note: The yaml files used in this tutorial are stored in [docs/examples](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -53,12 +55,12 @@ to install ZooKeeper CRDs. When you have installed KubeDB, it has created `ZooKeeperVersions` crd for all supported ZooKeeper versions. Check: ```bash -$ kubectl get zookeeperversions +kubectl get zookeeperversions +``` NAME VERSION DB_IMAGE DEPRECATED AGE 3.7.2 3.7.2 ghcr.io/appscode-images/zookeeper:3.7.2 94s 3.8.3 3.8.3 ghcr.io/appscode-images/zookeeper:3.8.3 94s 3.9.1 3.9.1 ghcr.io/appscode-images/zookeeper:3.9.1 94s -``` ## Create a ZooKeeper server @@ -85,9 +87,9 @@ spec: ``` ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/quickstart/zoo.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/quickstart/zoo.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Here, @@ -100,11 +102,14 @@ Here, KubeDB operator watches for `ZooKeeper` objects using Kubernetes api. When a `ZooKeeper` object is created, KubeDB operator will create a new PetSet and a Service with the matching ZooKeeper object name. KubeDB operator will also create a governing service for PetSets with the name `kubedb`, if one is not already present. ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME TYPE VERSION STATUS AGE zk-quickstart kubedb.com/v1alpha2 3.9.1 Ready 105s -$ kubectl describe zk -n demo zk-quickstart +```bash +kubectl describe zk -n demo zk-quickstart +``` Name: zk-quickstart Namespace: demo Labels: @@ -215,37 +220,41 @@ Status: Phase: Ready Events: - -$ kubectl get petset -n demo +```bash +kubectl get petset -n demo +``` NAME AGE zk-quickstart 3m14s - -$ kubectl get pvc -n demo +```bash +kubectl get pvc -n demo +``` NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE zk-quickstart-data-zk-quickstart-0 Bound pvc-1e1850b8-4e5c-418c-a722-89df98f28998 1Gi RWO standard 3m40s zk-quickstart-data-zk-quickstart-1 Bound pvc-e2bb4b02-b138-4589-9e43-bcaf599b6513 1Gi RWO standard 3m31s zk-quickstart-data-zk-quickstart-2 Bound pvc-988ab6b2-e5ed-4c75-8418-31186bd1d3db 1Gi RWO standard 3m25s - -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-1e1850b8-4e5c-418c-a722-89df98f28998 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-0 standard 3m52s pvc-988ab6b2-e5ed-4c75-8418-31186bd1d3db 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-2 standard 3m40s pvc-e2bb4b02-b138-4589-9e43-bcaf599b6513 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-1 standard 3m46s - -$ kubectl get service -n demo +```bash +kubectl get service -n demo +``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE zk-quickstart ClusterIP 10.96.26.38 2181/TCP 4m15s zk-quickstart-admin-server ClusterIP 10.96.49.134 8080/TCP 4m15s zk-quickstart-pods ClusterIP None 2181/TCP,2888/TCP,3888/TCP 4m15s -``` KubeDB operator sets the `status.phase` to `Ready` once the database is successfully created. Run the following command to see the modified ZooKeeper object: ```bash -$ kubectl get zk -n demo zk-quickstart -o yaml +kubectl get zk -n demo zk-quickstart -o yaml +``` apiVersion: kubedb.com/v1alpha2 kind: ZooKeeper metadata: @@ -355,39 +364,44 @@ status: status: "True" type: Provisioned phase: Ready -``` Now, you can connect to this database using created service. In this tutorial, we are connecting to the ZooKeeper server from inside of pod. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- sh +kubectl exec -it -n demo zk-quickstart-0 -- sh +``` -$ echo ruok | nc localhost 2181 +```bash +echo ruok | nc localhost 2181 +``` imok -$ zkCli.sh create /hello-dir hello-messege +```bash +zkCli.sh create /hello-dir hello-messege +``` Connecting to localhost:2181 ... Connection Log Messeges ... Created /hello-dir -$ zkCli.sh get /hello-dir +```bash +zkCli.sh get /hello-dir +``` Connecting to localhost:2181 ... Connection Log Messeges ... hello-messege -``` ## DoNotTerminate Property When `deletionPolicy` is `DoNotTerminate`, KubeDB takes advantage of `ValidationWebhook` feature in Kubernetes 1.9.0 or later clusters to implement `DoNotTerminate` feature. If admission webhook is enabled, It prevents users from deleting the database as long as the `spec.deletionPolicy` is set to `DoNotTerminate`. You can see this below: ```bash -$ kubectl delete zk zk-quickstart -n demo -The ZooKeeper "zk-quickstart" is invalid: spec.deletionPolicy: Invalid value: "zk-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" +kubectl delete zk zk-quickstart -n demo ``` +The ZooKeeper "zk-quickstart" is invalid: spec.deletionPolicy: Invalid value: "zk-quickstart": Can not delete as deletionPolicy is set to "DoNotTerminate" Now, run `kubectl edit zk zk-quickstart -n demo` to set `spec.deletionPolicy` to `Halt` . Then you will be able to delete/halt the database. @@ -397,16 +411,19 @@ Now, run `kubectl edit zk zk-quickstart -n demo` to set `spec.deletionPolicy` to To clean up the Kubernetes resources created by this tutorial, run: ```bash - -$ kubectl patch -n demo zk/zk-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +kubectl patch -n demo zk/zk-quickstart -p '{"spec":{"deletionPolicy":"WipeOut"}}' --type="merge" +``` zookeeper.kubedb.com/zk-quickstart patched -$ kubectl delete -n demo zk/zk-quickstart +```bash +kubectl delete -n demo zk/zk-quickstart +``` zookeeper.kubedb.com "zk-quickstart" deleted -$ kubectl delete ns demo -namespace "demo" deleted +```bash +kubectl delete ns demo ``` +namespace "demo" deleted ## Tips for Testing diff --git a/docs/guides/zookeeper/reconfigure-tls/reconfigure-tls.md b/docs/guides/zookeeper/reconfigure-tls/reconfigure-tls.md index 91ebbae90e..c3585697d0 100644 --- a/docs/guides/zookeeper/reconfigure-tls/reconfigure-tls.md +++ b/docs/guides/zookeeper/reconfigure-tls/reconfigure-tls.md @@ -27,9 +27,9 @@ KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL cer - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/zookeeper](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/zookeeper) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -64,22 +64,23 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ watch kubectl get zookeeper -n demo +watch kubectl get zookeeper -n demo +``` NAME TYPE VERSION STATUS AGE zk-quickstart kubedb.com/v1alpha2 3.9.1 Ready 60s -``` Now, we can exec one zookeeper broker pod and verify configuration that the TLS is disabled. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ cat ../conf/zoo.cfg 4lw.commands.whitelist=* @@ -106,7 +107,6 @@ reconfigEnabled=true standaloneEnabled=false dynamicConfigFile=/data/zoo.cfg.dynamic zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ -``` We can verify from the above output that TLS is disabled for this Ensemble. @@ -117,23 +117,23 @@ Now, We are going to create an example `Issuer` that will be used to enable SSL/ - 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=ca/O=kubedb" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/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 zookeeper-ca \ +kubectl create secret tls zookeeper-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/zookeeper-ca created ``` +secret/zookeeper-ca created Now, Let's create an `Issuer` using the `zookeeper-ca` secret that we have just created. The `YAML` file looks like this: @@ -151,9 +151,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-issuer.yaml -issuer.cert-manager.io/zk-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-issuer.yaml ``` +issuer.cert-manager.io/zk-issuer created ### Create ZooKeeperOpsRequest @@ -195,24 +195,25 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-add-tls.yaml -zookeeperopsrequest.ops.kubedb.com/zkops-add-tls created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-add-tls.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zkops-add-tls created #### Verify TLS Enabled Successfully Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CRO, ```bash -$ kubectl get zookeeperopsrequest -n demo +kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE zkops-add-tls ReconfigureTLS Successful 4m36s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe zookeeperopsrequest -n demo zkops-add-tls +kubectl describe zookeeperopsrequest -n demo zkops-add-tls +``` Name: zkops-add-tls Namespace: demo Labels: @@ -319,12 +320,12 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now, Let's exec into a zookeeper ensemble pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ cat ../conf/zoo.cfg 4lw.commands.whitelist=* @@ -364,7 +365,6 @@ ssl.quorum.trustStore.location=/var/private/ssl/server.truststore.jks ssl.quorum.trustStore.password=fdjk2dgffqn9 ssl.quorum.hostnameVerification=false zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ -``` We can see from the above output that, keystore location is `/var/private/ssl/server.keystore.jks` which means that TLS is enabled. @@ -373,11 +373,11 @@ We can see from the above output that, keystore location is `/var/private/ssl/se Now we are going to rotate the certificate of this cluster. First let's check the current expiration date of the certificate. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ openssl x509 -in /var/private/ssl/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 2 12:53:30 2025 GMT -``` So, the certificate will expire on this time `Feb 2 12:53:30 2025 GMT`. @@ -408,24 +408,25 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zkops-rotate.yaml -zookeeperopsrequest.ops.kubedb.com/zkops-rotate created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zkops-rotate.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zkops-rotate created #### Verify Certificate Rotated Successfully Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CRO, ```bash -$ kubectl get zookeeperopsrequests -n demo zkops-rotate +kubectl get zookeeperopsrequests -n demo zkops-rotate +``` NAME TYPE STATUS AGE zkops-rotate ReconfigureTLS Successful 4m4s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe zookeeperopsrequest -n demo zkops-rotate +kubectl describe zookeeperopsrequest -n demo zkops-rotate +``` Name: zkops-rotate Namespace: demo Labels: @@ -559,16 +560,15 @@ Events: Normal RestartNodes 18s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 18s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 18s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: zkops-rotate -``` Now, let's check the expiration date of the certificate. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ openssl x509 -in /var/private/ssl/tls.crt -inform PEM -enddate -nameopt RFC2253 -noout notAfter=Feb 2 13:12:42 2025 GMT -``` As we can see from the above output, the certificate has been rotated successfully. @@ -579,23 +579,23 @@ 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=ca-update,O=kubedb-updated`. ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated" +openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-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 zookeeper-new-ca \ +kubectl create secret tls zookeeper-new-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo -secret/zookeeper-new-ca created ``` +secret/zookeeper-new-ca created Now, Let's create a new `Issuer` using the `zookeeper-new-ca` secret that we have just created. The `YAML` file looks like this: @@ -613,9 +613,9 @@ spec: Let's apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-new-issuer.yaml -issuer.cert-manager.io/zk-new-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-new-issuer.yaml ``` +issuer.cert-manager.io/zk-new-issuer created ### Create ZooKeeperOpsRequest @@ -647,24 +647,25 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-update-tls-issuer.yaml -zookeeperopsrequest.ops.kubedb.com/zkops-update-issuer created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zookeeper-update-tls-issuer.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zkops-update-issuer created #### Verify Issuer is changed successfully Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CRO, ```bash -$ kubectl get zookeeperopsrequests -n demo zkops-update-issuer +kubectl get zookeeperopsrequests -n demo zkops-update-issuer +``` NAME TYPE STATUS AGE zkops-update-issuer ReconfigureTLS Successful 8m6s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe zookeeperopsrequest -n demo zkops-update-issuer +kubectl describe zookeeperopsrequest -n demo zkops-update-issuer +``` Name: zkops-update-issuer Namespace: demo Labels: @@ -799,17 +800,16 @@ Events: Normal RestartNodes 18s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 18s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 18s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: zkops-update-issuer -``` Now, Let's exec into a zookeeper node and find out the ca subject to see if it matches the one we have provided. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ keytool -list -v -keystore /var/private/ssl/server.keystore.jks -storepass fdjk2dgffqn9 | grep 'Issuer' Issuer: O=kubedb-updated, CN=ca-updated Issuer: O=kubedb-updated, CN=ca-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. @@ -844,24 +844,25 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zkops-remove.yaml -zookeeperopsrequest.ops.kubedb.com/zkops-remove created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfigure-tls/zkops-remove.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zkops-remove created #### Verify TLS Removed Successfully Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CRO, ```bash -$ kubectl get zookeeperopsrequest -n demo zkops-remove +kubectl get zookeeperopsrequest -n demo zkops-remove +``` NAME TYPE STATUS AGE zkops-remove ReconfigureTLS Successful 105s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed. ```bash -$ kubectl describe zookeeperopsrequest -n demo zkops-remove +kubectl describe zookeeperopsrequest -n demo zkops-remove +``` Name: zkops-remove Namespace: demo Labels: @@ -960,12 +961,12 @@ Events: Normal RestartNodes 3s KubeDB Ops-manager Operator Successfully restarted all nodes Normal Starting 3s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 3s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: zkops-remove -``` Now, Let's exec into one of the broker node and find out that TLS is disabled or not. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ cat ../conf/zoo.cfg 4lw.commands.whitelist=* @@ -992,7 +993,6 @@ reconfigEnabled=true standaloneEnabled=false dynamicConfigFile=/data/zoo.cfg.dynamic zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ -``` So, we can see from the above that, output that tls is disabled successfully. diff --git a/docs/guides/zookeeper/reconfigure/reconfigure.md b/docs/guides/zookeeper/reconfigure/reconfigure.md index 0eb4437d29..5094c79fbf 100644 --- a/docs/guides/zookeeper/reconfigure/reconfigure.md +++ b/docs/guides/zookeeper/reconfigure/reconfigure.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to reconfigure To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [examples](/docs/examples/zookeeper) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -60,9 +60,9 @@ Here, `maxClientCnxns` is set to `70`, whereas the default value is `60`. Now, we will apply the secret with custom configuration. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/secret.yaml -secret/zk-configuration created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/secret.yaml ``` +secret/zk-configuration created In this section, we are going to create a ZooKeeper object specifying `spec.configuration` field to apply this custom configuration. Below is the YAML of the `ZooKeeper` CR that we are going to create, @@ -90,24 +90,25 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/sample-zk-configuration.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/sample-zk-configuration.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 23s -``` Now, we will check if the database has started with the custom configuration we have provided. Now, you can exec into the zookeeper pod and find if the custom configuration is there, ```bash -$ Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +``` zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ echo conf | nc localhost 2181 clientPort=2181 secureClientPort=-1 @@ -133,7 +134,6 @@ server.2=zk-quickstart-1.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:par server.3=zk-quickstart-2.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:participant;0.0.0.0:2181 version=100000011zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ exit exit -``` As we can see from the configuration of running zookeeper, the value of `maxClientCnxns` has been set to `70`. @@ -157,9 +157,9 @@ Here, `maxClientCnxns` is set to `100`. Now, we will apply the secret with custom configuration. ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/new-secret.yaml -secret/zk-new-configuration created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/new-secret.yaml ``` +secret/zk-new-configuration created #### Create ZooKeeperOpsRequest @@ -189,9 +189,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/zkops-reconfiguration.yaml -zookeeperopsrequest.ops.kubedb.com/zk-reconfig created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/zkops-reconfiguration.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zk-reconfig created #### Verify the new configuration is working @@ -200,16 +200,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the `configSe Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ watch kubectl get zookeeperopsrequest -n demo +watch kubectl get zookeeperopsrequest -n demo +``` Every 2.0s: kubectl get zookeeperopsrequest -n demo NAME TYPE STATUS AGE zk-reconfig Reconfigure Successful 1m -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe zookeeperopsrequest -n demo zk-reconfig +kubectl describe zookeeperopsrequest -n demo zk-reconfig +``` Name: zk-reconfig Namespace: demo Labels: @@ -293,22 +294,22 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now need to check the new configuration we have provided. Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 20s -``` Now let’s exec into the zookeeper pod and check the new configuration we have provided. ```bash -$ Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +``` zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ echo conf | nc localhost 2181 clientPort=2181 secureClientPort=-1 @@ -334,7 +335,6 @@ server.2=zk-quickstart-1.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:par server.3=zk-quickstart-2.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:participant;0.0.0.0:2181 version=100000011zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ exit exit -``` As we can see from the configuration of running zookeeper, the value of `maxClientCnxns` has been changed from `70` to `100`. So the reconfiguration of the zookeeper is successful. @@ -371,9 +371,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/zkops-apply-reconfiguration.yaml -zookeeperopsrequest.ops.kubedb.com/zk-reconfig-apply created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/reconfiguration/zkops-apply-reconfiguration.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zk-reconfig-apply created #### Verify the new configuration is working @@ -382,15 +382,16 @@ If everything goes well, `KubeDB` Ops-manager operator will merge this new confi Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ watch kubectl get zookeeperopsrequest -n demo +watch kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE zk-reconfig-apply Reconfigure Successful 38s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to reconfigure the database. ```bash -$ kubectl describe zookeeperopsrequest -n demo zk-reconfig-apply +kubectl describe zookeeperopsrequest -n demo zk-reconfig-apply +``` Name: zk-reconfig-apply Namespace: demo Labels: @@ -474,22 +475,22 @@ Status: Observed Generation: 1 Phase: Successful Events: -``` Now need to check the new configuration we have provided. Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 20s -``` Now let’s exec into the zookeeper pod and check the new configuration we have provided. ```bash -$ Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) +``` zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ echo conf | nc localhost 2181 clientPort=2181 secureClientPort=-1 @@ -515,7 +516,6 @@ server.2=zk-quickstart-1.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:par server.3=zk-quickstart-2.zk-quickstart-pods.demo.svc.cluster.local:2888:3888:participant;0.0.0.0:2181 version=100000011zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ exit exit -``` As we can see from the configuration of running zookeeper, the value of `maxClientCnxns` has been changed from `100` to `90`. So, the reconfiguration of the database using the `applyConfig` field is successful. diff --git a/docs/guides/zookeeper/restart/restart.md b/docs/guides/zookeeper/restart/restart.md index b05f21347f..e1ec3392e4 100644 --- a/docs/guides/zookeeper/restart/restart.md +++ b/docs/guides/zookeeper/restart/restart.md @@ -24,10 +24,10 @@ KubeDB supports restarting the ZooKeeper database via a ZooKeeperOpsRequest. Res - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. -```bash - $ kubectl create ns demo - namespace/demo created + ```bash + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/zookeeper](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/zookeeper) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -59,9 +59,9 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/restart/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/restart/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created ## Apply Restart opsRequest @@ -88,18 +88,21 @@ spec: Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/restart/ops.yaml -zookeeperopsrequest.ops.kubedb.com/zk-restart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/restart/ops.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zk-restart created Now the Ops-manager operator will restart the pods sequentially by their cardinal suffix. -```shell -$ kubectl get zookeeperopsrequest -n demo +```bash +kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE zk-restart Restart Successful 10m -$ kubectl get zookeeperopsrequest -n demo -oyaml zk-restart +```bash +kubectl get zookeeperopsrequest -n demo -oyaml zk-restart +``` apiVersion: ops.kubedb.com/v1alpha1 kind: ZooKeeperOpsRequest metadata: @@ -186,8 +189,6 @@ status: observedGeneration: 1 phase: Successful -``` - ## Cleaning up diff --git a/docs/guides/zookeeper/scaling/horizontal-scaling/horizontal-scaling.md b/docs/guides/zookeeper/scaling/horizontal-scaling/horizontal-scaling.md index 8f6d2d89ad..d6e4abec15 100644 --- a/docs/guides/zookeeper/scaling/horizontal-scaling/horizontal-scaling.md +++ b/docs/guides/zookeeper/scaling/horizontal-scaling/horizontal-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to scale the Z To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/zookeeper](/docs/examples/zookeeper) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -66,27 +66,29 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 5m56s -``` Let's check the number of replicas this zookeeper has from the ZooKeeper object, number of pods the PetSet have, ```bash -$ kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' ``` +3 We can see from both command that the zookeeper has 3 replicas. @@ -123,9 +125,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-hscale-up-ops.yaml -zookeeperopsrequest.ops.kubedb.com/horizontal-scale-up created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-hscale-up-ops.yaml ``` +zookeeperopsrequest.ops.kubedb.com/horizontal-scale-up created #### Verify replicas scaled up successfully @@ -134,15 +136,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ watch kubectl get zookeeperopsrequest -n demo +watch kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE horizontal-scale-up HorizontalScaling Successful 2m49s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to scale the zookeeper. ```bash -$ kubectl describe zookeeperopsrequest -n demo horizontal-scale-up +kubectl describe zookeeperopsrequest -n demo horizontal-scale-up +``` Name: horizontal-scale-up Namespace: demo Labels: @@ -222,17 +225,18 @@ Events: Normal UpdateDatabase 27s KubeDB Ops-manager Operator Successfully updated ZooKeeper Normal Starting 27s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 27s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: horizontal-scale-up -``` Now, we are going to verify the number of replicas this zookeeper has from the ZooKeeper object, number of pods the PetSet have, ```bash -$ kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +``` 5 -$ kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' -5 +```bash +kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' ``` +5 From all the above outputs we can see that the replicas of the zookeeper is `5`. That means we have successfully scaled up the replicas of the ZooKeeper. @@ -268,9 +272,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-hscale-down-ops.yaml -zookeeperopsrequest.ops.kubedb.com/horizontal-scale-down created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-hscale-down-ops.yaml ``` +zookeeperopsrequest.ops.kubedb.com/horizontal-scale-down created #### Verify replicas scaled down successfully @@ -279,15 +283,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the replicas Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ watch kubectl get zookeeperopsrequest -n demo +watch kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE horizontal-scale-down HorizontalScaling Successful 75s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to scale the zookeeper. ```bash -$ kubectl describe zookeeperopsrequest -n demo horizontal-scale-down +kubectl describe zookeeperopsrequest -n demo horizontal-scale-down +``` Name: horizontal-scale-down Namespace: demo Labels: @@ -396,17 +401,18 @@ Events: Normal UpdateDatabase 109s KubeDB Ops-manager Operator Successfully updated ZooKeeper Normal Starting 109s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 109s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: horizontal-scale-down -``` Now, we are going to verify the number of replicas this zookeeper has from the ZooKeeper object, number of pods the petset have, ```bash -$ kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +kubectl get zookeeper -n demo zk-quickstart -o json | jq '.spec.replicas' +``` 3 -$ kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' -3 +```bash +kubectl get petset -n demo zk-quickstart -o json | jq '.spec.replicas' ``` +3 From all the above outputs we can see that the replicas of the zookeeper is `3`. That means we have successfully scaled up the replicas of the ZooKeeper. ## Cleaning Up diff --git a/docs/guides/zookeeper/scaling/vertical-scaling/vertical-scaling.md b/docs/guides/zookeeper/scaling/vertical-scaling/vertical-scaling.md index ad6fdc9bb5..1091b1ec58 100644 --- a/docs/guides/zookeeper/scaling/vertical-scaling/vertical-scaling.md +++ b/docs/guides/zookeeper/scaling/vertical-scaling/vertical-scaling.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/zookeeper](/docs/examples/zookeeper) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -72,22 +72,23 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 5m56s -``` Let's check the Pod containers resources, ```bash -$ kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "memory": "1Gi" @@ -97,7 +98,6 @@ $ kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resou "memory": "1Gi" } } -``` You can see the Pod has default resources which is assigned by the KubeDB operator. @@ -144,9 +144,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-vscale.yaml -zookeeperopsrequest.ops.kubedb.com/vscale created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/scaling/zk-vscale.yaml ``` +zookeeperopsrequest.ops.kubedb.com/vscale created #### Verify ZooKeeper Standalone resources updated successfully @@ -155,16 +155,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the resources Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ kubectl get zookeeperopsrequest -n demo +kubectl get zookeeperopsrequest -n demo +``` Every 2.0s: kubectl get zookeeperopsrequest -n demo NAME TYPE STATUS AGE vscale VerticalScaling Successful 108s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to scale the database. ```bash -$ kubectl describe zookeeperopsrequest -n demo vscale +kubectl describe zookeeperopsrequest -n demo vscale +``` Name: vscale Namespace: demo Labels: @@ -263,12 +264,11 @@ Events: Warning get pod; ConditionStatus:True; PodName:zk-quickstart-2 116s KubeDB Ops-manager Operator get pod; ConditionStatus:True; PodName:zk-quickstart-2 Warning evict pod; ConditionStatus:True; PodName:zk-quickstart-2 116s KubeDB Ops-manager Operator evict pod; ConditionStatus:True; PodName:zk-quickstart-2 -``` - Now, we are going to verify from the Pod yaml whether the resources of the standalone database has updated to meet up the desired state, Let's check, ```bash -$ kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resources' +kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resources' +``` { "limits": { "cpu": "1", @@ -279,7 +279,6 @@ $ kubectl get pod -n demo zk-quickstart-0 -o json | jq '.spec.containers[].resou "memory": "2Gi" } } -``` The above output verifies that we have successfully scaled up the resources of the ZooKeeper standalone database. diff --git a/docs/guides/zookeeper/tls/configure-ssl.md b/docs/guides/zookeeper/tls/configure-ssl.md index 003492f959..3c2845d646 100644 --- a/docs/guides/zookeeper/tls/configure-ssl.md +++ b/docs/guides/zookeeper/tls/configure-ssl.md @@ -27,9 +27,9 @@ KubeDB supports providing TLS/SSL encryption for ZooKeeper Ensemble. This tutori - To keep things isolated, this tutorial uses a separate namespace called `demo` throughout this tutorial. ```bash - $ kubectl create ns demo - namespace/demo created + kubectl create ns demo ``` + namespace/demo created > Note: YAML files used in this tutorial are stored in [docs/examples/zookeeper](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/zookeeper) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -82,9 +82,9 @@ spec: Apply the `YAML` file: ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/tls/zookeeper-issuer.yaml -issuer.cert-manager.io/zookeeper-ca-issuer created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/tls/zookeeper-issuer.yaml ``` +issuer.cert-manager.io/zookeeper-ca-issuer created ## TLS/SSL encryption in ZooKeeper Ensemble @@ -123,22 +123,23 @@ Here, ### Deploy ZOoKeeper Ensemble with TLS/SSL ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/tls/zookeeper-tls.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/tls/zookeeper-tls.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ watch kubectl get zookeeper -n demo +watch kubectl get zookeeper -n demo +``` NAME TYPE VERSION STATUS AGE zk-quickstart kubedb.com/v1alpha2 3.9.1 Ready 60s -``` ### Verify TLS/SSL in ZooKeeper Ensemble ```bash -$ kubectl describe secret -n demo zk-quickstart-client-cert +kubectl describe secret -n demo zk-quickstart-client-cert +``` Name: zk-quickstart-client-cert Namespace: demo Labels: app.kubernetes.io/component=database @@ -166,12 +167,12 @@ tls-combined.pem: 3198 bytes tls.crt: 1493 bytes tls.key: 1704 bytes truststore.jks: 873 bytes -``` Now, Let's exec into a ZooKeeper pod and verify the configuration that the TLS is enabled. ```bash -$ kubectl exec -it -n demo zk-quickstart-0 -- bash +kubectl exec -it -n demo zk-quickstart-0 -- bash +``` Defaulted container "zookeeper" out of: zookeeper, zookeeper-init (init) zookeeper@zk-quickstart-0:/apache-zookeeper-3.9.1-bin$ cd ../var/private/ssl zookeeper@zk-quickstart-0:/var/private/ssl$ openssl s_client -connect localhost:2182 -CAfile ca.crt -cert tls.crt -key tls.key @@ -248,7 +249,6 @@ SSL-Session: Verify return code: 0 (ok) Extended master secret: yes --- -``` From the above output, we can see that we are able to connect to the ZooKeeper Ensemble using the TLS configuration. diff --git a/docs/guides/zookeeper/update-version/update-version.md b/docs/guides/zookeeper/update-version/update-version.md index 8bd308aa37..b8032ea5ac 100644 --- a/docs/guides/zookeeper/update-version/update-version.md +++ b/docs/guides/zookeeper/update-version/update-version.md @@ -30,9 +30,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to update the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > **Note:** YAML files used in this tutorial are stored in [docs/examples/zookeeper](/docs/examples/zookeeper) directory of [kubedb/docs](https://github.com/kubedb/docs) repository. @@ -68,17 +68,17 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/update-version/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/update-version/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` created has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.8.3 Ready 109s -``` We are now ready to apply the `ZooKeeperOpsRequest` CR to update this database. @@ -116,9 +116,9 @@ Here, Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/update-version/zk-version-upgrade-ops.yaml -zookeeperopsrequest.ops.kubedb.com/upgrade-topology created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/update-version/zk-version-upgrade-ops.yaml ``` +zookeeperopsrequest.ops.kubedb.com/upgrade-topology created #### Verify ZooKeeper version updated successfully @@ -127,16 +127,17 @@ If everything goes well, `KubeDB` Ops-manager operator will update the image of Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ kubectl get zookeeperopsrequest -n demo +kubectl get zookeeperopsrequest -n demo +``` Every 2.0s: kubectl get zookeeperopsrequest -n demo NAME TYPE STATUS AGE upgrade-topology UpdateVersion Successful 84s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to update the database version. ```bash -$ kubectl describe zookeeperopsrequest -n demo upgrade-topology +kubectl describe zookeeperopsrequest -n demo upgrade-topology +``` Name: upgrade-topology Namespace: demo Labels: @@ -248,20 +249,23 @@ Events: Normal RestartPods 7m25s KubeDB Ops-manager Operator Successfully Restarted ZooKeeper nodes Normal Starting 7m25s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 7m25s KubeDB Ops-manager Operator -``` Now, we are going to verify whether the `ZooKeeper` and the related `PetSets` and their `Pods` have the new version image. Let's check, ```bash -$ kubectl get zk -n demo zk-quickstart -o=jsonpath='{.spec.version}{"\n"}' +kubectl get zk -n demo zk-quickstart -o=jsonpath='{.spec.version}{"\n"}' +``` 3.9.1 -$ kubectl get petset -n demo zk-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +```bash +kubectl get petset -n demo zk-quickstart -o=jsonpath='{.spec.template.spec.containers[0].image}{"\n"}' +``` ghcr.io/appscode-images/zookeeper:3.9.1@sha256:21365fd1bd55cacd6bf556394d6dcb76ad559ad3767adc304e62db205e4b10b7 -$ kubectl get pods -n demo zk-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' -ghcr.io/appscode-images/zookeeper:3.9.1 +```bash +kubectl get pods -n demo zk-quickstart-0 -o=jsonpath='{.spec.containers[0].image}{"\n"}' ``` +ghcr.io/appscode-images/zookeeper:3.9.1 You can see from above, our `ZooKeeper` cluster has been updated with the new version. So, the updateVersion process is successfully completed. diff --git a/docs/guides/zookeeper/volume-expansion/volume-expansion.md b/docs/guides/zookeeper/volume-expansion/volume-expansion.md index dd7388473c..9a3c6c0d78 100644 --- a/docs/guides/zookeeper/volume-expansion/volume-expansion.md +++ b/docs/guides/zookeeper/volume-expansion/volume-expansion.md @@ -32,9 +32,9 @@ This guide will show you how to use `KubeDB` Ops-manager operator to expand the To keep everything isolated, we are going to use a separate namespace called `demo` throughout this tutorial. ```bash -$ kubectl create ns demo -namespace/demo created +kubectl create ns demo ``` +namespace/demo created > Note: The yaml files used in this tutorial are stored in [docs/examples/ZooKeeper](https://github.com/kubedb/docs/tree/{{< param "info.version" >}}/docs/examples/zookeeper) folder in GitHub repository [kubedb/docs](https://github.com/kubedb/docs). @@ -47,11 +47,11 @@ Here, we are going to deploy a `ZooKeeper` standalone using a supported version At first verify that your cluster has a storage class, that supports volume expansion. Let's check, ```bash -$ kubectl get storageclass +kubectl get storageclass +``` NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE standard (default) driver.standard.io Delete Immediate true 93s standard-static driver.standard.io Delete Immediate true 90s -``` We can see from the output the `standard` storage class has `ALLOWVOLUMEEXPANSION` field as true. So, this storage class supports volume expansion. We can use it. @@ -84,30 +84,32 @@ spec: Let's create the `ZooKeeper` CR we have shown above, ```bash -$ kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/volume-expansion/zookeeper.yaml -zookeeper.kubedb.com/zk-quickstart created +kubectl create -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/volume-expansion/zookeeper.yaml ``` +zookeeper.kubedb.com/zk-quickstart created Now, wait until `zk-quickstart` has status `Ready`. i.e, ```bash -$ kubectl get zk -n demo +kubectl get zk -n demo +``` NAME VERSION STATUS AGE zk-quickstart 3.9.1 Ready 5m56s -``` Let's check volume size from PetSet, and from the persistent volume, ```bash -$ kubectl get petset -n demo zk-quickstart -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo zk-quickstart -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "1Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-3551d7c0-0df6-4f94-b1e0-21834319ecab 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-0 standard 92s pvc-b5882e9e-3c61-4609-b5ba-0eb9f32edbbc 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-2 standard 58s pvc-dccf2b12-d695-4792-8e4b-de4342e7fed4 1Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-1 standard 74s -``` You can see the PetSet has 1GB storage, and the capacity of the persistent volume is also 1GB. @@ -148,9 +150,9 @@ During `Online` VolumeExpansion KubeDB expands volume without pausing database o Let's create the `ZooKeeperOpsRequest` CR we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/volume-expansion/zkops-volume-exp-offline.yaml -zookeeperopsrequest.ops.kubedb.com/zk-offline-volume-expansion created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/zookeeper/volume-expansion/zkops-volume-exp-offline.yaml ``` +zookeeperopsrequest.ops.kubedb.com/zk-offline-volume-expansion created #### Verify ZooKeeper Standalone volume expanded successfully @@ -159,15 +161,16 @@ If everything goes well, `KubeDB` Ops-manager operator will update the volume si Let's wait for `ZooKeeperOpsRequest` to be `Successful`. Run the following command to watch `ZooKeeperOpsRequest` CR, ```bash -$ kubectl get zookeeperopsrequest -n demo +kubectl get zookeeperopsrequest -n demo +``` NAME TYPE STATUS AGE zk-offline-volume-expansion VolumeExpansion Successful 75s -``` We can see from the above output that the `ZooKeeperOpsRequest` has succeeded. If we describe the `ZooKeeperOpsRequest` we will get an overview of the steps that were followed to expand the volume of the database. ```bash -$ kubectl describe zookeeperopsrequest -n demo zk-offline-volume-expansion +kubectl describe zookeeperopsrequest -n demo zk-offline-volume-expansion +``` Name: zk-offline-volume-expansion Namespace: demo Labels: @@ -359,20 +362,21 @@ Events: Normal ReadyPetSets 76s KubeDB Ops-manager Operator PetSet is recreated Normal Starting 76s KubeDB Ops-manager Operator Resuming ZooKeeper database: demo/zk-quickstart Normal Successful 76s KubeDB Ops-manager Operator Successfully resumed ZooKeeper database: demo/zk-quickstart for ZooKeeperOpsRequest: zk-offline-volume-expansion -``` Now, we are going to verify from the `Petset`, and the `Persistent Volume` whether the volume of the standalone database has expanded to meet the desired state, Let's check, ```bash -$ kubectl get petset -n demo zk-quickstart -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +kubectl get petset -n demo zk-quickstart -o json | jq '.spec.volumeClaimTemplates[].spec.resources.requests.storage' +``` "2Gi" -$ kubectl get pv -n demo +```bash +kubectl get pv -n demo +``` NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE pvc-1b112414-6162-4e75-99c9-3e62cb4efb4a 2Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-1 standard 16m pvc-3159b881-1954-4008-8594-599bee9fd11e 2Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-0 standard 17m pvc-43ba80bd-9029-413e-b89c-1f373fd0cd3d 2Gi RWO Delete Bound demo/zk-quickstart-data-zk-quickstart-2 standard 16m -``` The above output verifies that we have successfully expanded the volume of the ZooKeeper standalone database. diff --git a/docs/operatormanual/recommendation/configuration.md b/docs/operatormanual/recommendation/configuration.md index f42295dde8..8711218917 100644 --- a/docs/operatormanual/recommendation/configuration.md +++ b/docs/operatormanual/recommendation/configuration.md @@ -28,8 +28,11 @@ Before using KubeDB Recommendations, ensure that: * A demo namespace exists for examples: ```bash - $ kubectl create namespace demo - $ kubectl get namespace + kubectl create namespace demo + ``` + + ```bash + kubectl get namespace ``` ### Install the Supervisor CRDs first diff --git a/docs/operatormanual/recommendation/recommendation-spec.md b/docs/operatormanual/recommendation/recommendation-spec.md index 3fa665501b..67d3244bc2 100644 --- a/docs/operatormanual/recommendation/recommendation-spec.md +++ b/docs/operatormanual/recommendation/recommendation-spec.md @@ -80,9 +80,10 @@ status: The Supervisor evaluates the rules against the **operation resource** (not the recommendation itself). For example, given this `spec.operation`: -```shell -$ kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee \ +```bash +kubectl get recommendation -n es elastic-x-elasticsearch-x-update-version-2juuee \ -o jsonpath='{.spec.operation}' | yq -y +``` apiVersion: ops.kubedb.com/v1alpha1 kind: ElasticsearchOpsRequest metadata: @@ -95,7 +96,6 @@ spec: updateVersion: targetVersion: xpack-9.2.3 status: {} -``` the rules are evaluated against the OpsRequest's `status`: diff --git a/docs/operatormanual/recommendation/rotate-auth-recommendation.md b/docs/operatormanual/recommendation/rotate-auth-recommendation.md index 9a1350a2cf..4a3f666f90 100644 --- a/docs/operatormanual/recommendation/rotate-auth-recommendation.md +++ b/docs/operatormanual/recommendation/rotate-auth-recommendation.md @@ -58,24 +58,24 @@ spec: Wait until MongoDB reports `Ready`. The time depends on image pull speed. ```bash -$ kubectl get mongodb,pods -n demo +kubectl get mongodb,pods -n demo +``` NAME VERSION STATUS AGE mongodb.kubedb.com/mg-ra-recommendation 8.0.10 Ready 10m NAME READY STATUS RESTARTS AGE pod/mg-ra-recommendation-0 1/1 Running 0 10m -``` ## A rotate-auth Recommendation appears With `rotateAfter: 1h`, the recommendation engine creates a rotation Recommendation roughly **40 minutes** after the auth secret was created (two-thirds of the lifespan). Once it appears, you will see something like: ```bash -$ kubectl get recommendation -n demo +kubectl get recommendation -n demo +``` NAME STATUS OUTDATED AGE mg-ra-recommendation-x-mongodb-x-rotate-auth- false mg-ra-recommendation-x-mongodb-x-update-version- Pending false -``` The Recommendation name follows the pattern `-x--x--`. Let's look at the full manifest: @@ -159,17 +159,17 @@ What this manifest tells you: After auto-approval, an `MongoDBOpsRequest` is created and reaches `Successful`: ```bash -$ kubectl get mongodbopsrequest -n demo +kubectl get mongodbopsrequest -n demo +``` NAME TYPE STATUS AGE mg-ra-recommendation--rotate-auth-auto RotateAuth Successful -``` `RotateAuth` rotates the auth secret with negligible downtime — the database keeps accepting connections throughout the rolling restart. You can re-check the Recommendation status as JSON: ```bash -$ kubectl get recommendation \ +kubectl get recommendation \ -n demo -o json | jq '.status' ``` @@ -180,13 +180,13 @@ You will see `phase: Succeeded` and `reason: SuccessfullyExecutedOperation`. If you need to skip a rotation (for example because you're about to change auth strategy), reject it: ```bash -$ kubectl patch recommendation \ +kubectl patch recommendation \ -n demo \ --type merge \ --subresource='status' \ -p '{"status":{"approvalStatus":"Rejected"}}' -recommendation.supervisor.appscode.com/ patched ``` +recommendation.supervisor.appscode.com/ patched ## Automating execution with a maintenance window diff --git a/docs/operatormanual/recommendation/rotate-tls-recommendation.md b/docs/operatormanual/recommendation/rotate-tls-recommendation.md index f1f5cd8f5c..a7fc73d0fe 100644 --- a/docs/operatormanual/recommendation/rotate-tls-recommendation.md +++ b/docs/operatormanual/recommendation/rotate-tls-recommendation.md @@ -36,7 +36,7 @@ We will create a self-signed CA and an `Issuer` to back the demo. In production, Generate a CA with openssl: ```bash -$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ +openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout ./ca.key -out ./ca.crt \ -subj "/CN=es/O=kubedb" ``` @@ -44,7 +44,7 @@ $ openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ Create a TLS secret in the target namespace: ```bash -$ kubectl create secret tls es-ca \ +kubectl create secret tls es-ca \ --cert=ca.crt \ --key=ca.key \ --namespace=demo @@ -64,9 +64,9 @@ spec: ``` ```bash -$ kubectl apply -f issuer.yaml -issuer.cert-manager.io/es-issuer created +kubectl apply -f issuer.yaml ``` +issuer.cert-manager.io/es-issuer created ## Deploy Elasticsearch with short-lived certificates @@ -106,24 +106,24 @@ spec: Wait until the cluster reports `Ready`: ```bash -$ kubectl get elasticsearch,pods -n demo +kubectl get elasticsearch,pods -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-tls xpack-9.1.9 Ready 4m39s NAME READY STATUS RESTARTS AGE pod/es-tls-0 1/1 Running 0 4m34s pod/es-tls-1 1/1 Running 0 4m28s -``` ## A rotate-tls Recommendation appears Once one of the certificates crosses the threshold (about two-thirds of its lifespan, given the very short durations we set), the Ops-manager creates a `Recommendation`. With the durations above, the first one shows up roughly 35–40 minutes after the cluster comes up — and another every time another certificate nears expiry. ```bash -$ kubectl get recommendation -n demo +kubectl get recommendation -n demo +``` NAME STATUS OUTDATED AGE es-tls-x-elasticsearch-x-rotate-tls-w3j40x Succeeded false 37m -``` The Recommendation name follows the pattern `-x--x--`. Let's look at the full manifest: @@ -206,17 +206,17 @@ What this manifest tells you: ## Watching the OpsRequest ```bash -$ kubectl get elasticsearchopsrequest -n demo es-tls-1780935896-rotate-tls-auto +kubectl get elasticsearchopsrequest -n demo es-tls-1780935896-rotate-tls-auto +``` NAME TYPE STATUS AGE es-tls-1780935896-rotate-tls-auto ReconfigureTLS Successful 25m -``` The `ReconfigureTLS` operation re-issues the affected certificates via cert-manager, reloads each Elasticsearch pod in a controlled order, and finishes with no client-visible downtime when the cluster has more than one replica. You can re-check the Recommendation status as JSON: ```bash -$ kubectl get recommendation es-tls-x-elasticsearch-x-rotate-tls-w3j40x \ +kubectl get recommendation es-tls-x-elasticsearch-x-rotate-tls-w3j40x \ -n demo -o json | jq '.status' ``` @@ -227,13 +227,13 @@ You will see `phase: Succeeded` and `reason: SuccessfullyExecutedOperation`. If you ever need to skip a rotation (for example, because you're about to swap issuers), reject it: ```bash -$ kubectl patch recommendation es-tls-x-elasticsearch-x-rotate-tls-w3j40x \ +kubectl patch recommendation es-tls-x-elasticsearch-x-rotate-tls-w3j40x \ -n demo \ --type merge \ --subresource='status' \ -p '{"status":{"approvalStatus":"Rejected"}}' -recommendation.supervisor.appscode.com/es-tls-x-elasticsearch-x-rotate-tls-w3j40x patched ``` +recommendation.supervisor.appscode.com/es-tls-x-elasticsearch-x-rotate-tls-w3j40x patched ## Automating execution with a maintenance window diff --git a/docs/operatormanual/recommendation/version-update-recommendation.md b/docs/operatormanual/recommendation/version-update-recommendation.md index d6497cc8ab..a2b2d3da10 100644 --- a/docs/operatormanual/recommendation/version-update-recommendation.md +++ b/docs/operatormanual/recommendation/version-update-recommendation.md @@ -36,7 +36,8 @@ KubeDB watches the versions you actually have running and generates a `Recommend Let's walk through a complete demo. First, list the Elasticsearch versions provided by KubeDB: ```bash -$ kubectl get elasticsearchversions | grep xpack +kubectl get elasticsearchversions | grep xpack +``` xpack-6.8.23 6.8.23 ElasticStack ghcr.io/appscode-images/elastic:6.8.23 12d xpack-7.17.15 7.17.15 ElasticStack ghcr.io/appscode-images/elastic:7.17.15 12d xpack-7.17.28 7.17.28 ElasticStack ghcr.io/appscode-images/elastic:7.17.28 12d @@ -52,7 +53,6 @@ xpack-9.0.8 9.0.8 ElasticStack ghcr.io/appscode-images/elastic:9.0 xpack-9.1.4 9.1.4 ElasticStack ghcr.io/appscode-images/elastic:9.1.4 12d xpack-9.1.9 9.1.9 ElasticStack ghcr.io/appscode-images/elastic:9.1.9 12d xpack-9.2.3 9.2.3 ElasticStack ghcr.io/appscode-images/elastic:9.2.3 12d -``` We will deliberately deploy an older version, `xpack-9.1.9`, so KubeDB will recommend the upgrade to `xpack-9.2.3`: @@ -79,7 +79,8 @@ spec: Wait until the Elasticsearch cluster reports `Ready`. The required time depends on image pull speed and node specs. ```bash -$ kubectl get elasticsearch,pods -n demo +kubectl get elasticsearch,pods -n demo +``` NAME VERSION STATUS AGE elasticsearch.kubedb.com/es-vurecommendation xpack-9.1.9 Ready 3m43s @@ -87,15 +88,14 @@ NAME READY STATUS RESTARTS AGE pod/es-vurecommendation-0 1/1 Running 0 3m37s pod/es-vurecommendation-1 1/1 Running 0 3m30s pod/es-vurecommendation-2 1/1 Running 0 3m25s -``` Once the Elasticsearch instance is `Ready`, the KubeDB Ops-manager creates a `Recommendation` automatically. It can take a couple of minutes for the create-event to be reconciled. ```bash -$ kubectl get recommendation -n demo +kubectl get recommendation -n demo +``` NAME STATUS OUTDATED AGE es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o Pending false 2m49s -``` The Recommendation name follows the pattern `-x--x--`. Initially the Supervisor sets `status.phase: Pending`. Let's look at the full manifest: @@ -164,57 +164,57 @@ What this manifest tells you: Approve via the AppsCode UI, or with `kubectl`: ```bash -$ kubectl patch Recommendation es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o \ +kubectl patch Recommendation es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o \ -n demo \ --type merge \ --subresource='status' \ -p '{"status":{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"}}}' -recommendation.supervisor.appscode.com/es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o patched ``` +recommendation.supervisor.appscode.com/es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o patched A new condition appears almost immediately confirming the OpsRequest was created: ```bash -$ kubectl get recommendation -n demo es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o -o jsonpath='{.status}' -{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"},"conditions":[{"lastTransitionTime":"2026-06-08T16:47:29Z","message":"OpsRequest is successfully created","reason":"SuccessfullyCreatedOperation","status":"True","type":"SuccessfullyCreatedOperation"}],"createdOperationRef":{"name":"es-vurecommendation-1780937248-update-version-auto"},"failedAttempt":0,"outdated":false,"parallelism":"Namespace","phase":"InProgress","reason":"StartedExecutingOperation"} +kubectl get recommendation -n demo es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o -o jsonpath='{.status}' ``` +{"approvalStatus":"Approved","approvedWindow":{"window":"Immediate"},"conditions":[{"lastTransitionTime":"2026-06-08T16:47:29Z","message":"OpsRequest is successfully created","reason":"SuccessfullyCreatedOperation","status":"True","type":"SuccessfullyCreatedOperation"}],"createdOperationRef":{"name":"es-vurecommendation-1780937248-update-version-auto"},"failedAttempt":0,"outdated":false,"parallelism":"Namespace","phase":"InProgress","reason":"StartedExecutingOperation"} The Supervisor has now created an `ElasticsearchOpsRequest` and is upgrading the cluster to `xpack-9.2.3` with negligible downtime. The Supervisor will keep retrying on transient failures up to `spec.backoffLimit` attempts. ```bash -$ kubectl get elasticsearchopsrequest -n demo +kubectl get elasticsearchopsrequest -n demo +``` NAME TYPE STATUS AGE es-vurecommendation-1780937248-update-version-auto UpdateVersion Successful 2m39s -``` Once the OpsRequest succeeds, the Recommendation rolls into `Succeeded`: ```bash -$ kubectl get recommendation -n demo es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o +kubectl get recommendation -n demo es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o +``` NAME STATUS OUTDATED AGE es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o Succeeded false 5m55s -``` The Elasticsearch cluster is now on the target version: ```bash -$ kubectl get es es-vurecommendation -n demo +kubectl get es es-vurecommendation -n demo +``` NAME VERSION STATUS AGE es-vurecommendation xpack-9.2.3 Ready 6m50s -``` ## Rejecting a recommendation If you do not want a recommendation to run, set its `approvalStatus` to `Rejected`: ```bash -$ kubectl patch Recommendation es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o \ +kubectl patch Recommendation es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o \ -n demo \ --type merge \ --subresource='status' \ -p '{"status":{"approvalStatus":"Rejected"}}' -recommendation.supervisor.appscode.com/es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o patched ``` +recommendation.supervisor.appscode.com/es-vurecommendation-x-elasticsearch-x-update-version-t7dy9o patched ## Automating execution diff --git a/docs/setup/install/kubedb/configuration.md b/docs/setup/install/kubedb/configuration.md index f97e68b98b..10e81081fa 100644 --- a/docs/setup/install/kubedb/configuration.md +++ b/docs/setup/install/kubedb/configuration.md @@ -58,7 +58,7 @@ global: Save these values to a file (e.g. `values.yaml`) and pass it to `helm install` / `helm upgrade`: ```bash -$ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -69,7 +69,7 @@ $ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ Or override individual engines inline with `--set`: ```bash -$ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -99,7 +99,7 @@ Set `enabled: true` to create the policies. The `flavor` field selects which API Enable it inline with `--set`: ```bash -$ helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -125,21 +125,20 @@ Within the cluster, the following paths must stay open. When `global.networkPoli To check if KubeDB operator pods have started, run the following command: ```bash -$ watch kubectl get pods --all-namespaces -l "app.kubernetes.io/instance=kubedb" - +watch kubectl get pods --all-namespaces -l "app.kubernetes.io/instance=kubedb" +``` NAME READY STATUS RESTARTS AGE kubedb-kubedb-autoscaler-b5dd47dc5-bxnrq 1/1 Running 0 48s kubedb-kubedb-ops-manager-6f766b86c6-h9m66 1/1 Running 0 48s kubedb-kubedb-provisioner-6fd44d5784-d8v9c 1/1 Running 0 48s kubedb-kubedb-webhook-server-6cf469bdf4-72wvz 1/1 Running 0 48s -``` Once the operator pod is running, you can cancel the above command by typing `Ctrl+C`. Now, to confirm CRD groups have been registered by the operator, run the following command: ```bash -$ kubectl get crd -l app.kubernetes.io/name=kubedb +kubectl get crd -l app.kubernetes.io/name=kubedb ``` Now, you are ready to [create your first database](/docs/guides/README.md) using KubeDB. diff --git a/docs/setup/install/kubedb/fluxcd.md b/docs/setup/install/kubedb/fluxcd.md index f67820d3bb..3b82c5c323 100644 --- a/docs/setup/install/kubedb/fluxcd.md +++ b/docs/setup/install/kubedb/fluxcd.md @@ -35,8 +35,11 @@ spec: Generate a license from the [AppsCode License Server](https://appscode.com/issue-license?p=kubedb) and store it in a Secret so `HelmRelease` can reference it via `valuesFrom`. ```bash -$ kubectl create namespace kubedb -$ kubectl create secret generic kubedb-license \ +kubectl create namespace kubedb +``` + +```bash +kubectl create secret generic kubedb-license \ --from-file=license=/path/to/the/license.txt \ -n kubedb ``` @@ -100,13 +103,15 @@ Instead of creating a per-cluster license Secret (steps 2–3 above), you can de Generate an online license-proxyserver token by following the [License Proxyserver guide](https://kubedb.com/docs/platform/v2026.5.22/guides/license-management/license-proxyserver/), then store it in a Secret that the `HelmRelease` references via `valuesFrom`: ```bash -$ cat > license-proxyserver.yaml <<'EOF' +cat > license-proxyserver.yaml <<'EOF' platform: baseURL: https://appscode.com token: '****************************************' EOF +``` -$ kubectl create secret generic ace-licenseserver-cred \ +```bash +kubectl create secret generic ace-licenseserver-cred \ --from-file=license-proxyserver.yaml \ -n kubeops ``` diff --git a/docs/setup/install/kubedb/helm.md b/docs/setup/install/kubedb/helm.md index a0c47091fe..b594e539e6 100644 --- a/docs/setup/install/kubedb/helm.md +++ b/docs/setup/install/kubedb/helm.md @@ -17,7 +17,7 @@ section_menu_id: setup KubeDB can be installed via [Helm](https://helm.sh/) using the [chart](https://github.com/kubedb/installer/tree/{{< param "info.installer" >}}/charts/kubedb) from [AppsCode Charts Repository](https://github.com/appscode/charts). To install, follow the steps below: ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -27,7 +27,7 @@ $ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ {{< notice type="warning" message="If you are using **private Docker registries** using *self-signed certificates*, please pass the registry domains to the operator like below:" >}} ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set global.insecureRegistries[0]=hub.example.com \ @@ -43,7 +43,7 @@ Instead of passing a license file to every operator, you can install the `licens Generate an online license-proxyserver token by following the [License Proxyserver guide](https://kubedb.com/docs/platform/v2026.5.22/guides/license-management/license-proxyserver/), then install the chart with that token: ```bash -$ helm install license-proxyserver oci://ghcr.io/appscode-charts/license-proxyserver \ +helm install license-proxyserver oci://ghcr.io/appscode-charts/license-proxyserver \ --version v2026.2.16 \ --namespace kubeops --create-namespace \ --set platform.baseURL=https://appscode.com \ @@ -54,7 +54,7 @@ $ helm install license-proxyserver oci://ghcr.io/appscode-charts/license-proxyse With the proxyserver running, install KubeDB without the license flag: ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --wait --burst-limit=10000 --debug @@ -120,7 +120,7 @@ Because the scripts copy every image under your registry host with its original Before installing, render the chart and confirm that every `image:` points at your private registry: ```bash -$ helm template kubedb oci://registry.example.com/appscode-charts/kubedb \ +helm template kubedb oci://registry.example.com/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set global.registryFQDN=registry.example.com \ @@ -154,7 +154,7 @@ Set the same proxies on both `kubedb-catalog` and `kubedb-kubestash-catalog`, an Once the chart and images are mirrored, install the operator. The `global.registryFQDN` value rewrites the operator image paths, and the `proxies.*` values rewrite the catalog (database) image paths: ```bash -$ helm upgrade -i kubedb oci://registry.example.com/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://registry.example.com/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -241,7 +241,7 @@ global: Render the chart first to confirm every image resolves to your registry: ```bash -$ helm template kubedb oci://registry.example.com/appscode-charts/kubedb \ +helm template kubedb oci://registry.example.com/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --values values.yaml \ @@ -256,7 +256,7 @@ $ helm template kubedb oci://registry.example.com/appscode-charts/kubedb \ Once the output is clean, install KubeDB with the same values and proxies plus the license: ```bash -$ helm upgrade -i kubedb oci://registry.example.com/appscode-charts/kubedb \ +helm upgrade -i kubedb oci://registry.example.com/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ diff --git a/docs/setup/install/kubedb/openshift.md b/docs/setup/install/kubedb/openshift.md index b1a5f17a1e..ea3d715ae4 100644 --- a/docs/setup/install/kubedb/openshift.md +++ b/docs/setup/install/kubedb/openshift.md @@ -21,7 +21,7 @@ KubeDB supports OpenShift in three different ways. Pick the one that best matche The standard `kubedb` chart can be deployed on OpenShift by enabling the OpenShift distro flags. The `openshift` flag is also auto-detected when the cluster exposes the `project.openshift.io/v1` API, so you can leave it `false` and only switch the image flavor to UBI. ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -46,10 +46,15 @@ AppsCode publishes a Red Hat OpenShift Certified Helm chart, [`kubedb-certified` **Step 1 — Install the CRDs:** ```bash -$ helm repo add appscode https://charts.appscode.com/stable/ -$ helm repo update +helm repo add appscode https://charts.appscode.com/stable/ +``` -$ helm upgrade -i kubedb-certified-crds appscode/kubedb-certified-crds \ +```bash +helm repo update +``` + +```bash +helm upgrade -i kubedb-certified-crds appscode/kubedb-certified-crds \ -n kubedb --create-namespace \ --version={{< param "info.version" >}} ``` @@ -57,7 +62,7 @@ $ helm upgrade -i kubedb-certified-crds appscode/kubedb-certified-crds \ **Step 2 — Install the operator:** ```bash -$ helm upgrade -i kubedb-certified appscode/kubedb-certified \ +helm upgrade -i kubedb-certified appscode/kubedb-certified \ -n kubedb --create-namespace \ --version={{< param "info.version" >}} \ --set-file global.license=/path/to/the/license.txt @@ -121,7 +126,7 @@ spec: Apply it with: ```bash -$ oc apply -f kubedb.yaml +oc apply -f kubedb.yaml ``` Next: [enable database engines and verify the installation](/docs/setup/install/kubedb/configuration.md). diff --git a/docs/setup/install/kubedb/yaml.md b/docs/setup/install/kubedb/yaml.md index a952c6463d..41ec46af85 100644 --- a/docs/setup/install/kubedb/yaml.md +++ b/docs/setup/install/kubedb/yaml.md @@ -17,7 +17,7 @@ section_menu_id: setup If you prefer to not use Helm, you can generate YAMLs from KubeDB chart and deploy using `kubectl`. Here we are going to show the procedure using Helm 3. ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ @@ -27,7 +27,7 @@ $ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ {{< notice type="warning" message="If you are using **private Docker registries** using *self-signed certificates*, please pass the registry domains to the operator like below:" >}} ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set-file global.license=/path/to/the/license.txt \ diff --git a/docs/setup/install/troubleshoting.md b/docs/setup/install/troubleshoting.md index 79af58e188..f788f0cddd 100644 --- a/docs/setup/install/troubleshoting.md +++ b/docs/setup/install/troubleshoting.md @@ -17,7 +17,7 @@ section_menu_id: setup If you are installing KubeDB on a GKE cluster, you will need cluster admin permissions to install KubeDB operator. Run the following command to grant admin permision to the cluster. ```bash -$ kubectl create clusterrolebinding "cluster-admin-$(whoami)" \ +kubectl create clusterrolebinding "cluster-admin-$(whoami)" \ --clusterrole=cluster-admin \ --user="$(gcloud config get-value core/account)" ``` @@ -29,10 +29,16 @@ In addition, if your GKE cluster is a [private cluster](https://cloud.google.com To detect KubeDB version, exec into the operator pod and run `kubedb version` command. ```bash -$ POD_NAMESPACE=kubedb -$ POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=kubedb-community -o jsonpath={.items[0].metadata.name}) -$ kubectl exec $POD_NAME -c operator -n $POD_NAMESPACE -- /operator version +POD_NAMESPACE=kubedb +``` + +```bash +POD_NAME=$(kubectl get pods -n $POD_NAMESPACE -l app.kubernetes.io/name=kubedb-community -o jsonpath={.items[0].metadata.name}) +``` +```bash +kubectl exec $POD_NAME -c operator -n $POD_NAMESPACE -- /operator version +``` Version = v0.20.0 VersionStrategy = tag GitTag = v0.20.0 @@ -42,4 +48,3 @@ CommitTimestamp = 2021-08-23T11:15:37 GoVersion = go1.16.7 Compiler = gcc Platform = linux/amd64 -``` diff --git a/docs/setup/monitoring/builtin-prometheus.md b/docs/setup/monitoring/builtin-prometheus.md index 2959e7125c..a1bedbea17 100644 --- a/docs/setup/monitoring/builtin-prometheus.md +++ b/docs/setup/monitoring/builtin-prometheus.md @@ -25,9 +25,9 @@ This tutorial will show you how to configure builtin [Prometheus](https://github - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy respective monitoring resources. ```bash - $ kubectl create ns monitoring - namespace/monitoring created + kubectl create ns monitoring ``` + namespace/monitoring created ## Enable KubeDB Operator Monitoring @@ -38,7 +38,7 @@ Let's install KubeDB with operator monitoring enabled. **Helm 3:** ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set global.monitoring.agent=prometheus.io/builtin @@ -47,7 +47,7 @@ $ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ **YAML (with Helm 3):** ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --no-hooks \ @@ -114,10 +114,10 @@ KubeDB has created a secret named `kubedb-apiserver-cert` in `monitoring` namesp Verify that the secret `kubedb-apiserver-cert` has been created in `monitoring` namespace. ```bash -$ kubectl get secret -n monitoring -l=app=kubedb +kubectl get secret -n monitoring -l=app=kubedb +``` NAME TYPE DATA AGE kubedb-apiserver-cert kubernetes.io/tls 2 3h33m -``` We are going to mount this secret in `/etc/prometheus/secret/kubedb-apiserver-cert` directory of Prometheus deployment. @@ -295,20 +295,20 @@ data: Let's create the ConfigMap we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prom-config.yaml -configmap/kubedb-prom-config created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prom-config.yaml ``` +configmap/kubedb-prom-config created **Create RBAC:** If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` > YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -371,9 +371,9 @@ Notice that, we have mounted `kubedb-apiserver-cert` secret as a volume at `/etc Now, let's create the deployment, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prom-deploy.yaml -deployment.apps/prometheus created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prom-deploy.yaml ``` +deployment.apps/prometheus created ### Verify Monitoring Metrics @@ -382,18 +382,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod -n monitoring -l=app=prometheus +kubectl get pod -n monitoring -l=app=prometheus +``` NAME READY STATUS RESTARTS AGE prometheus-5bcb9678c-kh8vt 1/1 Running 0 149m -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-5bcb9678c-kh8vt` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-5bcb9678c-kh8vt 9090 +kubectl port-forward -n monitoring prometheus-5bcb9678c-kh8vt 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `api` endpoint of `kubedb` service as target. diff --git a/docs/setup/monitoring/overview.md b/docs/setup/monitoring/overview.md index 621952ee03..eef790f1d6 100644 --- a/docs/setup/monitoring/overview.md +++ b/docs/setup/monitoring/overview.md @@ -102,7 +102,7 @@ You have to provides these flags while installing or upgrading or updating KubeD **Helm 3:** ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set monitoring.enabled=true \ @@ -114,7 +114,7 @@ $ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ **YAML (with Helm 3):** ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set monitoring.enabled=true \ diff --git a/docs/setup/monitoring/prometheus-operator.md b/docs/setup/monitoring/prometheus-operator.md index 0baf0765b9..056be7b05e 100644 --- a/docs/setup/monitoring/prometheus-operator.md +++ b/docs/setup/monitoring/prometheus-operator.md @@ -23,9 +23,9 @@ aliases: - To keep Prometheus resources isolated, we are going to use a separate namespace called `monitoring` to deploy Prometheus operator and respective resources. ```bash - $ kubectl create ns monitoring - namespace/monitoring created + kubectl create ns monitoring ``` + namespace/monitoring created - We need a [Prometheus operator](https://github.com/prometheus-operator/prometheus-operator) instance running. If you don't already have a running instance, deploy one following the docs from [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/operator/README.md). @@ -38,7 +38,7 @@ Let's install KubeDB operator with monitoring enabled. **Helm 3:** ```bash -$ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --set global.monitoring.agent=prometheus.io/operator \ @@ -48,7 +48,7 @@ $ helm install kubedb oci://ghcr.io/appscode-charts/kubedb \ **YAML (with Helm 3):** ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --version {{< param "info.version" >}} \ --namespace kubedb --create-namespace \ --no-hooks \ @@ -101,10 +101,10 @@ KubeDB has created a secret named `kubedb-apiserver-cert` in `monitoring` namesp Verify that the secret `kubedb-apiserver-cert` has been created in `monitoring` namespace. ```bash -$ kubectl get secret -n monitoring -l=app=kubedb +kubectl get secret -n monitoring -l=app=kubedb +``` NAME TYPE DATA AGE kubedb-apiserver-cert kubernetes.io/tls 2 40m -``` We are going to specify this secret in [Prometheus](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/design.md#prometheus) crd specification. Prometheus operator will mount this secret in `/etc/prometheus/secret/kubedb-apiserver-cert` directory of respective Prometheus server pod. @@ -146,11 +146,11 @@ If you don't have any existing Prometheus server running, you have to create a P If you are using an RBAC enabled cluster, you have to give necessary RBAC permissions for Prometheus. Let's create necessary RBAC stuffs for Prometheus, ```bash -$ kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +kubectl apply -f https://github.com/appscode/third-party-tools/raw/master/monitoring/prometheus/builtin/artifacts/rbac.yaml +``` clusterrole.rbac.authorization.k8s.io/prometheus created serviceaccount/prometheus created clusterrolebinding.rbac.authorization.k8s.io/prometheus created -``` >YAML for the RBAC resources created above can be found [here](https://github.com/appscode/third-party-tools/blob/master/monitoring/prometheus/builtin/artifacts/rbac.yaml). @@ -185,19 +185,19 @@ Here, `spec.serviceMonitorSelector` is used to select the `ServiceMonitor` crd t Let's create the `Prometheus` object we have shown above, ```bash -$ kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prometheus.yaml -prometheus.monitoring.coreos.com/prometheus created +kubectl apply -f https://github.com/kubedb/docs/raw/{{< param "info.version" >}}/docs/examples/monitoring/operator/prometheus.yaml ``` +prometheus.monitoring.coreos.com/prometheus created Prometheus operator watches for `Prometheus` crd. Once a `Prometheus` crd is created, it generates respective configuration and creates a `PetSet` to run Prometheus server. Let's check `PetSet` has been created, ```bash -$ kubectl get petset -n monitoring +kubectl get petset -n monitoring +``` NAME DESIRED CURRENT AGE prometheus-prometheus 1 1 2m14s -``` ### Verify Monitoring Metrics @@ -207,18 +207,18 @@ Prometheus server is listening to port `9090`. We are going to use [port forward At first, let's check if the Prometheus pod is in `Running` state. ```bash -$ kubectl get pod prometheus-prometheus-0 -n monitoring +kubectl get pod prometheus-prometheus-0 -n monitoring +``` NAME READY STATUS RESTARTS AGE prometheus-prometheus-0 3/3 Running 1 2m40s -``` Now, run following command on a separate terminal to forward 9090 port of `prometheus-prometheus-0` pod, ```bash -$ kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +kubectl port-forward -n monitoring prometheus-prometheus-0 9090 +``` Forwarding from 127.0.0.1:9090 -> 9090 Forwarding from [::1]:9090 -> 9090 -``` Now, we can access the dashboard at `localhost:9090`. Open [http://localhost:9090](http://localhost:9090) in your browser. You should see `api` endpoint of `kubedb` service as target. diff --git a/docs/setup/uninstall/kubedb.md b/docs/setup/uninstall/kubedb.md index 5f0445cc69..f951408c48 100644 --- a/docs/setup/uninstall/kubedb.md +++ b/docs/setup/uninstall/kubedb.md @@ -32,13 +32,13 @@ To uninstall KubeDB, run the following command: In Helm 3, release names are [scoped to a namespace](https://helm.sh/docs/v3/faq/changes_since_helm2/). So, provide the namespace you used to install the operator when installing. ```bash -$ helm uninstall kubedb --namespace kubedb +helm uninstall kubedb --namespace kubedb ``` Helm does not delete CRD objects. You can delete the ones KubeDB created with the following commands: ```bash -$ kubectl get crd -o name | grep kubedb.com | xargs kubectl delete +kubectl get crd -o name | grep kubedb.com | xargs kubectl delete ``` @@ -49,7 +49,7 @@ $ kubectl get crd -o name | grep kubedb.com | xargs kubectl delete If you prefer to not use Helm, you can generate YAMLs from KubeDB chart and uninstall using `kubectl`. ```bash -$ helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ +helm template kubedb oci://ghcr.io/appscode-charts/kubedb \ --namespace kubedb | kubectl delete -f - ```