私有Docker倉庫

言午日尧耳总發表於2024-11-11
  • 影片版本 > BiliBili
  • 由於眾所周不知的原因,Docker國內映象被禁用
  • 個人電腦可以使用魔法上網解決,但在多伺服器的情況下不方便,提供瞭如下解決方案

    • 其中一臺電腦設定代理(魔法上網),從Docker公共庫拉取映象(docker pull)
    • 轉換映象標籤(docker tag)
    • 推送到內網私有倉庫(docker push)
    • 其他內網伺服器都可以從私有倉庫拉取映象使用了(docker pull)

registry.png

倉庫方案

  • 使用Registry搭建私有倉庫(該倉庫僅服務,搭配UI介面方便使用)
  • Registry官網: https://distribution.github.io/distribution
  • 可選UI介面

    • docker-registry-browser(推薦): https://github.com/klausmeyer/docker-registry-browser
    • docker-registry-ui(夠用): https://joxit.dev/docker-registry-ui/
    • docker-registry-web(勿用,巨醜,斷更): https://github.com/mkuchin/docker-registry-web
  • 該方案適合小微企業,或起步階段
  • 其他倉庫方案

    • Harbor: 優秀但重量級,不缺伺服器資源可以直接上這個,Harbor官網
    • Nexus: Maven私有倉庫,Nexus3之後也可以放Docker映象,但是互動不好用,Nexus3官網

魔法環境

  • 本文章使用的是"Clash",請求轉發到7890埠就能魔法上網
  • 這臺可上魔法環境的電腦/伺服器,當做"代理節點"

配置

# 編輯Docker配置
vim /etc/docker/daemon.json

# 如下配置後,重啟服務
systemctl restart docker
  • 代理配置如下

    • "127.0.0.1:7890" 為VPN代理地址,要修改為自己的代理地址
{
    "proxies": {
        "http-proxy": "http://127.0.0.1:7890",
        "https-proxy": "http://127.0.0.1:7890"
    }
}

下載映象

  • 先從公共倉庫先下載使用到的映象
  • 以下版本是當前最新的穩定版(當前時間:2024-11-03)
docker pull registry:2.8.3
docker pull klausmeyer/docker-registry-browser:1.7.4
  • 映象打包成檔案
docker save registry:2.8.3 > registry_2.8.3.image
docker save klausmeyer/docker-registry-browser:1.7.4 > docker-registry-browser_1.7.4.image
  • 檔案上傳到要部署倉庫的伺服器
  • docker載入映象
docker load < registry_2.8.3.image
docker load < docker-registry-browser_1.7.4.image

部署(無鑑權)

  • 部署倉庫的伺服器在內網中,且不會開放外網訪問,可以不需要鑑權

    • 如果伺服器在公網,或者會開放公網訪問,看下面的有鑑權版本
  • 服務元件:registry + docker-registry-browser
  • 下面是博主的環境資訊,大家根據自己的環境,替換為自己的

    • 內網IP:192.168.1.3
    • 倉庫埠:8000
    • 倉庫UI埠:8001

使用Docker

  • 部署倉庫服務
  • 驗證

    • 訪問"http://IP:8000/v2/"
    • 返回"{}",則成功
# 刪除下面命令的註釋才能執行
docker run --name registry-server \
  --restart always \
  -p 8000:5000 \
  -v ./data:/var/lib/registry  \                # 替換為自己的持久化地址,無持久化需求去掉這個引數
  -e REGISTRY_STORAGE_DELETE_ENABLED=true \     # 是否允許刪除映象
  -d registry:2.8.3
  • 部署倉庫UI
  • 驗證

    • 瀏覽器訪問"http://IP:8001"
# 刪除下面命令的註釋才能執行
docker run --name registry-ui \
  --restart always \
  -p 8001:8080 \
  -e DOCKER_REGISTRY_URL=http://192.168.1.3:8000/v2 \   # 倉庫地址,替換為自己倉庫的IP及埠號
  -e SECRET_KEY_BASE=$(openssl rand -hex 64) \          # 金鑰使用"openssl rand -hex 64"生成
  -e PUBLIC_REGISTRY_URL=192.168.1.3:8000 \             # 複製PULL命令的地址,將IP改為自己的IP/域名和宿主機埠號
  -e ENABLE_DELETE_IMAGES=true \                        # 是否顯示刪除映象按鈕
  -d klausmeyer/docker-registry-browser:1.7.4

使用Docker Compose

  • 生成金鑰
# openssl生成隨機金鑰
openssl rand -hex 64
# 複製列印的金鑰,手動替換yaml中的"SECRET_KEY_BASE"的值
  • 建立"docker-compose.yaml"檔案,內容如下
version: '1.0'

services:
  registry-server:
    container_name: registry-server
    image: registry:2.8.3
    restart: always
    ports:
      - 8000:5000
    environment:
      - REGISTRY_STORAGE_DELETE_ENABLED=true    # 是否允許刪除映象
    volumes:
      - ./data:/var/lib/registry                # 替換為自己的持久化地址,無持久化需求去掉這個引數

  retistry-ui:
    container_name: registry-ui
    image: klausmeyer/docker-registry-browser:1.7.4
    restart: always
    ports:
      - 8001:8080
    environment:
      - DOCKER_REGISTRY_URL=http://registry-server:5000/v2  # registry埠號,不是宿主機埠號,所以不要改
      - PUBLIC_REGISTRY_URL=192.168.1.3:8000                # 複製PULL命令的地址,將IP改為自己的IP/域名和宿主機埠號
      - SECRET_KEY_BASE=手動替換生成的金鑰                   # 修改金鑰,使用"openssl rand -hex 64"命令生成一個
      - ENABLE_DELETE_IMAGES=true                           # 是否顯示刪除映象按鈕
  • 啟動命令
# 啟動服務
docker compose -f docker-compose.yaml up -d

# 關閉服務
docker compose -f docker-compose.yaml down
  • 驗證結果

    • 瀏覽器訪問"http://IP:8001"

部署(簡單鑑權)

  • 使用賬號密碼的簡單鑑權

    • pull/push命令前,先"docker login"登入
    • 倉庫UI訪問需輸入賬號密碼(配置了預設賬號密碼,不需要輸入)
  • 在上面無鑑權版本的基礎上加幾個配置就能實現鑑權
  • 服務元件:registry + docker-registry-browser
  • 下面是博主的環境資訊,大家根據自己的環境,替換為自己的

    • 內網IP:192.168.1.3
    • 倉庫埠:8000
    • 倉庫UI埠:8001

htpasswd密碼檔案

  • 使用htpasswd生成密碼檔案
htpasswd -Bbn username password > /path/to/file

# 示例
# htpasswd -Bbn xxc 123456 > ./htpasswd

使用Docker

  • 部署倉庫服務
  • 驗證

    • 訪問"http://IP:8000/v2/"
    • 返回"{}",則成功
# 刪除下面命令的註釋才能執行
docker run --name registry-server \
  --restart always \
  -p 8000:5000 \
  -v ./data:/var/lib/registry  \                # 替換為自己的持久化地址,無持久化需求去掉這個引數
  -v ./htpasswd:/auth/htpasswd \                # 替換為自己的htpasswd檔案(上個步驟生成)
  -e REGISTRY_STORAGE_DELETE_ENABLED=true \     # 是否允許刪除映象
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=basic-realm \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -d registry:2.8.3
  • 部署倉庫UI
  • 驗證

    • 瀏覽器訪問"http://IP:8001"
    • 如果設定了"BASIC_AUTH_USER"和"BASIC_AUTH_PASSWORD"引數,則與無鑑權感覺沒有差別
    • 如果未設定了,則需要輸入賬號密碼才能檢視倉庫
# 刪除下面命令的註釋才能執行
docker run --name registry-ui \
  --restart always \
  -p 8001:8080 \
  -e DOCKER_REGISTRY_URL=http://192.168.1.3:8000/v2 \   # 倉庫地址,替換為自己倉庫的IP及埠號
  -e SECRET_KEY_BASE=$(openssl rand -hex 64) \          # 金鑰使用"openssl rand -hex 64"生成
  -e PUBLIC_REGISTRY_URL=192.168.1.3:8000 \             # 複製PULL命令的地址,將IP改為自己的IP/域名和宿主機埠號
  -e ENABLE_DELETE_IMAGES=true \                        # 是否顯示刪除映象按鈕
  -e BASIC_AUTH_USER=xxc \                              # 配置預設賬號(htpasswd生成的),刪除該引數則需要手動輸入賬號
  -e BASIC_AUTH_PASSWORD=123456 \                       # 配置預設密碼(htpasswd生成的),刪除該引數則需要手動輸入密碼
  -d klausmeyer/docker-registry-browser:1.7.4

使用Docker Compose

  • 生成金鑰
# openssl生成隨機金鑰
openssl rand -hex 64
# 複製列印的金鑰,手動替換yaml中的"SECRET_KEY_BASE"的值
  • 建立"docker-compose.yaml",當前目錄結構如下
registry
    ├─ htpasswd
    └─ docker-compose.yml
  • "docker-compose.yaml"內容如下
version: '2.0'

services:
  registry-server:
    container_name: registry-server
    image: registry:2.8.3
    restart: always
    ports:
      - 8000:5000
    environment:
      - REGISTRY_STORAGE_DELETE_ENABLED=true    # 是否允許刪除映象
      - REGISTRY_AUTH=htpasswd
      - REGISTRY_AUTH_HTPASSWD_REALM=basic-realm
      - REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
    volumes:
      - ./data:/var/lib/registry                # 替換為自己的持久化地址,無持久化需求去掉這個引數
      - ./htpasswd:/auth/htpasswd               # 掛載htpasswd命令生成的密碼檔案

  retistry-ui:
    container_name: registry-ui
    image: klausmeyer/docker-registry-browser:1.7.4
    restart: always
    ports:
      - 8001:8080
    environment:
      - DOCKER_REGISTRY_URL=http://registry-server:5000/v2  # registry埠號,不是宿主機埠號,所以不要改
      - PUBLIC_REGISTRY_URL=192.168.1.3:8000                # 複製PULL命令的地址,將IP改為自己的IP/域名和宿主機埠號
      - SECRET_KEY_BASE=手動替換生成的金鑰                   # 修改金鑰,使用"openssl rand -hex 64"命令生成一個
      - ENABLE_DELETE_IMAGES=true                           # 是否顯示刪除映象按鈕
      - BASIC_AUTH_USER=xxc                                 # 配置預設賬號(htpasswd生成的),刪除該引數則需要手動輸入
      - BASIC_AUTH_PASSWORD=123456                          # 配置預設密碼(htpasswd生成的),刪除該引數則需要手動輸入
  • 啟動命令
# 啟動服務
docker compose -f docker-compose.yaml up -d

# 關閉服務
docker compose -f docker-compose.yaml down
  • 驗證結果

    • 瀏覽器訪問"http://IP:8001"

代理節點

配置

  • 該節點使用了代理,私有倉庫IP被代理導致無法訪問,所以禁用部分IP的代理
  • 修改配置

    • 增加 "proxies.no-proxy" 禁止代理私有倉庫的IP
    • 增加 "insecure-registries" ,將私有倉庫地址新增到信任列表
  • 重啟Docker
{
    "proxies": {
        "http-proxy": "http://127.0.0.1:7890",
        "https-proxy": "http://127.0.0.1:7890",
        "no-proxy": "localhost,127.0.0.1,192.168.1.3"
    },
    "insecure-registries": [
        "192.168.1.3:8000"
    ]
}
# 編輯Docker配置
vim /etc/docker/daemon.json

# 如下配置後,重啟服務
systemctl restart docker

使用

# 從公共庫拉取映象
docker pull alpine:latest

# 修改Tag
docker tag alpine:latest 192.168.1.3:8000/alpine:latest

# 登入(有鑑權的話)
docker login -u username -p password 192.168.1.3:8000

# 映象推送到私有倉庫
docker push 192.168.1.3:8000/alpine:latest

伺服器節點

允許私有倉庫

  • 增加 "insecure-registries" ,將私有倉庫地址新增到信任列表
{
    "insecure-registries": [
        "192.168.1.3:8000"
    ]
}
# 編輯Docker配置
vim /etc/docker/daemon.json

# 如下配置後,重啟服務
systemctl restart docker

使用

  • 執行直接帶上私有倉庫地址

    • 映象必須提前使用代理節點上傳
# 登入(有鑑權的話)
docker login -u username -p password 192.168.1.3:8000

# 拉取映象,命令可以從UI介面複製
docker pull 192.168.1.3:8000/alpine:latest

# 使用(和正常命令一樣使用,只是前面加了私有可的地址和埠號)
docker run -d 192.168.1.3:8000/alpine:latest
  • 如果是Dockerfile打包映象
  • tag名稱加上私有倉庫地址
# 在執行build命令
docker build -t 192.168.1.3:8000/xxx:latest .

# 登入(有鑑權的話)
docker login -u username -p password 192.168.1.3:8000

# 上傳私有倉庫
docker push 192.168.1.3:8000/xxx:latest

常見異常

EOF

  • 原因:倉庫地址錯誤
  • 解決方法:確認倉庫IP及埠號是否正確
# 推送私有倉庫映象
docker push 192.168.1.3:8000/alpine:latest
# The push refers to repository [192.168.1.5:8000/alpine]
# Get "https://192.168.1.5:8000/v2/": EOF

server gave HTTP response to HTTPS client

  • 原因:未設定私有倉庫
  • 解決方法:修改/etc/docker/daemon.json,將倉庫地址加入信任列表
docker push 192.168.1.3:8000/alpine:latest
# 報錯如下
The push refers to repository [192.168.1.3:8000/alpine]
Get "https://192.168.1.3:8000/v2/": http: server gave HTTP response to HTTPS client

no basic auth credentials

  • 原因:未登入
  • 解決方法:使用"docker login"登入
docker push 192.168.1.3:8000/alpine:latest
# 報錯如下
The push refers to repository [192.168.1.3:8000/alpine]
63ca1fbb43ae: Preparing 
no basic auth credentials

參考文章

  • https://baijiahao.baidu.com/s?id=1803388229356954283
  • https://www.cnblogs.com/netcore3/p/16982828.html
  • https://www.cnblogs.com/chen2ha/p/14787695.html
  • https://developer.aliyun.com/article/1094892

相關文章