Friday, November 1, 2024

Triển khai Redis Stack mô hình mô hình Setinel trên Kubernetes Cluster

-

1. Tổng quan.

Redis là một hệ thống cơ sở dữ liệu chất lượng cao được sử dụng để lưu trữ và truy xuất dữ liệu. Redis (viết tắt của REmote DIctionary Server) là một hệ thống lưu trữ dữ liệu trên RAM (in-memory data store), còn được gọi là cơ sở dữ liệu trên bộ nhớ. Nó được phát triển dựa trên kiến trúc key-value, trong đó dữ liệu được lưu trữ dưới dạng cặp key-value, giúp tạo ra một bộ nhớ cache nhanh và hỗ trợ nhiều kiểu dữ liệu khác nhau. Redis thường được sử dụng cho các tác vụ như lưu trữ phi cấu trúc, lấy và cập nhật dữ liệu tại tốc độ cao, xử lý hàng triệu yêu cầu mỗi giây, và nhiều ứng dụng khác.

Redis Stack là một sự mở rộng của Redis, mà nói cách khác là một phiên bản mở rộng của Redis, với khả năng thêm các mô hình dữ liệu và công cụ xử lý hiện đại để cung cấp một trải nghiệm phát triển hoàn chỉnh hơn

Bài viết này cung cấp một cách tiếp cận để triển khai Redis Stack Server trong Kubernetes bằng cách sử dụng Bitnami Helm chart, giúp bạn tận dụng các tính năng mở rộng của Redis Stack cho các ứng dụng của mình.

  • Lý do sử dụng Redis Stack:Redis Stack là một sự mở rộng của Redis, mà nói cách khác là một phiên bản mở rộng của Redis, với khả năng thêm các mô hình dữ liệu và công cụ xử lý hiện đại để cung cấp một trải nghiệm phát triển hoàn chỉnh hơn. Ngoài tất cả các tính năng của OSS Redis (Redis phiên bản mã nguồn mở), Redis Stack hỗ trợ các tính năng bổ sung sau:
    • RedisJSON: Cho phép bạn lưu trữ và truy vấn các tài liệu JSON.
    • RediSearch: Cung cấp tìm kiếm toàn văn bản (full-text search).
    • RedisTimeSeries: Hỗ trợ dữ liệu chuỗi thời gian, bao gồm việc ghi và truy vấn dữ liệu chuỗi thời gian.
    • RedisGraph: Cho phép bạn lưu trữ và truy vấn dữ liệu đồ thị bằng cách sử dụng ngôn ngữ truy vấn Cypher.
    • RedisBloom: Hỗ trợ các cấu trúc dữ liệu xác suất.
  • Triển khai Redis Stack trong Kubernetes:Bài viết này tập trung vào việc triển khai Redis Stack Server trong môi trường Kubernetes bằng cách sử dụng Bitnami Helm chart. Bitnami Helm chart là một cách tiện lợi để triển khai ứng dụng trong Kubernetes, và trong trường hợp này, nó đã được cấu hình để triển khai Redis Stack thay vì Redis thông thường.
  • Cấu hình Linh hoạt bằng Helm Chart:Một điểm quan trọng mà bài viết nhấn mạnh là tính linh hoạt của Bitnami Helm chart cho phép bạn cấu hình triển khai Redis Stack Server một cách dễ dàng bằng một lệnh Helm duy nhất. Bitnami Helm chart cho phép bạn đặt cấu hình các tính năng mở rộng của Redis Stack (ví dụ: RedisJSON, RediSearch, RedisTimeSeries, RedisGraph, RedisBloom) thông qua các tùy chọn cấu hình.
  • Nhược điểm và Cảnh báo:Bài viết cũng nhắc đến rằng tác giả đã tập trung vào việc đảm bảo việc triển khai thành công và đã thực hiện một số kiểm tra đơn giản để xác minh rằng các tính năng mở rộng của Redis Stack hoạt động. Tuy nhiên, tác giả cũng lưu ý rằng điều này không phải là một môi trường sản xuất và cần phải có nhiều kiểm tra và thử nghiệm hơn nếu bạn định sử dụng nó trong môi trường sản xuất.

Dưới đây là sơ đồ mô tả ngắn gọn về Redis Stack mô hình mô hình Setinel.

2. Cách triển khai.

Đầu tiên hãy tạo một namespace cho dự án này.

kubectl create ns redis-stack

Dùng lệnh helm search repo <tên repo> để tìm các version của Redis.

$ helm search repo redis
NAME                    CHART VERSION   APP VERSION     DESCRIPTION                                       
bitnami/redis           17.15.6         7.2.0           Redis(R) is an open source, advanced key-value ...
bitnami/redis-cluster   8.7.2           7.2.0           Redis(R) is an open source, scalable, distribut...

Hãy tải repo này về bằng lệnh helm fetch <tên repo> --version=<số version>.

helm fetch bitnami/redis --version=17.15.6

Sau khi tải thành công, bạn sẽ nhận được 1 file nén như dưới.

$ ls -al *.tgz
-rw-r--r-- 1 root root 93195 Aug 21 09:19 redis-17.15.6.tgz

Giải nén nó và di chuyển vào thư mục vừa giải nén.

tar -zxvf redis-17.15.6.tgz
cd redis/

Hãy dùng lệnh kubectl get storageclass để tìm các storageclass có sẵn trong hệ thống của bạn. Ví dụ của mình đã có sẵn 1 storage longhorn.

$ kubectl get storageclass
NAME                 PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
longhorn (default)   driver.longhorn.io   Delete          Immediate           true                   96d

Hãy mở file values.yaml và chỉnh sửa một số tham số sau:

global:
  storageClass: "longhorn"
  redis:
    password: "Hoanghd164"

password: "Hoanghd164" <- tất cả các tham số password

master:
  count: 1
replica:
  replicaCount: 3

storageClass: "<tên storageclass của bạn>"

sentinel:
  enabled: true

Dưới đây là file đầy đủ của mình https://wiki.hoanghd.com/wp-content/uploads/codes/redis-stack-values-17.15.6.yaml.

Sau khi thay đổi các tham số của values.yaml xong, hãy chạy lệnh helm upgrade -i sau:

helm upgrade -i \
  redis-stack-server /home/redis \
  --atomic \
  --repo https://charts.bitnami.com/bitnami \
  --version 17.15.6 \
  --namespace redis-stack \
  --values - <<EOF
global:
  redis:
    password: "Hoanghd164"
image:
  repository: "redis/redis-stack-server"
  tag: "6.2.4-v2"
master:
  args:
    - -c
    - /opt/bitnami/scripts/merged-start-scripts/start-master.sh
  extraVolumes:
    - name: merged-start-scripts
      configMap:
        name: bitnami-redis-stack-server-merged
        defaultMode: 0755
  extraVolumeMounts:
    - name: merged-start-scripts
      mountPath: /opt/bitnami/scripts/merged-start-scripts
replica:
  args:
    - -c
    - /opt/bitnami/scripts/merged-start-scripts/start-replica.sh
  extraVolumes:
    - name: merged-start-scripts
      configMap:
        name: bitnami-redis-stack-server-merged
        defaultMode: 0755
  extraVolumeMounts:
    - name: merged-start-scripts
      mountPath: /opt/bitnami/scripts/merged-start-scripts
extraDeploy:
  - apiVersion: v1
    kind: ConfigMap
    metadata:
      name: bitnami-redis-stack-server-merged
    data:
      start-master.sh: |
        #!/usr/bin/dumb-init /bin/bash

        ### docker entrypoint script, for starting redis stack
        BASEDIR=/opt/redis-stack
        cd \${BASEDIR}

        CMD=\${BASEDIR}/bin/redis-server

        if [ -z "\${REDISEARCH_ARGS}" ]; then
        REDISEARCH_ARGS="MAXSEARCHRESULTS 10000 MAXAGGREGATERESULTS 10000"
        fi

        if [ -z "\${REDISGRAPH_ARGS}" ]; then
        REDISGRAPH_ARGS="MAX_QUEUED_QUERIES 25 TIMEOUT 1000 RESULTSET_SIZE 10000"
        fi

        [[ -f \$REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="\$(< "\${REDIS_PASSWORD_FILE}")"
        if [[ -f /opt/bitnami/redis/mounted-etc/master.conf ]];then
            cp /opt/bitnami/redis/mounted-etc/master.conf /opt/bitnami/redis/etc/master.conf
        fi
        if [[ -f /opt/bitnami/redis/mounted-etc/redis.conf ]];then
            cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
        fi

        \${CMD} \
        --port "\${REDIS_PORT}" \
        --requirepass "\${REDIS_PASSWORD}" \
        --masterauth "\${REDIS_PASSWORD}" \
        --include "/opt/bitnami/redis/etc/redis.conf" \
        --include "/opt/bitnami/redis/etc/master.conf" \
        --loadmodule /opt/redis-stack/lib/redisearch.so \${REDISEARCH_ARGS} \
        --loadmodule /opt/redis-stack/lib/redisgraph.so \${REDISGRAPH_ARGS} \
        --loadmodule /opt/redis-stack/lib/redistimeseries.so \${REDISTIMESERIES_ARGS} \
        --loadmodule /opt/redis-stack/lib/rejson.so \${REDISJSON_ARGS} \
        --loadmodule /opt/redis-stack/lib/redisbloom.so \${REDISBLOOM_ARGS}
      start-replica.sh: |
        #!/usr/bin/dumb-init /bin/bash

        BASEDIR=/opt/redis-stack
        cd \${BASEDIR}
        CMD=\${BASEDIR}/bin/redis-server

        get_port() {
            hostname="\$1"
            type="\$2"

            port_var=\$(echo "\${hostname^^}_SERVICE_PORT_\$type" | sed "s/-/_/g")
            port=\${!port_var}

            if [ -z "\$port" ]; then
                case \$type in
                    "SENTINEL")
                        echo 26379
                        ;;
                    "REDIS")
                        echo 6379
                        ;;
                esac
            else
                echo \$port
            fi
        }

        get_full_hostname() {
            hostname="\$1"
            echo "\${hostname}.\${HEADLESS_SERVICE}"
        }

        REDISPORT=\$(get_port "\$HOSTNAME" "REDIS")

        [[ -f \$REDIS_PASSWORD_FILE ]] && export REDIS_PASSWORD="\$(< "\${REDIS_PASSWORD_FILE}")"
        [[ -f \$REDIS_MASTER_PASSWORD_FILE ]] && export REDIS_MASTER_PASSWORD="\$(< "\${REDIS_MASTER_PASSWORD_FILE}")"
        if [[ -f /opt/bitnami/redis/mounted-etc/replica.conf ]];then
            cp /opt/bitnami/redis/mounted-etc/replica.conf /opt/bitnami/redis/etc/replica.conf
        fi
        if [[ -f /opt/bitnami/redis/mounted-etc/redis.conf ]];then
            cp /opt/bitnami/redis/mounted-etc/redis.conf /opt/bitnami/redis/etc/redis.conf
        fi

        echo "" >> /opt/bitnami/redis/etc/replica.conf
        echo "replica-announce-port \$REDISPORT" >> /opt/bitnami/redis/etc/replica.conf
        echo "replica-announce-ip \$(get_full_hostname "\$HOSTNAME")" >> /opt/bitnami/redis/etc/replica.conf
        \${CMD} \
        --port "\${REDIS_PORT}" \
        --requirepass "\${REDIS_PASSWORD}" \
        --masterauth "\${REDIS_PASSWORD}" \
        --include "/opt/bitnami/redis/etc/redis.conf" \
        --include "/opt/bitnami/redis/etc/replica.conf" \
        --loadmodule /opt/redis-stack/lib/redisearch.so \${REDISEARCH_ARGS} \
        --loadmodule /opt/redis-stack/lib/redisgraph.so \${REDISGRAPH_ARGS} \
        --loadmodule /opt/redis-stack/lib/redistimeseries.so \${REDISTIMESERIES_ARGS} \
        --loadmodule /opt/redis-stack/lib/rejson.so \${REDISJSON_ARGS} \
        --loadmodule /opt/redis-stack/lib/redisbloom.so \${REDISBLOOM_ARGS}
EOF

Thông báo dưới cho biết redis-stack-server chưa tồn tại nên với tham số helm upgrade -i nó sẽ tự động cài đặt.

Release "redis-stack-server" does not exist. Installing it now.

Lệnh Helm trên dùng để triển khai ứng dụng Redis Stack Server trong Kubernetes. Dưới đây là phân tích tác dụng của từng lệnh:

  • helm upgrade -i là một cách rút gọn để thực hiện lệnh helm install nếu phiên bản chưa tồn tại (được sử dụng để cài đặt) và helm upgrade nếu phiên bản đã tồn tại (được sử dụng để cập nhật).
  • redis-stack-server là tên của chart.
  • /home/redis là đường dẫn lưu trữ của bản Helm chart.
  • --repo https://charts.bitnami.com/bitnami là địa chỉ webserver Bitnami sử dụng để lưu trữ các bản Helm chart của họ.
  • --atomic sẽ tự động chờ cho toàn bộ quá trình triển khai hoàn thành và thực hiện rollback (quay trở lại phiên bản trước đó) nếu bất kỳ thành phần nào thất bại.
  • --version 17.5.6 là phiên bản chart Redis của Bitnami.
  • --values - cho phép bạn truyền giá trị vào Helm chart.
  • global.redis.password: "Hoanghd164" đặt một mật khẩu cho tất cả các node Redis (master và replica).
  • image.repositoryimage.tag cho phép sử dụng một image và trong trường hợp này chúng ta muốn sử dụng image redis-stack-server và tag “latest” từ Docker Hub.
  • master.argsreplica.args là cần thiết để thực thi các script khởi động.
  • master.extraVolumes, replica.extraVolumes, master.extraVolumeMounts, và replica.extraVolumeMounts cần thiết để mount ConfigMap với script thực thi bên dưới.
  • extraDeploy là một cách để Helm chart này tạo một ConfigMap có tên bitnami-redis-stack-server-merged được mount ở trên. ConfigMap này kết hợp script khởi động từ image redis-stack-server và các script khởi động từ Helm chart Bitnami cho cả node master và replica.

Hãy verify các cài đặt của bạn.

$ kubectl get pod,svc,pvc -n redis-stack
NAME                            READY   STATUS    RESTARTS   AGE
pod/redis-stack-server-node-0   2/2     Running   0          24m
pod/redis-stack-server-node-1   2/2     Running   0          24m
pod/redis-stack-server-node-2   2/2     Running   0          16h

NAME                                  TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                          AGE
service/redis-stack-server            NodePort    10.96.86.175   <none>        6379:32205/TCP,26379:31983/TCP   16h
service/redis-stack-server-headless   ClusterIP   None           <none>        6379/TCP,26379/TCP               16h

NAME                                                         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/redis-data-redis-stack-server-node-0   Bound    pvc-bceb338e-91c4-4098-b0bc-4f4f6d6c4f10   8Gi        RWO            longhorn       16h
persistentvolumeclaim/redis-data-redis-stack-server-node-1   Bound    pvc-f712c29a-8572-4442-adc1-c87ff9f11877   8Gi        RWO            longhorn       16h
persistentvolumeclaim/redis-data-redis-stack-server-node-2   Bound    pvc-4a403ecf-8874-4499-81e6-38874a6ded05   8Gi        RWO            longhorn       16

Kết quả pvc trên Longhorn.

Bạn có thể vào một pod để xem

$ kubectl exec -it -n redis-stack pod/redis-stack-server-node-0 bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
Defaulted container "redis" out of: redis, sentinel
groups: cannot find name for group ID 1001
I have no name!@redis-stack-server-node-0:/$ redis-cli -a Hoanghd164
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> INFO

Bạn gõ INFO và kéo xuống phần Replication bạn sẽ nhìn thấy cluster đã nhìn thấy 2 slave như dưới.

# Replication
role:master
connected_slaves:2
slave0:ip=redis-stack-server-node-1.,port=6379,state=online,offset=5014304,lag=0
slave1:ip=redis-stack-server-node-2.,port=6379,state=online,offset=5014304,lag=0
master_failover_state:no-failover
master_replid:6b1d2cd944b7653edbc585aee580deb5e46c994e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:5014304
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:3965729
repl_backlog_histlen:1048576

Do service/redis-stack-server đang ở chế độ ClusterIP nên mình sẽ edit nó để chuyển sang NodePort ở port 32205.

(lý do mình sử dụng NodePort 32205 kà vì cụm Kubernetes của mình có node Loadbalancer chạy Haproxy đang listen Port 32205 từ các node Worker để chuyển nó thành port 6379 cho các client ngoài kết nối.

kubectl edit service/redis-stack-server -n redis-stack

Mình chỉnh sửa 2 tham số như dưới.

Kết quả.

$ kubectl get service/redis-stack-server -n redis-stack
NAME                 TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                          AGE
redis-stack-server   NodePort   10.105.172.140   <none>        6379:32205/TCP,26379:32420/TCP   7m21s

Mình sử dụng Redisinsight để kiểm tra kết quả.

Truyền IP Loadbalancer và mật khẩu vào.

Kết quả.

Bận giờ bạn có thể thoải mái xoá pod (chỉ cần dư 1 pod) thì hệ thống của bạn không downtime nhé.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories