【k8s管理--Helm包管理器】

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

3.1 下载二进制文件

cpp 复制代码
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)

cpp 复制代码
tar-xvf  helm-v3.10.0-linux-amd64.tar.gz

3.3 将helm的可执行文件复制到/usr/local/bin/目录下

cpp 复制代码
 mv linux-amd64/helm /usr/local/bin/

3.4 添加Helm的仓库(阿里云源)

cpp 复制代码
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的目录结构

cpp 复制代码
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源

cpp 复制代码
[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 修改配置安装

cpp 复制代码
# 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     
cpp 复制代码
##  详细配置文件如下
[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 查看安装情况

cpp 复制代码
[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集群

cpp 复制代码
# 获取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

cpp 复制代码
# 给redis设置一个密码,然后进行升级
global:
  redis:
    password: "redis123"
cpp 复制代码
# 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&reg; 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&reg; server:

1. Run a Redis&reg; 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&reg; 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

cpp 复制代码
# 查看服务的历史版本
[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

cpp 复制代码
# 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
相关推荐
SRExianxian2 小时前
kubernetes存储架构之PV controller源码解读
容器·架构·kubernetes
ether-lin4 小时前
DevOps实战:用Kubernetes和Argo打造自动化CI/CD流程(2)
kubernetes·自动化·devops
无所不在的物质5 小时前
Jenkins基础教程
运维·云原生·自动化·jenkins
是芽芽哩!7 小时前
【Kubernetes 指南】基础入门——Kubernetes 基本概念(二)
云原生·容器·kubernetes
SelectDB8 小时前
Apache Doris 创始人:何为“现代化”的数据仓库?
大数据·数据库·云原生
m0_663234018 小时前
云原生是什么
云原生
怡雪~9 小时前
k8s使用ceph
ceph·容器·kubernetes
运维小文10 小时前
K8S中的服务质量QOS
云原生·容器·kubernetes
华为云开发者联盟10 小时前
Karmada v1.12 版本发布!单集群应用迁移可维护性增强
云原生·kubernetes·开源·容器编排·karmada
Hadoop_Liang10 小时前
Kubernetes Secret的创建与使用
云原生·容器·kubernetes