最近重新配置过一遍 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 主要备份步骤为:
具体备份操作就不一一展开了,数据库可以运行个 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}"
),于是就对配置文件目录做了个调整:
将原来卷中 /gitea/conf/app.ini 复制到 gitea 同级目录:保证配置在 NFS 挂载的根目录
使用一个 PVC,挂载两次:保证数据和 app.ini 可以同时被读取到:
...
spec:
containers:
- name: gitea
image: gitea/gitea:latest-rootless
volumeMounts:
- name: nfs
mountPath: /var/lib/gitea
- name: nfs
mountPath: /etc/gitea
volumes:
- name: nfs
persistentVolumeClaim:
claimName: gitea-pvc
修改完卷挂载后,还需要调整原配置文件 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