迁移 Gitea 到 Gitea-rootless

2022-03-28 [基础设施] #K3s #K8s #Kubernetes #Homelab #NFS #Virtualization

最近重新配置过一遍 Homelab 环境(PVE、NFS、Kubernetes),粗略检查各个自建服务的 Web 访问后迁移工作就告一段落了。直到今天提交代码到 Gitea 时出现 SSH 无法访问,排查后得知是因为无权限读取 keys 导致 SSH 服务启动失败:

$ kubectl logs -f -n selfhosts deploy/gitea
chown: /data/ssh/ssh_host_dsa_key: Operation not permitted
chown: /data/ssh/ssh_host_dsa_key.pub: Operation not permitted
...
Unable to load host key: /data/ssh/ssh_host_ed25519_key
Unable to load host key: /data/ssh/ssh_host_dsa_key
sshd: no hostkeys available -- exiting.

查看 /data/ssh/ 目录后发现里面 key 的所有者都是 root,直接改为 1000:1000 是无效的,因为容器中进程是默认以 root 权限运行的,并且在 Gitea 源码 docker/root/etc/s6/openssh/setup#L57 显式将 /data/ssh/ 设置为所有者设置为 root: chown root:root /data/ssh/*

本想着先简单将权限问题解决好就行,但想着 Gitea 有 rootless 的镜像,之前迟迟犯懒不肯更换,正好借着本次机会做个迁移。

备份

做任何迁移前肯定少不了都原数据的备份, Gitea 主要备份步骤为:

  1. 导出数据库SQL
  2. 备份 NFS 挂载的 /data/ 目录

具体备份操作就不一一展开了,数据库可以运行个 mysql-client 进去 dump 出来,/data/ 目录可以打个包或者创建个 Snapshot。

迁移

思路很简单:相关目录和端口普通用户有权限管理。

官方文档中有关于 从标准镜像迁移到 rootless 镜像的步骤,主要变更为:

先贴出本次迁移 pod-gitea.yaml 的变更:

diff --git a/selfhosts/gitea/pod-gitea.yaml b/selfhosts/gitea/pod-gitea.yaml
index 380636f..112bdae 100644
--- a/selfhosts/gitea/pod-gitea.yaml
+++ b/selfhosts/gitea/pod-gitea.yaml
@@ -13,7 +13,7 @@ spec:
     kind: Rule
     services:
     - name: gitea-ssh
-      port: 22
+      port: 2222
       weight: 10
       terminationDelay: 400

@@ -85,8 +85,8 @@ spec:
   ports:
     - name: gitea-ssh
       protocol: TCP
-      port: 22
-      targetPort: 22
+      port: 2222
+      targetPort: 2222


 ---
@@ -111,17 +111,19 @@ spec:
     spec:
       containers:
       - name: gitea
-        image: gitea/gitea:latest
+        image: gitea/gitea:latest-rootless
         ports:
         - name: gitea-web
           containerPort: 3000
           protocol: TCP
         - name: gitea-ssh
-          containerPort: 22
+          containerPort: 2222
           protocol: TCP
         volumeMounts:
         - name: nfs
-          mountPath: /data
+          mountPath: /var/lib/gitea
+        - name: nfs
+          mountPath: /etc/gitea
       volumes:
       - name: nfs
         persistentVolumeClaim:

目录结构调整

先根据官方文档的描述,将原来卷中的 gitea 目录更名为 custom。

rootless 镜像将配置文件和数据目录拆分到了两个卷,由于我的数据目录是走 NFS,并且是一个 PVC,虽然可以按正常步骤再单独创建一个 PVC 并挂载来实现,但我还是想将 Gitea 的数据按原来一个 PVC 方式管理(nfs-provisioner 的 配置为: storageClass.pathPattern="\${.PVC.namespace}/\${.PVC.name}"),于是就对配置文件目录做了个调整:

修改完卷挂载后,还需要调整原配置文件 app.ini 中关于目录的相关配置项:

# 直接使用正则将原来的 /data/ 目录替换为 /var/lib/gitea/
$ vim app.ini
:%s/\/data/\/var\/lib\/gitea/g

最后确认下 app.ini 的权限(1000:1000),若权限不正确,会遇到以下日志:

2022/03/28 20:03:19 ...nvironment-to-ini.go:106:runEnvironmentToIni() [F] Failed to load custom conf '/etc/gitea/app.ini': open /etc/gitea/app.ini: permission denied

端口调整

在 Linux 中 1024 以下的端口默认只能由 root 帐号使用,切换到 rootless 镜像后,原来给 gitea 配置的默认 22 端口将无法使用:

2022/03/28 20:15:20 ...s/graceful/server.go:61:NewServer() [I] Starting new SSH server: tcp::22 on PID: 1
2022/03/28 20:15:20 ...s/graceful/server.go:87:ListenAndServe() [E] Unable to GetListener: listen tcp :22: bind: permission denied
2022/03/28 20:15:20 .../ssh/ssh_graceful.go:26:listen() [F] Failed to start SSH server: listen tcp :22: bind: permission denied

需要将端口改为 > 1024 的端口:

# 批量将 22 端口 改为 2222 端口
$ vim pod-gitea.yaml
:%s/: 22/: 2222/g
文章作者:eightpigs
创作时间:2022-03-28
更新时间:2022-03-28
许可协议:CC by-nc-nd 4.0