Docker技術入門與實戰筆記

Docker

一.底層技術支持cgroups/LXC/AUFS

1.cgroups

cgroups 進程分組化管理,Linux內核提供原生支持。經過分組實現對系統資源的限制與分配。python

cgroups中的重要概念是「子系統」,也就是資源控制器,每種子系統就是一個資源的分配器.好比cpu子系統是控制cpu時間分配的。首先掛載子系統,而後纔有control group的。好比先掛載memory子系統,而後在memory子系統中建立一個cgroup節點,在這個節點中,將須要控制的進程id寫入,而且將控制的屬性寫入,這就完成了內存的資源限制。nginx

2.LXC

LXC是Linux containers的簡稱,是一種基於容器的操做系統層級的虛擬化技術。git

藉助於namespace的隔離機制和cgroup限額功能,LXC提供了一套統一的API和工具來創建和管理container。github

LXC旨在提供一個共享kernel的OS級虛擬化方法,在執行時不用重複加載Kernel,且container的kernel與host共享.web

3.聯合文件系統(UnionFS)

聯合文件系統(UnionFS)是一種分層、輕量級而且高性能的文件系統。redis

聯合文件系統是 Docker 鏡像的基礎。鏡像能夠經過分層來進行繼承,基於基礎鏡像能夠製做各類具體的應用鏡像。docker

AuFS是ubantu上最經常使用的聯合文件系統。shell

Docker鏡像其實是由具備依賴關係的多個Layer組成的。數據庫

Union FS 是有最大層數限制的,好比 AUFS,曾經是最大不得超過42層,如今是不得超過127層。npm

二.基本概念

1.Docker Image

1)操做系統分爲內核和用戶空間。對於 Linux 而言,內核啓動後,會掛載 root 文件系統爲其提供用戶空間支持。而 Docker 鏡像(Image),就至關因而一個 root 文件系統。好比官方鏡像 ubuntu:14.04 就包含了完整的一套Ubuntu 14.04 最小系統的 root 文件系統。

2)Docker Image內不建議有運行期須要修改的配置文件

2.Docker Container

1)Docker Container是Image的實例,共享內核
2)Docker Container裏能夠運行不一樣Os的Image,好比Ubuntu的或者Centos
3)Docker Container不建議內部開啓一個SSHD服務,1.3版本後新增了docker exec命令進入容器排查問題。
4)Docker Container沒有IP地址,一般不會有服務端口暴露,是一個封閉的「盒子/沙箱」

3.Docker Daemon

1)Docker Daemon是建立和運行Container的Linux守護進程,也是Docker最主要的核心組件.
2)Docker Daemon 能夠理解爲Docker Container的Container

4.數據卷

數據卷的生存週期獨立於容器,容器消亡,數據卷不會消亡。所以,使用數據卷後,容器能夠隨意刪除、從新 run ,數據卻不會丟失。

數據卷是一個的特殊目錄,能夠在容器之間共享和重用,數據卷默認會一直存在,即便容器被刪除.Docker掛載數據卷的默認權限是讀寫,用戶也能夠經過:ro指定爲只讀。

數據卷容器 若是你有一些持續更新的數據須要在容器之間共享,最好建立數據卷容器。數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。

5. Docker Registry

1)一個Docker Registry中能夠包含多個倉庫(Repository);每一個倉庫能夠包含多個標籤(Tag);每一個標籤對應一個鏡像。

2)經過 <倉庫名>:<標籤> 的格式來指定具體是這個軟件哪一個版本的鏡像。若是不給出標籤,將以 latest 做爲默認標籤。

eg:registry.cn-qingdao.aliyuncs.com/dockerres/dockerres:webv1s1

3)虛懸鏡像 因爲新舊鏡像同名,舊鏡像名稱被取消,從而出現倉庫名、標籤均爲 <none> 的鏡像。這類無標籤鏡像也被稱爲 虛懸鏡像(dangling image)。要注意區分虛懸鏡像與中間層鏡像。

三.Dockerfile

1.建立docker鏡像

1)docker commit

docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]

eg:docker commit \
                  --author "Tao Wang <twang2218@gmail.com>" \
                  --message "修改了默認網頁" \
                  webserver \
                  nginx:v2

2)Dockerfile

docker build [選項] <上下文路徑/URL/->

eg:docker build -t nginx:v3 .  <.>表示上下文路徑爲當前目錄

2.docker build的用法

a.直接用Git進行構建

docker build https://github.com/twang2218/gitlab-ce-zh.git

b.用給定的 tar 壓縮包構建

docker build http://server/context.tar.gz

c.從標準輸入中讀取 Dockerfile 進行構建

docker build - < Dockerfile

d.從標準輸入中讀取上下文壓縮包進行構建

docker build - < context.tar.gz

3.dockerfile命令

dockerfile內容:
    FROM debian:jessie
    RUN buildDeps='gcc libc6-dev make' \
        && apt-get update \
        && apt-get install -y $buildDeps \
        && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
        && mkdir -p /usr/src/redis \
        && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
        && make -C /usr/src/redis \
        && make -C /usr/src/redis install \
        && rm -rf /var/lib/apt/lists/* \
        && rm redis.tar.gz \
        && rm -r /usr/src/redis \
        && apt-get purge -y --auto-remove $buildDeps

1)FROM 指定基礎鏡像。

若是不以任何鏡像爲基礎,則以FROM scratch代替。

2)RUN

shell 格式: RUN <命令>

exec 格式: RUN ["可執行文件", "參數1", "參數2"]

每一條RUN語句都會生成一個鏡像,能夠用&&將多條命令合成一條RUN語句。

3)COPY

COPY <源路徑>... <目標路徑>

COPY ["<源路徑1>",... "<目標路徑>"]

使用 COPY 指令,源文件的各類元數據都會保留。好比讀、寫、執行權限、文件變動時間等.

eg:
COPY hom* /mydir/
COPY hom?.txt /mydir/

4)ADD

ADD格式與COPY同樣 在COPY和ADD指令中選擇的時候,能夠遵循這樣的原則,全部的文件複製均使用COPY指令,僅在須要自動解壓縮的場合使用ADD。

5)CMD 啓動參數

CMD 指令用於指定容器默認的啓動程序及參數。

shell 格式: CMD <命令>

exec 格式: CMD ["可執行文件", "參數1", "參數2"...]

指令格式上,通常推薦使用exec格式。

對於容器而言,其啓動程序就是容器應用進程,容器就是爲了主進程而存在的,主 進程退出,容器就失去了存在的意義,從而退出。正確的作法是 直接執行可執行文件,而且要求之前臺形式運行,不要以服務後臺的形式啓動。

6)ENTRYPOINT 啓動參數

ENTRYPOINT 的目的和 CMD 同樣,都是在指定容器啓動程序及參數。

ENTRYPOINT的主要應用場景:

a.讓鏡像變成像命令同樣使用

b.應用運行前的準備工做

7)ENV 設置環境變量

ENV <key> <value>

ENV <key1>=<value1> <key2>=<value2>

eg:ENV VERSION=1.0 DEBUG=on \
              NAME="Happy Feet"

8)ARG 構建參數

ARG <參數名>[=<默認值>]

構建參數和 ENV 的效果同樣,都是設置環境變量。所不一樣的是, ARG 所設置的構建環境的環境變量,在未來容器運行時是不會存在這些環境變量的。

9)VOLUME 定義匿名卷

VOLUME ["<路徑1>", "<路徑2>"...] VOLUME <路徑>

容器運行時應該儘可能保持容器存儲層不發生寫操做,對於數據庫類須要保存動態數據的應用,其數據庫文件應該保存於卷(volume)中。爲了防止運行時用戶忘記掛載卷,在 Dockerfile 中,咱們能夠事先指定某些目錄掛載爲匿名卷.

10)EXPOSE 聲明端口

EXPOSE <端口1> [<端口2>...]

EXPOSE指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時並不會由於這個聲明應用就會開啓這個端口的服務。

11)WORKDIR 指定工做目錄

WORKDIR <工做目錄路徑>

12)USER 指定當前用戶

USER <用戶名>

13)HEALTHCHECK 健康檢查

HEALTHCHECK [選項] CMD <命令> :設置檢查容器健康情況的命令

HEALTHCHECK NONE :若是基礎鏡像有健康檢查指令,使用這行能夠屏蔽掉其健康檢查指令

eg:HEALTHCHECK --interval=5s --timeout=3s \
                                CMD curl -fs http://localhost/ || exit 1

14)ONBUILD 爲他人作嫁衣裳

ONBUILD <其它指令>

eg:ONBUILD COPY ./package.json /app
     ONBUILD RUN [ "npm", "install" ]
     ONBUILD COPY . /app/

Dockerfile 中的其它指令都是爲了定製當前鏡像而準備的,惟有 ONBUILD 是爲了幫助別人定製本身而準備的。

ONBUILD 是一個特殊的指令,它後面跟的是其它指令,好比 RUN , COPY 等,而這些指令,在當前鏡像構建時並不會被執行。只有當以當前鏡像爲基礎鏡像,去構建下一級鏡像的時候纔會被執行。

4、Docker網絡服務

1.外部訪問容器

能夠經過 -P 或-p 參數來指定端口映射。

a.使用 -P 標記時,Docker 會隨機映射一個 49000~49900 的端口到內部容器開放的網絡端口。
b.-p hostPort:containerPort 指定端口
eg:$ sudo docker run -d -p 5000:5000 training/webapp python app.py
c.-p ip:hostPort:containerPort
eg:sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
d.ip::containerPort 映射到指定地址的任意端口
eg:sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
e.使用 udp 標記來指定 udp 端口
eg:sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
f.docker port 來查看當前映射的端口配置
eg:docker port nostalgic_morse 5000

2.容器互聯

--link 參數的格式爲 --link name:alias ,其中 name 是要連接的容器的名稱, alias 是這個鏈接的別名。

eg:sudo docker run -d -P --name web --link db:db training/webapp python app.py

3.網橋

Docker啓動時,會自動在主機上建立一個docker0虛擬網橋。當建立一個Docker容器的時候,同時會建立了一對虛擬網卡(veth pair)接口,這對接口一端在容器內,即eth0;另外一端在本地並被掛載到docker0網橋。這樣全部容器在一個局域網內,經過docker0與主機通訊。

4.網絡配置

--net=bridge 這個是默認值,鏈接到默認的網橋。

--net=host 告訴 Docker 不要將容器網絡放到隔離的命名空間中,即不要容器化容器內的網絡。此時容器使用本地主機的網絡,它擁有徹底的本地主機接口訪問權限。

--net=container:NAME_or_ID 讓 Docker 將新建容器的進程放到一個已存在容器的網絡棧中,新容器進程有本身的文件系統、進程列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網絡資源,二者進程能夠直接經過lo 環回接口通訊。

--net=none 讓 Docker 將新容器放到隔離的網絡棧中,可是不進行網絡配置。以後,用戶能夠本身進行配置。

五.其餘

tomcat Dockerfile
FROM tomcat:8.5.37-jre8
  MAINTAINER "wdw"
  ADD web1.war /usr/local/tomcat/webapps/
  CMD ["catalina.sh", "run"]
相關文章
相關標籤/搜索