简体   繁体   English

在 kubernetes 中使用持久卷重新分析

[英]redisinsights with persistent volume in kubernetes

I have the following .yaml file to install redisinsights in kubernetes, with persistence support.我有以下.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

However, it fails to launch and gives an error:但是,它无法启动并给出错误:

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'

But the same docker image, when run locally via docker as:但是相同的 docker 映像,当通过 docker 在本地运行时:

docker run -v redisinsight:/db -p 8001:8001 redislabs/redisinsight

works fine.工作正常。 What am I doing wrong?我究竟做错了什么?

It feels like redisinsights is trying to read port as an int but somehow gets a string and is confused.感觉就像 redisinsights 试图将端口读取为 int 但不知何故得到一个字符串并且感到困惑。 But I cannot understand how this works fine the local docker run.但我无法理解本地 docker 运行如何正常工作。

UPDATE:更新:

RedisInsight's kubernetes documentation has been updated recently. RedisInsight 的kubernetes 文档最近更新了。 It clearly describes how to create a RedisInsight k8s deployment with and without a service.它清楚地描述了如何创建带有和不带有服务的 RedisInsight k8s 部署。

IT also explains what to do when there's a service named "redisinsight" already: IT 还解释了当已经存在名为“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.注意 - 如果部署将由名为“redisinsight”的服务公开,请设置 REDISINSIGHT_HOST 和 REDISINSIGHT_PORT 环境变量以覆盖服务创建的环境变量。


The problem is with the name of the service.问题在于服务的名称。

From thedocumentation , it is mentioned that RedisInsight has an environment variable REDISINSIGHT_PORT which can configure the port in which RedisInsight can run.文档中提到,RedisInsight 有一个环境变量REDISINSIGHT_PORT可以配置 RedisInsight 可以运行的端口。

When you create a service in Kubernetes, all the pods that match the service, gets an environment variable <SERVICE_NAME>_PORT=<SERVICE_IP>:<SERVICE_PORT> .当您在 Kubernetes 中创建服务时,所有匹配该服务的 pod 都会获取一个环境变量<SERVICE_NAME>_PORT=<SERVICE_IP>:<SERVICE_PORT>

So when you try to create the above mentioned service with name redisinsight , Kubernetes passes the service environment variable REDISINSIGHT_PORT=<SERVICE_IP>:SERVICE_PORT .因此,当您尝试创建名为redisinsight的上述服务时,Kubernetes 会传递服务环境变量REDISINSIGHT_PORT=<SERVICE_IP>:SERVICE_PORT But the port environment variable ( REDISINSIGHT_PORT ) is documented to be a port number and not an endpoint which makes the pod to crash when redisinsight running on the pod tries to use the environment variable as the port number.但是端口环境变量( REDISINSIGHT_PORT )被记录为端口号而不是端点,当在 Pod 上运行的 redisinsight 尝试使用环境变量作为端口号时,这会使 Pod 崩溃。

So change the name of the service to be something different and not redisinsight and it should work.因此,将服务的名称更改为不同的名称,而不是redisinsight ,它应该可以工作。

Here's a quick deployment and service file:这是一个快速部署和服务文件:

Deployment:部署:

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

Service:服务:

apiVersion: v1
kind: Service
metadata:
  name: redisinsight-http # name should not be redisinsight 
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8001
  selector:
    app: redisinsight

Please note the name of the service.请注意服务的名称。

Logs of redisinsight pod: 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.

Also the service end point (from minikube):还有服务端点(来自 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 |
|----------------------|------------------------------------|--------------|-------------------------|

BTW, If you don't want to create a service at all (which is not related the question), you can do port forwarding:顺便说一句,如果您根本不想创建服务(这与问题无关),您可以进行端口转发:

kubectl port-forward <redisinsight-pod-name> 8001:8001

Problem is related to service, as it's interfering with the pod causing it to crash.问题与服务有关,因为它干扰了pod导致它崩溃。

As we can read in the Redis docs Installing RedisInsight on Kubernetes正如我们在 Redis 文档中所读到的 在Kubernetes 上安装 RedisInsight

  1. Once the deployment has been successfully applied and the deployment complete, access RedisInsight.成功应用部署并完成部署后,访问 RedisInsight。 This can be accomplished by exposing the deployment as a K8s Service or by using port forwarding, as in the example below:这可以通过将部署公开为 K8s 服务或使用端口转发来实现,如下例所示:

kubectl port-forward deployment/redisinsight 8001

Open your browser and point to http://localhost:8001打开浏览器并指向 http://localhost:8001

Or a service which in your case while using GCP can look like this:或者在您的情况下使用 GCP 的服务可能如下所示:

apiVersion: v1
kind: Service
metadata:
  name: redisinsight
spec:
  ports:
    - protocol: TCP
      port: 8001
      targetPort: 8001
      name: redisinsight
  type: LoadBalancer
  selector:
    app: redisinsight

Once the service receives the External-IP you can use it to access Redis.服务收到外部 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

via http://34.67.171.112:8001/ in my example.通过http://34.67.171.112:8001/在我的示例中。

It happens to me too.它也发生在我身上。 In case anyone miss the conversation in the comments, here is the solution.如果有人错过评论中的对话,这里是解决方案。

  1. Deploy the redisinsight pod first and wait until it run successfully.先部署 redisinsight pod,等到它运行成功。

  2. Deploy the service.部署服务。

I think this is a bug and it is not really working because a pod can die anytime.我认为这是一个错误,它并没有真正起作用,因为 pod 随时可能死亡。 It is kinda against the reason of using Kubernetes.这有点违背使用 Kubernetes 的原因。

Someone have reported this issue here https://forum.redislabs.com/t/redisinsight-fails-to-launch-in-kubernetes/652/2有人在这里报告了这个问题https://forum.redislabs.com/t/redisinsight-fails-to-launch-in-kubernetes/652/2

There are several problems with redisinsight running in k8s as suggested by the current documentation.根据当前文档的建议,在 k8s 中运行 redisinsight 存在几个问题。 I will list them below:我将在下面列出它们:

  1. Suggestion is to use emptyDir Issue: Emptydir will most likely run out of space for larger redis clusters Solution: Use persistent volume建议使用 emptyDir 问题:对于较大的 redis 集群,Emptydir 很可能会用完空间 解决方案:使用持久卷
  2. redisinsight docker container uses a redisinsight use Issue: redisinsight users does not ties to a specific uid. redisinsight docker 容器使用 redisinsight 使用问题:redisinsight 用户不绑定到特定的 uid。 For this reason the persistent volume permissions cannot be set in a way that allows access to a pvc Solution: use cryptexlabs/redisinsight:latest which extends redislabs/redisinsight:latest but set uid for redisinsight to 777因此,无法以允许访问 pvc 的方式设置持久卷权限 解决方案:使用 cryptexlabs/redisinsight:latest 扩展 redislabs/redisinsight:latest 但将 redisinsight 的 uid 设置为 777
  3. default permissions do not allow access for redisinsight Issue: redisinsight will not be able to access the /db directory Solution: Use init container to set the directory permissions so that user 777 owns the /db directory默认权限不允许 redisinsight 访问问题:redisinsight 将无法访问 /db 目录解决方案:使用 init 容器设置目录权限,以便用户 777 拥有 /db 目录
  4. Suggestion is to use a nodeport for service Issue: this is a security hole Solution: Use ClusterIP instead and then use kubectl portforwarding to gain access or other secure access to redisinsight建议使用 nodeport 进行服务 问题:这是一个安全漏洞 解决方案:使用 ClusterIP 代替,然后使用 kubectl portforwarding 来获得访问权限或其他安全访问 redisinsight
  5. Accessing rdb files locally is impractical.在本地访问 rdb 文件是不切实际的。 Problem: rdb files for large clusters must be downloaded and uploaded via the kubectl Solution: Use the s3 solution.问题:大型集群的 rdb 文件必须通过 kubectl 下载和上传解决方案:使用 s3 解决方案。 If you are using kube2iam in an EKS cluster you'll need to create a special role that has access the bucket.如果您在 EKS 集群中使用 kube2iam,您需要创建一个可以访问存储桶的特殊角色。 Before that you must create a backup of your cluster and then export the backup following these instructions: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html在此之前,您必须创建集群备份,然后按照以下说明导出备份: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/backups-exporting.html

Summary Redisinsight is a good tool.总结 Redisinsight 是一个很好的工具。 But currently running it insight kubernetes cluster is an absolute nightmare and I t但目前运行它的洞察力 kubernetes 集群绝对是一场噩梦,而且它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM