跳轉至內容
回上頁

docker-自架私有映像檔倉庫

發布於:  at  AM 08:00

Who

每當開發者開發完成時,需要把打包好的image供於其它環境使用時,就得必須上傳至私有倉庫(push)供以其它人佈署(pull).

本教學會使用VMware所開發的開源image管理平台,進行image管理

伺服端: 供存放自建置的映像檔位置服務

前置

下戴 & 安裝前設置

  1. 下戴安裝檔(目前版本)
$ curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | grep browser_download_url | cut -d '"' -f 4 | grep '\.tgz$' | wget -i -
  1. 解壓縮剛下戴好的安裝檔(本教學使用offline版本): $ tar xzvf harbor-offline-installer-[version].tgz
  2. 完成後,您會得到一個目錄,則請把該目錄復制至/usr/local
    $ cp -R ./harbor /usr/local
  3. 請到復制好的目錄下: $ cd /usr/local/harbor

修改相關配置

00 前置

請從範本(harbor.yml.tmpl)修改配置(harbor.yml)

$ cp harbor.yml.tmpl harbor.yml
$ nano harbor.yml

01 需修改 harbor.yml 部分

03 開始配置且初始化環境

當初始化環境時,安裝程式會把剛配置完成harbor.yml轉換成供以啟動環境的docker-compose.yml,且同時會啟動服務

$ ./prepare
$ ./install.sh --with-trivy
[Step 0]: checking if docker is installed ...

Note: docker version: 28.2.2

[Step 1]: checking docker-compose is installed ...

Note: Docker Compose version v2.36.2

[Step 2]: loading Harbor images ...
Loaded image: goharbor/nginx-photon:v2.13.1
Loaded image: goharbor/registry-photon:v2.13.1
Loaded image: goharbor/trivy-adapter-photon:v2.13.1
Loaded image: goharbor/harbor-db:v2.13.1
Loaded image: goharbor/harbor-registryctl:v2.13.1
Loaded image: goharbor/harbor-exporter:v2.13.1
Loaded image: goharbor/redis-photon:v2.13.1
Loaded image: goharbor/harbor-jobservice:v2.13.1
Loaded image: goharbor/prepare:v2.13.1
Loaded image: goharbor/harbor-portal:v2.13.1
Loaded image: goharbor/harbor-core:v2.13.1
Loaded image: goharbor/harbor-log:v2.13.1


[Step 3]: preparing environment ...

[Step 4]: preparing harbor configs ...
prepare base dir is set to /usr/local/harbor
Clearing the configuration file: /config/portal/nginx.conf
Clearing the configuration file: /config/log/logrotate.conf
Clearing the configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
copy /data/secret/tls/harbor_internal_ca.crt to shared trust ca dir as name harbor_internal_ca.crt ...
ca file /hostfs/data/secret/tls/harbor_internal_ca.crt is not exist
copy  to shared trust ca dir as name storage_ca_bundle.crt ...
copy None to shared trust ca dir as name redis_tls_ca.crt ...
Generated and saved secret to file: /data/secret/keys/secretkey
Successfully called func: create_root_cert
Generated configuration file: /config/trivy-adapter/env
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir


Note: stopping existing Harbor instance ...


[Step 5]: starting Harbor ...
[+] Running 11/11
 ✔ Network harbor_harbor        Created                                                                         0.2s 
 ✔ Container harbor-log         Started                                                                         0.5s 
 ✔ Container redis              Started                                                                         0.9s 
 ✔ Container harbor-db          Started                                                                         0.9s 
 ✔ Container harbor-portal      Started                                                                         1.0s 
 ✔ Container registryctl        Started                                                                         1.1s 
 ✔ Container registry           Started                                                                         0.9s 
 ✔ Container trivy-adapter      Started                                                                         1.2s 
 ✔ Container harbor-core        Started                                                                         1.2s 
 ✔ Container nginx              Started                                                                         1.7s 
 ✔ Container harbor-jobservice  Started                                                                         1.5s 
 ✔ ----Harbor has been installed and started successfully.----

關於服務相關配置

生命週期

由於 harbor 是用docker-compose.yml進行服務管理。所以使用時,您必須了解 docker compose 的指令!

檢視運行記錄

Harbor 在運行時,會把相關 logs 存放至 /var/log/harbor/ 目錄下。

$ ls /var/log/harbor/
core.log        portal.log      proxy.log  registryctl.log  trivy-adapter.log
jobservice.log  postgresql.log  redis.log  registry.lo

讓 Systemd 管理相關服務

為了解決 Docker 啟動後 Harbor 無法同步啟動的問題,我們需撰寫一個服務設定檔,並利用 Systemd 進行服務管理,以實現 Harbor 隨系統自動啟動。

  1. 請在/etc/systemd/system 目錄下建立 harbor.service , 且填入如下內容
    [Unit]
    Description=harbor
    After=docker.service systemd-networkd.service systemd-resolved.service
    Requires=docker.service
    Documentation=http://github.com/vmware/harbor
    
    [Service]
    Type=simple
    Restart=on-failure
    RestartSec=5
    ExecStart=/usr/bin/docker compose -f  /usr/local/harbor/docker-compose.yml up
    ExecStop=/usr/bin/docker compose -f  /usr/local/harbor/docker-compose.yml down
    
    [Install]
    WantedBy=multi-user.target
  2. 啟用相關服務
    $ sudo systemctl enable --now harbor.service
    $ sudo systemctl daemon-reload
  3. 檢視是否正常啟用
    $ sudo systemctl status harbor
    ● harbor.service - harbor
         Loaded: loaded (/etc/systemd/system/harbor.service; enabled; preset: disabled)
         Active: active (running) since Fri 2025-08-29 15:49:46 CST; 7s ago
     Invocation: a88566a595cc45f8980b963e6c208637
           Docs: http://github.com/vmware/harbor
       Main PID: 19675 (docker)
          Tasks: 24 (limit: 48791)
         Memory: 28.2M (peak: 32.4M)
            CPU: 233ms
         CGroup: /system.slice/harbor.service
                 ├─19675 /usr/bin/docker compose -f /usr/local/harbor/docker-compose.yml up
                 └─19695 /usr/libexec/docker/cli-plugins/docker-compose compose -f /usr/local/harbor/docker-compose.yml>
    
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/worker/c>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/lcm/cont>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/worker/c>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/sync/sch>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/runtime/>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/sync/sch>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/sync/sch>
     8月 29 15:49:48 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:48Z [INFO] [/jobservice/sync/sch>
     8月 29 15:49:53 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:53Z [INFO] [/jobservice/worker/c>
     8月 29 15:49:53 SWT-CIserver docker[19695]: harbor-jobservice  | 2025-08-29T07:49:53Z [INFO] [/jobservice/worker/c>

客戶端: 從倉庫拉取/上傳映像檔

如何使 docker 允許上傳或下戴未經 SSL 驗証的私有倉庫

由於是自架環境(無相關SSL驗証),必須在 Client 端部分,得手動建立 Docker Engine 的相關配置文件(/etc/docker/daemon.json).

  1. 請修改: /etc/docker/daemon.json
    {
       "insecure-registries": [
            "localhost:8081",
            "localhost:8443"
        ]
    }
  2. 修改完成後,請務必重啟系統上的docker服務: $ sudo systemctl restart docker.service
  3. 測試是否可使用
    $ docker login  192.168.45.51:8081
    Username: swt_dev
    Password: 
    
    WARNING! Your credentials are stored unencrypted in '/home/user/.docker/config.json'.
    Configure a credential helper to remove this warning. See
    https://docs.docker.com/go/credential-store/
    
    Login Succeeded

Pull/Push Image

配合 Jenkins 把流程自動化

在試完手動推送後,您可選擇在 Jenkins 內寫 pipeline 腳本來跑自動化程序,把己經建置完成的 image 丟到 Harbor 上.

  1. 先新增一個Credential: 用於定義pipeline的環境變數
    • 位置: [管理Jenkins] -> [Credentials] -> [System] -> [Global credentials (unrestricted)]
      1. [Stores coped to Jenkins]部份,找到[Domains]欄位,然後按下[(global)]
      2. 按下 [+ Add Credentials]
      3. 輸入Harbor相關資料
        • username: 對映至HARBOR_USER
        • password: 對映至HARBOR_PSWD
        • ID: harbor-user
  2. 開始撰寫pipeline腳本
        pipeline {
        agent any
    
        stages {
            stage('Send To Harbor') {
                steps {
                    script {
                        def timestamp = sh(script: "date +%Y%m%d%H%M%S", returnStdout: true).trim()
                        def imageName = "frontend"
                        def imageTag = "${imageName}:${timestamp}"
                        def latestTag = "${imageName}:latest"
                        def registry = "localhost:8081/swt_erp"
    
                        withCredentials([usernamePassword(credentialsId: 'harbor-user', usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PSWD')]) {
                            sh(script: """
                                docker login ${registry} -u=\"${HARBOR_USER}\" --password-stdin <<<\"${HARBOR_PSWD}\"
                                docker tag build_frontend-frontend_deno ${registry}/${imageTag}
                                docker tag build_frontend-frontend_deno ${registry}/${latestTag}
                                docker push ${registry}/${imageTag}
                                docker push ${registry}/${latestTag}
                            """, credentials: [
                                usernamePassword(credentialsId: 'harbor-user', usernameVariable: 'HARBOR_USER', passwordVariable: 'HARBOR_PSWD')
                            ])
                        }
                    }
                 }
              }
          }
     }

REF

不想吃土嗎?就利用開源軟體打造CICD Pipeline吧!

Medium

Harbor Docs

Other



下一篇
Deno-在固定時間的排程管理