天天看點

企業——Docker容器之docker私有倉庫的搭建

一.什麼是Docker 倉庫?

  倉庫是集中存放鏡像檔案的場所。有時候會把倉庫和倉庫注冊伺服器(Registry)混為一談,并不嚴格區分。實際上,倉庫注冊伺服器上往往存放着多個倉庫,每個倉庫中又包含了多個鏡像,每個鏡像有不同的标簽(tag)。(之間的關系是:倉庫注冊伺服器 —> 各種各樣的倉庫 —> 每個倉庫中有大量的鏡像)

  倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。最大的公開倉庫是 Docker Hub,存放了數量龐大的鏡像供使用者下載下傳。 國内的公開倉庫包括 Docker Pool 等,可以提供大陸使用者更穩定快速的通路。私有倉庫和共有倉庫類似,不同之處在于前者不會在搜尋結果中顯示,也沒有通路它的權限。隻有使用者設定為合作者才能通路私有倉庫。

  使用者也可以在本地網絡内建立一個私有倉庫。當使用者建立了自己的鏡像之後就可以使用 push 指令将它上傳到公有或者私有倉庫,這樣下次在另外一台機器上使用這個鏡像時候,隻需要從倉庫上 pull 下來就可以了。

二、 私有倉庫registry的優勢

  有時候使用Docker Hub這樣的公共倉庫可能不友善,這種情況下使用者可以使用registry建立一個本地倉庫供私人使用。

  使用私有倉庫有許多優點:

    1)節省網絡帶寬,針對于每個鏡像不用每個人都去中央倉庫上面去下載下傳,隻需要從私有倉庫中下載下傳即可;

    2)提供鏡像資源利用,針對于公司内部使用的鏡像,推送到本地的私有倉庫中,以供公司内部相關人員使用。

  目前Docker Registry已經更新到了v2,最新版的Docker已不再支援v1。Registry v2使用Go語言編寫,在性能和安全性上做了很多優化,重新設計了鏡像的存儲格式。如果需要安裝registry v2,隻需下載下傳registry:2.2即可。

  Docker官方提供的工具docker-registry可以用于建構私有的鏡像倉庫。

三.建立私有倉庫

1.Docker 官方已經把倉庫封裝為鏡像,直接通過啟動容器就可以部署完成倉庫

  cd /opt/registry/

  ls

    docker

  docker load -i registry.tar  ##官方将建立私有倉庫封裝成了鏡像

  docker images registry (注意标簽TAG)

    REPOSITORY TAG IMAGE ID CREATED SIZE

    registry 2.3.1 83139345d017 3 years ago 166MB

  docker run -d --name registry -p 5000:5000 -v /opt/registry:/var/lib/registry registry:2.3.1  ##就相當于安裝了一個空的倉庫,運作上述指令後,會從DockerHub上拉取registry鏡像并在本地啟動Registry服務,并監聽5000端口。上面的操作已經将鏡像導入了,會直接使用上面的鏡像。基于容器的運作方式

  docker load -i registry  ###加載一個已經存在的鏡像  

  docker tag registry localhost:5000/registry  ##修改加載的鏡像的标簽,将原有的鏡像标記為本地的一個版本

  docker push localhost:5000/registry  ##将修改好的鏡像上傳到私有的倉庫裡

  docker rmi localhost:5000/registry   ###在這之前先執行如下指令移除本地未使用的鏡像,保證拉取的鏡像是從本地倉庫的,而不是從緩存中擷取的。

  docker pull localhost:5000/registry  ##拉取鏡像

  docker images registry  ##檢視拉取的自己的私有的倉庫中的鏡像資訊

    REPOSITORY TAG IMAGE ID CREATED SIZE

    registry latest 0a3eb3fde7fd 4 years ago 140MB

  

  然後就可以利用這個自己私有倉庫拉取的鏡像,建立需要的容器。

=====================================================================================

(1)使用标簽的目的是:

  docker将檔案等資訊的變動抽象為一次次的commit,每一次commit以後可能走向不同的分支,當我們完成dockerfile的建構後,會生成一串無規則的字元串代表此次生成的ID。此時,tag的作用就是為他建立一個友好的NAME,友善我們對鏡像庫的管理。

docker tag image image:v1

,系統又幫我們加上了latest,也就是說,當我們不指定tag的時候,系統會自動幫我們補上latest的tag,然後去比對,如果命中,就用對應的容器ID去建立新的tag。

(2)latest

這個latest其實在使用中不是最新的意思,而是預設值(defalut)的意思。也就是說,如果在tag為可選的指令中,我們沒有寫上tag,如 

docker pull image:v1;docker pull image

 ,前者有确定的tag,而後者沒有,這時系統會自動給後者添加一個:latest的标簽,然後去比對。這時如果latest對應的鏡像不存在就會報錯!

(3)docker的tag(标簽)的文法:

  docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

  docker run image  ##預設使用的是标簽為latest的鏡像

  docker run image:v1  ##使用的是指定的鏡像

(4)docker鏡像的版本控制

如果需要更新某個docker鏡像,我們可以這樣做。

  • 1.給每個新生成的鏡像都打上相應版本的tag。此時可能存在image:latest、image:v1、image:v2等。
  • 2.我們要從v1更新到v2,首先我們将導入的v2鏡像強制重命名為image:latest,指令為 docker tag -f image:v2 image:latest
  • 3.docker stop之前正在運作的容器
  • 4.啟用docker run image,此時image的等價鏡像image:latest就是最新的V2鏡像。

=====================================================================================

2.給私有庫添加證書  原來的庫任何人都可以通路,這樣不安全,接下來我們要增加庫的安全性

(1)建立服務端key以及證書

  cd /opt/docker/

  mkdir -p certs

  openssl req \    ##生成證書請求

    > -newkey rsa:4096 -nodes -sha256 -keyout certs/westos.org.key \  

                                    ##“-new”表示新生成一個新的證書請求檔案,"-key"指定私鑰檔案。"-keyout"選項可以指定私鑰儲存位置,"-nodes"選項禁止加密私鑰檔案,"-newkey"選項可以直接指定私鑰的算法和長度,是以它主要用在openssl req自動建立私鑰時。它的使用格式為"-newkey arg",其中arg的格式為"rsa:numbits",rsa表示建立rsa私鑰,numbits表示私鑰的長度,如果不給定長度(即"-newkey rsa")則預設從配置檔案中讀取長度值。其實不止支援rsa私鑰,隻不過現在基本都是用rsa私鑰,是以預設就使用rsa。

    > -x509 -days 365 -out certs/westos.org.crt  

                                    ##"-out"指定輸出檔案,此處輸出檔案即為證書請求檔案。使用openssl req自簽署證書時,需要使用"-x509"選項,由于是簽署證書請求檔案,是以可以指定"-days"指定所頒發的證書有效期

      

企業——Docker容器之docker私有倉庫的搭建

(2)添加本地解析

  vim /etc/hosts

    172.25.254.1  westos.org

(3)建立倉庫

  docker rm -f registry  ##之前基于容器安裝的倉庫,不支援證書,是以需要重新的配置。

  netstat -antlp | grep :443

  docker run -d \

  > --restart=always \

  > --name registry \

  > -v "$(pwd)"/certs:/certs \

  > -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \    ## -e 設定相應的環境變量

  > -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt \    ## -e 設定相應的環境變量  添加了相應的證書的環境變量的設定

  > -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key \  ## -e 設定相應的環境變量  添加了相應的私鑰的環境變量的設定

  > -p 443:443 \

  > -v /opt/registry:/var/lib/registry registry:2.3.1

    e97292700fe680c6124c6b3491fc8101b2658adfce7867050f488b519e71375d

  docker ps

    CONTAINER ID    IMAGE       COMMAND        CREATED    STATUS      PORTS             NAMES

    d91ba651fb74    registry:2.3.1  "/bin/registry /etc/…"    10 seconds ago  Up 8 seconds   0.0.0.0:443->443/tcp, 5000/tcp    registry

(4)建立證書存放目錄,并複制證書

  cd /etc/docker/

  mkdir certs.d

  cd certs.d/

  mkdir westos.org

  cd westos.org/

  ls

    ca.crt

  cp /opt/docker/certs/westos.org.crt  ca.crt

(5)導入一個鏡像并上傳到私有倉庫

  docker load -i game2048.tar

  docker tag game2048:latest  westos.org/game2048

  docker push westos.org/game2048

3.建立虛拟機然後試着将剛才push的虛拟機再拉取下來

(1)建立一個虛拟機   在 server1 上安裝docker

  systemctl start docker

  vim /etc/hosts

  172.25.254.1  westos.org

(2)建立同樣的證書目錄,并将服務端證書傳到此位置

  cd /etc/docker

  mkdir certs.d

  cd certs.d/

  mkdir westos.org

  cd westos.org/

  pwd

    /etc/docker/certs.d/westos.org

  ls

    ca.crt    ##将伺服器上的證書傳到server1上

(4)下拉上傳的鏡像

  docker pull westos.org/game2048

  

四.配置使用者權限,給證書加密

  如果想要控制registry的使用權限,使其隻有在登入使用者名和密碼之後才能使用的話,還需要做額外的設定。registry的使用者名密碼檔案可以通過htpasswd來生成

1.設定使用者密碼并檢視

  cd /opt/docker/

  mkdir auth

  docker run --entrypoint htpasswd registry:2.3.1 -Bbn wang westos > auth/htpasswd

  docker run --rm --entrypoint htpasswd registry:2.3.1 -Bbn admin westos >> auth/htpasswd

  cat auth/htpasswd

    wang:$2y$05$lyM5fqXxNOqWQLIlMUplxet.dPLMZMlZutV6oJk7AxyZCcDUkTyZ.

    admin:$2y$05$eFez8FCfUBM7BQG.uoxY9OtioSZNaaGJudyjDDm3gb4U0XBJg8q8q

2.建立倉庫

  docker stop registry

  docker rm registry

  docker run -d    --restart=always    --name registry    -v "$(pwd)"/certs:/certs    -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e  REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt    -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key    -p 443:443    -v /opt/registry:/var/lib/registry    -v "$(pwd)"/auth:/auth    -e "REGISTRY_AUTH=htpasswd"    -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"    -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2.3.1    ##這個新安裝的倉庫設定安裝,包含了:證書和使用者權限

  docker tag rhel7:latest westos/rhel7

  netstat -antlp | grep :443    ##過濾443端口

    tcp6 0 0 :::443 :::* LISTEN 27631/docker-proxy

  docker push westos/rhel7

    no basic auth credentials  ##此時上傳顯示沒有基礎認證,在沒有登入相應的docker倉庫的情況下,無法上傳\拉取相應的容器。

3.登入庫,輸入使用者名和設定的密碼

  docker login westos.org

    Username: wang

    Password: westos

  Login Succeeded ##顯示成功即可

4.在檔案config.json 中可以看到記錄的認證(認證一次,永久儲存)

  cd /root/.docker/

  ls

    config.json

  vim config.json

    {

    "auths": {

      "westos.org": {

        "auth": "aHVpOndlc3Rvcw=="

      }

    },

    "HttpHeaders": {

      "User-Agent": "Docker-Client/18.06.1-ce (linux)"

      }

    }

5.再次上傳剛才沒有上傳的那個鏡像

  docker push westos/rhel7    ##上傳成功

    The push refers to repository [westos/rhel7]

    18af9eb19b5f: Pushed

    latest: digest: sha256:58cd9120a4194edb0de4377b71bd564953255a1422baa1bbd9cb23d521c6873b size: 528

五.給建立的私有倉庫添加web的UI界面

1.導入相應的鏡像

  docker load -i docker-registry-web.tar

  docker load -i docker-registry-frontend.tar

2.重新建立倉庫(增加了一個删除參數)

  docker rm -f registry

  docker rm -f registry-web

  docker run -d --restart=always --name registry -v "$(pwd)"/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/westos.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/westos.org.key -p 443:443 -v /opt/registry:/var/lib/registry -v "$(pwd)"/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -e REGISTRY_STORAGE_DELETE_ENABLED=true registry:2.3.1    ##允許執行删除操作

  docker run -it -p 8080:8080 --name registry-web --lnk registry:westos.org -e REGISTRY_URL=https://westos.org/v2 -e REGISTRY_TRUST_ANY_SSL=true -e REGISTRY_BASIC_AUTH="aHVpOndlc3Rvcw==" -e REGISTRY_NAME=westos.org -e REGISTRY_READONLY=false docker-registry-web  ##運作web界面

3.測試

  在網頁的頁面上輸入:localhost:8080

      

企業——Docker容器之docker私有倉庫的搭建