cgroups 進程分組化管理,Linux內核提供原生支持。經過分組實現對系統資源的限制與分配。python
cgroups中的重要概念是「子系統」,也就是資源控制器,每種子系統就是一個資源的分配器.好比cpu子系統是控制cpu時間分配的。首先掛載子系統,而後纔有control group的。好比先掛載memory子系統,而後在memory子系統中建立一個cgroup節點,在這個節點中,將須要控制的進程id寫入,而且將控制的屬性寫入,這就完成了內存的資源限制。nginx
LXC是Linux containers的簡稱,是一種基於容器的操做系統層級的虛擬化技術。git
藉助於namespace的隔離機制和cgroup限額功能,LXC提供了一套統一的API和工具來創建和管理container。github
LXC旨在提供一個共享kernel的OS級虛擬化方法,在執行時不用重複加載Kernel,且container的kernel與host共享.web
聯合文件系統(UnionFS)是一種分層、輕量級而且高性能的文件系統。redis
聯合文件系統是 Docker 鏡像的基礎。鏡像能夠經過分層來進行繼承,基於基礎鏡像能夠製做各類具體的應用鏡像。docker
AuFS是ubantu上最經常使用的聯合文件系統。shell
Docker鏡像其實是由具備依賴關係的多個Layer組成的。數據庫
Union FS 是有最大層數限制的,好比 AUFS,曾經是最大不得超過42層,如今是不得超過127層。npm
1)操做系統分爲內核和用戶空間。對於 Linux 而言,內核啓動後,會掛載 root 文件系統爲其提供用戶空間支持。而 Docker 鏡像(Image),就至關因而一個 root 文件系統。好比官方鏡像 ubuntu:14.04 就包含了完整的一套Ubuntu 14.04 最小系統的 root 文件系統。
2)Docker Image內不建議有運行期須要修改的配置文件
1)Docker Container是Image的實例,共享內核 2)Docker Container裏能夠運行不一樣Os的Image,好比Ubuntu的或者Centos 3)Docker Container不建議內部開啓一個SSHD服務,1.3版本後新增了docker exec命令進入容器排查問題。 4)Docker Container沒有IP地址,一般不會有服務端口暴露,是一個封閉的「盒子/沙箱」
1)Docker Daemon是建立和運行Container的Linux守護進程,也是Docker最主要的核心組件. 2)Docker Daemon 能夠理解爲Docker Container的Container
數據卷的生存週期獨立於容器,容器消亡,數據卷不會消亡。所以,使用數據卷後,容器能夠隨意刪除、從新 run ,數據卻不會丟失。
數據卷是一個的特殊目錄,能夠在容器之間共享和重用,數據卷默認會一直存在,即便容器被刪除.Docker掛載數據卷的默認權限是讀寫,用戶也能夠經過:ro指定爲只讀。
數據卷容器 若是你有一些持續更新的數據須要在容器之間共享,最好建立數據卷容器。數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。
1)一個Docker Registry中能夠包含多個倉庫(Repository);每一個倉庫能夠包含多個標籤(Tag);每一個標籤對應一個鏡像。
2)經過 <倉庫名>:<標籤> 的格式來指定具體是這個軟件哪一個版本的鏡像。若是不給出標籤,將以 latest 做爲默認標籤。
eg:registry.cn-qingdao.aliyuncs.com/dockerres/dockerres:webv1s1
3)虛懸鏡像 因爲新舊鏡像同名,舊鏡像名稱被取消,從而出現倉庫名、標籤均爲 <none> 的鏡像。這類無標籤鏡像也被稱爲 虛懸鏡像(dangling image)。要注意區分虛懸鏡像與中間層鏡像。
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]
eg:docker commit \ --author "Tao Wang <twang2218@gmail.com>" \ --message "修改了默認網頁" \ webserver \ nginx:v2
docker build [選項] <上下文路徑/URL/->
eg:docker build -t nginx:v3 . <.>表示上下文路徑爲當前目錄
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
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
若是不以任何鏡像爲基礎,則以FROM scratch代替。
shell 格式: RUN <命令>
exec 格式: RUN ["可執行文件", "參數1", "參數2"]
每一條RUN語句都會生成一個鏡像,能夠用&&將多條命令合成一條RUN語句。
COPY <源路徑>... <目標路徑>
COPY ["<源路徑1>",... "<目標路徑>"]
使用 COPY 指令,源文件的各類元數據都會保留。好比讀、寫、執行權限、文件變動時間等.
eg: COPY hom* /mydir/ COPY hom?.txt /mydir/
ADD格式與COPY同樣 在COPY和ADD指令中選擇的時候,能夠遵循這樣的原則,全部的文件複製均使用COPY指令,僅在須要自動解壓縮的場合使用ADD。
CMD 指令用於指定容器默認的啓動程序及參數。
shell 格式: CMD <命令>
exec 格式: CMD ["可執行文件", "參數1", "參數2"...]
指令格式上,通常推薦使用exec格式。
對於容器而言,其啓動程序就是容器應用進程,容器就是爲了主進程而存在的,主 進程退出,容器就失去了存在的意義,從而退出。正確的作法是 直接執行可執行文件,而且要求之前臺形式運行,不要以服務後臺的形式啓動。
ENTRYPOINT 的目的和 CMD 同樣,都是在指定容器啓動程序及參數。
ENTRYPOINT的主要應用場景:
a.讓鏡像變成像命令同樣使用
b.應用運行前的準備工做
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>
eg:ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet"
ARG <參數名>[=<默認值>]
構建參數和 ENV 的效果同樣,都是設置環境變量。所不一樣的是, ARG 所設置的構建環境的環境變量,在未來容器運行時是不會存在這些環境變量的。
VOLUME ["<路徑1>", "<路徑2>"...] VOLUME <路徑>
容器運行時應該儘可能保持容器存儲層不發生寫操做,對於數據庫類須要保存動態數據的應用,其數據庫文件應該保存於卷(volume)中。爲了防止運行時用戶忘記掛載卷,在 Dockerfile 中,咱們能夠事先指定某些目錄掛載爲匿名卷.
EXPOSE <端口1> [<端口2>...]
EXPOSE指令是聲明運行時容器提供服務端口,這只是一個聲明,在運行時並不會由於這個聲明應用就會開啓這個端口的服務。
WORKDIR <工做目錄路徑>
USER <用戶名>
HEALTHCHECK [選項] CMD <命令> :設置檢查容器健康情況的命令
HEALTHCHECK NONE :若是基礎鏡像有健康檢查指令,使用這行能夠屏蔽掉其健康檢查指令
eg:HEALTHCHECK --interval=5s --timeout=3s \ CMD curl -fs http://localhost/ || exit 1
ONBUILD <其它指令>
eg:ONBUILD COPY ./package.json /app ONBUILD RUN [ "npm", "install" ] ONBUILD COPY . /app/
Dockerfile 中的其它指令都是爲了定製當前鏡像而準備的,惟有 ONBUILD 是爲了幫助別人定製本身而準備的。
ONBUILD 是一個特殊的指令,它後面跟的是其它指令,好比 RUN , COPY 等,而這些指令,在當前鏡像構建時並不會被執行。只有當以當前鏡像爲基礎鏡像,去構建下一級鏡像的時候纔會被執行。
能夠經過 -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
--link 參數的格式爲 --link name:alias ,其中 name 是要連接的容器的名稱, alias 是這個鏈接的別名。
eg:sudo docker run -d -P --name web --link db:db training/webapp python app.py
Docker啓動時,會自動在主機上建立一個docker0虛擬網橋。當建立一個Docker容器的時候,同時會建立了一對虛擬網卡(veth pair)接口,這對接口一端在容器內,即eth0;另外一端在本地並被掛載到docker0網橋。這樣全部容器在一個局域網內,經過docker0與主機通訊。
--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"]