如何建立私人的 docker registry 架設教學 (一)


一、建立自己的 docker registry 主機

參考docker registry 來源:https://hub.docker.com/_/registry

環境:CentOS 7

  • Docker-Registry:私倉主機(docker-registry.com.cc:5000)
  • nginx:連線至Docker_Registry主機進行 image push 流程

Docker-Registry主機上執行指令docker run -d -p 5000:5000 -v /home/docker-registry/storage:/var/lib/registry --name registry registry:latest

[root@Docker-Registry ~]# docker run -d -p 5000:5000 -v /home/docker-registry/storage:/var/lib/registry --name registry registry:latest
Unable to find image 'registry:latest' locally
Trying to pull repository docker.io/library/registry ... 
latest: Pulling from docker.io/library/registry
cbdbe7a5bc2a: Pull complete 
47112e65547d: Pull complete 
46bcb632e506: Pull complete 
c1cc712bcecd: Pull complete 
3db6272dcbfa: Pull complete 
Digest: sha256:8be26f81ffea54106bae012c6f349df70f4d5e7e2ec01b143c46e2c03b9e551d
Status: Downloaded newer image for docker.io/registry:latest
4c8c0b3e0981716be24d49c360a46c38ccdeaafd9f52ee541a250e8154f17941

指令說明:

-d 背景執行
-p 5000:5000 使用5000 port
-v 將本地的 /home/docker-registry/storage 關連至 /var/lib/registry
–name docker令名,可自定
registry:latest 取得docker hub 上 registry 最新的版本

建立完成後,可執行 docker ps -a 查看是否正常運行

[root@Docker-Registry ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
4c8c0b3e0981        registry:latest     "/entrypoint.sh /e..."   18 minutes ago      Up 18 minutes       0.0.0.0:5000->5000/tcp   registry

二、nginx主機設定

1.Docker-Registry主機設定,將 Registry 設定到 insecure 清單可忽略 TLS 協定

  • vim /etc/docker/daemon.json 修改daemon.json 檔
  • service docker restart 重起 Docker
[root@Docker-Registry ~]# vim /etc/docker/daemon.json
{
    "insecure-registries" : [
        "docker-registry.com.cc:5000"
    ],
    "hosts":[
        "unix:///var/run/docker.sock",
        "tcp://localhost:2375"
    ]
}
[root@Docker-Registry ~]# service docker restart

2.nginx 主機設定,因為私倉可能未設定「有效憑證」,所以在執行過程中會報錯Get https://docker-registry.com.cc:5000/v1/_ping: http: server gave HTTP response to HTTPS client

  • docker push docker-registry.com.cc:5000/php72-base 拉取私倉images 檔
[root@nginx ~]# docker push docker-registry.com.cc:5000/php72-base
The push refers to a repository [docker-registry.com.cc:5000/php72-base]
Get https://docker-registry.com.cc:5000/v1/_ping: http: server gave HTTP response to HTTPS client

Docker-Registry 主機域名(docker-registry.com.cc:5000)加入到nginx主機的 daemon.json 的 insecure 清單中的可忽略 TLS 協定,重起後即可正常使用。

  • vim /etc/docker/daemon.json 修改daemon.json 檔
  • service docker restart 重起 Docker
  • docker push docker-registry.com.cc:5000/php72-base 重新拉取私倉images 檔
[root@nginx ~]# vim /etc/docker/daemon.json
{
    "insecure-registries" : [
        "docker-registry.com.cc:5000"
    ]
}
[root@nginx ~]# service docker restart
[root@nginx ~]# docker push docker-registry.com.cc:5000/php72-base
The push refers to a repository [docker-registry.com.cc:5000/php72-base]
336461efe1e0: Pushed 
443db024a7a9: Pushed 
606d67d8e1b8: Pushed
latest: digest: sha256:3bf496ba417681c1e3de3efc0eb530a5fbd9eb854b9a758aa939493e9dccea43 size: 954

常見問題:

nginx 主機進行 docker push 時,Docker-Registry 主機 回報 retryingreceived unexpected HTTP status: 500 Internal Server Error

這問題比較常在 CentOS上發生,主要是 selinux 的權限問題

  • docker push docker-registry.com.cc:5000/php72-base 拉取私倉images 檔
[root@nginx ~]# docker push docker-registry.com.cc:5000/php72-base
The push refers to a repository [docker-registry.com.cc:5000/php72-base]
336461efe1e0: Retrying in 8 seconds 
443db024a7a9: Retrying in 8 seconds 
606d67d8e1b8: Retrying in 8 seconds
received unexpected HTTP status: 500 Internal Server Error

進入到 Docker-Registry 主機 進行確認

  • 輸出docker 日誌 journalctl -u docker.service > /tmp/docker.log
  • 查看輸出的日誌 vim /tmp/docker.log
  • 查到 permission denied 權限問題
[root@Docker-Registry]# journalctl -u docker.service > /tmp/docker.log
[root@Docker-Registry]# vim /tmp/docker.log
12月 22 11:35:36 Docker-Registry dockerd-current[42739]: 192.168.0.4 - - [22/Dec/2020:03:35:36 +0000] "HEAD /v2/php72-base/blobs/sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4 HTTP/1.1" 404 157 "" "docker/1.13.1 go/go1.10.3 kernel/3.10.0-1160.6.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.13.1 \(linux\))"
12月 22 11:35:36 Docker-Registry dockerd-current[42739]: time="2020-12-22T03:35:36.881712886Z" level=error msg="response completed with error" err.code=unknown err.detail="filesystem: mkdir /var/lib/registry/docker/registry/v2/repositories/php72-base/_uploads/52aaf259-53fe-40d2-8eaf-c8cd7ee698b3: permission denied" err.message="unknown error" go.version=go1.11.2 http.request.host="docker-registry.com.cc:5000" http.request.id=64007e2f-75ad-418f-83df-f1daac4afa35 http.request.method=POST http.request.remoteaddr="192.168.0.4:49976" http.request.uri="/v2/php72-base/blobs/uploads/" http.request.useragent="docker/1.13.1 go/go1.10.3 kernel/3.10.0-1160.6.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.13.1 (linux))" http.response.contenttype="application/json; charset=utf-8" http.response.duration=1.286217ms http.response.status=500 http.response.written=250 vars.name=php72-base
12月 22 11:35:36 Docker-Registry dockerd-current[42739]: 192.168.0.4 - - [22/Dec/2020:03:35:36 +0000] "POST /v2/php72-base/blobs/uploads/ HTTP/1.1" 500 250 "" "docker/1.13.1 go/go1.10.3 kernel/3.10.0-1160.6.1.el7.x86_64 os/linux arch/amd64 UpstreamClient(Docker-Client/1.13.1 \(linux\))"

處理方式:

進入到 Docker-Registry 主機 進行以下流程

  • 執行 setenforce 0 進行暫時關閉 selinux 功能
  • 也可以在 vim /etc/selinux/configSELINUX=disabled,重開機後會自動關閉
  • 登入至nginx主機執行:docker push docker-registry.com.cc:5000/php72-base 上傳私倉images 檔 即可通過上傳
[root@Docker-Registry]# setenforce 0
[root@Docker-Registry]# vim /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

//登入至nginx主機執行
[root@nginx ~]# docker push docker-registry.com.cc:5000/php72-base
The push refers to a repository [docker-registry.com.cc:5000/php72-base]
336461efe1e0: Pushed 
443db024a7a9: Pushed 
606d67d8e1b8: Pushed
latest: digest: sha256:3bf496ba417681c1e3de3efc0eb530a5fbd9eb854b9a758aa939493e9dccea43 size: 954

延伸教學:

如何在 nginx 主機上的 images 打好tag上傳至 Docker-Registry 主機上?

  • 執行 docker images 查看本地 images 檔
  • 執行 docker tag php72-base docker-registry.com.cc:5000/php72-base 本地images(php72-base) 慾建立的 tag images(docker-registry.com.cc:5000/php72-base)
  • 執行 docker push docker-registry.com.cc:5000/php72-base
[root@nginx ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
php72-base          latest              4edd7e99e741        15 months ago       807 MB
[root@nginx ~]# docker tag php72-base docker-registry.com.cc:5000/php72-base
[root@nginx ~]# docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
docker.onepic.cc:5000/php72-base   latest              4edd7e99e741        15 months ago       807 MB
php72-base                         latest              4edd7e99e741        15 months ago       807 MB
[root@nginx ~]# docker push docker-registry.com.cc:5000/php72-base
The push refers to a repository [docker-registry.com.cc5000/php72-base]
336461efe1e0: Layer already exists 
443db024a7a9: Layer already exists 
606d67d8e1b8: Layer already exists 
latest: digest: sha256:3bf496ba417681c1e3de3efc0eb530a5fbd9eb854b9a758aa939493e9dccea43 size: 954