在 kubernetes 中使用持久卷重新洞察
redisinsights with persistent volume in kubernetes
我有以下 .yaml
文件要在 kubernetes 中安装 redisinsights
,具有持久性支持。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: redisinsight-storage-class
provisioner: 'kubernetes.io/gce-pd'
parameters:
type: 'pd-standard'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redisinsight-volume-claim
spec:
storageClassName: redisinsight-storage-class
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redisinsight #deployment name
labels:
app: redisinsight #deployment label
spec:
replicas: 1 #a single replica pod
selector:
matchLabels:
app: redisinsight #which pods is the deployment managing, as defined by the pod template
template: #pod template
metadata:
labels:
app: redisinsight #label for pod/s
spec:
initContainers:
- name: change-data-dir-ownership
image: alpine:3.6
command:
- chmod
- -R
- '777'
- /db
volumeMounts:
- name: redisinsight
mountPath: /db
containers:
- name: redisinsight #Container name (DNS_LABEL, unique)
image: redislabs/redisinsight:1.6.1 #repo/image
imagePullPolicy: Always #Always pull image
volumeMounts:
- name: redisinsight #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
ports:
- containerPort: 8001 #exposed conainer port and protocol
protocol: TCP
volumes:
- name: redisinsight
persistentVolumeClaim:
claimName: redisinsight-volume-claim
---
apiVersion: v1
kind: Service
metadata:
name: redisinsight
spec:
ports:
- port: 8001
name: redisinsight
type: LoadBalancer
selector:
app: redisinsight
但是,启动失败并报错:
INFO 2020-07-03 06:30:08,117 redisinsight_startup Registered SIGTERM handler
ERROR 2020-07-03 06:30:08,131 redisinsight_startup Error in main()
Traceback (most recent call last):
File "./startup.py", line 477, in main
ValueError: invalid literal for int() with base 10: 'tcp://10.69.9.111:8001'
Traceback (most recent call last):
File "./startup.py", line 495, in <module>
File "./startup.py", line 477, in main
ValueError: invalid literal for int() with base 10: 'tcp://10.69.9.111:8001'
但是相同的 docker 图像,当 运行 在本地通过 docker 作为:
docker run -v redisinsight:/db -p 8001:8001 redislabs/redisinsight
工作正常。我做错了什么?
感觉就像 redisinsights 试图将端口读取为 int 但不知何故得到了一个字符串并且感到困惑。但是我不明白这在本地 docker 运行.
中是如何工作的
问题与服务有关,因为它干扰 pod
导致它崩溃。
正如我们在 Redis 文档中看到的那样 在 Kubernetes 上安装 RedisInsight
- Once the deployment has been successfully applied and the deployment complete, access RedisInsight. This can be accomplished by exposing the deployment as a K8s Service or by using port forwarding, as in the example below:
kubectl port-forward deployment/redisinsight 8001
Open your browser and point to http://localhost:8001
或者您使用 GCP 时的服务可能如下所示:
apiVersion: v1
kind: Service
metadata:
name: redisinsight
spec:
ports:
- protocol: TCP
port: 8001
targetPort: 8001
name: redisinsight
type: LoadBalancer
selector:
app: redisinsight
一旦服务收到外部 IP,您就可以使用它来访问 Redis。
crou@cloudshell:~ $ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.8.0.1 <none> 443/TCP 9d
redisinsight LoadBalancer 10.8.7.0 34.67.171.112 8001:31456/TCP 92s
在我的示例中通过 http://34.67.171.112:8001/。
我也遇到过。如果有人错过了评论中的对话,这里是解决方案。
先部署redisinsight pod,等待运行成功。
部署服务。
我认为这是一个 bug,它并没有真正起作用,因为 pod 随时都可能死掉。有点违背使用Kubernetes的理由。
有人在这里报告了这个问题https://forum.redislabs.com/t/redisinsight-fails-to-launch-in-kubernetes/652/2
更新:
RedisInsight 的 kubernetes documentation 最近更新了。它清楚地描述了如何在有和没有服务的情况下创建 RedisInsight k8s 部署。
IT 也 explains 当已经有名为“redisinsight”的服务时该怎么做:
Note - If the deployment will be exposed by a service whose name is ‘redisinsight’, set REDISINSIGHT_HOST and REDISINSIGHT_PORT environment variables to override the environment variables created by the service.
问题出在服务名称上。
来自documentation,提到RedisInsight有一个环境变量REDISINSIGHT_PORT
可以配置RedisInsight可以运行.
的端口
当你在 Kubernetes 中创建一个服务时,所有匹配该服务的pods,都会得到一个环境变量<SERVICE_NAME>_PORT=<SERVICE_IP>:<SERVICE_PORT>
。
因此,当您尝试使用名称 redisinsight
创建上述服务时,Kubernetes 会传递服务环境变量 REDISINSIGHT_PORT=<SERVICE_IP>:SERVICE_PORT
。但是端口环境变量 (REDISINSIGHT_PORT
) 被记录为 端口号 而不是 端点 这使得 pod 在以下情况下崩溃pod 上的 redisinsight 运行ning 尝试使用环境变量作为端口号。
因此,将服务名称更改为不同的名称而不是 redisinsight
,它应该可以工作。
这是一个快速部署和服务文件:
部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redisinsight #deployment name
labels:
app: redisinsight #deployment label
spec:
replicas: 1 #a single replica pod
selector:
matchLabels:
app: redisinsight #which pods is the deployment managing, as defined by the pod template
template: #pod template
metadata:
labels:
app: redisinsight #label for pod/s
spec:
containers:
- name: redisinsight #Container name (DNS_LABEL, unique)
image: redislabs/redisinsight:1.6.3 #repo/image
imagePullPolicy: IfNotPresent
volumeMounts:
- name: db #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
ports:
- containerPort: 8001 #exposed conainer port and protocol
protocol: TCP
volumes:
- name: db
emptyDir: {} # node-ephemeral volume https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
服务:
apiVersion: v1
kind: Service
metadata:
name: redisinsight-http # name should not be redisinsight
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8001
selector:
app: redisinsight
请注意服务的名称。
redisinsight pod 日志:
INFO 2020-09-02 11:46:20,689 redisinsight_startup Registered SIGTERM handler
INFO 2020-09-02 11:46:20,689 redisinsight_startup Starting webserver...
INFO 2020-09-02 11:46:20,689 redisinsight_startup Visit http://0.0.0.0:8001 in your web browser. Press CTRL-C to exit.
还有服务端点(来自 minikube):
$ minikube service list
|----------------------|------------------------------------|--------------|-------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|----------------------|------------------------------------|--------------|-------------------------|
| default | kubernetes | No node port |
| default | redisinsight-http | 80 | http://172.17.0.2:30860 |
| kube-system | ingress-nginx-controller-admission | No node port |
| kube-system | kube-dns | No node port |
| kubernetes-dashboard | dashboard-metrics-scraper | No node port |
| kubernetes-dashboard | kubernetes-dashboard | No node port |
|----------------------|------------------------------------|--------------|-------------------------|
顺便说一句,如果你根本不想创建服务(这与问题无关),你可以做端口转发:
kubectl port-forward <redisinsight-pod-name> 8001:8001
根据当前文档的建议,k8s 中的 redisinsight 运行ning 存在几个问题。我将在下面列出它们:
- 建议使用emptyDir
问题:Emptydir 很可能 运行 out of space 对于更大的 redis 集群
解决方案:使用持久卷
- redisinsight docker container uses a redisinsight use
问题:redisinsight 用户不绑定到特定的 uid。因此,无法以允许访问 pvc 的方式设置持久卷权限
解决方案:使用 cryptexlabs/redisinsight:latest 扩展 redislabs/redisinsight:latest 但将 redisinsight 的 uid 设置为 777
- 默认权限不允许访问 redisinsight
问题:redisinsight 将无法访问 /db 目录
解决方案:使用init容器设置目录权限,让用户777拥有/db目录
- 建议使用节点端口进行服务
问题:这是一个安全漏洞
解决方案:改为使用 ClusterIP,然后使用 kubectl portforwarding 获得对 redisinsight
的访问权或其他安全访问权
- 在本地访问 rdb 文件是不切实际的。
问题:大型集群的 rdb 文件必须通过 kubectl 下载和上传
解决方案:使用s3方案。如果您在 EKS 集群中使用 kube2iam,则需要创建一个可以访问存储桶的特殊角色。在此之前,您必须创建集群的备份,然后按照以下说明导出备份:https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html
总结
Redisinsight 是一个很好的工具。但目前 运行 洞察 kubernetes 集群绝对是一场噩梦,我
我有以下 .yaml
文件要在 kubernetes 中安装 redisinsights
,具有持久性支持。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: redisinsight-storage-class
provisioner: 'kubernetes.io/gce-pd'
parameters:
type: 'pd-standard'
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redisinsight-volume-claim
spec:
storageClassName: redisinsight-storage-class
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redisinsight #deployment name
labels:
app: redisinsight #deployment label
spec:
replicas: 1 #a single replica pod
selector:
matchLabels:
app: redisinsight #which pods is the deployment managing, as defined by the pod template
template: #pod template
metadata:
labels:
app: redisinsight #label for pod/s
spec:
initContainers:
- name: change-data-dir-ownership
image: alpine:3.6
command:
- chmod
- -R
- '777'
- /db
volumeMounts:
- name: redisinsight
mountPath: /db
containers:
- name: redisinsight #Container name (DNS_LABEL, unique)
image: redislabs/redisinsight:1.6.1 #repo/image
imagePullPolicy: Always #Always pull image
volumeMounts:
- name: redisinsight #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
ports:
- containerPort: 8001 #exposed conainer port and protocol
protocol: TCP
volumes:
- name: redisinsight
persistentVolumeClaim:
claimName: redisinsight-volume-claim
---
apiVersion: v1
kind: Service
metadata:
name: redisinsight
spec:
ports:
- port: 8001
name: redisinsight
type: LoadBalancer
selector:
app: redisinsight
但是,启动失败并报错:
INFO 2020-07-03 06:30:08,117 redisinsight_startup Registered SIGTERM handler
ERROR 2020-07-03 06:30:08,131 redisinsight_startup Error in main()
Traceback (most recent call last):
File "./startup.py", line 477, in main
ValueError: invalid literal for int() with base 10: 'tcp://10.69.9.111:8001'
Traceback (most recent call last):
File "./startup.py", line 495, in <module>
File "./startup.py", line 477, in main
ValueError: invalid literal for int() with base 10: 'tcp://10.69.9.111:8001'
但是相同的 docker 图像,当 运行 在本地通过 docker 作为:
docker run -v redisinsight:/db -p 8001:8001 redislabs/redisinsight
工作正常。我做错了什么?
感觉就像 redisinsights 试图将端口读取为 int 但不知何故得到了一个字符串并且感到困惑。但是我不明白这在本地 docker 运行.
中是如何工作的问题与服务有关,因为它干扰 pod
导致它崩溃。
正如我们在 Redis 文档中看到的那样 在 Kubernetes 上安装 RedisInsight
- Once the deployment has been successfully applied and the deployment complete, access RedisInsight. This can be accomplished by exposing the deployment as a K8s Service or by using port forwarding, as in the example below:
kubectl port-forward deployment/redisinsight 8001
Open your browser and point to http://localhost:8001
或者您使用 GCP 时的服务可能如下所示:
apiVersion: v1
kind: Service
metadata:
name: redisinsight
spec:
ports:
- protocol: TCP
port: 8001
targetPort: 8001
name: redisinsight
type: LoadBalancer
selector:
app: redisinsight
一旦服务收到外部 IP,您就可以使用它来访问 Redis。
crou@cloudshell:~ $ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.8.0.1 <none> 443/TCP 9d
redisinsight LoadBalancer 10.8.7.0 34.67.171.112 8001:31456/TCP 92s
在我的示例中通过 http://34.67.171.112:8001/。
我也遇到过。如果有人错过了评论中的对话,这里是解决方案。
先部署redisinsight pod,等待运行成功。
部署服务。
我认为这是一个 bug,它并没有真正起作用,因为 pod 随时都可能死掉。有点违背使用Kubernetes的理由。
有人在这里报告了这个问题https://forum.redislabs.com/t/redisinsight-fails-to-launch-in-kubernetes/652/2
更新:
RedisInsight 的 kubernetes documentation 最近更新了。它清楚地描述了如何在有和没有服务的情况下创建 RedisInsight k8s 部署。
IT 也 explains 当已经有名为“redisinsight”的服务时该怎么做:
Note - If the deployment will be exposed by a service whose name is ‘redisinsight’, set REDISINSIGHT_HOST and REDISINSIGHT_PORT environment variables to override the environment variables created by the service.
问题出在服务名称上。
来自documentation,提到RedisInsight有一个环境变量REDISINSIGHT_PORT
可以配置RedisInsight可以运行.
当你在 Kubernetes 中创建一个服务时,所有匹配该服务的pods,都会得到一个环境变量<SERVICE_NAME>_PORT=<SERVICE_IP>:<SERVICE_PORT>
。
因此,当您尝试使用名称 redisinsight
创建上述服务时,Kubernetes 会传递服务环境变量 REDISINSIGHT_PORT=<SERVICE_IP>:SERVICE_PORT
。但是端口环境变量 (REDISINSIGHT_PORT
) 被记录为 端口号 而不是 端点 这使得 pod 在以下情况下崩溃pod 上的 redisinsight 运行ning 尝试使用环境变量作为端口号。
因此,将服务名称更改为不同的名称而不是 redisinsight
,它应该可以工作。
这是一个快速部署和服务文件:
部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redisinsight #deployment name
labels:
app: redisinsight #deployment label
spec:
replicas: 1 #a single replica pod
selector:
matchLabels:
app: redisinsight #which pods is the deployment managing, as defined by the pod template
template: #pod template
metadata:
labels:
app: redisinsight #label for pod/s
spec:
containers:
- name: redisinsight #Container name (DNS_LABEL, unique)
image: redislabs/redisinsight:1.6.3 #repo/image
imagePullPolicy: IfNotPresent
volumeMounts:
- name: db #Pod volumes to mount into the container's filesystem. Cannot be updated.
mountPath: /db
ports:
- containerPort: 8001 #exposed conainer port and protocol
protocol: TCP
volumes:
- name: db
emptyDir: {} # node-ephemeral volume https://kubernetes.io/docs/concepts/storage/volumes/#emptydir
服务:
apiVersion: v1
kind: Service
metadata:
name: redisinsight-http # name should not be redisinsight
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8001
selector:
app: redisinsight
请注意服务的名称。
redisinsight pod 日志:
INFO 2020-09-02 11:46:20,689 redisinsight_startup Registered SIGTERM handler
INFO 2020-09-02 11:46:20,689 redisinsight_startup Starting webserver...
INFO 2020-09-02 11:46:20,689 redisinsight_startup Visit http://0.0.0.0:8001 in your web browser. Press CTRL-C to exit.
还有服务端点(来自 minikube):
$ minikube service list
|----------------------|------------------------------------|--------------|-------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|----------------------|------------------------------------|--------------|-------------------------|
| default | kubernetes | No node port |
| default | redisinsight-http | 80 | http://172.17.0.2:30860 |
| kube-system | ingress-nginx-controller-admission | No node port |
| kube-system | kube-dns | No node port |
| kubernetes-dashboard | dashboard-metrics-scraper | No node port |
| kubernetes-dashboard | kubernetes-dashboard | No node port |
|----------------------|------------------------------------|--------------|-------------------------|
顺便说一句,如果你根本不想创建服务(这与问题无关),你可以做端口转发:
kubectl port-forward <redisinsight-pod-name> 8001:8001
根据当前文档的建议,k8s 中的 redisinsight 运行ning 存在几个问题。我将在下面列出它们:
- 建议使用emptyDir 问题:Emptydir 很可能 运行 out of space 对于更大的 redis 集群 解决方案:使用持久卷
- redisinsight docker container uses a redisinsight use 问题:redisinsight 用户不绑定到特定的 uid。因此,无法以允许访问 pvc 的方式设置持久卷权限 解决方案:使用 cryptexlabs/redisinsight:latest 扩展 redislabs/redisinsight:latest 但将 redisinsight 的 uid 设置为 777
- 默认权限不允许访问 redisinsight 问题:redisinsight 将无法访问 /db 目录 解决方案:使用init容器设置目录权限,让用户777拥有/db目录
- 建议使用节点端口进行服务 问题:这是一个安全漏洞 解决方案:改为使用 ClusterIP,然后使用 kubectl portforwarding 获得对 redisinsight 的访问权或其他安全访问权
- 在本地访问 rdb 文件是不切实际的。 问题:大型集群的 rdb 文件必须通过 kubectl 下载和上传 解决方案:使用s3方案。如果您在 EKS 集群中使用 kube2iam,则需要创建一个可以访问存储桶的特殊角色。在此之前,您必须创建集群的备份,然后按照以下说明导出备份:https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html
总结 Redisinsight 是一个很好的工具。但目前 运行 洞察 kubernetes 集群绝对是一场噩梦,我