Docker基礎命令
## 即從注冊服務器 registry.hub.docker.com 中的 alpine 倉庫來下載標記為 3.7 的鏡像
docker pull registry.hub.docker.com/alpine:3.7
## 存出鏡像
docker save -o alpine-3.7.tar alpine:3.7
## 載入鏡像
docker load --input alpine-3.7.tar
docker load < alpine-3.7.tar
## 導出容器
docker ps -a
#-- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#-- 7691a814370e alpine:3.7 "/bin/sh" 36 hours ago Exited (0) 21 hours ago test
docker export 7691a814370e > alpine-3.7.tar
## 導入容器快照
cat alpine-3.7.tar | docker import - test/alpine:v1.0
docker import http://example.com/exampleimage.tgz example/imagerepo
# 注:用戶既可以使用 docker load 來導入鏡像存儲文件到本地鏡像庫,也可以使用 docker import
# 來導入一個容器快照到本地鏡像庫。這兩者的區(qū)別在于容器快照文件將丟棄所有的歷史記錄和元數(shù)據(jù)信息
# (即僅保存容器當時的快照狀態(tài)),而鏡像存儲文件將保存完整記錄,體積也要大。此外,從容器快照文
# 件導入時可以重新指定標簽等元數(shù)據(jù)信息。
## 進入容器或執(zhí)行命令
docker exec -it $cname/$id $command
## 刪除所有容器
docker rm $(docker ps -a -q)
# 刪除所有鏡像
docker rmi (docker images | grep none | awk '{print3}' | sort -r)
# 一個容器連接到另一個容器
# sonar容器連接到mmysql容器,并將mmysql容器重命名為db。
# 這樣,sonar容器就可以使用db的相關的環(huán)境變量了。
docker run -i -t –name sonar -d -link mmysql:db tpires/sonar-server
# 構建自己的鏡像
# 如Dockerfile在當前路徑:docker build -t xx/gitlab .
docker build --no-cache=ture -t <鏡像名> <Dockerfile路徑>
# ----- 查看容器的 -----
# 容器的狀態(tài)
docker inspect -f '{{.State.Running}}' $cid
# 容器的IP
docker inspect –format='{{.NetworkSettings.IPAddress}}' 87d22e81a3a3
Dockerfile指令
# 選擇鏡像
FROM ubuntu:14.04
# 指定作者
MAINTAINER darebeat@126.com
# 增加標簽(labels)來協(xié)助通過項目組織鏡像,記錄授權信息,幫助自動化,或者其他原因
# 一行一行設置標簽
LABEL com.example.version="0.0.1-beta"
LABEL vendor="ACME Incorporated"
LABEL com.example.release-date="2015-02-12"
LABEL com.example.version.is-production=""
# 一行設置多個標簽
LABEL com.example.version="0.0.1-beta" com.example.release-date="2015-02-12"
# 多行設置多個標簽
LABEL vendor=ACME\ Incorporated \
com.example.is-beta= \
com.example.is-production="" \
com.example.version="0.0.1-beta" \
com.example.release-date="2015-02-12"
# 變量參數(shù),可以build時候傳入
## docker build --build-arg user=darebeat .
ARG user
ARG CONT_IMG_VER
# 修改環(huán)境變量將軟件安裝目錄加到PATH
ENV PATH /usr/local/nginx/bin:$PATH # 將使 CMD [“nginx”] 可以工作
# 也可用于指定通用版本號,這樣版本易于維護
ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
# 運行系統(tǒng)構建指令
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
RUN apt-get update && apt-get install -y \
aufs-tools \
automake \
build-essential \
curl \
dpkg-sig \
libcap-dev \
libsqlite3-dev \
mercurial \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.* \
&& rm -rf /var/lib/apt/lists/*
# 文件操作
## 對于不需要ADD tar自動提取功能的其他項目(文件,目錄),應始終使用COPY
COPY requirements.txt /tmp/
ADD rootfs.tar.xz /
ADD arr[[]0].tar.xz /mydir/
## 避免如下用法,而用wget或curl
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
## 應換成如下用法
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all
# 指示容器將監(jiān)聽鏈接的端口
EXPOSE 27017
EXPOSE 80
# 默認用戶
## 變量可以設置默認值
USER ${user:-root}
# 工作目錄
WORKDIR /root
# 設置鏡像主命令,允許鏡像把它作為命令運行(然后使用CMD作為默認標識)
ENTRYPOINT ["ls"]
CMD ["--help"]
# 與輔助腳本組合使用,允許其以類似于上述命令的方式運行,即使啟動工具可能需要多于一個步驟
ENTRYPOINT ["/docker-entrypoint.sh"]
# 用于運行你鏡像包含中的軟件,連同任意參數(shù)
CMD [“executable”, “param1”, “param2”…]
編寫Dockerfile原則
- 1.減少鏡像層:
一次RUN指令形成新的一層,盡量Shell命令都寫在一行 - 2.使用.dockerignore文件來排除文件和目錄。該文件與 .gitignore 類似
- 3.避免安裝不需要的包,優(yōu)化鏡像大小:
一次RUN形成新的一層,如果沒有在同一層刪除,無論文件是否最后刪除,都會帶到下一層,所以要在每一層清理對應的殘留數(shù)據(jù),減小鏡像大小。 - 4.每個容器只關心一個問題
解耦應用為多個容器使水平擴容和復用容器更容易 - 5.對多行參數(shù)排序
無論何時,以排序多行參數(shù)來緩解以后的變化,避免重復的包并且使里列表更容易更新。這也使得PR更容易閱讀和審查。 - 6.減少網(wǎng)絡傳輸時間:
最好在內(nèi)部有一個存放軟件包的地方,提高鏡像構建速度。 - 7.多階段進行鏡像構建
如果運行一個項目,根據(jù)咱們上面的做法,是直接把代碼拷貝到基礎鏡像里,如果是一個需要預先代碼編譯的項目呢?例如JAVA語言,如何代碼編譯、部署在一起完成呢!
1.上面做法需要事先在一個Dockerfile構建一個基礎鏡像,包括項目運行時環(huán)境及依賴庫,再寫一個Dockerfile將項目拷貝到運行環(huán)境中,有點略顯復雜了
2.像JAVA這類語言如果代碼編譯是在Dockerfile里操作,還需要把源代碼構建進去,但實際運行時只需要構建出的包,這種把源代碼放進去有一定安全風險,并且也增加了鏡像體積
3.為了解決上述問題,Docker 17.05開始支持多階段構建(multi-stage builds),可以簡化Dockerfile,減少鏡像大小
-
例如,構建JAVA項目鏡像:
# git clone https://github.com/lizhenliang/tomcat-java-demo # cd tomcat-java-demo # vi Dockerfile FROM maven AS build ADD ./pom.xml pom.xml ADD ./src src/ RUN mvn clean package FROM lizhenliang/tomcat RUN rm -rf /usr/local/tomcat/webapps/ROOT COPY --from=build target/*.war /usr/local/tomcat/webapps/ROOT.war # docker build -t demo:v1 . # docker container run -d -v demo:v1
首先,第一個FROM 后邊多了個 AS 關鍵字,可以給這個階段起個名字。
然后,第二部分FROM用的我們上面構建的Tomcat鏡像,COPY關鍵字增加了--from參數(shù),用于拷貝某個階段的文件到當前階段。這樣一個Dockerfile就都搞定了
解決了什么問題: 減少鏡像大小,快速部署、快速回滾。減少服務中斷時間,同時鏡像倉庫占用磁盤空間也少了