今天來記錄地端 Gitea, 目的:不倚賴雲端,有更好安全性。寫得差的程式比較不會被發現…
root@chunk03:~# mkdir -p /var/lib/gitea
root@chunk03:~# mkdir -p /var/lib/local-registry
root@chunk03:~# mkdir -p /var/lib/gitea-runner
root@chunk03:~# chown -R 1000:1000 /var/lib/gitea /var/lib/gitea-runner
因為我這台有K3s master, 純管沒做事,負載很低,所以直接拿來用(正常最好分開
registry.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-registry
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: local-registry
template:
metadata:
labels:
app: local-registry
spec:
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
volumeMounts:
- name: data
mountPath: /var/lib/registry
volumes:
- name: data
hostPath:
path: /var/lib/local-registry
---
apiVersion: v1
kind: Service
metadata:
name: local-registry-service
namespace: kube-system
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30500 # 👈 叢集內外皆可以透過 30500 埠存取 Registry
selector:
app: local-registry
gitea.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:1.22
env:
- name: GITEA__actions__ENABLED
value: "true" # 👈 強制開啟 Actions 功能
ports:
- containerPort: 3000
name: http
- containerPort: 22
name: ssh
volumeMounts:
- name: gitea-data
mountPath: /data
volumes:
- name: gitea-data
hostPath:
path: /var/lib/gitea
---
apiVersion: v1
kind: Service
metadata:
name: gitea-service
namespace: default
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
nodePort: 30080 # 👈 瀏覽器輸入 http://10.0.0.1:30080 打開網頁
selector:
app: gitea
Apply it.
kubectl apply -f gitea.yaml
deployment.apps/gitea created
service/gitea-service created
root@chunk01:~/k8s# kubectl apply -f registry.yaml
deployment.apps/local-registry created
service/local-registry-service created
前往browser http://x.x.x.x:30080/
選SQLite3 最輕便
然後註冊帳號
讓它跑一下就完成
因為我要搭K3s, 所以需要再加上套件
gitea-runner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea-runner
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: gitea-runner
template:
metadata:
labels:
app: gitea-runner
spec:
containers:
- name: runner
image: gitea/act_runner:latest
env:
- name: GITEA_INSTANCE_URL
value: "http://cluster.local" # K3s 內部 Service 網址
- name: GITEA_RUNNER_REGISTRATION_TOKEN
value: "YOUR_COPIED_TOKEN_HERE" # 👈 貼上剛剛在 Gitea 後台複製的 Token
- name: GITEA_RUNNER_NAME
value: "k3s-master-runner"
- name: GITEA_RUNNER_LABELS
value: "ubuntu-latest:docker://node:16-bullseye,ubuntu-22.04:docker://node:16-bullseye"
securityContext:
privileged: true # 執行 Docker-in-Docker 需要特權
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
- name: data
mountPath: /data
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock # 借用 Master 的 Docker 引擎來編譯 Image
- name: data
hostPath:
path: /var/lib/gitea-runner
root@chunk01:~/k8s# kubectl apply -f gitea-runner.yaml
deployment.apps/gitea-runner created
###加上驗証,目前還沒打通內網###
mkdir -p /var/lib/local-registry/auth
docker run --entrypoint htpasswd httpd:2.4 -Bbn k3suser k3spassword | tee /var/lib/local-registry/auth/htpasswd
記得替換成你需要的帳、密
修改先前的registry.yaml 加上驗證帳、密
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-registry
namespace: kube-system
spec:
replicas: 1
selector:
matchLabels:
app: local-registry
template:
metadata:
labels:
app: local-registry
spec:
containers:
- name: registry
image: registry:2
env:
# 👇 加上這三行,開啟 htpasswd 驗證機制
- name: REGISTRY_AUTH
value: "htpasswd"
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: "Registry Realm"
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: "/var/lib/registry/auth/htpasswd"
ports:
- containerPort: 5000
volumeMounts:
- name: data
mountPath: /var/lib/registry
volumes:
- name: data
hostPath:
path: /var/lib/local-registry # 👈 對應 Master 本地目錄,內含 auth/htpasswd
---
apiVersion: v1
kind: Service
metadata:
name: local-registry-service
namespace: kube-system
spec:
type: NodePort
ports:
- port: 5000
targetPort: 5000
nodePort: 30500
selector:
app: local-registry
kubectl apply -f registry.yaml
deployment.apps/local-registry configured
service/local-registry-service unchanged
修改 Master 與 2 台 Worker 的 /etc/rancher/k3s/registries.yaml
mirrors:
"10.0.0.1:30500":
endpoint:
- "http://10.0.0.1:30500"
configs:
"10.0.0.1:30500":
auth:
username: "k3suser" # 改成你的帳號
password: "k3spassword" # 改成你的密碼
- Master 執行:
systemctl restart k3s - Worker 執行:
systemctl restart k3s-agent
再來自己建立兩個庫,一個放程式,一個放deployment
再來將以下的程式放在自己的程式碼下
name: 地端 CI 流水線
on:
push:
branches: [ "main" ]
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: 1. 檢查程式碼
uses: actions/checkout@v4
#使用官方 Action 搭配 Gitea Secrets 進行加密登入
- name: 2. 登入地端私有倉庫
uses: docker/login-action@v3
with:
registry: 10.0.0.1:30500
username: k3suser
password: ${{ secrets.REGISTRY_PASSWORD }} # 這邊用secrets, 記得到gitea 裡面新增
- name: 3. 編譯並推送 Docker Image 到 Master 倉庫
run: |
TAG=$(date +%Y%m%d-%H%M%S)
IMAGE_URI="10.0.0.1:30500/my-project/my-app:${TAG}"
docker build -t ${IMAGE_URI} .
docker push ${IMAGE_URI}
echo "最新映像檔已安全推送: ${IMAGE_URI}"
相同Gitea也加一個Token, 這樣能讓Argo幫你自動回寫版本號到Git, 可以方便追蹤
在 Gitea 產生 Access Token (通行證)
這張通行證是給 Argo CD Image Updater 用的,讓它能代表你進行 Git 提交。
- 登入地端 Gitea 網頁(
http://10.0.0.1:30080)。 - 點選右上角你的個人頭像 點選 「個人設定 (Settings)」。
- 在左側選單中,點選 「應用程式 (Applications)」。
- 在 「產生本地存取權杖 (Manage Access Tokens)」 區塊:
- Token Name:輸入
argocd-updater。 - 選取權限:為了安全,可以只勾選
repository(讀取與寫入) 即可。
- Token Name:輸入
- 點選 「產生權杖 (Generate Token)」。
- 關鍵:複製畫面上出現的長串 Token(它只會出現一次,離開網頁就看不到了)。
更新K3S 的資訊,把剛剛建立的告知
vi gitea-token-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: gitea-token-secret
namespace: argocd # 務必放在 argocd 命名空間
type: Opaque
stringData:
# 格式必須是:http://<Gitea帳號>:<Token>@<Gitea內網網址>
# 注意:因為是在 K3s 內部通訊,網址直接填 K3s 內部 Service 網址最快且最穩定
credential: "http://cluster.local"
Apply it.
root@chunk01:~/k8s# kubectl apply -f gitea-token-secret.yaml
secret/gitea-token-secret created
最後更新一下ARGO的Annotations.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
annotations:
# 1. 監控你的地端加密倉庫
argocd-image-updater.argoproj.io/image-list: my-app=10.0.0.1:30500/my-project/my-app
argocd-image-updater.argoproj.io/my-app.update-strategy: latest
# 2. 關鍵:設定回寫模式為 git,並指向剛才建立的 Secret
argocd-image-updater.argoproj.io/write-back-method: git
argocd-image-updater.argoproj.io/write-back-repository: git-secret:argocd/gitea-token-secret
spec:
project: default
source:
# 4. 讓 Argo CD 盯著你地端 Gitea 的配置庫
repoURL: 'http://cluster.local'
targetRevision: HEAD
path: .
destination:
server: 'https://default.svc'
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true # 開啟自動同步,YAML 一變更,Worker 馬上換新版 Image
補一下加secrets in Gitea
在 Gitea 網頁後台設定 Secret
- 開啟瀏覽器,進入你的 專案網頁
- 點選右上角的 「設定 (Settings)」
- 在左側選單中,依序點選 「Actions」 「Secrets」
- 點選右上角的 「Create New Secret」 鈕。
- 填入以下資訊:
- Name:
REGISTRY_PASSWORD(必須完全大寫且一字不差) - Value:
k3spassword(填入你剛才設定的 Registry 實際密碼)
- Name:
- 點選 「Save Secret」 保存。
這樣密碼就不會被看到,自動變成*
到此只要
git add ??? .
git commit -m "test 1 2 3 "
git push origin main
Gitea Actions 會在 Master 內網原地 Build Image、原地 Push 到 Registry、Argo CD 零延遲接手、2 台 Worker 透過 WireGuard 瞬間拉取並完成滾動更新。