註:筆者居住於韓國,部分內容包含韓國特有的背景。
1. 前言
既然已經把基礎建設準備好了,我們順便也來自己建一個私有 Docker Registry 吧。
我自己的情況是,後來在這個叢集上另外部署了一些個人伺服器,為了管理這些容器映像,所以使用了私有 Registry。
如果你願意付費使用 Dockerhub,或者使用公開映像就足夠,那麼本指南可以跳過。
由於我們會使用私有 Repo,因此 ID 和密碼的設定也會一併進行!
2. 安裝
這次也使用 ArgoCD 快速安裝吧!
modules/docker-registry-system/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-docker-registry-pvc
namespace: docker-registry-system
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn-ssd
resources:
requests:
storage: 300Gi我自己有運行 ML 伺服器,映像體積較大,所以寬鬆地分配了 300Gi。你可以依照自己的需求調整。
modules/docker-registry-system/service.yaml
apiVersion: v1
kind: Service
metadata:
name: registry-service
namespace: docker-registry-system
spec:
selector:
app: registry
type: LoadBalancer
ports:
- name: docker-port
protocol: TCP
port: 5000
targetPort: 5000
loadBalancerIP: 192.168.0.202modules/docker-registry-system/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry
namespace: docker-registry-system
spec:
replicas: 1
selector:
matchLabels:
app: registry
template:
metadata:
labels:
app: registry
name: registry
spec:
nodeSelector:
node-type: worker
containers:
- name: registry
image: registry:2
ports:
- containerPort: 5000
env:
- name: REGISTRY_HTTP_ADDR
value: 0.0.0.0:5000
- name: REGISTRY_AUTH
value: htpasswd
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: docker-registry
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: /auth/registry.password
- name: REGISTRY_STORAGE_DELETE_ENABLED
value: "true"
volumeMounts:
- name: lv-storage
mountPath: /var/lib/registry
subPath: registry
- name: docker-registry-account-htpasswd
mountPath: /auth
readOnly: true
volumes:
- name: lv-storage
persistentVolumeClaim:
claimName: longhorn-docker-registry-pvc
- name: docker-registry-account-htpasswd
secret:
secretName: docker-registry-account-htpasswd透過名為 docker-registry-account-htpasswd 的 Secret 指定 Registry 所使用的 ID 與密碼。詳細內容後續會說明。
modules/docker-registry-system/sealed-docker-registry-account-htpasswd.yaml
Secrets 的設定稍微複雜一點。我們 Step By Step 來吧!
- 在 Control Node 上執行
htpasswd -Bbn <id> <password>,取得 Docker Registry 要使用的 id/password 字串。 - 使用在 7-1 中建置的 kubeseal-webgui 將該 Secret 加密。

- 將加密後的 Secret 貼到 sealed-docker-registry-account-htpasswd.yaml 中。
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: docker-registry-account-htpasswd
namespace: docker-registry-system
annotations: {}
spec:
encryptedData:
registry.password: dfadf...modules/docker-registry-system/ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: docker-registry-ingress
namespace: docker-registry-system
spec:
tls:
certResolver: le
routes:
- kind: Rule
match: Host(`<要使用的 subdomain>`)
services:
- name: registry-service
port: 50003. 確認是否正常運作
確認正常運作後再進行部署!
部署完成後,確認是否能用 id/password 正常登入。
在已安裝 docker 的機器上,於終端機執行以下指令。
docker login <my-registry.lemon.com>接著輸入 id/password,確認是否能正常登入。
4. 從私有 Registry 拉取映像的方法
接下來需要了解如何從需要 Id/Password 的私有 Registry 拉取映像,否則上傳的映像也無法使用對吧。
我先分享我自己使用的方法。也許有更乾淨的做法,如果你知道的話歡迎告訴我!
假設要在名為 auth-server-system 的 namespace 中使用:
- 使用
kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>在 default Namespace 中建立一個名為 regcred 的 secret。 - 使用
kubectl get secret regcred --output=yaml > secret.yaml將 secret 資訊存到 secret.yaml。該 Secret 請另外備份。 - 輸入
kubectl delete secret regcred刪除剛才在 default namespace 建立的 secret。 - 之後將第 2 步 Secret 的 Namespace 改成你要使用的 namespace(例如:auth-server-system)。
apiVersion: v1
data:
.dockerconfigjson: ddfadf...
kind: Secret
metadata:
name: regcred
namespace: auth-server-system # 每次修改這裡
type: kubernetes.io/dockerconfigjson- 接著執行
cat secret.yaml | kubeseal --controller-namespace=sealed-secrets-system --controller-name=sealed-secrets -oyaml > sealed-regcred.yaml指令產生 Sealed Secret。 - 部署時一起部署 Sealed regcred,並在 Deployment 中如下加入 ImagePullSecret。
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-server
namespace: auth-server-system
spec:
replicas: 1
selector:
matchLabels:
app: auth-server
template:
metadata:
labels:
app: auth-server
name: auth-server
spec:
nodeSelector:
node-type: worker
containers:
- name: auth-server
image: registry.lemon.com/auth_server_repository:2023.12.10.1
imagePullPolicy: Always
ports:
- name: http
containerPort: 80
imagePullSecrets:
- name: regcred # 加入這個5. 結語
恭喜!現在你已經完成私有 Docker Registry 的建置,
可以透過 Id/Password 安全地保護自己的映像了!
下一篇將介紹如何透過 Web UI 管理映像,以及 Docker GC 的方法。

Comments