【问题标题】:Kubernetes Access service nextcloud from /nextcloudKubernetes 从 /nextcloud 访问服务 nextcloud
【发布时间】:2021-11-24 19:31:56
【问题描述】:

我正在尝试使用 Kubernetes 托管我自己的 Nextcloud 服务器。

我希望从 http://localhost:32738/nextcloud 访问我的 Nextcloud 服务器,但每次我访问该 URL 时,它都会重定向到 http://localhost:32738/login 并给我 404 Not Found

如果我将路径替换为:

path: /

然后,它在http://localhost:32738/login 上没有问题,但正如我所说,这不是我正在寻找的解决方案。登录页面应从http://localhost:32738/nextcloud/login访问。

转到http://127.0.0.1:32738/nextcloud/ 确实适用于初始设置,但之后它变得无法访问,因为它总是重定向到:

http://127.0.0.1:32738/apps/dashboard/

而不是:

http://127.0.0.1:32738/nextcloud/apps/dashboard/

这是我的 yaml:

#Nextcloud-Dep
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud-server
  labels:
    app: nextcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      pod-label: nextcloud-server-pod
  template:
    metadata:
      labels:
        pod-label: nextcloud-server-pod
    spec:
      containers:
      - name: nextcloud
        image: nextcloud:22.2.0-apache
        env:
        - name: POSTGRES_DB
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-name
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-password
        - name: POSTGRES_HOST
          value: nextcloud-database:5432
        volumeMounts:
        - name: server-storage
          mountPath: /var/www/html
          subPath: server-data
      volumes:
      - name: server-storage
        persistentVolumeClaim:
          claimName: nextcloud
---
#Nextcloud-Serv
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-server
  labels:
    app: nextcloud
spec:
  selector:
    pod-label: nextcloud-server-pod
  ports:
  - port: 80
    protocol: TCP
    name: nextcloud-server
---
#Database-Dep
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextcloud-database
  labels:
    app: nextcloud
spec:
  replicas: 1
  selector:
    matchLabels:
      pod-label: nextcloud-database-pod
  template:
    metadata:
      labels:
        pod-label: nextcloud-database-pod
    spec:
      containers:
      - name: postgresql
        image: postgres:13.4
        env:
        - name: POSTGRES_DATABASE
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-name
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-username
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-password
        - name: POSTGRES_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: nextcloud
              key: db-rootpassword
        - name: PGDATA
          value: /var/lib/postgresql/data/
        volumeMounts:
        - name: database-storage
          mountPath: /var/lib/postgresql/data/
          subPath: data
      volumes:
      - name: database-storage
        persistentVolumeClaim:
          claimName: nextcloud
---
#Database-Serv
apiVersion: v1
kind: Service
metadata:
  name: nextcloud-database
  labels:
    app: nextcloud
spec:
  selector:
    pod-label: nextcloud-database-pod
  ports:
  - port: 5432
    protocol: TCP
    name: nextcloud-database
---
#PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nextcloud-pv
  labels:
    type: local
spec:
  capacity:
    storage: 8Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp"
---
#PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nextcloud
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
---
#Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nextcloud-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - http:
      paths:
      - backend:
          service:
            name: nextcloud-server
            port:
              number: 80
        pathType: Prefix
        path: /nextcloud(/.*)
---
#Secret
apiVersion: v1
kind: Secret
metadata:
  name: nextcloud
  labels:
    app: nextcloud
immutable: true
stringData:
  db-name: nextcloud
  db-username: nextcloud
  db-password: changeme
  db-rootpassword: longpassword
  username: admin
  password: changeme

ingress-nginx 安装时:

helm install nginx ingress-nginx/ingress-nginx

如果您希望我提供更多信息,请告诉我。

【问题讨论】:

    标签: docker kubernetes kubernetes-ingress nginx-ingress nextcloud


    【解决方案1】:

    在您的情况下,后端服务中公开的 URL 与 Ingress 规则中的指定路径之间存在差异。这就是你得到错误的原因。

    为避免这种情况,您可以使用重写规则。

    使用该方法,您的入口路径将被重写为您提供的值。 这个注解ingress.kubernetes.io/rewrite-target: /login会在将请求发送到后端服务之前将URL/nextcloud/login重写为/login

    但是:

    从版本 0.22.0 开始,使用注解 nginx.ingress.kubernetes.io/rewrite-target 的入口定义与以前的版本不向后兼容。

    this documentation 上,您可以找到以下示例:

    $ echo '
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /$2
      name: rewrite
      namespace: default
    spec:
      rules:
      - host: rewrite.bar.com
        http:
          paths:
          - backend:
              serviceName: http-svc
              servicePort: 80
            path: /something(/|$)(.*)
    ' | kubectl create -f -
    

    在此入口定义中,(.*) 捕获的任何字符都将分配给占位符 $2,然后将其用作 rewrite-target 注释中的参数。

    因此,在您的 URL 中,您可能会看到想要的 /nextcloud/login,但重写会导致在 Ingress 规则中将路径更改为 /login 并找到您的后端。我建议使用以下选项之一:

    path: /nextcloud(/.*)
    
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    

    path: /nextcloud/login
    
    nginx.ingress.kubernetes.io/rewrite-target: /login
    

    另见this article

    【讨论】:

    • 您好!谢谢你的回答。该服务仍然无法访问,因为即使指定了这些参数,它仍然会重定向到 /apps... 等等。 /nextcloud 被删除。我已经发布了我的 yamls,也许它在某种程度上有所帮助。
    • “/nextcloud 被删除”是什么意思?