1. 项目概述:企业级内容服务的基石
如果你正在寻找一个能够支撑起整个企业文档管理、协作和业务流程自动化的开源解决方案,那么 Alfresco Content Services (ACS) 绝对是一个绕不开的名字。而alfresco/acs-deployment这个项目,就是打开这扇大门的钥匙。它不是 ACS 本身,而是官方提供的、用于在各种环境下部署和运行 ACS 的“部署工具包”。简单来说,ACS 是功能强大的“大脑”,而acs-deployment则是为这个大脑搭建一个稳定、可扩展、易于管理的“身体”的蓝图和脚手架。
我接触过不少团队,他们被 Alfresco 强大的 ECM(企业内容管理)能力所吸引,却在第一步——部署上就栽了跟头。手动配置数据库、消息队列、搜索服务,再小心翼翼地编排各个容器,这个过程不仅耗时,而且极易出错,环境不一致的问题更是后期的噩梦。acs-deployment项目正是为了解决这些问题而生。它基于 Docker Compose 和 Kubernetes (K8s) 的声明式配置,将 ACS 及其所有依赖(如 PostgreSQL 数据库、ActiveMQ 消息队列、Alfresco Search Services 等)打包成一套标准化的、可复现的部署方案。无论你是想在本地开发机快速拉起一个测试环境,还是要在生产环境的 K8s 集群中构建高可用的内容服务集群,这个项目都提供了经过验证的起点。
对于开发者,它意味着可以快速获得一个与生产环境架构一致的开发沙箱;对于运维工程师,它提供了可版本化、可审计的基础设施代码;对于架构师,它展示了 Alfresco 现代化微服务架构的最佳实践。接下来,我将深入拆解这个部署项目的核心设计、实操要点以及那些官方文档里不会写的“踩坑”经验。
2. 核心架构与设计思路拆解
2.1 微服务架构下的组件拓扑
理解acs-deployment的前提是理解 ACS 7.x 之后的微服务架构。与早期版本单体应用不同,现代 ACS 被拆分为多个职责单一的微服务,通过 REST API 和消息队列进行通信。acs-deployment项目清晰地反映了这一架构。
核心服务层:
- 内容存储库 (alfresco/alfresco-content-repository):这是 ACS 的心脏,负责核心的文档存储、版本控制、权限管理和元数据服务。它通过 REST API 对外提供 CMIS 和自定义服务。
- 共享前端 (alfresco/alfresco-share):基于 Aikau 框架的传统 Web 用户界面,为用户提供文档浏览、搜索、协作等功能的交互入口。在最新版本中,Alfresco 也大力推广其基于 Angular 的Alfresco Application Development Framework (ADF)来构建更现代化的前端,但 Share 仍是重要组成部分。
- 搜索服务 (alfresco/alfresco-search-services):基于 Apache Solr 构建的搜索微服务。它为内容库提供全文检索、分面搜索和高性能查询能力。在部署中,它通常作为一个独立服务运行,与内容库分离,实现了搜索能力的独立伸缩。
- 同步服务 (alfresco/alfresco-sync-service):这是实现 Alfresco Desktop Sync(类似于 OneDrive/Google Drive 的桌面同步客户端)功能的后端服务。它负责处理桌面客户端与云端内容库之间的增量同步和冲突解决。
- 数字工作区 (alfresco/alfresco-digital-workspace):一个基于 ADF 构建的、用户体验更佳的现代化内容管理界面,旨在逐步替代或补充传统的 Share 界面。
支撑服务层:
- 数据库 (PostgreSQL):存储所有内容元数据、用户信息、权限关系等结构化数据。ACS 对事务一致性要求高,PostgreSQL 是官方推荐和测试最充分的数据库。
- 消息队列 (ActiveMQ Artemis):作为微服务间的异步通信总线,处理如内容转换、工作流事件、行为审计等需要解耦和后台处理的任务。Artemis 是 ActiveMQ 的下一代产品,性能更强。
- 文件存储 (本地卷或对象存储):实际二进制文件(如 PDF、Word 文档)的存储位置。在 Docker 部署中通常映射到宿主机卷;在生产环境中,强烈建议集成如 AWS S3、Azure Blob Storage 或兼容 S3 协议的对象存储,以实现存储的无限扩展和高可用。
- 反向代理/入口 (nginx 或 Ingress Controller):负责将外部 HTTP/HTTPS 请求路由到正确的后端服务(如 Share 或 Digital Workspace),并通常承担 SSL 终结、负载均衡和静态资源缓存的任务。
acs-deployment的 Docker Compose 文件 (docker-compose.yml) 就是将这些服务及其依赖关系,通过服务定义、网络、卷和环境变量有机地编织在一起的一张蓝图。这种设计使得每个组件都可以独立升级、伸缩和故障隔离,是构建稳健企业应用的基础。
2.2 部署模式的选择:Docker Compose vs. Kubernetes
项目提供了两种主流的部署范式,对应不同的使用场景和运维复杂度。
Docker Compose 模式:
- 目标场景:开发、测试、演示环境,或小规模、非关键的生产部署。
- 核心文件:
docker-compose.yml及其引用的环境变量文件 (.env)。 - 优点:
- 简单快捷:一条
docker-compose up -d命令即可启动全套服务,极大降低了入门门槛。 - 环境一致:确保了从开发到测试环境的完全一致。
- 资源清晰:所有服务定义、网络和卷映射集中在一个文件中,一目了然。
- 简单快捷:一条
- 缺点:
- 缺乏高可用:单点故障风险高(尽管可以配置多个实例,但编排能力弱)。
- 伸缩性差:手动伸缩服务实例比较麻烦。
- 不适合大规模生产:在服务发现、健康检查、自愈、滚动更新等方面能力有限。
Kubernetes 模式:
- 目标场景:中大型生产环境,要求高可用性、弹性伸缩和自动化运维。
- 核心文件:位于
kubernetes/目录下的各类 YAML 清单文件,包括 Deployment、StatefulSet、Service、ConfigMap、Secret、Ingress 等。 - 优点:
- 生产级特性:内置服务发现、负载均衡、自动伸缩、滚动更新、故障自愈和密钥管理。
- 声明式配置:所需状态由 YAML 文件定义,由 K8s 控制器自动驱使其实现,运维更高效。
- 生态丰富:可以轻松集成监控(Prometheus)、日志(EFK/ELK)、服务网格(Istio)等云原生工具链。
- 缺点:
- 复杂度高:需要学习和维护 K8s 集群及其相关概念,运维成本陡增。
- 起步较慢:初始搭建和配置需要更多时间和专业知识。
实操心得:对于绝大多数团队,我的建议是“开发用 Compose,生产上 K8s”。用 Docker Compose 快速搭建开发测试环境,让开发人员尽早开始功能开发和集成测试。同时,利用
acs-deployment提供的 K8s manifests 作为模板,结合公司的 CI/CD 流水线(如 GitLab CI, Jenkins)和配置管理工具(如 Helm, Kustomize),构建自动化的生产部署流程。不要试图用 Docker Compose 去硬扛生产流量。
3. 基于 Docker Compose 的本地部署实战
3.1 环境准备与前置检查
在运行docker-compose up之前,充分的准备工作能避免很多后续的麻烦。
系统要求:
- 操作系统:Linux (推荐 Ubuntu 20.04/22.04 LTS, CentOS 7/8), macOS, 或 Windows 10/11 (需安装 WSL2 以获得最佳体验)。生产环境强烈推荐 Linux。
- Docker Engine:版本 20.10.x 或更高。确保当前用户已加入
docker用户组,无需sudo即可执行docker命令。 - Docker Compose:版本 v2.x。现在 Docker Desktop 已内置 Compose V2,如果是独立安装,请注意命令可能是
docker compose(没有横杠)。 - 资源分配:ACS 是一套完整的 Java 应用栈,比较吃资源。建议为 Docker 分配至少4-6 GB 内存和2-4 个 CPU 核心。在 Docker Desktop 的设置中可进行调整。
- 磁盘空间:确保有至少 20GB 的可用磁盘空间,用于存储镜像、数据库和文档内容。
关键检查步骤:
- 验证安装:打开终端,运行
docker --version和docker compose version(或docker-compose --version)确认版本。 - 拉取项目:
git clone https://github.com/Alfresco/acs-deployment.git并进入项目根目录。 - 检查默认配置:查看根目录下的
.env文件。这个文件定义了所有服务的版本、端口、密码等关键变量。在首次部署前,务必修改默认密码!# 编辑 .env 文件,至少修改以下关键密码 POSTGRES_PASSWORD=yourStrongPassword123! DB_USERNAME=alfresco DB_PASSWORD=yourStrongDBPassword456! # 管理员密码(用于首次登录Share) ADMIN_PASSWORD=yourAdminPass789!
3.2 配置文件深度解析与定制
docker-compose.yml文件是部署的核心。我们挑几个关键服务块来解析:
内容存储库服务 (alfresco) 配置要点:
services: alfresco: image: alfresco/alfresco-content-repository:${REPO_TAG} environment: # 数据库连接,引用自.env文件 spring.datasource.url: jdbc:postgresql://postgres:5432/alfresco spring.datasource.username: ${DB_USERNAME} spring.datasource.password: ${DB_PASSWORD} # 消息队列连接 spring.artemis.broker.url: tcp://activemq:61616 # 搜索服务集成 solr.host: solr6 solr.port: 8983 # 文件存储路径(容器内) dir.contentstore: /tmp/alfresco-content-store/contentstore dir.contentstore.deleted: /tmp/alfresco-content-store/contentstore.deleted # JVM内存参数 - 根据机器配置调整 JAVA_OPTS: " -Ddb.driver=org.postgresql.Driver -Xms1500m -Xmx1500m -Dencryption.keystore.type=JCEKS -Dencryption.cipherAlgorithm=DESede/CBC/PKCS5Padding -Dencryption.keyAlgorithm=DESede -Dencryption.keystore.location=/usr/local/tomcat/shared/classes/alfresco/extension/keystore/encryption.keystore " volumes: # 将宿主机目录映射到容器内的内容存储和索引目录 - alfresco-content-store:/tmp/alfresco-content-store - alfresco-index:/usr/local/tomcat/alf_data # 挂载自定义扩展(如AMP、JAR包、属性文件) - ./customizations/alfresco/extension:/usr/local/tomcat/shared/classes/alfresco/extension:ro - ./customizations/alfresco/amps:/usr/local/tomcat/amps:ro depends_on: - postgres - activemq - solr6- JVM 调优:
-Xms和-Xmx设置堆内存初始和最大值。对于开发环境,1.5GB 可能足够;生产环境需要根据用户量和文档数量评估,通常建议从 4GB 起步,并设置-Xms和-Xmx相同以避免运行时调整带来的停顿。 - 卷映射:
alfresco-content-store和alfresco-index是 Docker 管理的命名卷,数据会持久化。生产环境中,你应该将这些卷映射到高性能、高可用的共享存储或对象存储。 - 自定义扩展:通过挂载本地
./customizations目录,你可以无缝地注入自定义的 AMP 模块、JAR 包或alfresco-global.properties覆盖文件,这是实现定制化的标准方式。
PostgreSQL 数据库服务配置要点:
postgres: image: postgres:${POSTGRES_TAG} environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: ${DB_USERNAME} POSTGRES_DB: alfresco volumes: - postgres-data:/var/lib/postgresql/data command: postgres -c max_connections=300 -c shared_buffers=512MB- 连接数:
max_connections=300是一个合理的起点。在生产中,你需要根据 ACS 的db.pool.max设置和并发用户数来调整此值。 - 共享缓冲区:
shared_buffers=512MB是 PostgreSQL 用于缓存数据的内存。规则通常是系统总内存的 25%,但在容器中需谨慎设置,避免与宿主或其他容器争抢内存。
3.3 启动、验证与初始化
- 启动服务:在项目根目录执行
docker compose up -d。-d参数表示后台运行。首次运行会从 Docker Hub 拉取所有镜像,耗时取决于网络。 - 监控启动日志:使用
docker compose logs -f alfresco来跟踪内容库服务的启动过程。关键的日志行包括:Database connection is available:表示数据库连接成功。Connected to broker at:表示消息队列连接成功。Server startup in [XXXXX] milliseconds:表示 Tomcat 服务器启动完成。- 搜索服务 (
solr6) 的日志中会出现Alfresco Content Services Solr 6 indexing server started。
- 验证服务健康:
- Alfresco Repository:访问
http://localhost:8080/alfresco,应看到 Alfresco 的欢迎页面或 REST API Explorer。 - Alfresco Share:访问
http://localhost:8080/share,使用用户名admin和你在.env中设置的ADMIN_PASSWORD登录。 - Alfresco Search Services:访问
http://localhost:8080/solr,应看到 Solr 管理界面。
- Alfresco Repository:访问
- 初始化搜索索引:这是最关键的一步!ACS 启动后,内容库和搜索服务之间的索引是空的。你需要触发一个“重建索引”或等待后台的增量索引。对于全新安装,最快的方式是通过 Share 管理员界面或调用 Reindex API。
- 通过 Share:以管理员登录 Share -> 管理员工具 -> 搜索管理器 -> 执行“新建索引”。
- 通过 API:
curl -u admin:password -X POST http://localhost:8080/alfresco/api/-default-/public/search/versions/1/search/rebuild-index - 重建索引耗时取决于数据库中的内容量(初始为空则很快)。完成后,才能在 Share 或 Digital Workspace 中搜索到内容。
注意事项:启动后如果 Share 能访问但提示“无法连接到 Alfresco 存储库”,通常是因为内容库服务 (
alfresco) 尚未完全启动(尽管端口已开放)。请耐心等待其日志显示启动完成,或检查alfresco服务的健康端点http://localhost:8080/alfresco/api/-default-/public/alfresco/versions/1/healthcheck。
4. 向 Kubernetes 生产环境迁移的核心策略
4.1 Kubernetes Manifests 结构解析
acs-deployment项目中的kubernetes/目录提供了完整的 K8s 资源配置。理解其结构是定制化的前提。
kubernetes/ ├── charts/ # (如果使用)Helm chart 目录 ├── manifests/ # 核心的 K8s YAML 文件 │ ├── persistent-volumes/ # PV 定义(需根据实际存储类创建) │ ├── statefulsets/ # 有状态服务:PostgreSQL, ActiveMQ │ ├── deployments/ # 无状态服务:Alfresco Repo, Share, Search, Sync │ ├── services/ # Service 定义,用于内部服务发现和负载均衡 │ ├── configmaps/ # 配置文件,如 alfresco-global.properties 片段 │ ├── secrets/ # 密码等敏感信息(示例,实际需用 sealed-secrets 或外部管理) │ └── ingress/ # Ingress 配置,定义外部访问规则 └── README.md关键设计理念:
- 有状态 vs. 无状态:数据库 (
postgresql-statefulset.yaml) 和消息队列 (activemq-statefulset.yaml) 使用StatefulSet,因为它们需要稳定的网络标识和持久化存储。而内容库、Share 等应用服务使用Deployment,便于水平伸缩和滚动更新。 - 配置外置:将环境相关的配置(如数据库连接串、JVM 参数)通过
ConfigMap和Secret注入,实现“一次构建,多处部署”。 - 健康检查:每个
Deployment都配置了livenessProbe和readinessProbe,这是生产可用性的基石。例如,内容库的存活探针检查/alfresco/api/-default-/public/alfresco/versions/1/healthcheck端点。 - 资源限制:每个 Pod 都设置了
resources.requests和resources.limits,这对于 K8s 调度和防止单个服务耗尽节点资源至关重要。
4.2 生产级定制与配置管理
直接使用仓库里的 manifests 可以跑起来,但离生产就绪还有距离。以下是必须定制的环节:
1. 存储类 (StorageClass) 与持久卷 (PersistentVolume): 项目中的persistent-volumes/目录提供的是hostPath类型的示例,仅适用于单节点测试。生产环境必须使用网络存储,如:
- 云平台:AWS EBS/EFS、Azure Disk/Files、GCP Persistent Disk
- 本地/混合云:Ceph RBD、GlusterFS、Longhorn、OpenEBS 等 CSI 兼容的存储方案。 你需要根据存储提供商创建对应的
StorageClass,然后在StatefulSet和Deployment的volumeClaimTemplates或persistentVolumeClaim中引用它。
2. 密钥管理: 切勿将明文密码写在 YAML 文件中提交到 Git。标准做法是:
- 使用 K8s Secret:通过
kubectl create secret generic命令创建。kubectl create secret generic alfresco-db-secret \ --from-literal=postgres-password='yourStrongPassword' \ --from-literal=db-password='yourDBPassword' - 集成外部密钥库:对于更严格的安全要求,可以使用 HashiCorp Vault、Azure Key Vault 等,并通过 sidecar 或 CSI 驱动将密钥注入到 Pod 中。
3. 配置管理 (ConfigMap): 将alfresco-global.properties的覆盖配置、自定义log4j.properties等放入ConfigMap。
# configmap-custom.properties.yaml apiVersion: v1 kind: ConfigMap metadata: name: alfresco-custom-config data: alfresco-global.properties: | # 自定义属性 index.subsystem.name=solr6 solr.host=solr6 solr.port=8983 # 邮件服务器配置 mail.host=your.smtp.server mail.port=587 mail.username=your-email@company.com然后在alfresco的Deployment中,将这个 ConfigMap 挂载到/usr/local/tomcat/shared/classes/alfresco/extension/目录下。
4. 网络与入口 (Ingress): 生产环境需要 HTTPS、自定义域名和路径路由。
- TLS 证书:使用 Let‘s Encrypt (cert-manager) 或从内部 CA 获取证书,配置到 Ingress 中。
- Ingress 控制器:使用 Nginx Ingress Controller、Traefik 或 ALB Ingress Controller (AWS)。
# ingress-alfresco.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: alfresco-ingress annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" # 自动申请证书 spec: tls: - hosts: - alfresco.yourcompany.com secretName: alfresco-tls-secret rules: - host: alfresco.yourcompany.com http: paths: - path: /alfresco pathType: Prefix backend: service: name: alfresco port: number: 80 - path: /share pathType: Prefix backend: service: name: share port: number: 804.3 高可用与伸缩性配置
1. 应用层伸缩 (HPA): 为alfresco和share的Deployment配置 Horizontal Pod Autoscaler,基于 CPU 或内存使用率自动调整 Pod 副本数。
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: alfresco-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: alfresco minReplicas: 2 maxReplicas: 5 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 702. 数据库高可用: 单点的 PostgreSQL 是故障的薄弱环节。生产环境应考虑:
- 云托管数据库:直接使用 AWS RDS、Azure Database for PostgreSQL 或 Google Cloud SQL,它们提供了开箱即用的高可用、备份和监控。
- 自建集群:使用 PostgreSQL 高可用方案,如 Patroni + etcd 或 Stolon,部署在 K8s 上。这复杂度较高,需要专业的 DBA 知识。
3. 文件存储高可用: 将内容存储 (contentstore) 指向高可用的共享文件系统或对象存储。
- 修改内容库配置:在
alfresco-global.properties中配置 S3 兼容的对象存储。s3.endpoint=https://s3.your-region.amazonaws.com s3.bucketName=your-alfresco-bucket s3.accessKey=${env:S3_ACCESS_KEY} s3.secretKey=${env:S3_SECRET_KEY} s3.flatRoot=true - 通过环境变量传递密钥:将
S3_ACCESS_KEY和S3_SECRET_KEY通过Secret注入到 Pod 环境变量中。
5. 运维监控、日志与故障排查实战
5.1 监控指标体系搭建
一个健康的 ACS 集群需要全方位的监控。
1. 应用层监控 (JVM/应用指标):
- 启用 JMX:在
alfresco容器的JAVA_OPTS中添加 JMX 远程连接参数,使用 Prometheus 的 JMX Exporter 或 Micrometer 来抓取 JVM 指标(堆内存、GC 时间、线程数)和自定义业务指标。 - Alfresco 内置监控端点:ACS 提供了
/alfresco/api/-default-/public/alfresco/versions/1/healthcheck和/alfresco/s/enterprise/admin/admin-monitoring(Enterprise 版) 等端点,可以监控服务状态、活动会话、缓存命中率等。
2. 系统层监控:
- Node Exporter:部署在 K8s 每个节点上,收集 CPU、内存、磁盘 I/O、网络等主机指标。
- cAdvisor:通常内置于 Kubelet,提供容器级别的资源使用情况。
3. 存储与数据库监控:
- PostgreSQL:使用
postgres_exporter收集数据库连接数、查询性能、锁、表大小等关键指标。 - 对象存储:如果使用 S3,监控其请求率、延迟、错误率和存储桶大小。
4. 使用 Prometheus + Grafana: 这是云原生领域的监控事实标准。
- 部署 Prometheus Stack:使用
kube-prometheus-stackHelm chart,它会自动部署 Prometheus、Grafana 以及针对 K8s 核心组件、节点、Pod 的监控规则和仪表盘。 - 配置服务发现:为 ACS 的各个服务(
alfresco,share,solr6)添加 Prometheus 所需的注解 (prometheus.io/scrape: "true",prometheus.io/port: "8080"),让 Prometheus 自动抓取指标。 - 导入/制作 Grafana 仪表盘:可以从社区寻找 Alfresco 相关的仪表盘,或根据关键指标(如 HTTP 请求延迟、JVM 堆使用率、活跃用户数、索引延迟)自行创建。
5.2 集中式日志收集与分析
当你有多个 Pod 时,查看日志变得困难。EFK (Elasticsearch, Fluentd/Fluent Bit, Kibana) 或 ELK 栈是标准解决方案。
1. 部署 Fluent Bit 作为日志代理: Fluent Bit 更轻量,适合作为 DaemonSet 运行在每个节点上,收集容器日志。
# fluent-bit-config.yaml 片段 [INPUT] Name tail Path /var/log/containers/*alfresco*.log Parser docker Tag kube.alfresco.* [OUTPUT] Name es Match kube.alfresco.* Host elasticsearch-logging Port 9200 Logstash_Format On Logstash_Prefix logstash-alfresco2. 配置应用日志格式: 确保 ACS 的日志输出是结构化的(如 JSON),便于解析和过滤。可以在log4j.properties配置中使用 JsonLayout。
3. 在 Kibana 中分析:
- 错误追踪:设置告警规则,当出现
ERROR或WARN级别的日志达到一定频率时触发告警(如通过 ElastAlert)。 - 性能分析:通过日志中的时间戳和耗时字段,分析慢请求。
- 用户行为审计:Alfresco 会记录详细的操作日志,可以用于安全审计和用户行为分析。
5.3 常见问题与排查技巧实录
以下是我在运维 ACS 集群中遇到的一些典型问题及解决思路:
问题 1:Share 界面加载缓慢或部分功能无法使用,控制台报 JavaScript/CSS 404 错误。
- 可能原因:Share 的 Web 资源(静态文件)未能正确加载。这通常发生在反向代理(如 Nginx Ingress)配置不正确时。
- 排查步骤:
- 检查浏览器开发者工具的网络面板,确认是哪些资源(
.js,.css)加载失败。 - 检查 Ingress 或反向代理的配置,确保对
/share/res/、/share/modules/等路径的请求被正确路由到share服务,并且没有丢失必要的请求头(如Host)。 - 检查
sharePod 的日志,看是否有相关的错误或警告。
- 检查浏览器开发者工具的网络面板,确认是哪些资源(
- 解决方案:在 Ingress 注解或 Nginx 配置中,为
/share路径下的静态资源设置更长的缓存时间,并确保代理设置正确。例如,在 Nginx Ingress 中添加注解:nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/proxy-buffer-size: "128k" nginx.ingress.kubernetes.io/proxy-buffers-number: "4" nginx.ingress.kubernetes.io/configuration-snippet: | location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
问题 2:文档上传或预览失败,日志显示“内容转换超时”或“转换器不可用”。
- 可能原因:ACS 依赖 LibreOffice 进行文档格式转换(如 Word 转 PDF)。如果
alfrescoPod 内的 LibreOffice 进程崩溃或资源不足,就会导致转换失败。 - 排查步骤:
- 进入
alfrescoPod 的 Shell:kubectl exec -it <alfresco-pod-name> -- /bin/bash。 - 检查 LibreOffice 进程:
ps aux | grep soffice。正常情况下应该能看到一个soffice.bin进程。 - 检查 Pod 的资源使用情况(CPU/内存),看是否因达到 Limit 而被 OOMKilled。
- 查看
alfresco日志中与JodConverter相关的错误。
- 进入
- 解决方案:
- 增加资源:适当提高
alfrescoDeployment 的resources.limits.memory,例如从 2Gi 增加到 4Gi。LibreOffice 处理大文档时比较耗内存。 - 调整转换器配置:在
alfresco-global.properties中调整转换器超时时间和队列大小。content.transformer.default.timeoutMs=120000 jodconverter.maxTasksPerProcess=20 - 考虑外部转换服务:对于高并发转换场景,可以考虑将转换任务卸载到外部的、可伸缩的转换微服务集群。
- 增加资源:适当提高
问题 3:搜索功能失效,在 Share 中搜索不到新上传的文档。
- 可能原因:Alfresco Search Services (Solr) 与内容库之间的索引同步出现问题。
- 排查步骤:
- 检查
solr6Pod 的日志,看是否有索引错误或连接失败。 - 检查
alfrescoPod 的日志,搜索tracking或index关键词,看是否有索引提交失败的信息。 - 访问 Solr 管理界面 (
http://<solr-service>:8983/solr),查看核心(core)状态,检查alfresco和archive核心的索引文档数量是否与内容库中文档数量大致相符。 - 在 Share 管理员工具中检查“搜索管理器”的状态。
- 检查
- 解决方案:
- 重建索引:如果索引完全损坏,在 Solr 管理界面或通过 API 触发重建索引(非生产时间进行,因为耗时且影响性能)。
- 检查网络与防火墙:确保
alfrescoPod 能通过网络访问solr6Service 的 8983 端口。 - 检查配置:确认
alfresco-global.properties中的solr.host和solr.port指向正确的 Solr 服务地址(在 K8s 中应为服务名solr6和端口8983)。
问题 4:Kubernetes 集群升级或节点维护后,部分 Pod 无法启动,陷入CrashLoopBackOff状态。
- 可能原因:Pod 依赖的持久化存储卷(PVC)可能由于节点调度变化,无法被新调度的 Pod 挂载。或者,新节点上缺少某些必要的系统库。
- 排查步骤:
- 使用
kubectl describe pod <pod-name>查看 Pod 的详细事件,通常会给出失败原因,如Unable to attach volume,MountVolume.SetUp failed或容器启动失败的具体错误码。 - 检查 PVC 的状态:
kubectl get pvc。确保其状态为Bound。 - 检查 PV 的状态:
kubectl get pv。确保其状态为Bound且RECLAIM POLICY不是Delete(除非你确定数据可丢失)。 - 查看失败容器的日志:
kubectl logs <pod-name> --previous(查看上一次崩溃的日志)。
- 使用
- 解决方案:
- 存储卷问题:如果使用的是
ReadWriteOnce访问模式的卷,确保 Pod 被调度到原来挂载该卷的节点上,或者使用支持ReadWriteMany的存储类(如 NFS、对象存储 CSI 驱动)。 - 镜像兼容性:检查 Pod 使用的 Docker 镜像标签是否与 K8s 集群版本兼容。有时基础镜像的更新可能导致兼容性问题。
- 初始化容器失败:如果 Pod 有初始化容器 (
initContainers),检查其是否成功完成。初始化容器失败会阻止主容器启动。
- 存储卷问题:如果使用的是
运维一个像 ACS 这样的复杂系统,完善的监控和清晰的日志是排障的生命线。建立好 Prometheus/Grafana 监控和 EFK 日志栈,并养成定期查看关键仪表盘的习惯,能让你在用户抱怨之前就发现潜在问题。对于acs-deployment这个项目,它给了你一个优秀的起点,但真正的生产就绪,需要你在此基础上,结合自己公司的技术栈和运维规范,进行深度的定制和加固。记住,基础设施即代码 (IaC) 是你的好朋友,所有对部署的修改都应该通过 Git 进行版本控制,并通过 CI/CD 流水线来自动化执行。