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 下载二进制文件
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® 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
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