在Kubernetes上创建副本数据库
如何使用数据库控制器创建和自动化数据库副本
您可以通过在Redis Enterprise数据库规范的replicaSources
部分创建一个项目来配置数据库的副本。replicaSourceType
的值必须为'SECRET';replicaSourceName
必须是一个包含副本源URL的密钥的名称。
必须使用包含副本源URI的stringData
部分来创建秘密,如下所示:
apiVersion: v1
kind: Secret
metadata:
name: my-replica-source
stringData:
uri: replica-source-uri-goes-here
可以通过在管理界面中转到“UI > 数据库 > 配置 > 按下获取源URL副本的按钮”来检索副本源URL。但是,这些信息也可以直接从REST API中检索。
数据库CR的副本只需使用replicaSources
部分中的密钥:
apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: name-of-replica
spec:
redisEnterpriseCluster:
name: name-of-cluster
replicaSources:
- replicaSourceType: SECRET
replicaSourceName: my-replica-source
在上述情况下,只要源数据库存在于源集群上并且密钥包含该数据库的正确副本源URL,name-of-replica
数据库将作为源数据库的副本被创建。
通过kubectl检索副本源URL
您需要安装kubectl
、curl
和jq
来完成此过程。
-
设置您的元数据:
CLUSTER_NAME=test SOURCE_DB=db1 TARGET_DB=db2 TARGET_CLUSTER_NAME=test
-
检索集群认证:
CLUSTER_USER=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.username | base64 -d` CLUSTER_PASSWORD=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.password | base64 -d`
-
转发源集群的REST API服务端口:
kubectl port-forward pod/${CLUSTER_NAME}-0 9443
-
从REST API请求信息:
JQ='.[] | select(.name=="' JQ+="${SOURCE_DB}" JQ+='") | ("redis://admin:" + .authentication_admin_pass + "@"+.endpoints[0].dns_name+":"+(.endpoints[0].port|tostring))' URI=`curl -sf -k -u "$CLUSTER_USER:$CLUSTER_PASSWORD" "https://localhost:9443/v1/bdbs?fields=uid,name,endpoints,authentication_admin_pass" | jq "$JQ" | sed 's/"//g'`
注意:URI 现在包含副本源 URI。
-
构建副本的密钥:
cat << EOF > secret.yaml apiVersion: v1 kind: Secret metadata: name: ${SOURCE_DB}-url stringData: uri: ${URI} EOF kubectl apply -f secret.yaml
-
创建副本数据库:
cat << EOF > target.yaml apiVersion: app.redislabs.com/v1alpha1 kind: RedisEnterpriseDatabase metadata: name: ${TARGET_DB} spec: redisEnterpriseCluster: name: ${TARGET_CLUSTER_NAME} replicaSources: - replicaSourceType: SECRET replicaSourceName: ${SOURCE_DB}-url EOF kubectl apply -f target.yaml
通过作业自动化创建
以下过程使用ConfigMap和Job从源数据库构建副本源URL密钥并配置目标数据库。
有四个参数:
source
- 源数据库的名称cluster
- 源数据库的集群名称target
- 目标数据库的名称targetCluster
- 目标数据库的集群名称
这些参数可以通过以下方式设置:
kubectl create configmap replica-of-database-parameters \
--from-literal=source=name-of-source \
--from-literal=cluster=name-of-cluster \
--from-literal=target=name-of-target \
--from-literal=targetCluster=name-of-cluster
其中 "name-of-..." 被替换为数据库源、源集群、数据库目标和目标集群的名称。
下面的Job和ConfigMap在提交时,将创建secret和副本数据库:
apiVersion: batch/v1
kind: Job
metadata:
name: replica-of-database
spec:
backoffLimit: 4
template:
spec:
serviceAccountName: redis-enterprise-operator
restartPolicy: Never
volumes:
- name: scripts
configMap:
name: replica-of-database
containers:
- name: createdb
image: debian:stable-slim
env:
- name: MY_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SCRIPT
value: create.sh
- name: SOURCE_DB
valueFrom:
configMapKeyRef:
name: replica-of-database-parameters
key: source
- name: TARGET_DB
valueFrom:
configMapKeyRef:
name: replica-of-database-parameters
key: target
- name: CLUSTER_SERVICE
value: .svc.cluster.local
- name: CLUSTER_NAME
valueFrom:
configMapKeyRef:
name: replica-of-database-parameters
key: cluster
- name: CLUSTER_PORT
value: "9443"
- name: TARGET_CLUSTER_NAME
valueFrom:
configMapKeyRef:
name: replica-of-database-parameters
key: targetCluster
volumeMounts:
- mountPath: /opt/scripts/
name: scripts
command:
- /bin/bash
- -c
- |
apt-get update; apt-get install -y curl jq apt-transport-https gnupg2
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 6A030B21BA07F4FB
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubectl
bash /opt/scripts/$SCRIPT
---
apiVersion: v1
kind: ConfigMap
metadata:
name: replica-of-database
data:
create.sh: |
CLUSTER_USER=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.username | base64 -d`
CLUSTER_PASSWORD=`kubectl get secret/${CLUSTER_NAME} -o json | jq -r .data.password | base64 -d`
CLUSTER_HOST=${CLUSTER_NAME}.${MY_NAMESPACE}${CLUSTER_SERVICE}
JQ='.[] | select(.name=="'
JQ+="${SOURCE_DB}"
JQ+='") | ("redis://admin:" + .authentication_admin_pass + "@"+.endpoints[0].dns_name+":"+(.endpoints[0].port|tostring))'
URI=`curl -sf -k -u "$CLUSTER_USER:$CLUSTER_PASSWORD" "https://${CLUSTER_HOST}:${CLUSTER_PORT}/v1/bdbs?fields=uid,name,endpoints,authentication_admin_pass" | jq "$JQ" | sed 's/"//g'`
echo "URL: ${URL}"
echo ""
cat << EOF > /tmp/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ${SOURCE_DB}-url
stringData:
uri: ${URI}
EOF
cat /tmp/secret.yaml
cat << EOF > /tmp/target.yaml
apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: ${TARGET_DB}
spec:
redisEnterpriseCluster:
name: ${TARGET_CLUSTER_NAME}
replicaSources:
- replicaSourceType: SECRET
replicaSourceName: ${SOURCE_DB}-url
EOF
echo "---"
cat /tmp/target.yaml
echo ""
kubectl -n ${MY_NAMESPACE} apply -f /tmp/secret.yaml
kubectl -n ${MY_NAMESPACE} apply -f /tmp/target.yaml