Docker镜像的分层和镜像的创建(Dockerfile)
目錄
- 一、docker鏡像分層(基于AUFS構(gòu)建)
- 二、鏡像分層模型
- 三、Dockerfile結(jié)構(gòu)四部分
- 操作指令
- 四、實(shí)驗(yàn)
- 1、nginx鏡像
- 2、構(gòu)建ssh鏡像
- 3、Tomcat鏡像
一、docker鏡像分層(基于AUFS構(gòu)建)
Docker鏡像位于bootfs之上每一層鏡像的下一層成為父鏡像
第一層鏡像成為base image(操作系統(tǒng)環(huán)境鏡像>容器層(可讀可寫),在最頂層(writable)
容器層以下都是readonly
docker將readonly的FS層成為image
bootfs (boot file system):主要包含bootloader和kernel
bootloader主要是引導(dǎo)加載kernel,Linux剛啟動(dòng)時(shí)會(huì)加載bootfs文件系統(tǒng),在Docker鏡像的最底層是bootfs
這一層與我們典型的Linux/Unix系統(tǒng)是一樣的,包含boot加載器和內(nèi)核。當(dāng)boot加載完成之后整個(gè)內(nèi)核就都在內(nèi)存中了,此時(shí)內(nèi)存的使用權(quán)已由bootfs轉(zhuǎn)交給內(nèi)核,此時(shí)系統(tǒng)也會(huì)卸載bootfs
rootfs (root file system):在bootfs之上 (base images)包含的就是典型 Linux系統(tǒng)中的/dev,/proc,/bin,/etc等標(biāo)準(zhǔn)目錄和文件
rootfs就是各種不同的操作系統(tǒng)發(fā)行版,比如Ubuntu,Centos等等
為什么docker的centos鏡像只有200M多一點(diǎn)
- 對(duì)于一個(gè)精簡的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序庫就可以了,因?yàn)榈讓又苯佑肦ost的kernel,自己只需要提供 rootfs就行了。由此可見對(duì)于不同的linux發(fā)行版,bootfs基本是一致的,rootfs會(huì)有差別,因此不同的發(fā)行版可以公用bootfs
二、鏡像分層模型
- Docker 鏡像是有特殊的文件系統(tǒng)疊加而成
- 最底端是 bootfs,并使用宿主機(jī)的 bootfs
- 第二層是 root 文件系統(tǒng) rootfs,稱為 base image
- 然后在往上可以疊加其他的鏡像文件
- 統(tǒng)一文件系統(tǒng)(Union File System)技術(shù)能夠?qū)⒉煌膶诱铣梢粋€(gè)文件系統(tǒng),為這些層提供了一個(gè)統(tǒng)一的視角,這樣就隱藏了多層的存在,在用戶的角度看,只存在一個(gè)文件系統(tǒng)。
- 一個(gè)鏡像可以放在另一個(gè)鏡像的上面。位于下面的鏡像稱為父鏡像,最底部的鏡像成為基礎(chǔ)鏡像。
- 當(dāng)從一個(gè)鏡像啟動(dòng)容器是,Docker 會(huì)在最頂層加載一個(gè)讀寫文件系統(tǒng)作為部署
三、Dockerfile結(jié)構(gòu)四部分
Dockerfile是由一組指令組成的文件
- 基礎(chǔ)鏡像信息(指定操作系統(tǒng)鏡像是什么鏡像、什么版本)
- 【維護(hù)者信息】(可選填)
- 鏡像操作指令
- 容器啟動(dòng)時(shí)執(zhí)行指令(啟動(dòng)容器的時(shí)候,執(zhí)行的腳本/命令參數(shù)等等)
Dockerfile每行支持一條指令,每條指令可攜帶多個(gè)參數(shù),支持使用以"#"號(hào)開頭的注釋
操作指令
| FROM + 鏡像 | 指定新鏡像所基于的鏡像,第一條指令必須為FROM指令,每創(chuàng)建一個(gè)鏡像就需要一條FROM指令 |
| MAINTAINER + 名字 | 說明新鏡像的維護(hù)人信息 |
| RUN + 命令 | 在所基于的鏡像執(zhí)行命令,并提交到新的鏡像中 |
| CMD + [“要運(yùn)行的程序”,“參數(shù)1”、“參數(shù)2”] | 指令啟動(dòng)容器時(shí)要運(yùn)行的命令或者腳本,Dockerfile只能有一條CMD命令,如果指定多條則只能執(zhí)行最后一條 |
| EXPOSE + 端口號(hào) | 指定新鏡像加載到Docker時(shí)要開啟的端口 |
| ENV + 環(huán)境變量 + 變量值 | 設(shè)置一個(gè)環(huán)境變量的值,會(huì)被后面的RUN使用 |
| ADD + 源文件/目錄 + 目標(biāo)文件/目錄 | 將源文件復(fù)制到目標(biāo)文件,源文件要與Dockerfile位于相同目錄中,或者是一個(gè)URL,若源文件是壓縮包則會(huì)將其解壓縮 |
| COPY + 源文件/目錄 + 目標(biāo)文件/目錄 | 將本地主機(jī)上的文件/目錄復(fù)制到目標(biāo)地點(diǎn),源文件/目錄要與Dockerfile在相同的目錄中 |
| VOLUME + [“目錄”] | 在容器中創(chuàng)建一個(gè)掛載點(diǎn) |
| USER + 用戶名/UID | 指定運(yùn)行容器時(shí)的用戶 |
| WORKDIR + 路徑 | 為下一步的RUN、CMD、ENTRYPOINT指定工作目錄,相當(dāng)于是一個(gè)臨時(shí)的"CD",否則需要使用絕對(duì)路徑 |
| ONBUILD + 命令 | 指定所生成的鏡像作為一個(gè)基礎(chǔ)鏡像時(shí)所要運(yùn)行的命令 |
| HEALTHCHECK | 健康檢查 |
四、實(shí)驗(yàn)
1、nginx鏡像
mkdir nginx cd nginx/ //拷貝nginx-1.12.0源碼包到nginx/中 vim Dockerfile #基于基礎(chǔ)鏡像 FROM centos:7#添加環(huán)境包 RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null#下載nginx軟件包 ADD nginx-1.12.0.tar.gz /opt#指定工作目錄 WORKDIR /opt/nginx-1.12.0 RUN ./configure \--prefix=/usr/local/nginx && make &> /dev/null && make install &> /dev/null && rm -rf /opt/nginx-1.12.0 RUN ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/#指定http端口 EXPOSE 80 CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]2、構(gòu)建ssh鏡像
cd /opt mkdir sshd cd sshd vim sshdfile#基礎(chǔ)鏡像 FROM centos#更新基于鏡像yum源 RUN yum -y update#在基于鏡像上安裝軟件 #openssh是SSH協(xié)議的免費(fèi)開源實(shí)現(xiàn) #net-tools組件可支持使用ifconfig命令查看網(wǎng)卡信息 #lsof查看進(jìn)程打開的文件、打開文件的進(jìn)程、進(jìn)程打開的端口 #telnet支持遠(yuǎn)程登陸 #passwd用于設(shè)置密碼,更新用戶身份令牌 RUN yum -y install openssh* net-tools lsof telnet passwd#更改root用戶密碼為123123 RUN echo '123123' | passwd --stdin root#將ssh服務(wù)端配置文件中所有的UsePAM yes替換為UsePAM no,關(guān)閉第三方認(rèn)證登陸,別人都無法遠(yuǎn)程登陸該主機(jī) RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config#創(chuàng)建非密鑰對(duì)文件,生成到/etc/ssh/目錄下為ssh_host_rsa_key RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_keyRUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd#嵌套創(chuàng)建/root/.ssh目錄并且將/root目錄屬主和屬組改為root并且為/root/.ssh目錄賦權(quán)700,只有root用戶可讀寫執(zhí)行 RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh#指定端口22 EXPOSE 22#在運(yùn)行容器時(shí)啟動(dòng)ssh服務(wù),并開啟守護(hù)進(jìn)程 CMD ["/usr/sbin/sshd","-D"]#構(gòu)建新鏡像,因?yàn)檫@次dockerfile文件不是官方默認(rèn)的名稱了,所以我們-f指定以/opt/sshd/sshdfile來生成鏡像,-t指定新鏡像名為mysshd,tag為1.0 docker build -f /opt/sshd/sshdfile -t mysshd:1.0 .#后臺(tái)運(yùn)行并生成容器,暴露端口1111 docker run -d -p 1111:22 mysshd:1.0#驗(yàn)證 ssh localhost -p 11113、Tomcat鏡像
mkdir tomcat cd tomcat/ 拷貝apache-tomcat-9.0.16.tar.gz和jdk-8u201-linux-x64.rpm #基于基礎(chǔ)鏡像 FROM centos:7#復(fù)制rpm包,并安裝 COPY jdk-8u201-linux-x64.rpm / RUN rpm -qpl jdk-8u201-linux-x64.rpm RUN rpm -ivh jdk-8u201-linux-x64.rpm#配置環(huán)境變量 ENV JAVA_HOME=/usr/java/jdk1.8.0_201-amd64 ENV CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar ENV PATH=$JAVA_HOME/bin:$PATH#解壓tomcat包到容器,并改名為tomcat ADD apache-tomcat-9.0.16.tar.gz /usr/local/tomcat EXPOSE 8080 CMD ["/usr/local/tomcat/bin/catalina.sh","run"]總結(jié)
以上是生活随笔為你收集整理的Docker镜像的分层和镜像的创建(Dockerfile)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker的四种网络模式和相关网络命令
- 下一篇: Docker创建私有仓库 | 数据卷和数