No menu items!
No menu items!
More

    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é.

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email