🌟 引言:为什么你的团队需要一个轻量级项目管理工具?

在敏捷开发与 DevOps 实践日益普及的今天,项目可视化管理已成为团队协作的核心需求。

你是否面临以下挑战?

❓ 团队使用 Excel 或纸质看板,信息不同步?
❓ Jira 太重,Trello 功能有限,缺乏自定义能力?
❓ 希望拥有一个开源、轻量、可私有化部署的任务看板系统?

Kanboard 正是为此而生。

它是一个基于看板(Kanban)方法的开源项目管理平台,简洁、高效、可扩展,非常适合中小型团队进行任务跟踪、敏捷迭代与流程自动化。

本文将带你从零开始,在 Kubernetes(k8s)生产级集群中完成 Kanboard 的高可用、可扩展、安全可控的云原生部署,涵盖:

✅ 容器镜像构建与优化
✅ Helm Chart 封装与参数化配置
✅ 持久化存储(PersistentVolume)设计
✅ Ingress 路由与 TLS 加密
✅ 数据库分离部署(PostgreSQL)
✅ RBAC 权限控制与安全策略
✅ 健康检查、资源限制与自动扩缩容
✅ CI/CD 自动化部署流水线设计

无论你是 DevOps 工程师、SRE 还是技术负责人,本文都将为你提供一套可落地、可复用的云原生应用部署范式


🧩 第一章:Kanboard 与云原生架构全景图

1.1 Kanboard 核心特性与适用场景

特性 说明
开源免费 MIT 协议,可自由使用与二次开发
轻量简洁 界面清爽,学习成本低,适合敏捷团队
看板驱动 支持列(Column)、泳道(Swimlane)、任务(Task)
插件生态 支持数十种插件(如 Gantt、Calendar、Git Integration)
API 支持 提供 RESTful API,便于集成 CI/CD、自动化脚本
多用户支持 支持角色权限(Admin、Manager、User)

典型场景:敏捷开发、运维工单、内容发布、个人任务管理


1.2 云原生部署优势对比

传统部署
物理机/虚拟机
单点故障
扩展困难
备份复杂
云原生部署
Kubernetes 集群
高可用
自动扩缩容
声明式配置
CI/CD 集成

结论:Kubernetes 提供了弹性、可靠、可观测的运行环境,是 Kanboard 生产部署的理想选择。
阿里云38元每年起:https://www.aliyun.com/minisite/goods?userCode=ifzmrq1c


1.3 整体架构设计

Kubernetes Cluster
Kanboard Service
Kanboard Pod
PostgreSQL
PersistentVolume
用户浏览器
Ingress Controller

组件说明

  • Ingress:统一入口,支持域名与 TLS
  • Kanboard Pod:运行应用容器
  • PostgreSQL:独立数据库服务(可部署在 k8s 内或外部)
  • PersistentVolume:持久化存储配置文件与附件

🔧 第二章:环境准备与前置依赖

2.1 基础环境要求

组件 版本要求 说明
Kubernetes v1.25+ 支持 CSI、Ingress v1 API
Helm v3.8+ 用于部署与管理应用
Containerd / Docker 最新版 容器运行时
StorageClass 支持动态供给 如 NFS、Ceph、云厂商存储
Ingress Controller Nginx, Traefik, ALB 建议使用 Nginx Ingress

2.2 命名空间创建

为 Kanboard 创建独立命名空间,实现资源隔离:

kubectl create namespace kanboard-prod

2.3 存储类(StorageClass)检查

kubectl get storageclass

输出示例:

NAME            PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE
nfs-client      cluster.local/nfs   Delete          Immediate

✅ 记下可用的 StorageClass 名称,后续用于 PVC。


🐳 第三章:容器化构建与镜像优化

3.1 官方镜像 vs 自定义构建

方式 优点 缺点
kanboard/kanboard 快速启动,官方维护 功能固定,无法定制插件
自定义 Dockerfile 可预装插件、主题、配置 需维护构建流程

3.2 自定义 Dockerfile(推荐)

FROM kanboard/kanboard:v1.2.23

# 预装常用插件
COPY plugins/Gantt /var/www/app/plugins/Gantt
COPY plugins/Calendar /var/www/app/plugins/Calendar
COPY plugins/Customizer /var/www/app/plugins/Customizer

# 复制自定义配置
COPY config.php /var/www/app/config.php

# 设置权限
RUN chown -R www-data:www-data /var/www/app/plugins

EXPOSE 80
CMD ["apache2-foreground"]

3.3 构建与推送镜像

docker build -t myrepo/kanboard:1.2.23-custom .
docker push myrepo/kanboard:1.2.23-custom

✅ 推荐使用私有镜像仓库(如 Harbor、ECR、ACR)。


📦 第四章:Helm Chart 封装与参数化部署

4.1 Helm Chart 目录结构

kanboard/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── pvc.yaml
│   └── secret.yaml
└── charts/

4.2 values.yaml 核心配置

replicaCount: 2

image:
  repository: myrepo/kanboard
  tag: 1.2.23-custom
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: kanboard.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: kanboard-tls
      hosts:
        - kanboard.example.com

persistence:
  enabled: true
  storageClass: "nfs-client"
  accessModes:
    - ReadWriteOnce
  size: 10Gi

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 200m
    memory: 256Mi

env:
  DB_HOST: postgresql.kanboard-prod.svc.cluster.local
  DB_NAME: kanboard
  DB_USER: kanboard
  DB_PASSWORD: "your-secure-password"

4.3 deployment.yaml 关键片段

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "kanboard.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app: {{ include "kanboard.name" . }}
  template:
    metadata:
      labels:
        app: {{ include "kanboard.name" . }}
    spec:
      containers:
      - name: kanboard
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        ports:
        - containerPort: 80
        env:
        - name: DATABASE_URL
          value: "pgsql:host={{ .Values.env.DB_HOST }};dbname={{ .Values.env.DB_NAME }}"
        - name: DB_USERNAME
          value: "{{ .Values.env.DB_USER }}"
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: kanboard-secret
              key: db-password
        volumeMounts:
        - name: data
          mountPath: /var/www/app/data
          subPath: data
        - name: plugins
          mountPath: /var/www/app/plugins
          subPath: plugins
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 60
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 30
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: {{ include "kanboard.fullname" . }}-data
      - name: plugins
        persistentVolumeClaim:
          claimName: {{ include "kanboard.fullname" . }}-plugins

关键点

  • 使用 livenessProbereadinessProbe 实现健康检查
  • 数据与插件目录分别挂载,便于管理
  • 密码通过 Secret 注入,保障安全
    阿里云38元每年起:https://www.aliyun.com/minisite/goods?userCode=ifzmrq1c

🗄️ 第五章:数据库部署与连接配置

5.1 PostgreSQL 部署(Helm 方式)

helm repo add bitnami https://charts.bitnami.com/bitnami
helm install kanboard-db bitnami/postgresql \
  --namespace kanboard-prod \
  --set auth.database=kanboard \
  --set auth.username=kanboard \
  --set auth.password=secure-pass-123 \
  --set primary.persistence.storageClass=nfs-client

5.2 数据库初始化脚本(可选)

若需预置数据,可通过 initdbScripts 配置:

initdbScripts:
  init-kanboard.sql: |
    CREATE DATABASE kanboard;
    CREATE USER kanboard WITH PASSWORD 'xxx';
    GRANT ALL PRIVILEGES ON DATABASE kanboard TO kanboard;

5.3 连接测试

进入 Kanboard Pod 测试数据库连通性:

kubectl exec -n kanboard-prod -it <pod-name> -- \
  pg_isready -h postgresql.kanboard-prod.svc.cluster.local -U kanboard

🔐 第六章:安全策略与 RBAC 配置

6.1 NetworkPolicy(限制网络访问)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: kanboard-policy
spec:
  podSelector:
    matchLabels:
      app: kanboard
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: ingress-nginx
    ports:
    - protocol: TCP
      port: 80
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kanboard-prod
    ports:
    - protocol: TCP
      port: 5432  # PostgreSQL

6.2 RBAC 角色定义

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: kanboard-prod
  name: kanboard-editor
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list"]
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "patch"]

✅ 可结合企业 LDAP/AD 实现统一身份认证。


🌐 第七章:Ingress 配置与 TLS 加密

7.1 启用 HTTPS(使用 cert-manager)

# values.yaml
ingress:
  tls:
    - secretName: kanboard-tls
      hosts:
        - kanboard.example.com
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
# Certificate 资源
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: kanboard-cert
  namespace: kanboard-prod
spec:
  secretName: kanboard-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - kanboard.example.com

7.2 访问测试

curl -k https://kanboard.example.com --resolve kanboard.example.com:443:10.0.0.100

✅ 应返回 Kanboard 登录页面 HTML。


🔄 第八章:CI/CD 自动化部署流水线

8.1 流水线设计

代码提交
GitHub Actions
构建 Docker 镜像
推送至镜像仓库
Helm Chart 版本更新
部署至 K8s 集群
运行健康检查
通知 Slack/企业微信

8.2 GitHub Actions 示例

name: Deploy Kanboard
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Build and Push Docker Image
      run: |
        docker build -t myrepo/kanboard:$GITHUB_SHA .
        docker push myrepo/kanboard:$GITHUB_SHA
    - name: Deploy to Kubernetes
      run: |
        helm upgrade --install kanboard ./kanboard \
          --namespace kanboard-prod \
          --set image.tag=$GITHUB_SHA

📊 第九章:监控、日志与告警

9.1 Prometheus 指标采集

Kanboard 本身不暴露 Prometheus 指标,但可通过 Sidecar 或日志分析实现监控。

# 添加 Prometheus 注解
annotations:
  prometheus.io/scrape: "true"
  prometheus.io/port: "80"

9.2 日志收集(EFK/ELK)

Kanboard Pod
Filebeat
Elasticsearch
Kibana
可视化查询

✅ 可监控登录失败、任务创建等关键事件。
阿里云38元每年起:https://www.aliyun.com/minisite/goods?userCode=ifzmrq1c


🚀 第十章:最终验证与访问

10.1 检查部署状态

kubectl get pods,svc,ingress -n kanboard-prod

输出应类似:

NAME                            READY   STATUS    RESTARTS   AGE
pod/kanboard-7c6d8f9b7c-abc12   1/1     Running   0          5m

NAME                 TYPE        CLUSTER-IP     PORT(S)
service/kanboard     ClusterIP   10.96.123.45   80/TCP

NAME                       CLASS   HOSTS                    ADDRESS       PORTS
ingress/kanboard-ingress   nginx   kanboard.example.com     203.0.113.10   80, 443

10.2 访问 Kanboard

打开浏览器访问:
👉 https://kanboard.example.com

首次访问将进入安装向导,使用以下信息:

  • 数据库类型:PostgreSQL
  • 主机postgresql.kanboard-prod.svc.cluster.local
  • 数据库名kanboard
  • 用户名/密码:按 Helm 配置填写

✅ 总结:云原生部署的核心价值

传统部署 云原生部署
扩展性差 自动扩缩容(HPA)
故障恢复慢 滚动更新、健康检查
配置分散 声明式 YAML 管理
安全性弱 RBAC、NetworkPolicy
部署低效 CI/CD 自动化

Kanboard + Kubernetes = 轻量、敏捷、可靠的项目管理解决方案。


📎 附录:完整 Helm Chart 下载

GitHub 仓库:
👉 https://github.com/example/k8s-kanboard

包含:

  • Helm Chart
  • CI/CD 流水线配置
  • 监控模板
  • 安全策略示例
    阿里云38元每年起:https://www.aliyun.com/minisite/goods?userCode=ifzmrq1c
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐