1、Helm的概念
-  
Kubernetes包管器
 -  
Helm是查找、分享和使用软件构件Kubernetes的最优方式。
 -  
Helm管理名为chart的Kubernetes包的工具。Helm可以做以下的事情:
- 从头开始创建新的chat
 - 将chart打包成归档tgz)文件
 - 与存储chat的仓库进行交互
 - 在现有的Kubernetes集群中安装和卸载chart
 - 管理与Helm一起安装的chart的发布周期
 
 
2、Helm的架构
2.1 Helm的三个重要概念
- 1.chart创建Kubernetes应用程序所必需的一组信息。
 - 2.config包含了可以合并到打包的charte中的配置信息,用于创建一个可发布的对象。
 - 3.release是一个与特定配置相结台的chart的运行实例,
 
2.2 Helm的组件
2.2.1 Helm客户端
- Helm客端是终端 用户的命令行客户端,负责以下内容: 
  
- 本地chat开发
 - 管理仓库
 - 管理发布
 - 与Helm库建立接口 
    
- 发送安装的chart
 - 发送升级或卸载现有发布的请求
 
 
 
2.2.2 Helm库
- Helm库提供执行所有Helm操作的逻辑。与Kubernetes API服务交互并提供以下功能: 
  
- 结合chat和配置来构建版本
 - 将chat安装到Kubernetes中,并提供后续发布对象
 - 与Kubernetes交互升级和卸载chart
 
 - 独立的Helm库封装了Helm逻辑以便不同的客户端可以使用它。
 
3、安装Helm
- Helm官网:https://helm.sh/zh/docs/intro/quickstart/
 - 注:安装Helm的时候需要注意k8s的版本
 
3.1 下载二进制文件
wget https://get.helm.sh/helm-v3.10.0-linux-amd64.tar.gz  -O helm-v3.10.0-linux-amd64.tar.gz
 
3.2 解压(helm-v3.10.0-linux-amd64.tar.gz)
tar-xvf  helm-v3.10.0-linux-amd64.tar.gz
 
3.3 将helm的可执行文件复制到/usr/local/bin/目录下
 mv linux-amd64/helm /usr/local/bin/
 
3.4 添加Helm的仓库(阿里云源)
helm repo add ingress-nginx  https://kubernetes.github.io/ingress-nginx
 
4、Helm的常用命令
| 命令 | 作用 | 
|---|---|
| helm repo | 列出、增加、更新、删除chart仓库 | 
| helm search | 使用关键词搜索chart | 
| helm pull | 拉取远仓库中的chart到本地 | 
| helm create | 在本地创建新的chart | 
| helm dependency | 管理chart 依赖 | 
| helm install | 安装chart | 
| helm list | 列出所有release | 
| helm lint | 检查chart配置是否有误 | 
| helm package | 打包本地chart | 
| helm rollback | 回滚release到历史版本 | 
| helm uninstall | 卸载release | 
| helm upgrade | 升级release | 
5、chart
5.1 chart的目录结构
mychart
├── Chart.yaml
├── charts   # 该目录保存其他依赖的chart(子chart)
├── templates  # chart配置模板,用于渲染最终的kubernetes yaml
│   ├── NOTES.txt  # 用户运行helm install的提示信息
│   ├── _helpers.tpl  # 用于创建模板时的帮助类
│   ├── deployment.yaml  # kubernetes deployment 的配置
│   ├── ingress.yaml  # kubernetes ingress 配置
│   ├── service.yaml  # kubernetes service 配置
│   ├── serviceaccount.yaml # kubernetes serviceaccount 配置
│   └── tests
│       └── test-connection.yaml
└── values.yaml  # 定义chart模板中的自定义配置的默认值
 
5.2 redis chart 实战
5.2.1 修改helm源
[root@k8s-master ~]# helm repo  list
NAME         	URL
ingress-nginx	https://kubernetes.github.io/ingress-nginx
[root@k8s-master ~]# helm repo add bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories
[root@k8s-master ~]# helm repo add azure http://mirror.azure.cn/kubernetes/charts
"azure" has been added to your repositories
[root@k8s-master ~]# helm repo add ali-stable    https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
"ali-stable" has been added to your repositories
[root@k8s-master ~]# helm  repo list
NAME         	URL
ingress-nginx	https://kubernetes.github.io/ingress-nginx
bitnami      	https://charts.bitnami.com/bitnami
azure        	http://mirror.azure.cn/kubernetes/charts
ali-stable   	https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
 
5.2.2 搜索redis chart
- 搜索redis chart: helm search repo redis
 - 查看redis chart的描述信息:helm show readme bitnami/redis
 

5.2.3 修改配置安装
# 1、拉取redis的chart包
[root@k8s-master k8s]# helm pull bitnami/redis
# 2、解压这个redis的chart包
[root@k8s-master k8s]# tar -xvf   redis-18.17.0.tgz
redis/Chart.yaml
redis/Chart.lock
redis/values.yaml
redis/values.schema.json
redis/templates/NOTES.txt
redis/templates/_helpers.tpl
redis/templates/configmap.yaml
redis/templates/extra-list.yaml
redis/templates/headless-svc.yaml
redis/templates/health-configmap.yaml
redis/templates/master/application.yaml
redis/templates/master/psp.yaml
redis/templates/master/pvc.yaml
redis/templates/master/service.yaml
redis/templates/master/serviceaccount.yaml
redis/templates/metrics-svc.yaml
redis/templates/networkpolicy.yaml
redis/templates/pdb.yaml
redis/templates/podmonitor.yaml
redis/templates/prometheusrule.yaml
redis/templates/replicas/application.yaml
redis/templates/replicas/hpa.yaml
redis/templates/replicas/service.yaml
redis/templates/replicas/serviceaccount.yaml
redis/templates/role.yaml
redis/templates/rolebinding.yaml
redis/templates/scripts-configmap.yaml
redis/templates/secret-svcbind.yaml
redis/templates/secret.yaml
redis/templates/sentinel/hpa.yaml
redis/templates/sentinel/node-services.yaml
redis/templates/sentinel/ports-configmap.yaml
redis/templates/sentinel/service.yaml
redis/templates/sentinel/statefulset.yaml
redis/templates/serviceaccount.yaml
redis/templates/servicemonitor.yaml
redis/templates/tls-secret.yaml
redis/.helmignore
redis/README.md
redis/charts/common/Chart.yaml
redis/charts/common/values.yaml
redis/charts/common/templates/_affinities.tpl
redis/charts/common/templates/_capabilities.tpl
redis/charts/common/templates/_errors.tpl
redis/charts/common/templates/_images.tpl
redis/charts/common/templates/_ingress.tpl
redis/charts/common/templates/_labels.tpl
redis/charts/common/templates/_names.tpl
redis/charts/common/templates/_resources.tpl
redis/charts/common/templates/_secrets.tpl
redis/charts/common/templates/_storage.tpl
redis/charts/common/templates/_tplvalues.tpl
redis/charts/common/templates/_utils.tpl
redis/charts/common/templates/_warnings.tpl
redis/charts/common/templates/validations/_cassandra.tpl
redis/charts/common/templates/validations/_mariadb.tpl
redis/charts/common/templates/validations/_mongodb.tpl
redis/charts/common/templates/validations/_mysql.tpl
redis/charts/common/templates/validations/_postgresql.tpl
redis/charts/common/templates/validations/_redis.tpl
redis/charts/common/templates/validations/_validations.tpl
redis/charts/common/.helmignore
redis/charts/common/README.md
# 3、修改配置
## 修改全局的storageClass制备器,这个制备器是之前创建nfs的创建的
global:
  storageClass: "managed-nfs-storage"
## 修改master节点的service类型:内部访问 
master:
  service:
    type: ClusterIP     
 
##  详细配置文件如下
[root@k8s-master k8s]# cat redis/redis.yaml
global:
  imageRegistry: ""
  imagePullSecrets: []
  storageClass: "managed-nfs-storage"
  redis:
    password: ""
kubeVersion: ""
nameOverride: ""
fullnameOverride: ""
namespaceOverride: ""
commonLabels: {}
commonAnnotations: {}
secretAnnotations: {}
clusterDomain: cluster.local
extraDeploy: []
useHostnames: true
nameResolutionThreshold: 5
nameResolutionTimeout: 5
diagnosticMode:
  enabled: false
  command:
    - sleep
  args:
    - infinity
image:
  registry: docker.io
  repository: bitnami/redis
  tag: 7.2.4-debian-12-r9
  digest: ""
  pullPolicy: IfNotPresent
  pullSecrets: []
  debug: false
architecture: replication
auth:
  enabled: true
  sentinel: true
  password: ""
  existingSecret: ""
  existingSecretPasswordKey: ""
  usePasswordFiles: false
  usePasswordFileFromSecret: true
commonConfiguration: |-
  appendonly yes
  save ""
existingConfigmap: ""
master:
  count: 1
  configuration: ""
  disableCommands:
    - FLUSHDB
    - FLUSHALL
  command: []
  args: []
  enableServiceLinks: true
  preExecCmds: []
  extraFlags: []
  extraEnvVars: []
  extraEnvVarsCM: ""
  extraEnvVarsSecret: ""
  containerPorts:
    redis: 6379
  startupProbe:
    enabled: false
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 5
  livenessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 5
  readinessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 5
  customStartupProbe: {}
  customLivenessProbe: {}
  customReadinessProbe: {}
  resourcesPreset: "none"
  resources: {}
  podSecurityContext:
    enabled: true
    fsGroupChangePolicy: Always
    sysctls: []
    supplementalGroups: []
    fsGroup: 1001
  containerSecurityContext:
    enabled: true
    seLinuxOptions: null
    runAsUser: 1001
    runAsGroup: 0
    runAsNonRoot: true
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: false
    seccompProfile:
      type: RuntimeDefault
    capabilities:
      drop: ["ALL"]
  kind: StatefulSet
  schedulerName: ""
  updateStrategy:
    type: RollingUpdate
  minReadySeconds: 0
  priorityClassName: ""
  automountServiceAccountToken: false
  hostAliases: []
  podLabels: {}
  podAnnotations: {}
  shareProcessNamespace: false
  podAffinityPreset: ""
  podAntiAffinityPreset: soft
  nodeAffinityPreset:
    type: ""
    key: ""
    values: []
  affinity: {}
  nodeSelector: {}
  tolerations: []
  topologySpreadConstraints: []
  dnsPolicy: ""
  dnsConfig: {}
  lifecycleHooks: {}
  extraVolumes: []
  extraVolumeMounts: []
  sidecars: []
  initContainers: []
  persistence:
    enabled: true
    medium: ""
    sizeLimit: ""
    path: /data
    subPath: ""
    subPathExpr: ""
    storageClass: ""
    accessModes:
      - ReadWriteOnce
    size: 1Gi
    annotations: {}
    labels: {}
    selector: {}
    dataSource: {}
    existingClaim: ""
  persistentVolumeClaimRetentionPolicy:
    enabled: false
    whenScaled: Retain
    whenDeleted: Retain
  service:
    type: ClusterIP
    ports:
      redis: 6379
    nodePorts:
      redis: ""
    externalTrafficPolicy: Cluster
    extraPorts: []
    internalTrafficPolicy: Cluster
    clusterIP: ""
    loadBalancerIP: ""
    loadBalancerClass: ""
    loadBalancerSourceRanges: []
    externalIPs: []
    annotations: {}
    sessionAffinity: None
    sessionAffinityConfig: {}
  terminationGracePeriodSeconds: 30
  serviceAccount:
    create: true
    name: ""
    automountServiceAccountToken: false
    annotations: {}
replica:
  kind: StatefulSet
  replicaCount: 3
  configuration: ""
  disableCommands:
    - FLUSHDB
    - FLUSHALL
  command: []
  args: []
  enableServiceLinks: true
  preExecCmds: []
  extraFlags: []
  extraEnvVars: []
  extraEnvVarsCM: ""
  extraEnvVarsSecret: ""
  externalMaster:
    enabled: false
    host: ""
    port: 6379
  containerPorts:
    redis: 6379
  startupProbe:
    enabled: true
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 22
  livenessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 5
  readinessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 5
  customStartupProbe: {}
  customLivenessProbe: {}
  customReadinessProbe: {}
  resourcesPreset: "none"
  resources: {}
  podSecurityContext:
    enabled: true
    fsGroupChangePolicy: Always
    sysctls: []
    supplementalGroups: []
    fsGroup: 1001
  containerSecurityContext:
    enabled: true
    seLinuxOptions: null
    runAsUser: 1001
    runAsGroup: 0
    runAsNonRoot: true
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: false
    seccompProfile:
      type: RuntimeDefault
    capabilities:
      drop: ["ALL"]
  schedulerName: ""
  updateStrategy:
    type: RollingUpdate
  minReadySeconds: 0
  priorityClassName: ""
  podManagementPolicy: ""
  automountServiceAccountToken: false
  hostAliases: []
  podLabels: {}
  podAnnotations: {}
  shareProcessNamespace: false
  podAffinityPreset: ""
  podAntiAffinityPreset: soft
  nodeAffinityPreset:
    type: ""
    key: ""
    values: []
  affinity: {}
  nodeSelector: {}
  tolerations: []
  topologySpreadConstraints: []
  dnsPolicy: ""
  dnsConfig: {}
  lifecycleHooks: {}
  extraVolumes: []
  extraVolumeMounts: []
  sidecars: []
  initContainers: []
  persistence:
    enabled: true
    medium: ""
    sizeLimit: ""
    path: /data
    subPath: ""
    subPathExpr: ""
    storageClass: ""
    accessModes:
      - ReadWriteOnce
    size: 8Gi
    annotations: {}
    labels: {}
    selector: {}
    dataSource: {}
    existingClaim: ""
  persistentVolumeClaimRetentionPolicy:
    enabled: false
    whenScaled: Retain
    whenDeleted: Retain
  service:
    type: ClusterIP
    ports:
      redis: 6379
    nodePorts:
      redis: ""
    externalTrafficPolicy: Cluster
    internalTrafficPolicy: Cluster
    extraPorts: []
    clusterIP: ""
    loadBalancerIP: ""
    loadBalancerClass: ""
    loadBalancerSourceRanges: []
    annotations: {}
    sessionAffinity: None
    sessionAffinityConfig: {}
  terminationGracePeriodSeconds: 30
  autoscaling:
    enabled: false
    minReplicas: 1
    maxReplicas: 11
    targetCPU: ""
    targetMemory: ""
  serviceAccount:
    create: true
    name: ""
    automountServiceAccountToken: false
    annotations: {}
sentinel:
  enabled: false
  image:
    registry: docker.io
    repository: bitnami/redis-sentinel
    tag: 7.2.4-debian-12-r7
    digest: ""
    pullPolicy: IfNotPresent
    pullSecrets: []
    debug: false
  annotations: {}
  masterSet: mymaster
  quorum: 2
  getMasterTimeout: 90
  automateClusterRecovery: false
  redisShutdownWaitFailover: true
  downAfterMilliseconds: 60000
  failoverTimeout: 180000
  parallelSyncs: 1
  configuration: ""
  command: []
  args: []
  enableServiceLinks: true
  preExecCmds: []
  extraEnvVars: []
  extraEnvVarsCM: ""
  extraEnvVarsSecret: ""
  externalMaster:
    enabled: false
    host: ""
    port: 6379
  containerPorts:
    sentinel: 26379
  startupProbe:
    enabled: true
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 22
  livenessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 6
  readinessProbe:
    enabled: true
    initialDelaySeconds: 20
    periodSeconds: 5
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 6
  customStartupProbe: {}
  customLivenessProbe: {}
  customReadinessProbe: {}
  persistence:
    enabled: false
    storageClass: ""
    accessModes:
      - ReadWriteOnce
    size: 100Mi
    annotations: {}
    labels: {}
    selector: {}
    dataSource: {}
    medium: ""
    sizeLimit: ""
  persistentVolumeClaimRetentionPolicy:
    enabled: false
    whenScaled: Retain
    whenDeleted: Retain
  resourcesPreset: "none"
  resources: {}
  containerSecurityContext:
    enabled: true
    seLinuxOptions: null
    runAsUser: 1001
    runAsGroup: 0
    runAsNonRoot: true
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: false
    seccompProfile:
      type: RuntimeDefault
    capabilities:
      drop: ["ALL"]
  lifecycleHooks: {}
  extraVolumes: []
  extraVolumeMounts: []
  service:
    type: ClusterIP
    ports:
      redis: 6379
      sentinel: 26379
    nodePorts:
      redis: ""
      sentinel: ""
    externalTrafficPolicy: Cluster
    extraPorts: []
    clusterIP: ""
    loadBalancerIP: ""
    loadBalancerClass: ""
    loadBalancerSourceRanges: []
    annotations: {}
    sessionAffinity: None
    sessionAffinityConfig: {}
    headless:
      ## @param sentinel.service.headless.annotations Annotations for the headless service.
      ##
      annotations: {}
  terminationGracePeriodSeconds: 30
serviceBindings:
  enabled: false
networkPolicy:
  enabled: true
  allowExternal: true
  allowExternalEgress: true
  extraIngress: []
  extraEgress: []
  ingressNSMatchLabels: {}
  ingressNSPodMatchLabels: {}
  metrics:
    allowExternal: true
    ingressNSMatchLabels: {}
    ingressNSPodMatchLabels: {}
podSecurityPolicy:
  create: false
  enabled: false
rbac:
  create: false
  rules: []
serviceAccount:
  create: true
  name: ""
  automountServiceAccountToken: false
  annotations: {}
pdb:
  create: false
  minAvailable: 1
  maxUnavailable: ""
tls:
  enabled: false
  authClients: true
  autoGenerated: false
  existingSecret: ""
  certificatesSecret: ""
  certFilename: ""
  certKeyFilename: ""
  certCAFilename: ""
  dhParamsFilename: ""
metrics:
  enabled: false
  image:
    registry: docker.io
    repository: bitnami/redis-exporter
    tag: 1.58.0-debian-12-r3
    digest: ""
    pullPolicy: IfNotPresent
    pullSecrets: []
  containerPorts:
    http: 9121
  startupProbe:
    enabled: false
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 5
  livenessProbe:
    enabled: true
    initialDelaySeconds: 10
    periodSeconds: 10
    timeoutSeconds: 5
    successThreshold: 1
    failureThreshold: 5
  readinessProbe:
    enabled: true
    initialDelaySeconds: 5
    periodSeconds: 10
    timeoutSeconds: 1
    successThreshold: 1
    failureThreshold: 3
  customStartupProbe: {}
  customLivenessProbe: {}
  customReadinessProbe: {}
  command: []
  redisTargetHost: "localhost"
  extraArgs: {}
  extraEnvVars: []
  containerSecurityContext:
    enabled: true
    seLinuxOptions: null
    runAsUser: 1001
    runAsGroup: 0
    runAsNonRoot: true
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: false
    seccompProfile:
      type: RuntimeDefault
    capabilities:
      drop: ["ALL"]
  extraVolumes: []
  extraVolumeMounts: []
  resourcesPreset: "none"
  resources: {}
  podLabels: {}
  podAnnotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9121"
  service:
    enabled: true
    type: ClusterIP
    ports:
      http: 9121
    externalTrafficPolicy: Cluster
    extraPorts: []
    loadBalancerIP: ""
    loadBalancerClass: ""
    loadBalancerSourceRanges: []
    annotations: {}
    clusterIP: ""
  serviceMonitor:
    port: http-metrics
    enabled: false
    namespace: ""
    interval: 30s
    scrapeTimeout: ""
    relabellings: []
    metricRelabelings: []
    honorLabels: false
    additionalLabels: {}
    podTargetLabels: []
    sampleLimit: false
    targetLimit: false
    additionalEndpoints: []
  podMonitor:
    port: metrics
    enabled: false
    namespace: ""
    interval: 30s
    scrapeTimeout: ""
    relabellings: []
    metricRelabelings: []
    honorLabels: false
    additionalLabels: {}
    podTargetLabels: []
    sampleLimit: false
    targetLimit: false
    additionalEndpoints: []
  prometheusRule:
    enabled: false
    namespace: ""
    additionalLabels: {}
    rules: []
volumePermissions:
  enabled: false
  image:
    registry: docker.io
    repository: bitnami/os-shell
    tag: 12-debian-12-r16
    digest: ""
    pullPolicy: IfNotPresent
    pullSecrets: []
  resourcesPreset: "none"
  resources: {}
  containerSecurityContext:
    seLinuxOptions: null
    runAsUser: 0
sysctl:
  enabled: false
  image:
    registry: docker.io
    repository: bitnami/os-shell
    tag: 12-debian-12-r16
    digest: ""
    pullPolicy: IfNotPresent
    pullSecrets: []
  command: []
  mountHostSys: false
  resourcesPreset: "none"
  resources: {}
useExternalDNS:
  enabled: false
  suffix: ""
  annotationKey: external-dns.alpha.kubernetes.io/
  additionalAnnotations: {}
 
5.2.4 查看安装情况
[root@k8s-master k8s]# kubectl create namespace  redis 
[root@k8s-master k8s]# helm install redis ./redis/  -n redis
NAME: redis
LAST DEPLOYED: Thu Feb 29 15:00:51 2024
NAMESPACE: redis
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: redis
CHART VERSION: 18.17.0
APP VERSION: 7.2.4
** Please be patient while the chart is being deployed **
Redis® can be accessed on the following DNS names from within your cluster:
    redis-master.redis.svc.cluster.local for read/write operations (port 6379)
    redis-replicas.redis.svc.cluster.local for read-only operations (port 6379)
To get your password run:
    export REDIS_PASSWORD=$(kubectl get secret --namespace redis redis -o jsonpath="{.data.redis-password}" | base64 -d)
To connect to your Redis® server:
1. Run a Redis® pod that you can use as a client:
   kubectl run --namespace redis redis-client --restart='Never'  --env REDIS_PASSWORD=$REDIS_PASSWORD  --image docker.io/bitnami/redis:7.2.4-debian-12-r9 --command -- sleep infinity
   Use the following command to attach to the pod:
   kubectl exec --tty -i redis-client \
   --namespace redis -- bash
2. Connect using the Redis® CLI:
   REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-master
   REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-replicas
To connect to your database from outside the cluster execute the following commands:
    kubectl port-forward --namespace redis svc/redis-master 6379:6379 &
    REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h 127.0.0.1 -p 6379
WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
  - master.resources
  - replica.resources
+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
# 获取在namespace 是redis的所有资源
[root@k8s-master k8s]# kubectl get all -n redis
NAME                   READY   STATUS    RESTARTS      AGE
pod/redis-master-0     1/1     Running   0             12m
pod/redis-replicas-0   1/1     Running   1 (11m ago)   12m
pod/redis-replicas-1   1/1     Running   0             10m
pod/redis-replicas-2   1/1     Running   0             9m35s
NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
service/redis-headless   ClusterIP   None          <none>        6379/TCP   12m
service/redis-master     ClusterIP   10.1.165.79   <none>        6379/TCP   12m
service/redis-replicas   ClusterIP   10.1.241.14   <none>        6379/TCP   12m
NAME                              READY   AGE
statefulset.apps/redis-master     1/1     12m
statefulset.apps/redis-replicas   3/3     12m
# 获取 pv 的信息
[root@k8s-master k8s]# kubectl get pv -owide  -n redis
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS          REASON   AGE     VOLUMEMODE
pvc-276280e7-0606-4c2f-86bf-0f0ee5c780be   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-2   managed-nfs-storage            9m54s   Filesystem
pvc-3ae8520e-3a40-4e21-9bb8-3659b496846e   1Gi        RWO            Delete           Bound    redis/redis-data-redis-master-0     managed-nfs-storage            12m     Filesystem
pvc-a4075967-0575-434e-86d6-b6aea075080f   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-0   managed-nfs-storage            12m     Filesystem
pvc-c21c3655-e6f4-4a1c-bc7c-61f49c2c5799   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-1   managed-nfs-storage            11m     Filesystem
# 获取 pvc 的信息
[root@k8s-master k8s]# kubectl get pvc  -owide    -n redis
NAME                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE   VOLUMEMODE
redis-data-redis-master-0     Bound    pvc-3ae8520e-3a40-4e21-9bb8-3659b496846e   1Gi        RWO            managed-nfs-storage   13m   Filesystem
redis-data-redis-replicas-0   Bound    pvc-a4075967-0575-434e-86d6-b6aea075080f   8Gi        RWO            managed-nfs-storage   13m   Filesystem
redis-data-redis-replicas-1   Bound    pvc-c21c3655-e6f4-4a1c-bc7c-61f49c2c5799   8Gi        RWO            managed-nfs-storage   11m   Filesystem
redis-data-redis-replicas-2   Bound    pvc-276280e7-0606-4c2f-86bf-0f0ee5c780be   8Gi        RWO            managed-nfs-storage   10m   Filesystem
# 获取service的信息 
[root@k8s-master k8s]# kubectl get service   -owide    -n redis
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE   SELECTOR
redis-headless   ClusterIP   None          <none>        6379/TCP   13m   app.kubernetes.io/instance=redis,app.kubernetes.io/name=redis
redis-master     ClusterIP   10.1.165.79   <none>        6379/TCP   13m   app.kubernetes.io/component=master,app.kubernetes.io/instance=redis,app.kubernetes.io/name=redis
redis-replicas   ClusterIP   10.1.241.14   <none>        6379/TCP   13m   app.kubernetes.io/component=replica,app.kubernetes.io/instance=redis,app.kubernetes.io/name=redis
# 获取制备器 storageclass的信息
[root@k8s-master k8s]# kubectl get  sc     -owide   
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  42h
# 获取数据卷nfs pod的信息
[root@k8s-master k8s]# kubectl get  po  -n kube-system  | grep nfs
nfs-client-provisioner-64f976f4cd-7gdq7   1/1     Running   0               42h
 
5.2.5 使用这个redis集群
# 获取redis的密码,会把这个写入到环境变量中,由于未设置密码,所以redis自己设置为了一个随机密码
[root@k8s-master redis]# export REDIS_PASSWORD=$(kubectl get secret --namespace redis redis -o jsonpath="{.data.redis-password}" | base64 -d)
[root@k8s-master k8s]# echo $REDIS_PASSWORD
oWx22K6221tUBe
# 创建一个redis的客户端通过客户端访问redis
[root@k8s-master redis]#  kubectl run --namespace redis redis-client --restart='Never'  --env REDIS_PASSWORD=$REDIS_PASSWORD  --image docker.io/bitnami/redis:7.2.4-debian-12-r9 --command -- sleep infinity
pod/redis-client created
# 进入这个redis的容器中执行命令
[root@k8s-master redis]# kubectl exec --tty -i redis-client \
>    --namespace redis -- bash
# 连接redis的master端,可以设置数据,查看数据
I have no name!@redis-client:/$ REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-master
redis-master:6379> set name xiaobai
OK
redis-master:6379> get name
"xiaobai"
redis-master:6379> exit
# 连接redis的replicas,可以查看数据,但是不能创建数据
I have no name!@redis-client:/$ REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-replicas
redis-replicas:6379> get name
"xiaobai"
redis-replicas:6379> set age 12
(error) READONLY You can't write against a read only replica.
redis-replicas:6379> exit
I have no name!@redis-client:/$
 
5.2.6 通过helm升级redis
# 给redis设置一个密码,然后进行升级
global:
  redis:
    password: "redis123"
 
# 1、升级redis 
[root@k8s-master k8s]# helm upgrade redis  ./redis/   -n redis
Release "redis" has been upgraded. Happy Helming!
NAME: redis
LAST DEPLOYED: Thu Feb 29 15:44:47 2024
NAMESPACE: redis
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: redis
CHART VERSION: 18.17.0
APP VERSION: 7.2.4
** Please be patient while the chart is being deployed **
Redis® can be accessed on the following DNS names from within your cluster:
    redis-master.redis.svc.cluster.local for read/write operations (port 6379)
    redis-replicas.redis.svc.cluster.local for read-only operations (port 6379)
To get your password run:
    export REDIS_PASSWORD=$(kubectl get secret --namespace redis redis -o jsonpath="{.data.redis-password}" | base64 -d)
To connect to your Redis® server:
1. Run a Redis® pod that you can use as a client:
   kubectl run --namespace redis redis-client --restart='Never'  --env REDIS_PASSWORD=$REDIS_PASSWORD  --image docker.io/bitnami/redis:7.2.4-debian-12-r9 --command -- sleep infinity
   Use the following command to attach to the pod:
   kubectl exec --tty -i redis-client \
   --namespace redis -- bash
2. Connect using the Redis® CLI:
   REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-master
   REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h redis-replicas
To connect to your database from outside the cluster execute the following commands:
    kubectl port-forward --namespace redis svc/redis-master 6379:6379 &
    REDISCLI_AUTH="$REDIS_PASSWORD" redis-cli -h 127.0.0.1 -p 6379
WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
  - master.resources
  - replica.resources
+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
# 2、查看pod情况,这个redis的副本是statefulset资源,升级的时候从大到小
[root@k8s-master k8s]# kubectl get po -n redis
NAME               READY   STATUS              RESTARTS      AGE
redis-client       1/1     Running             0             8m56s
redis-master-0     0/1     ContainerCreating   0             2s
redis-replicas-0   1/1     Running             1 (42m ago)   44m
redis-replicas-1   1/1     Running             0             42m
redis-replicas-2   0/1     ContainerCreating   0             2s
[root@k8s-master k8s]# kubectl get po -n redis
NAME               READY   STATUS    RESTARTS   AGE
redis-client       1/1     Running   0          12m
redis-master-0     1/1     Running   0          3m17s
redis-replicas-0   1/1     Running   0          108s
redis-replicas-1   1/1     Running   0          2m16s
redis-replicas-2   1/1     Running   0          3m17s
# 3、查看redis更新过后,数据是否还存在
[root@k8s-master k8s]# kubectl exec --tty -i redis-client    --namespace redis -- bash
I have no name!@redis-client:/$ redis-cli -h redis-master
redis-master:6379> auth redis123
OK
redis-master:6379> get name
"xiaobai"
redis-master:6379> get age
(nil)
redis-master:6379> exit
[root@k8s-master k8s]# kubectl exec --tty -i redis-client    --namespace redis -- bash
I have no name!@redis-client:/$ redis-cli  -h redis-replicas
redis-replicas:6379> auth redis123
OK
redis-replicas:6379> get name
"xiaobai"
redis-replicas:6379> set age  18
(error) READONLY You can't write against a read only replica.
redis-replicas:6379> exit
I have no name!@redis-client:/$
 
5.2.7 通过helm回滚redis
# 查看服务的历史版本
[root@k8s-master k8s]# helm history redis    -n redis
REVISION	UPDATED                 	STATUS    	CHART        	APP VERSION	DESCRIPTION
1       	Thu Feb 29 15:00:51 2024	superseded	redis-18.17.0	7.2.4      	Install complete
2       	Thu Feb 29 15:44:47 2024	deployed  	redis-18.17.0	7.2.4      	Upgrade complete
# 通过rollback 回滚到指定的版本 
[root@k8s-master k8s]# helm rollback  redis  1 -n redis
Rollback was a success! Happy Helming!
[root@k8s-master k8s]# echo $REDIS_PASSWORD
oWx2K6tUBe
[root@k8s-master k8s]# kubectl exec --tty -i redis-client    --namespace redis -- bash
I have no name!@redis-client:/$ redis-cli  -h redis-master
redis-master:6379> auth oWx2K6tUBe
OK
redis-master:6379> get name
"xiaobai"
redis-master:6379> exit
I have no name!@redis-client:/$
 
5.2.8 helm卸载redis
# 1、helm 卸载了redis
[root@k8s-master k8s]# helm delete redis  -n redis
release "redis" uninstalled
[root@k8s-master k8s]# kubectl get po   -n redis
NAME           READY   STATUS    RESTARTS   AGE
redis-client   1/1     Running   0          35m
# 2、但是在查看pvc的时候发现pcv并没有删除,这是因为为了数据的安全性,所以没有删除
[root@k8s-master k8s]# kubectl get pvc -ne redis
Error from server (NotFound): namespaces "e" not found
[root@k8s-master k8s]# kubectl get pvc -n redis
NAME                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
redis-data-redis-master-0     Bound    pvc-3ae8520e-3a40-4e21-9bb8-3659b496846e   1Gi        RWO            managed-nfs-storage   70m
redis-data-redis-replicas-0   Bound    pvc-a4075967-0575-434e-86d6-b6aea075080f   8Gi        RWO            managed-nfs-storage   70m
redis-data-redis-replicas-1   Bound    pvc-c21c3655-e6f4-4a1c-bc7c-61f49c2c5799   8Gi        RWO            managed-nfs-storage   68m
redis-data-redis-replicas-2   Bound    pvc-276280e7-0606-4c2f-86bf-0f0ee5c780be   8Gi        RWO            managed-nfs-storage   67m
[root@k8s-master k8s]# kubectl get pv -n redis
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                               STORAGECLASS          REASON   AGE
pvc-276280e7-0606-4c2f-86bf-0f0ee5c780be   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-2   managed-nfs-storage            67m
pvc-3ae8520e-3a40-4e21-9bb8-3659b496846e   1Gi        RWO            Delete           Bound    redis/redis-data-redis-master-0     managed-nfs-storage            70m
pvc-a4075967-0575-434e-86d6-b6aea075080f   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-0   managed-nfs-storage            70m
pvc-c21c3655-e6f4-4a1c-bc7c-61f49c2c5799   8Gi        RWO            Delete           Bound    redis/redis-data-redis-replicas-1   managed-nfs-storage            68m
                

















