Docker鏡像制作與倉庫搭建過程
1,docker鏡像制作
docker官方和個人發(fā)布的鏡像由于版本等各種原因,漏洞較多,已統(tǒng)計Docker Hub超過30%的官方鏡像包含高位漏洞。此外,由于網(wǎng)絡(luò)等原因也會造成docker pull 下載鏡像的速度很慢。
基于這種情況,我們可以手動定制docker系統(tǒng)鏡像。構(gòu)建鏡像的方式有兩種:
- 使用docker commit命令
- 使用docker build和Dockerfile文件
方式一:docker commit
步驟1:拉取一個基礎(chǔ)鏡像(其實就是OS)
docker pull centos

步驟2:創(chuàng)建一個交互式容器
docker run -it --name mycentos centos /bin/bash

這里的 ll 命令找不到,可能是因為版本問題,這個不影響
步驟3:將需要的資源上傳到宿主機上

注意?。。。罕纠侵谱饕粋€tomcat鏡像,所以需要這些資源
步驟4:將宿主機上的資源拷貝到容器
docker cp apache-tomcat-7.0.64.tar.gz mycentos:/root docker cp jdk-8u181-linux-x64.tar.gz mycentos:/root


步驟5:在容器安裝jdk,解壓并配置
# 解壓jdk到/usr/local/目錄下 tar -zxvf jdk-8u181-linux-x64.tar.gz -C /usr/local/ # 打開profile文件,配置環(huán)境 vi /etc/profile


這里就跟Linux安裝jdk一樣的,配置好之后刷新一下,就可以了

步驟6:在容器安裝tomcat,解壓并配置
# 解壓tomcat到/usr/local/目錄下 tar -zxvf apache-tomcat-7.0.64.tar.gz -C /usr/local/ # 編輯tomcat的setclsspath.sh文件 vi /usr/local/apache-tomcat-7.0.64/bin/setclasspath.sh


步驟7:將運行的mycentos容器提交為一個新的鏡像,新的鏡像名稱為mytomcat
docker commit mycentos mytomcat

到這里,我們的鏡像就已經(jīng)制作好了
- 端口映射
基于mytomcat鏡像創(chuàng)建一個容器
docker run -itd --name t1 -p 8888:8080 mytomcat /bin/bash #進(jìn)入容器,并去執(zhí)行startup.sh文件 docker exec t1 /usr/local/apache-tomcat-7.0.64/bin/startup.sh

訪問看到如下效果就說明成功了

- 容器/鏡像打包
#1,鏡像打包 docker save -o /root/tomcat7.tar mytomcat #2,將打包的鏡像上傳到其他服務(wù)器 scp tomcat7.tar 其他服務(wù)器ip:.root #1,容器打包 docker export -o /root/t1.tar t1 #2,導(dǎo)入容器 docker import t1.tar mytomcat:latest



打包完成了,該導(dǎo)入了
docker load -i /root/tomcat7.tar

至此算是完成了
方式二:docker builder
Dockerfile使用基本的基于DSL語法的指令來構(gòu)建一個Docker鏡像,之后使用docker builder命令基于該Dockerfile中的指令構(gòu)建一個新的鏡像
- DSL語法

DSL語法: 1)FROM(指定基礎(chǔ)image) 構(gòu)建指令,必須指定且需要在Dockerfile其他指令的前面。后續(xù)的指令都依賴于該指令指定的image。FROM指令指定的基礎(chǔ)image可以是官方遠(yuǎn)程倉庫中的,也可以位于本地倉庫。 FROM命令告訴docker我們構(gòu)建的鏡像是以哪個(發(fā)行版)鏡像為基礎(chǔ)的。第一條指令必須是FROM指令。并且,如果在同一個Dockerfile中創(chuàng)建多個鏡像時,可以使用多個 FROM 指令。 該指令有兩種格式: FROM <image> 指定基礎(chǔ)image為該image的最后修改的版本?;蛘撸? FROM <image>:<tag> 指定基礎(chǔ)image為該image的一個tag版本。 RUN后面接要執(zhí)行的命令,比如,我們想在鏡像中安裝vim,只需在Dockfile中寫入 RUN yum install -y vim 2)MAINTAINER(用來指定鏡像創(chuàng)建者信息) 構(gòu)建指令,用于將image的制作者相關(guān)的信息寫入到image中。當(dāng)我們對該image執(zhí)行docker inspect命令時,輸出中有相應(yīng)的字段記錄該信息。 格式: MAINTAINER <name> 3)RUN(安裝軟件用) 構(gòu)建指令,RUN可以運行任何被基礎(chǔ)image支持的命令。如基礎(chǔ)image選擇了ubuntu,那么軟件管理部分只能使用ubuntu的命令。 該指令有兩種格式: RUN <command> 4)CMD(設(shè)置container啟動時執(zhí)行的操作) 設(shè)置指令,用于container啟動時指定的操作。該操作可以是執(zhí)行自定義腳本,也可以是執(zhí)行系統(tǒng)命令。該指令只能在文件中存在一次,如果有多個,則只執(zhí)行最后一條。 該指令有三種格式: CMD ["executable","param1","param2"] CMD command param1 param2 當(dāng)Dockerfile指定了ENTRYPOINT,那么使用下面的格式: CMD ["param1","param2"] 其中: ENTRYPOINT指定的是一個可執(zhí)行的腳本或者程序的路徑,該指定的腳本或者程序?qū)詐aram1和param2作為參數(shù)執(zhí)行。 所以如果CMD指令使用上面的形式,那么Dockerfile中必須要有配套的ENTRYPOINT。 5)ENTRYPOINT (設(shè)置container啟動時執(zhí)行的操作) 設(shè)置指令:指定容器啟動時執(zhí)行的命令,可以多次設(shè)置,但是只有最后一個有效。 兩種格式: ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 該指令的使用分為兩種情況,一種是獨自使用,另一種和CMD指令配合使用。 當(dāng)獨自使用時,如果你還使用了CMD命令且CMD是一個完整的可執(zhí)行的命令,那么CMD指令和ENTRYPOINT會互相覆蓋,只有最后一個CMD或者ENTRYPOINT有效。 # CMD指令將不會被執(zhí)行,只有ENTRYPOINT指令被執(zhí)行 CMD echo “Hello, World!” ENTRYPOINT ls -l 另一種語法和CMD指令配合使用來指定ENTRYPOINT的默認(rèn)參數(shù),這時CMD指令不是一個完整的可執(zhí)行命令,僅僅是參數(shù)部分; ENTRYPOINT指令只能使用JSON方式指定執(zhí)行命令,而不能指定參數(shù)。 FROM ubuntu CMD ["-l"] ENTRYPOINT ["/usr/bin/ls"] 6)USER(設(shè)置container容器的用戶) 設(shè)置指令,設(shè)置啟動容器的用戶,默認(rèn)是root用戶。 # 指定memcached的運行用戶 ENTRYPOINT ["memcached"] USER daemon 或者 ENTRYPOINT ["memcached", "-u", "daemon"] 7)EXPOSE(指定容器需要映射到宿主機器的端口) 設(shè)置指令,該指令會將容器中的端口映射成宿主機器中的某個端口。當(dāng)你需要訪問容器的時候,可以不是用容器的IP地址,而是使用宿主機器的IP地址和映射后的端口。 要完成整個操作需要兩個步驟,首先在Dockerfile使用EXPOSE設(shè)置需要映射的容器端口,然后再運行容器的時候指定-p選項加上EXPOSE設(shè)置的端口,這樣EXPOSE設(shè)置的端口號會被隨機映射成宿主機器中的一個端口號。 也可以指定需要映射到宿主機器的那個端口,這時要確保宿主機器上的端口號沒有被使用。EXPOSE指令可以一次設(shè)置多個端口,相應(yīng)的運行容器的時候,可以配套的多次使用-p選項 EXPOSE <port> [<port>...] # 映射一個端口 EXPOSE port1 # 相應(yīng)的運行容器使用的命令 docker run -p port1 image # 映射多個端口 EXPOSE port1 port2 port3 # 相應(yīng)的運行容器使用的命令 docker run -p port1 -p port2 -p port3 image # 還可以指定需要映射到宿主機器上的某個端口號 docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image 端口映射是docker比較重要的一個功能,原因在于我們每次運行容器的時候容器的IP地址不能指定而是在橋接網(wǎng)卡的地址范圍內(nèi)隨機生成的。 宿主機器的IP地址是固定的,我們可以講容器的端口的映射到宿主機器上的一個端口,免去每次訪問容器中的某個服務(wù)時都要查看容器的IP的地址。 對于一個運行的容器,可以使用docker port加上容器中需要映射的端口和容器的ID來看該端口號在宿主機器上的映射端口。 8)ENV(用于設(shè)置環(huán)境變量) 主要用于設(shè)置容器運行時的環(huán)境變量 格式: ENV <key> <value> 設(shè)置了后,后續(xù)的RUN命令都可以使用,container啟動后,可以通過docker inspect查看這個環(huán)境變量,也可以通過在docker run --env key=value時設(shè)置或修改環(huán)境變量。 假如你安裝了JAVA程序,需要設(shè)置JAVA_HOME,那么可以在Dockerfile中這樣寫: ENV JAVA_HOME /path/to/java/dirent 9)ADD(從src復(fù)制文件到container的dest路徑) 主要用于將宿主機中的文件添加到鏡像中 構(gòu)建指令,所有拷貝到container中的文件和文件夾權(quán)限為0755,uid和gid為0:如果是一個目錄,那么會將該目錄下的所有文件添加到container中,不包括目錄: 如果文件是可識別的壓縮格式,則docker會幫忙解壓縮(注意壓縮格式):如果<src>是文件且<dest>中不使用斜杠結(jié)束,則會將<dest>視為文件,<src>的內(nèi)容會寫入<dest>: 如果<src>是文件且<dest>中使用斜杠結(jié)束,則會<src>文件拷貝到<dest>目錄下。 格式: ADD <src> <dest> <src> 是相對被構(gòu)建的源目錄的相對路徑,可以是文件或目錄的路徑,也可以是一個遠(yuǎn)程的文件url; <dest> 是container中的絕對路徑 10)VOLUME(指定掛載點) 設(shè)置指定,使容器中的一個目錄具有持久化存儲數(shù)據(jù)的功能,該目錄可以被容器本身使用,也可以共享給其他容器使用。我們知道容器使用的是AUFS, 這種文件系統(tǒng)不能持久化數(shù)據(jù),當(dāng)容器關(guān)閉后,所有的更改都會丟失。當(dāng)容器中的應(yīng)用有持久化數(shù)據(jù)的需求時可以在Dockerfile中使用該指令 格式: VOLUME ["<mountpoint>"] VOLUME ["/tmp/data"] 運行通過該Dockerfile生成image的容器,/tmp/data目錄中的數(shù)據(jù)在容器關(guān)閉后,里面的數(shù)據(jù)還存在。例如另一個容器也有持久化數(shù)據(jù)的需求,且想使用上面容器共享的/tmp/data目錄,那么可以運行下面的命令啟動一個容器: docker run -t -i -rm -volumes-from container1 image2 bash 其中:container1為第一個容器的ID,image2為第二個容器運行image的名字。 11)WORKDIR(切換目錄) 設(shè)置指令,可以多次切換(相當(dāng)于cd命令),對RUN,CMD,ENTRYPOINT生效。 格式: WORKDIR /path/to/workdir # 在/p1/p2下執(zhí)行vim a.txt WORKDIR /p1 WORKDIR p2 RUN vim a.txt 12)ONBUILD(在子鏡像中執(zhí)行) 格式: ONBUILD <Dockerfile關(guān)鍵字> ONBUILD 指定的命令在構(gòu)建鏡像時并不執(zhí)行,而是在它的子鏡像中執(zhí)行
dockerfile構(gòu)建鏡像:
步驟1:創(chuàng)建一個目錄
mkdir rw-test

步驟2:編輯Dockerfile文件,注意D要大寫
vim Dockerfile
編輯內(nèi)容如下:
#pull down centos image FROM docker.io/centos MAINTAINER ruanwen onlien033_login@126.com #install nginx RUN yum install -y pcre pcre-devel openssl openssl-devel gcc gcc+ wget vim net-tools RUN useradd www -M -s /sbin/nologin RUN cd /usr/local/src && wget http://nginx.org/download/nginx-1.8.0.tar.gz && tar -zxvf nginx-1.8.0.tar.gz RUN cd /usr/local/src/nginx-1.8.0 && ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_ssl_module && make && make install ENTRYPOINT /usr/local/nginx/sbin/nginx && tail -f /usr/local/nginx/logs/access.log


步驟3:在rw-test目錄下構(gòu)建鏡像:
docker build -t rw_nginx --rm=true . -t 表示選擇指定生成鏡像的用戶名,倉庫名和tag --rm=true 表示指定在生成鏡像過程中刪除中間產(chǎn)生的臨時容器 注意:上面構(gòu)建命令中最后的.符合不要漏了,表示使用當(dāng)前目錄下的Dockerfile構(gòu)建鏡像

會依次運行Dockerfile文件的每一個步驟
步驟4:測試
docker run -ti -d --name test_nginx -p 8899:80 rw_nginx /bin/bash docker exec test_nginx /bin/bash # 通過瀏覽器訪問:http://ip:8899
2,docker倉庫搭建
Docker倉庫(Repository)類似與代碼倉庫,是Docker集中存放鏡像文件的地方。
- docker hub
1,打開https://hub.docker.com/
2,注冊賬號,略
3,創(chuàng)建倉庫(Create Repository):略
4,設(shè)置鏡像標(biāo)簽
docker tag local-image:tagname new-repo:tagname
示例:docker tag hello-word:latest myqxin/test-hello-world:v1
5,登錄docker hub
docker login(回車,輸入賬號和密碼)
6,推送鏡像
docker push new-repo:tagname
示例:
docker push myqxin/test-hello-world:v1




我這里把test-hello-world弄成了test-hell-world,你們注意一下
- 阿里云
略:參考官方文檔
步驟:
1,創(chuàng)建阿里云賬號
2,創(chuàng)建命令空間
3,創(chuàng)建鏡像倉庫
4,操作指南
$ sudo docker login --username=[賬號名稱] registry.cn-hangzhou.aliyuncs.com $ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/360buy/portal:[鏡像版本號] $ sudo docker push registry.cn-hangzhou.aliyuncs.com/360buy/portal:[鏡像版本號]




- 搭建私有倉庫
1,啟動docker Registry,使用Docker官方提供的Registry鏡像就可以搭建本地私有鏡像倉庫,具體指令如下。
docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v /mnt/registry:/var/lib/registry \ registry:2

指令參數(shù)說明:
- -d:表示在后臺運行該容器
- -p 5000:5000:表示將私有鏡像倉庫容器內(nèi)部默認(rèn)暴露的5000端口映射到宿主機的5000端口
- –restart=always:表示容器啟動后自動啟動本地私有鏡像倉庫
- –name registry:表示為生成的容器命名為registry
- -v /mnt/registry:/var/lib/registry:表示將容器內(nèi)的默認(rèn)存儲位置/var/lib/registry中的數(shù)據(jù)掛載到宿主機的/mnt/registry目錄下,這樣當(dāng)容器銷毀后,在容器中/var/lib/registry目錄下的數(shù)據(jù)會自動備份到宿主機指定目錄
提示:
Docker Registry目前有v1和v2兩個版本,v2版本并不是v1版本的簡單升級,而是在很多功能上都有了改進(jìn)和優(yōu)化。v1版本使用的是Python開發(fā)的,而v2版本是用go語言開發(fā)的,v1版本本地鏡像倉庫容器中數(shù)據(jù)默認(rèn)掛載點是/tmp/registry,而v2版本的本地鏡像倉庫容器中數(shù)據(jù)默認(rèn)掛載點是/var/lib/registry
- 重命名鏡像:之前推送鏡像時,都是默認(rèn)推送到遠(yuǎn)程鏡像倉庫,而本次是將指定鏡像推送到本地私有鏡像倉庫。由于推送到本地私有鏡像倉庫的鏡像名稱必須符合“倉庫IP:端口號/repository”的形式,因此需要按照要求修改鏡像名稱,具體操作指令如下。
docker tag hello-world:latest localhost:5000/myhellodocker

推送鏡像:本地私有鏡像倉庫搭建并啟動完成,同時要推送的鏡像也已經(jīng)準(zhǔn)備就緒后,就可以將指定鏡像推送到本地私有鏡像倉庫了,具體操作指令如下
docker push localhost:5000/myhellodocker

查看本地倉庫鏡像
http://localhost:5000/v2/myhellodocker/tags/list (注意:使用該地址時注意鏡像名稱)
由于做了目錄掛載,因此可以在本地的該目錄下查看:
/mnt/registry/docker/registry/v2/repositories
推送,不需要輸入賬號密碼(不安全)
- 配置私有倉庫認(rèn)證
1,查看Docker Registry私有倉庫搭建所在服務(wù)器地址:ipconfig
例如:服務(wù)器地址為:192.168.204.130
2,生成自簽名證書(在home目錄下執(zhí)行上述指令后)
要確保Docker Registry本地鏡像倉庫的安全性,還需要一個安全認(rèn)證證書,來保證其他Docker機器不能隨意訪問該機器上的Docker Registry本地鏡像倉庫,所以需要在搭建Docker Registry本地鏡像倉庫的Docker主機上先生成自簽名證書(如果已購買證書就無需生成),具體操作指令如下:
mkdir registry && cd registry && mkdir certs && cd certs openssl req -x509 -days 3650 -subj '/CN=192.168.204.130:5000/' \ -nodes -newkey rsa:2048 -keyout domain.key -out domain.crt
指令參數(shù)說明:
- -x509:x509是一個自簽發(fā)證書的格式
- rsa:2048,是證書算法長度
- domain.key和domain.crt:就是生成的證書文件
3,生成用戶名和密碼
在Docker Registry本地鏡像倉庫所在的Docker主機上生成自簽名證書后,為了確保Docker機器與該Docker Registry本地鏡像倉庫的交互,還需要生成一個連接認(rèn)證的用戶名和密碼,使其他Docker用戶只有通過用戶名和密碼登錄后才允許連接到Docker Registry本地鏡像倉庫
cd .. && mkdir auth docker run --entrypoint htpasswd registry:2 -Bbn ruanwen 123456 > auth/htpasswd
4、啟動Docker Registry本地鏡像倉庫服務(wù)(將之前創(chuàng)建的容器刪除)
docker run -d \ -p 5000:5000 \ --restart=always \ --name registry \ -v /mnt/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 \ -v `pwd`/certs:/certs \ -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \ -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \ registry:2
5、配置Docker Registry訪問接
完成Docker Registry本地鏡像倉庫服務(wù)啟動后,還需要在搭建了Docker Registry本地鏡像倉庫所在的Docker主機上配置供其他Docker機器訪問的接口,具體指令如下:
sudo mkdir -p /etc/docker/certs.d/192.168.204.130:5000 sudo cp certs/domain.crt /etc/docker/certs.d/192.168.204.130:5000
6、Docker Registry私有倉庫使用登記
在Docker機器終端使用sudo vim /etc/docker/daemon.json命令編輯daemon.json文件,在該文件中添加如下內(nèi)容
{“insecure-registries”:[“192.168.200.162:5000”]}7、重啟并加載docker配置文件
sudo /etc/init.d/docker restart
二、驗證測試
1、裝備鏡像
docker tag hello-world:latest 192.168.200.162:5000/myhelloworld
2、推送鏡像
docker push 192.168.200.141:5000/myhelloworld
送過程中出現(xiàn)錯誤,信息提示為:no basic auth credentials(即沒有通過身份驗證),所以無法進(jìn)行推送,這也就說明身份驗證的配置有效。要想成功推送,需要先登錄成功后再推送
3、登錄Docker Registry鏡像倉庫
docker login 192.168.200.162:5000
4、再次推送
docker push 192.168.200.139:5000/myhelloworld
5、結(jié)果驗證
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Docker如何部署SQL?Server?2017?Always?On集群
這篇文章主要介紹了Docker如何部署SQL?Server?2017?Always?On集群問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-07-07
docker 命令報異常permission denied的解決方案
這篇文章主要介紹了docker 命令報異常permission denied的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03
淺談docker Dockerfile 指令 VOLUME 介紹
本篇文章主要介紹了淺談docker Dockerfile 指令 VOLUME 介紹 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
Docker搭建并啟動Logstash的實現(xiàn)方式
這篇文章主要介紹了Docker搭建并啟動Logstash的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08
關(guān)于Docker 刪除dead狀態(tài)的容器問題及解決方案
這篇文章主要介紹了Docker 刪除dead狀態(tài)的容器,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05
win10子系統(tǒng)ubuntu(WSL) 安裝Docker的教程(圖文詳解)
現(xiàn)在 Docker 有專門的 Win10 專業(yè)版系統(tǒng)的安裝包,需要開啟Hyper-V,具體開啟方法文中給大家介紹的很詳細(xì),這篇文章主要介紹了win10子系統(tǒng)ubuntu(WSL) 安裝Docker,需要的朋友可以參考下2019-10-10

