Kubernetes1.25中Redis单机和集群部署实例一

本文介绍了在Kubernetes1.25环境下如何搭建Redis单实例和集群,强调了配置文件的安全性和使用hostPath的风险,推荐使用configMap结合动态卷的方式。文中详细展示了通过hostPath和configMap部署Redis的步骤,包括创建配置、调整节点标签以确保配置文件生效,并讨论了hostPath部署的局限性。
摘要由CSDN通过智能技术生成

1、概述

我们知道在 Kubernetes 容器编排平台中, 我们可以非常方便的进行应用的扩容缩, 同时也能非常方便的进行业务的迭代,本章主要讲解在Kubernetes1.25搭建Redis单实例和Redis集群主从同步的环境流程步骤, 如果是高频访问重要的线上业务我们最好是部署在物理机器上;

2、Kubernetes环境说明

# 集群信息
[root@k8s-master ~]# kubectl cluster-info
Kubernetes control plane is running at https://10.211.55.11:6443
CoreDNS is running at https://10.211.55.11:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@k8s-master ~]#

# 集群节点
[root@k8s-master ~]# kubectl get nodes -owide
NAME         STATUS   ROLES           AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE          KERNEL-VERSION          CONTAINER-RUNTIME
k8s-master   Ready    control-plane   18h   v1.25.0   10.211.55.11   <none>        CentOS Stream 8   4.18.0-408.el8.x86_64   docker://20.10.22
k8s-node1    Ready    <none>          18h   v1.25.0   10.211.55.12   <none>        CentOS Stream 8   4.18.0-408.el8.x86_64   docker://20.10.22
k8s-node2    Ready    <none>          18h   v1.25.0   10.211.55.13   <none>        CentOS Stream 8   4.18.0-408.el8.x86_64   docker://20.10.22

# 动态卷
[root@k8s-master ~]# kubectl get sc -n dev
NAME          PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-storage   storage-nfs   Delete          Immediate           false                  6s

动态卷制作如果不会的朋友可以参考这篇文章:https://blog.csdn.net/u011837804/article/details/128692744

3、单例Redis部署

本次我们采用两种方式部署单例Redis

  • hostPath 方式

警告 ⚠️ 这种方式不推荐
HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求 volumeMounts 使用 readOnly 挂载以使策略生效。
  • configMap + 动态卷方式 这种方式是推荐的方式

3.1、准备工作

Redis配置文件/root/redis/redis.conf

# 绑定任意接口、服务端口、后台运行。
bind 0.0.0.0
port 6379
# 非常大的巨坑在使用k8s中的container作为redis容器时其daemonize no一定要设置为no 
daemonize no
supervised no

# redis服务pid进程文件名
pidfile "/var/run/redis.pid"

# 关闭保护模式,并配置使用密码访问
protected-mode no
requirepass 123456

# 数据文件保存路径,rdb/AOF文件也保存在这里
dir "/data"

# 日志文件记录文件(notice / verbose)
# /var/log/redis/redis.log
loglevel verbose  
logfile "/logs/redis.log"

# 最大客户端连接数
maxclients 10000

# 客户端连接空闲多久后断开连接,单位秒,0表示禁用
timeout 300
tcp-keepalive 60 


# 内存初始化
maxmemory 1gb
maxmemory-policy volatile-lru
slowlog-max-len 128
lua-time-limit 5000

# Redis 数据持久化(rdb/aof)配置
# 数据自动保存脚本条件例如300s中有10key发生变化
save 300 100
save 60 10000
# RDB 文件名
dbfilename "dump.rdb"
# 对RDB文件进行压缩,建议以(磁盘)空间换(CPU)时间。
rdbcompression yes
# 版本5的RDB有一个CRC64算法的校验和放在了文件的最后。这将使文件格式更加可靠。
rdbchecksum yes
# RDB自动触发策略是否启用,默认为yes
rdb-save-incremental-fsync yes

# AOF开启
appendonly yes
# AOF文件名
appendfilename "appendonly.aof"
# 可选值 always, everysec,no,建议设置为everysec
appendfsync everysec

# Redis风险命令重命名
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
rename-command FLUSHDB b840fc02d524045429941cc15f59e41cb7be6c53
rename-command FLUSHALL b840fc02d524045429941cc15f59e41cb7be6c54
rename-command EVAL b840fc02d524045429941cc15f59e41cb7be6c55
rename-command DEBUG b840fc02d524045429941cc15f59e41cb7be6c56
# rename-command SHUTDOWN SHUTDOWN

在master中配置Redis相关目录

# 数据与日志存储目录
mkdir /root/redis/{data,logs}

# 配置文件目录已创建好
[root@k8s-master redis]# pwd
/root/redis
[root@k8s-master redis]# ls
data  logs  redis.conf
[root@k8s-master redis]#

3.2、hostpath卷方式

创建redis-single.yaml

这里通过StatefulSet 部署有状态Redis,生产环境需要通过k8s服务发现机制连接redis,必须用到StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: dev
spec:
  serviceName: redis-single-service
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          name: server
        command: [ "redis-server", "/conf/redis.conf" ]
        # 单个文件与目录挂载
        volumeMounts:
        - name: conf
          mountPath: /conf/redis.conf
          readOnly: true
        - name: data
          mountPath: /data
        - name: logs
          mountPath: /logs
        # 时区设置
        - name: timezone
          mountPath: /etc/localtime
      volumes:
      - name: conf
        # 采用hostPath卷,只映射配置文件到pod中
        hostPath:
          type: FileOrCreate
          path: /root/redis/redis.conf
      - name: data
        # 采用hostPath卷
        hostPath:
          type: DirectoryOrCreate     
          path: /root/redis/data
      - name: logs
        # 采用hostPath卷
        hostPath:
          type: DirectoryOrCreate 
          path: /root/redis/logs
        # 时区定义
      - name: timezone                             
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
---
apiVersion: v1
kind: Service
metadata:
  name: redis-single-service
  namespace: dev
spec:
  type: ClusterIP
  ports:
  - port: 6379
    targetPort: 6379
    name: server
  selector:
    app: redis

执行效果

# 创建
[root@k8s-master ~]# kubectl apply -f redis-single.yaml
statefulset.apps/redis created
service/redis-single-service created
[root@k8s-master ~]#
# 查看sts
[root@k8s-master ~]# kubectl get sts -n dev
NAME    READY   AGE
redis   1/1     6s
# 查看svc
[root@k8s-master ~]# kubectl get svc -n dev
NAME                   TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
redis-single-service   ClusterIP   10.9.64.181   <none>        6379/TCP   10s
# 查看pod 发现pod被部署在k8s-node1上了
[root@k8s-master ~]# kubectl get pod -n dev -owide
NAME      READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
redis-0   1/1     Running   0          45s   172.17.36.77   k8s-node1   <none>           <none
>

# 查看redis启动日志
[root@k8s-master ~]# kubectl logs redis-0 -n dev
1:C 15 Jan 2023 13:51:13.138 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:C 15 Jan 2023 13:51:13.138 # Redis version=7.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
1:C 15 Jan 2023 13:51:13.138 # Configuration loaded
1:M 15 Jan 2023 13:51:13.139 * monotonic clock: POSIX clock_gettime
1:M 15 Jan 2023 13:51:13.140 * Running mode=standalone, port=6379.
1:M 15 Jan 2023 13:51:13.140 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:M 15 Jan 2023 13:51:13.140 # Server initialized
1:M 15 Jan 2023 13:51:13.141 * Loading RDB produced by version 7.0.7
1:M 15 Jan 2023 13:51:13.141 * RDB age 54 seconds
1:M 15 Jan 2023 13:51:13.141 * RDB memory usage when created 0.82 Mb
1:M 15 Jan 2023 13:51:13.141 * Done loading RDB, keys loaded: 0, keys expired: 0.
1:M 15 Jan 2023 13:51:13.141 * DB loaded from disk: 0.000 seconds
1:M 15 Jan 2023 13:51:13.141 * Ready to accept connections

# 进入容器确认配置文件是否生效   发现我们挂载的配置文件存在,但是是空的 这是为什么呢?
[root@k8s-master ~]# kubectl exec -it redis-0 -n dev /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@redis-0:/data#
root@redis-0:/data# cd /conf/
root@redis-0:/conf# ls
redis.conf
root@redis-0:/conf# cat redis.conf
root@redis-0:/conf#

# 连接redis  发现不需要密码也可以连上,再次确认配置文件未生效
root@redis-0:/conf# redis-cli
127.0.0.1:6379>
127.0.0.1:6379> set test test
OK
127.0.0.1:6379> get test
"test"
127.0.0.1:6379>

问题:在master上创建了配置文件,通过hostpath模式挂载,未生效

原因是,hostpath挂载的是当前pod部署节点上的文件

解决方式:通过定向调度将pod部署在存放配置文件的那台节点上

  • 给指定nodes增加label(我这里选择k8s-node2)

# 查看各个节点当前拥有的label
[root@k8s-master ~]# kubectl get nodes --show-labels=true
NAME         STATUS   ROLES           AGE   VERSION   LABELS
k8s-master   Ready    control-plane   24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s-node1    Ready    <none>          24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2    Ready    <none>          24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux
[root@k8s-master ~]#
# 给k8s-node2节点增加 redis=single label
[root@k8s-master ~]# kubectl label nodes k8s-node2 redis=single
node/k8s-node2 labeled
[root@k8s-master ~]#
# 再次查看label 发现已增加
[root@k8s-master ~]# kubectl get nodes --show-labels=true
NAME         STATUS   ROLES           AGE   VERSION   LABELS
k8s-master   Ready    control-plane   24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s-node1    Ready    <none>          24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2    Ready    <none>          24h   v1.25.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux,redis=single
  • 将配置文件挪动至k8s-node2节点上

  • 修改配置文件定向调度只k8s-node2上

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: dev
spec:
  serviceName: redis-single-service
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      # 通过node选择器,定向调度到k8s-node2节点上,当然也可以nodeName直接设置
      nodeSelector: 
        redis: single
      containers:
      - name: redis
        image: redis:7.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
          name: server
        command: [ "redis-server", "/conf/redis.conf" ]
        # 单个文件与目录挂载
        volumeMounts:
        - name: conf
          mountPath: /conf/redis.conf
          readOnly: true
        - name: data
          mountPath: /data
        - name: logs
          mountPath: /logs
        # 时区设置
        - name: timezone
          mountPath: /etc/localtime
      volumes:
      - name: conf
        # 采用hostPath卷,只映射配置文件到pod中
        hostPath:
          type: FileOrCreate
          path: /root/redis/redis.conf
      - name: data
        # 采用hostPath卷
        hostPath:
          type: DirectoryOrCreate     
          path: /root/redis/data
      - name: logs
        # 采用hostPath卷
        hostPath:
          type: DirectoryOrCreate 
          path: /root/redis/logs
        # 时区定义
      - name: timezone                             
        hostPath:
          path: /usr/share/zoneinfo/Asia/Shanghai
---
apiVersion: v1
kind: Service
metadata:
  name: redis-single-service
  namespace: dev
spec:
  type: ClusterIP
  ports:
  - port: 6379
    targetPort: 6379
    name: server
  selector:
    app: redis
  • 执行并查看效果

# 进入容器,查看配置文件并校验
root@redis-0:/conf# ls
redis.conf
root@redis-0:/conf#
# 配置文件已挂载成功
root@redis-0:/conf# more -n 3 redis.conf
# 绑定任意接口、服务端口、后台运行。
bind 0.0.0.0
port 6379
root@redis-0:/conf#
root@redis-0:/conf# redis-cli
127.0.0.1:6379> get test
(error) NOAUTH Authentication required.
127.0.0.1:6379> AUTH 123456
OK
127.0.0.1:6379> set test test
OK
127.0.0.1:6379> get test
"test"
127.0.0.1:6379>

# 进入k8s-node2节点查看log\data文件夹是否已有数据
[root@k8s-node2 redis]# ls
data  logs  redis.conf
[root@k8s-node2 redis]#
[root@k8s-node2 redis]# ls ./data/
appendonlydir
[root@k8s-node2 redis]# ls ./logs/
redis.log
[root@k8s-node2 redis]#

至此通过hostpath部署单实例redis已部署成功,大家可以看出通过hostpath部署有局限性还是比较多的,这种方式不推荐,下篇文章,我们讲解通过confmap部署单实例redis

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈行动派

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值