摘要:指定了自己的執行器,還有其他的寫法注意我們在取鏡像名的時候,這里要注意,字母只能全部小寫。
這部分介紹比較實用,在開中會經常用到,因為我們會根據自己的項目來構建自己的鏡像,然后發布。
第一種定制方式首先跑起來一個ubuntu,在ubuntu上安裝相應的軟件。
docker run -it --name temp ubuntu /bin/bash
進來后,安裝一個apache2吧
apt-get update && apt-get install apache2
使用dpkg -L來查看下apache2安裝的位置。在/usr/local/apache2就是我們安裝的。
開始以這個容器為基礎來制作鏡像吧!
docker commit -a "robinyang" temp robinyang0909/apache2:latest
好了,很快就會出現長uuid說明生成完成了。執行docker ps看看
你肯定有疑惑,開發要是這樣來為應用制作鏡像的話,豈不是要瘋了,確實,我也這么覺得,死難用!別慌,下面來看看第二種制作鏡像的方法。
第二種定制方式首先,在學習目錄下新建一個buildImage下新建一個Dockerfile文件(buildImage是一個docker上下文)。并在新建文件里加入下面指令:
FROM ubuntu:14.04 MAINTAINER robinyang RUN apt-get update && apt-get install nginx RUN echo "HelloWorld">/usr/share/nginx/html/index.html EXPOSR 80
保存退出,先來執行下:
docker build -t robinyang0909/nginx:latest .
上面指定不知道什么意思嗎?第一節有操作過,當然,記不住啊!確實有時候忘記了,docker build --help 查看。
這里說下原理,每執行一條指令都穿創建一個鏡像層,并且會commit提交,執行嚇一跳指定,就是基于剛才的鏡像層來創建。
你會發現在你的鏡像列表里多出一個你剛才構建的鏡像。這樣的好,我們可以在我們的項目的頂級目錄下新建一個Dockerfile來給你的應用定制鏡像。既然用Dockerfile來構建鏡像的話,我們先來系統了解一下Dockerfile所需要的基本指令。
Dockerfile 基本參數 FROMDockerfile的第一條指令,后面指定一個基礎鏡像。你新建的鏡像是想基于那個基礎鏡像來構建的。一定要放在第一句。
FROM ubuntu:14.04
你可以 docker search 去搜索你需要的鏡像。
MAINTAINER指定這個鏡像的作者信息。
MAINTAINER robinyang robinyang_beijing@163.comRUN
這個用的很多,就詳細說說。在構建鏡像的時候,在當前鏡像層里執行這些shell腳本,并且會commit,構建成新一層鏡像。
RUN//默認是使用/bin/sh 來執行 RUN ["", "", "", ...] //默認調用docker exec來執行,有的鏡像沒有sh
來看幾個例子
RUN touch /tmp/hello.html && echo hello>hello.html RUN /bin/bash -c "touch /tmp/hello.html && echo hello>hello.html" RUN ["/bin/bash", "-c", "touch /tmp/hello.html && echo hello>hello.html"] RUN ["touch", "/tmp/hello.html && echo hello>hello.html"]EXPOSE
這個很簡單,讓你的容器在運行的時候監聽哪個端口。但是有一點要注意,他監聽的是容器的端口,而不是主機的端口,所以我們創建容器的時候,要用 -p 來指定端口。
EXPOSE 8080
學了以上的幾個命令的話,現在可以來個小練習。以tomcat為基礎,加入一個hello.html頁面,并在頁面中加入一個helloWorld內容。
FROM tomcat MAINTAINER robinyang robinyang_beijing@163.com RUN touch /usr/local/tomcat/webapps/ROOT/hello.html RUN ["/bin/bash", "-c", "echo helloWorld>/usr/local/tomcat/webapps/ROOT/hello.html"] EXPOSE 8080
構建下
docker build -t robinyang09090/tomcat:latest .
鏡像制作完成了,現在可以創建容器了
docker run -d -p 8080:8080 --name testTomcat robinyang09090/tomcat 【-p 宿主機:容器】
可以用你的瀏覽器訪問下 host:8080/hello.html試試。
ENV在上面的Dockerfile 構建文件中,我們會發現很多有重復的,可以用一個變量來帶代替重復的地方。改寫下上面Dockerfile
FROM tomcat MAINTAINER robinyang robinyang_beijing@163.com ENV rootPath=/usr/local/tomcat/webapps/ROOT/hello.html RUN touch $rootPath RUN ["/bin/bash", "-c", "echo helloWorld>$rootPath"] EXPOSE 8080
是不是簡潔很多。這里ENV的書寫有兩種方式:
ENV key1=val1 key2=val2 //推薦 或者 ENV key1 val1 ENV key2 val2
這些變量會被持久保存到我們創建的任何容器里,所以我們取的變量名要注意,別和系統自帶變量名沖突就行。
CMD在容器啟動的時候執行的命令,RUN則是在構建鏡像的時候執行的命令,這里要區分開。還記得我們在之前容器里執行循環,docker run后面 /bin/sh -c "while [ true ]; do echo helloWorld; sleep 1; done"相當于CMD的作用。
FROM ubuntu CMD ["/bin/sh", "-c", "while [ true ];do echo helloWorld; sleep 1;"]
//指定了自己的執行器, CMD ["executable","param1","param2"] //還有其他的寫法 CMD ["param1","param2"] (as default parameters to ENTRYPOINT) CMD command param1 param2 (shell form)
注意:我們在docker build -t 取鏡像名的時候,這里要注意,字母只能全部小寫。給容器取名的可以大寫。
可以構建我們的鏡像了
docker build -t robinyang0909/loop .
創建并運行容器
docker run -d --name testLoop robinyang0909/loop //接著打印日志 docker logs testLoopENTRYPOINT
這個指令跟CMD有點類似,都是容器啟動成功開始運行執行腳本;但又不同的地方,CMD會被覆蓋,而ENTRYPOINT不會被覆蓋;ENTRYPOINT是一個基礎前綴指令。
ENTRYPOINT ["/bin/sh", "-c"] CMD ["java Hello"]
上面的會構成一個完整的指令/bin/sh -c java Hello,CMD或者docker run后面的參數,都會傳入ENTRYPOINT,他來指定執行器,我們這里的執行器是/bin/bash -c,一般我們會ENTRYPOINT和CMD搭配起來一起用。
WORKDIR上面ENTRYPOINT里我們指定了一個java Hello運行我們自己的jar包,但是有一個問題,你怎么知道你的jar在哪里。就算你知道目錄了,你難道要在Hello前拼接路徑嗎?這樣確實可以,但是不優雅,這里有更好的方法,就是WORKDIR。
WORKDIR指定一個工作目錄,這樣CMD和ENTRYPOINT就會在該目錄下執行我們的程序。
FROM java ENV jarPath=/var/class/ ENTRYPOINT ["/bin/sh", "-c"] WORKDIR $jarPath CMD ["java Hello"]
構建鏡像后,run一個容器,啟動會失敗!別慌,還有一步沒有完成,等下一步完成后,就可以了。
COPYWORKDIR可以多次出現,意思就是切換目錄。
上面的例子跑不起來,還缺少COPY一個Hello文件,接下來,將會拷貝一個文件到鏡像里去。在Dockerfile同級目錄下新建一個tmp文件,生成一個Hello.class文件。
COPY tmp/Hello.class /var/class/
補充上面的,完整的是
FROM java ENV jarPath=/var/class/ ENTRYPOINT ["/bin/sh", "-c"] WORKDIR $jarPath COPY tmp/Hello.class $jarPath CMD ["java Hello"]
生成鏡像docker build -t roinyang0909/hello . ,創建啟動容器docker run -d --name hello robinyang0909/hello,看下容器的日志docker logs hello發現我們的java程序跑起來了。
上面的 CMD ["java Hello"]千萬別寫成了CMD ["java", "Hello"]系統會先執行java再執行Hello的,是分步執行的,很顯然只運行java指令就出錯。建議 一個 ""就引起一個完整的指令。
上面COPY文件的時候,我們只能拷貝上下文里的文件,上下文之外的文件是沒法拷貝成功的。什么是上下文了,就是Dockerfile文件所在目錄及其子目錄,都是上下文。
VOLUMN這個指令,估計有點陌生,確實!首先我們來談談容器的存儲機制,我們知道,容器只能在最上面的讀寫層進行文件的讀寫,這樣做理論上沒有問題,但是你有沒有想過一個很嚴重的問題,我在這個容器里寫了一些東西,下次升級,舊容器里的文件是不是要拷貝出來,然后放入到新容器里去,最典型的應用就是數據庫容器。現在我們可以將宿主機的一個目錄掛在到容器上,這樣可以將數據放到宿主機上。
來吧!我們用容器跑一個mysql
docker pull mysql //拉去mysql鏡像 docker run -d -p 3307:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root mysql //創建啟動mysql容器
用SQLyog工具連接3307,密碼為root ,沒有問題。我們創建一個demo庫。docker stop mysql1關閉容器,重新創建啟動一個mysql2的容器docker run -d -p 3307:3306 --name mysql1 -e MYSQL_ROOT_PASSWORD=root mysql,再次連接,發現我們剛才創建的demo庫沒有了。然后你可能想到的解釋就是,mysql容器將數據放在了容器里面,不同的容器數據當然不一樣。這樣理解,也不能算錯。其實數據是寫在宿主機上的,因為mysql這個鏡像指定了VOLUMN,https://github.com/docker-lib... 這是docker鏡像的制作github倉庫,在Dockerfile 里可以看到VOLUME /var/lib/mysql已經掛在了/var/lib/mysql。
其實Dockerfile的VOLUMN掛在,只是掛在了/var/lib/docker/volumes/w75wew.../_date/這個下面的一個零食目錄里的,可以docker inspect mysql1看到Mounts信息,掛在在Source指定的宿主機目錄下
name的一長串數字字符組成的id是唯一的,每次啟動一個Dockerfile指定了VOLUMN的容器,都會創建一個像這樣的目錄,所以新建容器就是一個新的,是沒有數據的。
容器刪除的時候,這些零時文件不會被刪除的。假設我們沒有將這些目錄掛在到宿主機上,容器刪除了,數據還在。只不過尋找過程麻煩點,但是這也會是一個補救的機會。
小結: 在Dockerfile里指定VOLUMN會映射到宿主機上,但是他會在/var/lib/docker/volumns/下生成一個唯一的目錄來做掛載。
能不能讓容器的掛在目錄映射到我指定的目錄下?當然能
docker run -d -p 3307:3306 --name mysql2 -e MYSQL_ROOT_PASSWORD=root -v /home/mysql/data/:/var/lib/mysql mysql //將容器的/var/lib/mysql映射到宿主機的/home/mysql/data/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26907.html
摘要:基于年底或年初沒有推廣的現狀,唯品會部門目前已經做了兩年的時間。唯品會現狀唯品會目前線上有一千多個域,每個域之間相互的依賴比較復雜,每次的部署發布困難。這是唯品會的架構,主要包含持續集成和持續部署。 數人云上海&深圳兩地容器之Mesos/K8S/Swarm三國演義的嘉賓精彩實錄第三更來啦。唯品會是數人云Meetup的老朋友,去年曾做過RPC服務框架和Mesos容器化的分享。本次分享中,...
摘要:此命令下載測試鏡像并在容器中運行它。國內很多云服務商都提供了加速器服務,例如阿里云加速器注冊用戶并且申請加速器,會獲得如這樣的地址。獲取鏡像阿里云鏡像庫上有大量的高質量的鏡像可以用,這里我們就說一下怎么獲取這些鏡像并運行。 showImg(https://segmentfault.com/img/remote/1460000012924583); 這篇文章是我學習 Docker 的記錄...
摘要:如何用定制你自己的環境前言學習幾個月了,一直在論壇和群里潛水,一直都想寫點什么回報大家積極的知識分享。關于如何使用,可以參考上面的文章和官方文檔二小試牛刀,用構建一個的環境并運行程序首先來貼上我的先附上這個項目地址。 如何用Docker定制你自己的Beego環境 前言: 學習golang幾個月了,一直在論壇和qq群里潛水,一直都想寫點什么回報大家積極的知識分享。 前幾日在CSDN上...
摘要:分層存儲因為鏡像包含操作系統完整的文件系統,其體積往往是龐大的,因此在設計時,就充分利用的技術,將其設計為分層存儲的架構。分層存儲的特征還使得鏡像的復用定制變的更為容易。 什么是Docker Docker 是一個開源的應用容器引擎,基于 Go 語言 并遵從Apache2.0協議開源。Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 L...
摘要:的主要作用是自己根據基礎鏡像,重新定制鏡像,而不是直接從官方倉庫拿現成的使用。以接下來要構建的環境來說明下,下面我將要搭建一個的開發環境,需要進行配合。它的主要作用是持久化數據,避免容器銷毀后內部數據丟失暴露到宿主機的端口。 以前一直使用 Vagrant 作為自己的開發環境,并且在上家公司也推行大家采用 Vagrant 作為開發環境,保障公司使用的是同一套開發環境。隨著docker的流...
閱讀 1882·2021-11-11 16:55
閱讀 2064·2021-10-08 10:13
閱讀 739·2019-08-30 11:01
閱讀 2155·2019-08-29 13:19
閱讀 3277·2019-08-28 18:18
閱讀 2620·2019-08-26 13:26
閱讀 579·2019-08-26 11:40
閱讀 1864·2019-08-23 17:17