前言
由于实验室需要内部共享存储来统一管理文档,故而在 K3s 中部署 Nextcloud,并接入 FreeIPA 管理用户认证和用户组权限。
之前的NAS 折腾日记(1)容器化部署 nextcloud介绍了 QNAP Container Station 下的 Compose 部署。本篇使用服务器操作指北(8)FreeIPA、K3s 部署与 HTTPS 证书配置中的集群和 HTTPS 入口,记录持久卷、数据库、后台任务、LDAP 及共享目录的配置。代码仓库的部署参考服务器操作指北(9)Gitea 部署与 FreeIPA 认证配置。
本文以 Nextcloud 32.0.2、MariaDB 10.6.24 为基础,采用 Apache 镜像,并介绍 Redis、后台任务和组文件夹的配置。新安装时应检查版本维护状态与插件兼容性。文中域名、目录、节点和端口均为示例,使用时自行修改。
- 20260919:补充部署前检查、初始化与后台任务顺序、独立 LDAP 查询账户、共享目录操作和文件读写检查。
本篇只依赖第8篇完成的 K3s、FreeIPA、内部 DNS 和 Traefik 正式证书,不要求先安装 Gitea。命令默认在已入域的控制节点 host-a 执行;网页和文件操作另行标注。先确认基础服务:
bash1234567sudo apt update sudo apt install -y ldap-utils openssl curl sudo k3s kubectl get nodes getent hosts ipa.lab.example.com getent hosts files.lab.example.com test -r /etc/ipa/ca.crt curl -I https://files.lab.example.com:8443/
业务还未部署时允许返回 404,但不应有证书错误或连接超时。浏览器所在电脑也需要使用能解析内网区域的 DNS。
一、部署方案
1.1 使用 K3s 管理服务
服务器已经部署 K3s,因此 Nextcloud 复用现有 Traefik 入口和证书,通过 Service 连接数据库,使用 Secret 保存凭据、PVC 挂载数据。应用、数据库和后台任务的配置统一保存在 Kubernetes 清单中。
本例使用单副本 Nextcloud 和单实例 MariaDB,local PV 固定到数据节点。重建 Pod 后重新挂载原目录,节点故障时仍需恢复该节点或从备份恢复数据,不具备跨节点存储高可用。
1.2 组件配置
| 组件 | 用途 | 数据保存方式 |
|---|---|---|
| Nextcloud Apache | 网页、同步客户端与 WebDAV 接口 | /var/www/html 挂载 PVC |
| MariaDB | 用户映射、文件索引和共享配置 | /var/lib/mysql 挂载 PVC |
| Redis | 缓存与事务文件锁 | 本例不持久化 |
| Cron | 执行 Nextcloud 后台任务 | 与网页容器共用应用卷 |
| FreeIPA | LDAP 用户认证和组查询 | 使用现有服务 |
| Traefik | HTTPS 反向代理 | 使用现有证书配置 |
Nextcloud 保存共享文档,代码与实验脚本使用 Gitea 管理。大型原始数据集按容量和读写需求另行规划。Office 在线编辑需要另外部署 Collabora 或 ONLYOFFICE,本篇不包含该部分。
二、准备持久卷与数据库
2.1 数据目录与 PVC
示例命名空间为 nextcloud,数据节点为 host-a。在该节点创建两个目录:
bash123456789sudo k3s kubectl create namespace nextcloud sudo install -d -m 0750 /srv/example/nextcloud-html sudo install -d -m 0750 /srv/example/nextcloud-db # Debian Apache 镜像中的 www-data 为 UID/GID 33 sudo chown 33:33 /srv/example/nextcloud-html findmnt -T /srv/example/nextcloud-html findmnt -T /srv/example/nextcloud-db
应用卷挂载到 /var/www/html,包含配置、应用及默认 data 目录;数据库卷挂载到 /var/lib/mysql。磁盘应先正常挂载,防止同名空目录实际落在根文件系统。
保存为 nextcloud-storage.yaml:
yaml1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465apiVersion: v1 kind: PersistentVolume metadata: name: example-nextcloud-html spec: capacity: storage: 200Gi accessModes: [ReadWriteOnce] persistentVolumeReclaimPolicy: Retain storageClassName: "" local: path: /srv/example/nextcloud-html nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: [host-a] --- apiVersion: v1 kind: PersistentVolume metadata: name: example-nextcloud-db spec: capacity: storage: 20Gi accessModes: [ReadWriteOnce] persistentVolumeReclaimPolicy: Retain storageClassName: "" local: path: /srv/example/nextcloud-db nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: [host-a] --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nextcloud-html namespace: nextcloud spec: accessModes: [ReadWriteOnce] storageClassName: "" volumeName: example-nextcloud-html resources: requests: storage: 200Gi --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nextcloud-db namespace: nextcloud spec: accessModes: [ReadWriteOnce] storageClassName: "" volumeName: example-nextcloud-db resources: requests: storage: 20Gi
bash12sudo k3s kubectl apply -f nextcloud-storage.yaml sudo k3s kubectl -n nextcloud get pvc
容量按实际磁盘空间修改。local PV 的容量字段不是目录配额,Nextcloud 中的用户与共享目录配额仍需单独设置。Retain 用于保留卷数据,不承担备份功能。
2.2 生成初始凭据
数据库 root、应用数据库用户和 Nextcloud 本地管理员使用不同密码。下面只用于全新安装,避免把实际密码写进 YAML:
bash123456789101112sudo install -d -m 0700 /root/example-nextcloud sudo sh -c ' umask 077 for name in db-root db-password admin-password; do openssl rand -hex 32 | tr -d "\n" > "/root/example-nextcloud/$name" done ' sudo k3s kubectl -n nextcloud create secret generic nextcloud-auth \ --from-file=db-root=/root/example-nextcloud/db-root \ --from-file=db-password=/root/example-nextcloud/db-password \ --from-file=admin-password=/root/example-nextcloud/admin-password
初始化后修改这些文件或 Secret,不会自动修改数据库和管理员账户密码。后续轮换需同步修改应用中的实际凭据。
2.3 部署 MariaDB
保存为 nextcloud-db.yaml:
yaml123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869apiVersion: apps/v1 kind: Deployment metadata: name: nextcloud-db namespace: nextcloud spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nextcloud-db template: metadata: labels: app: nextcloud-db spec: nodeSelector: kubernetes.io/hostname: host-a containers: - name: mariadb image: mariadb:10.6.24 args: - --transaction-isolation=READ-COMMITTED - --binlog-format=ROW env: - name: MARIADB_DATABASE value: nextcloud - name: MARIADB_USER value: nextcloud - name: MARIADB_PASSWORD valueFrom: secretKeyRef: name: nextcloud-auth key: db-password - name: MARIADB_ROOT_PASSWORD valueFrom: secretKeyRef: name: nextcloud-auth key: db-root ports: - name: mysql containerPort: 3306 readinessProbe: exec: command: [healthcheck.sh, --connect, --innodb_initialized] initialDelaySeconds: 15 periodSeconds: 10 volumeMounts: - name: db mountPath: /var/lib/mysql volumes: - name: db persistentVolumeClaim: claimName: nextcloud-db --- apiVersion: v1 kind: Service metadata: name: nextcloud-db namespace: nextcloud spec: type: ClusterIP selector: app: nextcloud-db ports: - name: mysql port: 3306 targetPort: mysql
bash12sudo k3s kubectl apply -f nextcloud-db.yaml sudo k3s kubectl -n nextcloud rollout status deployment/nextcloud-db
数据库只通过集群 Service 提供连接,不映射公网端口。ClusterIP 也不是访问隔离或传输加密,如果集群运行不受信任的任务,需要按实际 CNI 配置 NetworkPolicy,并按需求增加数据库 TLS。
三、部署 Nextcloud 与后台任务
3.1 准备 IPA CA
PHP LDAP 使用的证书信任需要在容器内配置。从已入域的可信客户端取得 /etc/ipa/ca.crt,核对指纹后创建 ConfigMap:
bash123openssl x509 -in /etc/ipa/ca.crt -noout -subject -fingerprint -sha256 sudo k3s kubectl -n nextcloud create configmap ipa-ca \ --from-file=ipa-ca.crt=/etc/ipa/ca.crt
下面用 initContainer 合并镜像自带 CA 和 IPA CA,网页与 Cron 容器使用同一证书文件。只导入 CA 公共证书,不复制私钥,也不关闭 LDAPS 校验。
3.2 应用、Redis 与 Cron
本例采用同一个 Pod 中的三个容器:Apache 提供网页,Redis 用于缓存与事务文件锁,Cron 处理后台任务。Redis 仅监听 Pod 的回环地址,避免另外暴露一个无认证的 Redis Service。它不保存用户文件,示例关闭 Redis 数据持久化。
所有容器固定到持久卷所在节点,应用采用 Recreate。Cron 与网页容器共用 /var/www/html,不会因调度到另一台机器而读到不同的数据目录。镜像配置方式参考 Nextcloud 容器项目。
保存为 nextcloud-app.yaml:
yaml123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131apiVersion: apps/v1 kind: Deployment metadata: name: nextcloud namespace: nextcloud spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nextcloud template: metadata: labels: app: nextcloud spec: nodeSelector: kubernetes.io/hostname: host-a initContainers: - name: prepare-ca image: nextcloud:32.0.2-apache command: [/bin/sh, -ec] args: - | cat /etc/ssl/certs/ca-certificates.crt /ipa/ipa-ca.crt > /trust/ca-certificates.crt chmod 0644 /trust/ca-certificates.crt volumeMounts: - name: ipa-ca mountPath: /ipa readOnly: true - name: trust mountPath: /trust containers: - name: nextcloud image: nextcloud:32.0.2-apache env: &nextcloud-env - name: MYSQL_HOST value: nextcloud-db - name: MYSQL_DATABASE value: nextcloud - name: MYSQL_USER value: nextcloud - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: nextcloud-auth key: db-password - name: NEXTCLOUD_ADMIN_USER value: site-admin - name: NEXTCLOUD_ADMIN_PASSWORD valueFrom: secretKeyRef: name: nextcloud-auth key: admin-password - name: NEXTCLOUD_TRUSTED_DOMAINS value: files.lab.example.com:8443 - name: OVERWRITEHOST value: files.lab.example.com:8443 - name: OVERWRITEPROTOCOL value: https - name: OVERWRITECLIURL value: https://files.lab.example.com:8443 - name: TRUSTED_PROXIES value: 10.44.0.0/16 - name: REDIS_HOST value: 127.0.0.1 - name: REDIS_HOST_PORT value: "6379" - name: LDAPTLS_CACERT value: /etc/ssl/certs/ca-certificates.crt - name: LDAPTLS_REQCERT value: demand ports: - name: http containerPort: 80 readinessProbe: httpGet: path: /status.php port: http initialDelaySeconds: 30 periodSeconds: 10 volumeMounts: &nextcloud-mounts - name: html mountPath: /var/www/html - name: trust mountPath: /etc/ssl/certs/ca-certificates.crt subPath: ca-certificates.crt readOnly: true - name: cron image: nextcloud:32.0.2-apache command: [/bin/sh, -ec] args: - | until php -r '$CONFIG=[]; @include "/var/www/html/config/config.php"; exit(empty($CONFIG["installed"]) ? 1 : 0);'; do sleep 10 done exec /cron.sh env: *nextcloud-env volumeMounts: *nextcloud-mounts - name: redis image: redis:7.4-alpine args: [redis-server, --bind, 127.0.0.1, --save, "", --appendonly, "no"] readinessProbe: exec: command: [redis-cli, ping] initialDelaySeconds: 5 periodSeconds: 10 volumes: - name: html persistentVolumeClaim: claimName: nextcloud-html - name: ipa-ca configMap: name: ipa-ca - name: trust emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: nextcloud namespace: nextcloud spec: type: ClusterIP selector: app: nextcloud ports: - name: http port: 80 targetPort: http
YAML 中的锚点只用于让 Cron 与网页容器取得相同环境变量和挂载。Cron 会读取持久目录中的配置,其环境也需包含数据库、Redis 和反向代理参数,不能只挂载文件而遗漏镜像配置中引用的环境变量。
TRUSTED_PROXIES 必须改成实际代理来源范围,示例沿用上一篇的 Pod 网段。不能直接填任意来源。若数据节点带有 NoSchedule 污点,还需在 Pod 中补充对应 tolerations。
bash12sudo k3s kubectl apply -f nextcloud-app.yaml sudo k3s kubectl -n nextcloud logs deployment/nextcloud -c nextcloud --tail=100
首次启动会安装应用并创建 site-admin。Cron 启动命令先等待持久配置中出现 installed=true,然后交给镜像自带 /cron.sh 调度。这个等待不表示安装已成功;如果持续未就绪,检查网页容器和数据库日志,不能只看 Cron 容器处于 Running。
bash123sudo k3s kubectl -n nextcloud rollout status deployment/nextcloud --timeout=600s sudo k3s kubectl -n nextcloud get pods sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c redis -- redis-cli ping
Redis 应返回 PONG。后续管理命令通过镜像中的 www-data 执行:
bash12345sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ status' sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ background:cron'
确认 installed: true、非维护模式,数据库无需升级后再公开入口。/status.php 的 readiness 只能反映网页状态,不能替代这个安装状态检查。后台任务选择 Cron,并在管理页面确认最近执行时间会更新;官方镜像的 /cron.sh 提供调度,不需要进入正在运行的容器临时安装 cron。参见 后台任务配置。
本例 Redis 随整个 Pod 重建而重启,缓存和锁状态会丢失;它适用于这里的单副本安排。以后扩展多副本时必须重新设计共享文件存储、公共 Redis、会话与任务执行方式,不能只把 replicas 改成 2。
3.3 接入 Traefik
沿用上一篇的 business 入口和默认公共证书,保存为 nextcloud-route.yaml:
yaml1234567891011121314apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: nextcloud namespace: nextcloud spec: entryPoints: [business] routes: - match: Host(`files.lab.example.com`) kind: Rule services: - name: nextcloud port: 80 tls: {}
bash12sudo k3s kubectl apply -f nextcloud-route.yaml curl -IL https://files.lab.example.com:8443/
打开 https://files.lab.example.com:8443/,使用 site-admin 登录。初始密码保存在控制节点的 /root/example-nextcloud/admin-password;在可信终端执行 sudo cat /root/example-nextcloud/admin-password 读取后录入密码管理器,不分享终端输出。这个本地管理员用于维护 LDAP 和应用,不是 FreeIPA 的 admin。
内网 DNS 为业务名称返回内部地址,成员在内网直接访问内部入口。“内部共享”指成员与权限范围,并不要求对所有外网用户开放注册或匿名下载。若需要外部访问,复用已有 HTTPS 转发,同时保留登录和共享限制。
overwritehost、overwriteprotocol 和 overwrite.cli.url 使网页、WebDAV 与后台生成的地址保持一致。使用环境变量配置后,应修改 Deployment 中的值,避免只改 config.php 后被原环境覆盖。详细含义见 反向代理配置。
上传较大文件时还要检查 PHP 上传限制、Apache 请求体限制和代理超时。用实际文件验证浏览器和 WebDAV 上传,不因首页返回 200 就认为大文件路径已经通过。
四、接入 FreeIPA 用户与用户组
4.1 查询账户与成员组
为 Nextcloud 建立独立的查询账户,无需先部署 Gitea。在已入域的控制节点先执行 umask 077,用编辑器创建 nextcloud-bind.ldif,替换示例域名和随机密码:
ldif12345678dn: uid=nextcloud-bind,cn=sysaccounts,cn=etc,dc=lab,dc=example,dc=com changetype: add objectClass: account objectClass: simpleSecurityObject uid: nextcloud-bind userPassword: REPLACE_WITH_A_UNIQUE_PASSWORD passwordExpirationTime: 20380119031407Z nsIdleTimeout: 0
将密码保存到密码管理器,按实际轮换周期设置有效期。导入时使用 Directory Manager 密码,不是 IPA admin 的密码:
bash1234chmod 0600 nextcloud-bind.ldif LDAPTLS_CACERT=/etc/ipa/ca.crt ldapmodify \ -H ldaps://ipa.lab.example.com:636 \ -x -D 'cn=Directory Manager' -W -f nextcloud-bind.ldif
导入成功后删除已不再需要的明文 LDIF。该系统账户用于目录查询,不与其他应用共用密码,也不加入管理员组。环境定制过 LDAP ACI 时,需确认它可读取所需用户、组和成员关系。
本例以 lab-members 控制谁可以登录,再按项目区分共享目录权限:
bash123456789# 在已配置 IPA CLI 的管理环境执行 kinit admin ipa group-add lab-members --desc='Laboratory members' ipa group-add lab-project-a --desc='Project A members' ipa group-add lab-doc-maintainers --desc='Shared document maintainers' ipa group-add-member lab-members --users=yourname ipa group-add-member lab-project-a --users=yourname ipa group-add-member lab-doc-maintainers --users=yourname
yourname 是第8篇已经创建并完成首次密码修改的 IPA 用户。用 ipa user-show yourname --all 核对邮箱、姓名与锁定状态;不要在 Nextcloud 中预先创建同名本地账户。项目成员也需属于登录允许组,本例先使用直接成员关系。
在填写 Nextcloud 页面前,使用新建的绑定账户验证查询。以下 -W 输入 nextcloud-bind 密码:
bash12345678910111213LDAPTLS_CACERT=/etc/ipa/ca.crt ldapsearch \ -H ldaps://ipa.lab.example.com:636 \ -x -D 'uid=nextcloud-bind,cn=sysaccounts,cn=etc,dc=lab,dc=example,dc=com' -W \ -b 'cn=users,cn=accounts,dc=lab,dc=example,dc=com' \ '(&(objectClass=posixAccount)(uid=yourname)(memberOf=cn=lab-members,cn=groups,cn=accounts,dc=lab,dc=example,dc=com)(!(nsAccountLock=TRUE)))' \ dn uid cn mail ipaUniqueID memberOf LDAPTLS_CACERT=/etc/ipa/ca.crt ldapsearch \ -H ldaps://ipa.lab.example.com:636 \ -x -D 'uid=nextcloud-bind,cn=sysaccounts,cn=etc,dc=lab,dc=example,dc=com' -W \ -b 'cn=groups,cn=accounts,dc=lab,dc=example,dc=com' \ '(&(objectClass=groupOfNames)(|(cn=lab-members)(cn=lab-project-a)(cn=lab-doc-maintainers)))' \ dn cn member ipaUniqueID
应分别返回该成员和三个组,组的 member 中包含预期用户 DN。无结果时先修正目录属性或权限,再继续页面配置。
4.2 启用 LDAP 应用
bash12sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ app:enable user_ldap'
用 site-admin 登录,在右上角头像菜单进入“管理设置 → LDAP / AD 整合”,选择新建配置。按 Nextcloud 32 LDAP 文档填写服务器信息:
| 字段 | 示例 |
|---|---|
| 主机 | ldaps://ipa.lab.example.com |
| 端口 | 636 |
| 用户 DN | uid=nextcloud-bind,cn=sysaccounts,cn=etc,dc=lab,dc=example,dc=com |
| 密码 | 独立查询账户密码 |
| Base DN | dc=lab,dc=example,dc=com |
| Base User Tree | cn=users,cn=accounts,dc=lab,dc=example,dc=com |
| Base Group Tree | cn=groups,cn=accounts,dc=lab,dc=example,dc=com |
这里的 Host 可以填写 ldaps:// URI,与 Gitea 页面中的主机字段格式不同。使用 LDAPS 时不再额外开启 StartTLS。保持证书校验,容器中也不要设置 TLS_REQCERT NEVER 或 ALLOW 来跳过错误。
4.3 分别配置用户枚举和登录过滤器
Nextcloud 的“用户”页决定列出哪些用户,“登录属性”页决定如何匹配登录输入。两处原始过滤器分别配置,不能照搬 Gitea 的单个登录过滤器。
用户过滤器中不使用登录名占位符:
text1(&(objectClass=posixAccount)(memberOf=cn=lab-members,cn=groups,cn=accounts,dc=lab,dc=example,dc=com)(!(nsAccountLock=TRUE)))
登录过滤器在相同范围上增加登录名匹配:
text1(&(objectClass=posixAccount)(memberOf=cn=lab-members,cn=groups,cn=accounts,dc=lab,dc=example,dc=com)(!(nsAccountLock=TRUE))(uid=%uid))
Nextcloud 使用 %uid,Gitea 使用 %[1]s。这里也不是 %uid%,末尾不能再加一个百分号。写错后可能出现 LDAP 绑定成功,但找不到用户或登录失败的情况。
如果允许邮箱登录,将 (uid=%uid) 改成 (|(uid=%uid)(mail=%uid))。需要确保用户的 mail 属性有效,并继续保留组和锁定状态限制。
4.4 稳定标识与组属性
在高级设置中配置以下字段,首次导入用户前完成确认:
| 用途 | 配置 |
|---|---|
| 用户显示名称 | cn |
| 用户搜索属性 | uid、cn、mail,逐项确认实际存在 |
| 邮箱属性 | mail |
| 用户 UUID 属性 | ipaUniqueID |
| 组显示名称 | cn |
| 组成员关联属性 | member |
Nextcloud 内部用户 ID 用于关联文件和共享记录,应保持稳定。ipaUniqueID 用于标识目录对象,显示名称只是展示用途;不要在用户已经开始存文件后随意更换 UUID 属性或内部用户名映射。
在“组”页限制导入实验室使用的组,例如:
text1(&(objectClass=groupOfNames)(|(cn=lab-members)(cn=lab-project-a)(cn=lab-doc-maintainers)))
导入后确认各组实际成员正确,不把所有 IPA 管理组顺带映射成 Nextcloud 管理员。
在高级设置中确认 Configuration Active 已启用,测试连接成功,并检查“用户”和“组”页统计结果符合预期。配置完成后可检查认证源。s01 为示例 ID,先查询当前配置:
bash12345sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ ldap:show-config' sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ ldap:test-config s01'
配置输出包含内部地址和 DN,不宜原样公开。测试通过后,用普通成员验证登录,再用不属于 lab-members 的测试账户检查访问限制。同步与缓存可能影响变更生效时间,不能只根据用户列表瞬间变化来判断权限结果。
五、配置实验室共享目录
5.1 安装 Group folders
实验室公共目录使用 Group folders 由管理员创建,并关联 FreeIPA 用户组。个人文件继续保存在各自账户下。
可安装与 Nextcloud 32 兼容的 Group folders 应用,应用 ID 为 groupfolders,不同版本界面可能显示组文件夹或团队文件夹。安装前检查兼容版本,下面命令使用应用商店为当前服务器选择的版本:
bash12sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ app:install groupfolders'
如果已经安装,使用 app:enable groupfolders。先执行下面命令记录安装版本与 Nextcloud 实际看到的组:
bash1234sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ app:list' sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ group:list'
若应用商店提示不兼容或下载失败,先解决兼容性或网络问题,不加 --force 强行安装。下面的界面操作在“管理设置 → 团队文件夹/组文件夹”完成:
- 输入“公共模板与使用说明”,点击创建;先设一个适合测试的配额,例如 1 GB。
- 为该目录添加已导入的
lab-members,保留读取,取消写入、创建、删除和分享权限。 - 再添加
lab-doc-maintainers,允许读取、写入、创建和删除。维护成员同时属于两个组时,检查实际合并后的权限。 - 新建“项目 A”,添加
lab-project-a,允许读取、写入、创建;删除和分享根据项目需求开启。 - 保存后退出管理员账户,用普通成员重新登录“文件”页面,确认目录出现。只在应用界面授权,不直接对宿主 data 目录执行 chmod 来分配成员权限。
初始权限可整理为:
| 目录 | 访问组 | 权限安排 |
|---|---|---|
| 公共模板与使用说明 | lab-members |
读取;维护组负责修改 |
| 项目 A | lab-project-a |
成员读写;共享与删除按项目需要分配 |
| 公共资料归档 | 指定成员组 | 读取;管理员负责整理和归档 |
共享目录按用途配置配额。高级 ACL 有自己的权限合并规则,实际权限应使用普通账户验证,尤其是同时属于多个组的用户。不要依赖一个“拒绝”选项去推断所有组合下都无法访问。
5.2 配置共享权限
在“管理设置 → 共享”中配置公开链接、转分享和用户搜索范围。内部资料使用用户或组分享;需要公开链接时,设置密码、有效期及允许的操作。
FreeIPA 的 lab-members 组控制登录范围,项目组控制共享目录访问。分别使用项目成员和非项目成员测试读取、上传、删除与分享权限。
5.3 调整成员权限
新增成员时,在 FreeIPA 中加入 lab-members 及对应项目组。移除成员时,同步检查 Nextcloud 会话、应用密码和分享链接;LDAP 组变更不一定立即终止已有会话。
删除 Nextcloud 用户前,先转移需要保留的个人文件并完成备份。管理员创建的组文件夹单独维护,不依赖个人分享链接。
5.4 客户端与文件导入
客户端按需选择同步目录。设置存储容量时,为文件版本和回收站预留空间。
文件通过网页、客户端或 WebDAV 导入,避免直接修改 data 目录导致文件与数据库索引不一致。接入已有 NAS 目录时,使用 External storage 应用另外配置挂载和访问权限。
六、后台检查与备份
6.1 检查实际配置
运行状态可以通过 occ 查看,Redis 文件锁配置也应检查是否生效:
bash1234567sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ status' sudo k3s kubectl -n nextcloud exec deployment/nextcloud -c nextcloud -- \ su -s /bin/sh www-data -c 'php /var/www/html/occ config:system:get memcache.locking' sudo k3s kubectl -n nextcloud logs deployment/nextcloud -c cron --tail=100
本例锁缓存应指向 Redis。若有文件锁报错,应检查 Redis 可达性和应用配置,不要通过禁用文件锁来消除提示。
管理页面还需检查后台任务最近执行时间、数据库索引提示、HTTPS 与邮件配置。网页能打开之后,仍应测试文件上传、下载、WebDAV,以及用户组权限。
6.2 检查文件读写与持久化
使用普通 IPA 成员登录,在自己的个人目录上传 deployment-check.txt,下载后比较内容;再进入“项目 A”重复上传、改名和删除。公共模板目录应由维护成员先上传文件,再用只属于 lab-members 的成员确认可读但不可写。
需要准备另一个测试成员时,在已入域控制节点执行以下命令,然后用 kinit reader-test 完成首次密码修改。只加入登录组,暂不加入项目组或维护组:
bash123456kinit admin ipa user-add reader-test --first=Reader --last=Test --email=reader@example.com --password ipa group-add-member lab-members --users=reader-test kdestroy kinit reader-test kdestroy
验证 reader-test 看不到项目 A,能读取公共模板但不能上传、改名或删除。另建一个未加入 lab-members 的测试账户,并完成首次改密,用来检查登录拒绝;不要用尚未改密的用户代替权限测试。
WebDAV 可用个人“设置 → 安全”创建的应用密码测试。到“文件 → 文件设置”复制实际 WebDAV 地址,其中的内部用户 ID 不一定等于 IPA 登录名,不要手工猜测。下面在客户端执行,替换地址与登录名,curl 会交互询问密码:
bash1234567printf 'Nextcloud deployment check\n' > deployment-check.txt curl --fail --user yourname -T deployment-check.txt \ 'https://files.lab.example.com:8443/remote.php/dav/files/ACTUAL_USER_ID/deployment-check.txt' curl --fail --user yourname \ 'https://files.lab.example.com:8443/remote.php/dav/files/ACTUAL_USER_ID/deployment-check.txt' \ -o deployment-check-downloaded.txt cmp deployment-check.txt deployment-check-downloaded.txt
随后在允许中断服务的时间重建 Pod:
bash12sudo k3s kubectl -n nextcloud rollout restart deployment/nextcloud sudo k3s kubectl -n nextcloud rollout status deployment/nextcloud --timeout=600s
重新登录,检查文件、LDAP 配置和团队目录权限仍在,再运行 6.1 的检查。后台任务最近执行时间应在后续调度后更新。
6.3 一致性备份
Nextcloud 备份需要同时包含数据库、配置、应用和文件数据。文件系统中的文件与数据库里的共享、版本和文件索引互相关联,只复制 data 目录不足以恢复服务。
安排维护窗口后,让网页与 Cron 都停止写入,再进行数据库导出和应用卷归档。本例 Cron 在同一个 Pod 中,仅暂停网页请求不足以保证没有后台写入。应用配置中的实例标识、密码盐和 Secret 也需要受限保存。
共享目录的版本和回收站有助于日常误操作恢复,但不能替代异机备份。完成首份备份后,应在隔离环境测试恢复和普通用户读取文件,避免只检查压缩包能列出文件名。
存储仍依赖数据节点,应保留异机备份,并定期进行恢复演练。
参考
支付宝
微信