docker-基礎命令和使用案例

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就都搞定了

解決了什么問題: 減少鏡像大小,快速部署、快速回滾。減少服務中斷時間,同時鏡像倉庫占用磁盤空間也少了

問題與支持

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容