基于K3s搭建GitOps环境6-部署Gitea

一、核心定位

本文作为GitOps环境搭建系列的第六篇,聚焦Gitea代码仓库的部署与配置。Gitea是轻量级、高性能的Git服务,专为资源受限环境设计,适合在K3s集群中搭建私有代码仓库。

在GitOps环境中,Gitea扮演”代码托管中枢”角色,作为GitOps流程的单一可信数据源,存储所有应用配置、部署清单和流水线定义。通过Gitea与PostgreSQL、Redis的集成,为后续的Tekton CI流水线和ArgoCD GitOps部署提供可靠的代码存储和版本管理能力。

二、部署前置检查

部署前需验证基础组件(PostgreSQL、Redis)状态及K3s集群环境:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 验证K3s集群状态
kubectl get nodes

# 2. 验证PostgreSQL运行状态
kubectl get pods -n postgres
kubectl exec -it postgres-0 -n postgres -- psql -U gitea -d gitea -c "SELECT 1;" 2>/dev/null || echo "需要创建gitea数据库"

# 3. 验证Redis运行状态
kubectl get pods -n redis
kubectl exec -it redis-0 -n redis -- redis-cli -a redis123456 ping

# 4. 验证Traefik运行状态
kubectl get pods -n kube-system -l app=traefik

# 5. 验证cert-manager运行状态
kubectl get pods -n cert-manager

# 6. 验证域名解析
nslookup gitea.example.io

前置条件检查清单:

  • K3s集群运行正常
  • PostgreSQL数据库可用(已创建gitea数据库)
  • Redis缓存服务可用
  • Traefik反向代理运行正常
  • cert-manager证书管理可用
  • 域名gitea.example.io已解析至K3s节点IP

三、创建Gitea命名空间

为保持资源隔离规范,Gitea独立运行在gitea命名空间:

1
2
3
4
5
6
7
8
# gitea-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: gitea
labels:
app: gitea
component: gitops

应用配置:

1
2
3
4
kubectl apply -f gitea-namespace.yaml

# 验证命名空间创建
kubectl get namespace gitea

四、部署Gitea持久化存储

采用local-path存储类,保障Gitea数据持久化:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# gitea-pvc-local-path.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-pvc
namespace: gitea
labels:
app: gitea
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 50Gi

五、配置Gitea应用

5.1 创建Gitea配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# gitea-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: gitea-config
namespace: gitea
labels:
app: gitea
data:
# 基础配置
APP_NAME: "Gitea Git Repository"
RUN_MODE: prod
HTTP_PORT: "3000"

# 数据库配置(使用前序部署的PostgreSQL)
DB_TYPE: postgres
DB_HOST: postgres.postgres.svc.cluster.local:5432
DB_NAME: gitea
DB_USER: gitea
DB_PASSWD: gitea123

# Redis缓存配置
REDIS_TYPE: redis
REDIS_HOST: redis.redis.svc.cluster.local:6379
REDIS_PASSWORD: redis123456

# 安全配置
DISABLE_REGISTRATION: "true"
REQUIRE_SIGNIN_VIEW: "true"
ENABLE_OPENID_SIGNIN: "false"
ENABLE_OPENID_SIGNUP: "false"

# SSH配置
SSH_LISTEN_PORT: "2222"
SSH_PORT: "22"

# 路径配置
GITEA_APP_INI: /data/gitea/conf/app.ini
GITEA_CUSTOM: /data/gitea
GITEA_WORK_DIR: /data
GITEA_TEMP: /tmp/gitea
TMPDIR: /tmp/gitea
HOME: /data/gitea/git

# 功能开关
ACTIONS_ENABLED: "false"
GITEA_packages_ENABLED: "false"
GITE_actions_ENABLED: "false"

# Webhook配置
GITEA_webhook_ALLOWED_HOST_LIST: "*.example.io"
GITEA_webhook_SKIP_TLS_VERIFY: "true"

5.2 创建Gitea数据库(如未创建)

1
2
3
4
# 在PostgreSQL中创建gitea数据库
kubectl exec -it postgres-0 -n postgres -- psql -U postgres -c "CREATE DATABASE gitea;"
kubectl exec -it postgres-0 -n postgres -- psql -U postgres -c "CREATE USER gitea WITH PASSWORD 'gitea123';"
kubectl exec -it postgres-0 -n postgres -- psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE gitea TO gitea;"

六、部署Gitea服务

6.1 创建Service资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# gitea-service.yaml
apiVersion: v1
kind: Service
metadata:
name: gitea-http
namespace: gitea
labels:
app: gitea
spec:
ports:
- name: http
port: 3000
protocol: TCP
targetPort: 3000
selector:
app: gitea
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: gitea-ssh
namespace: gitea
labels:
app: gitea
spec:
ports:
- name: ssh
port: 22
protocol: TCP
targetPort: 22
selector:
app: gitea
type: ClusterIP

6.2 部署Gitea应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# gitea-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: gitea
labels:
app: gitea
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:1.22.0-rootless
envFrom:
- configMapRef:
name: gitea-config
imagePullPolicy: IfNotPresent
ports:
- containerPort: 22
name: ssh
protocol: TCP
- containerPort: 3000
name: http
protocol: TCP
volumeMounts:
- mountPath: /tmp
name: temp
- mountPath: /data
name: gitea-persistent-storage
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /api/healthz
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/healthz
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
restartPolicy: Always
volumes:
- name: temp
emptyDir: {}
- name: gitea-persistent-storage
persistentVolumeClaim:
claimName: gitea-pvc

七、配置HTTPS访问

7.1 创建Gitea证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# gitea-certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: gitea-cert
namespace: gitea
spec:
secretName: gitea-tls-secret
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
commonName: gitea.example.io
dnsNames:
- gitea.example.io
duration: 2160h # 90天
renewBefore: 360h # 过期前15天自动续签
privateKey:
algorithm: RSA
size: 2048
usages:
- server auth

7.2 配置IngressRoute

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# gitea-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: gitea-websecure
namespace: gitea
annotations:
traefik.ingress.kubernetes.io/service.sticky.cookie: "true"
spec:
entryPoints:
- websecure
routes:
- match: Host(`gitea.example.io`) && PathPrefix(`/`)
kind: Rule
services:
- name: gitea-http
passHostHeader: true
port: 3000
tls:
secretName: gitea-tls-secret

八、应用所有配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 一键部署Gitea
kubectl apply -f gitea-pvc-local-path.yaml
kubectl apply -f gitea-config.yaml
kubectl apply -f gitea-service.yaml
kubectl apply -f gitea-deployment.yaml
kubectl apply -f gitea-certificate.yaml
kubectl apply -f gitea-ingressroute.yaml

# 或使用在线配置(推荐)
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-pvc-local-path.yaml
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-config.yaml
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-service.yaml
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-deployment.yaml
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-certificate.yaml
kubectl apply -f https://gitee.com/Chemmy/kube-template/raw/master/devops/Gitea/gitea-ingressroute.yaml

九、验证部署结果

9.1 验证组件状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看Gitea Pod状态
kubectl get pods -n gitea -w

# 查看PVC状态
kubectl get pvc -n gitea

# 查看Service状态
kubectl get svc -n gitea

# 查看证书状态
kubectl get certificate -n gitea
kubectl describe certificate gitea-cert -n gitea

# 查看IngressRoute状态
kubectl get ingressroute -n gitea

9.2 测试Gitea功能

1
2
3
4
5
6
7
8
9
10
11
12
# 等待Gitea完全启动(约1-2分钟)
sleep 60

# 测试HTTP访问
curl -k https://gitea.example.io

# 查看Gitea日志
kubectl logs -f deployment/gitea -n gitea --tail=50

# 进入容器检查状态
kubectl exec -it $(kubectl get pod -n gitea -l app=gitea -o jsonpath='{.items[0].metadata.name}') -n gitea -- /bin/sh
# 容器内执行:gitea admin status

9.3 初始化Gitea管理员

首次访问Gitea需要完成初始化配置:

  1. 浏览器访问:https://gitea.example.io
  2. 数据库类型:PostgreSQL
  3. 数据库主机:postgres.postgres.svc.cluster.local:5432
  4. 数据库名称:gitea
  5. 数据库用户名:gitea
  6. 数据库密码:gitea123
  7. 站点名称:Gitea Git Repository
  8. 服务器域名:gitea.example.io
  9. 管理员账号设置:
    • 用户名:gitea_admin
    • 密码:GiteaAdmin123!
    • 确认密码:GiteaAdmin123!
    • 邮箱:admin@example.io

十、服务访问方式

10.1 集群内访问

  • Web界面gitea-http.gitea.svc.cluster.local:3000
  • Git HTTPhttp://gitea-http.gitea.svc.cluster.local:3000
  • Git SSHssh://git@gitea-ssh.gitea.svc.cluster.local:22

10.2 集群外访问

  • Web界面https://gitea.example.io
  • Git HTTPhttps://gitea.example.io
  • Git SSHssh://git@gitea.example.io:22(需配置SSH端口转发)

十一、日常运维命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查看实时日志
kubectl logs -f deployment/gitea -n gitea

# 重启Gitea服务
kubectl rollout restart deployment/gitea -n gitea

# 备份Gitea数据
kubectl cp gitea/$(kubectl get pod -n gitea -l app=gitea -o jsonpath='{.items[0].metadata.name}'):/data ./gitea-backup-$(date +%Y%m%d)

# 进入容器调试
kubectl exec -it $(kubectl get pod -n gitea -l app=gitea -o jsonpath='{.items[0].metadata.name}') -n gitea -- /bin/sh

# 查看资源使用情况
kubectl top pods -n gitea

十二、常见问题修复

问题现象 排查方向 修复方案
Gitea无法启动 数据库连接失败 检查PostgreSQL连接:kubectl logs deployment/gitea -n gitea
证书签发失败 cert-manager配置 检查证书状态:kubectl describe certificate gitea-cert -n gitea
HTTPS访问失败 IngressRoute配置 检查IngressRoute:kubectl describe ingressroute gitea-websecure -n gitea
SSH连接失败 端口配置/网络 确认SSH Service端口正确,检查网络策略
性能问题 资源不足 调整Deployment资源配置,增加Redis缓存使用
数据持久化失败 PVC绑定问题 检查PVC状态:kubectl describe pvc gitea-pvc -n gitea

十三、配置参考

所有Gitea配置文件和部署脚本请参考:
https://gitee.com/Chemmy/kube-template/tree/master/devops/Gitea

该目录包含:

  • Gitea完整部署配置
  • 数据库初始化脚本
  • 生产环境优化配置
  • 备份和恢复脚本
  • 集成配置示例(与Tekton、ArgoCD集成)

总结

本文完成了Gitea在K3s集群中的标准化部署,实现了代码托管服务的完整功能。Gitea作为GitOps环境的核心组件,为后续的Tekton CI流水线和ArgoCD GitOps部署提供了可靠的代码存储和版本管理基础。

部署完成后,建议创建测试仓库,验证Git操作和Webhook功能正常。下一篇文章将部署ArgoCD,为GitOps环境提供持续部署能力。