Docker是PaaS 提供商 dotCloud 開源的一個基于 LXC 的高級容器引擎,源代碼托管在 Github 上, 基于go語言并遵從Apache2.0協(xié)議開源。
Docker是通過內(nèi)核虛擬化技術(shù)(namespace以及cgroups等)來提供容器的資源隔離與安全保障。由于Docker通過操作系統(tǒng)層的虛擬化實現(xiàn)隔離,所以Docker容器在運(yùn)行時,不需要類似虛擬機(jī)( VM)額外的操作系統(tǒng)開銷,提高資源利用率。
原理:建立-->傳送-->運(yùn)行
架構(gòu):C/S架構(gòu)
組件:鏡像(Image)、容器(Container)、倉庫(Repository)
Docker與VM的區(qū)別:
docker與Openstack的對比
Docker用途:簡單配置、代碼流水線管理、開發(fā)效率、應(yīng)用隔離、服務(wù)器整合、調(diào)試能力、多租戶、快速部署
Docker改變了什么?
面向產(chǎn)品:產(chǎn)品交付
面向開發(fā):簡化環(huán)境配置
面向測試:多版本測試
面向運(yùn)維:環(huán)境一致性
面向架構(gòu):自動化擴(kuò)容
Docker環(huán)境的安裝部署
環(huán)境準(zhǔn)備(centos7)
yum install -y dockersystemctl start dockersystemctl enable docker
鏡像的查看(docker images信息結(jié)果包括:鏡像倉庫、標(biāo)簽、鏡像ID、創(chuàng)建時間、鏡像大小 )
[root@linux-node2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEdocker.io/centos latest 60e65a8e4030 36 hours ago 196.6 MBdocker.io/nginx latest 813e3731b203 9 days ago 133.8 MBdocker.io/registry latest a8706c2bfd21 2 weeks ago 422.8 MB
鏡像的導(dǎo)出、導(dǎo)入和下載(可以將本機(jī)下載的鏡像導(dǎo)出,然后將導(dǎo)出文件上傳到別的機(jī)器上,在別的機(jī)器上進(jìn)行鏡像導(dǎo)入)
1 2 3 4 5 | [root@linux-node2 ~] # docker pull centos [root@linux-node2 ~] # docker save centos > /opt/centos.tar.gz 將linux-node2的鏡像導(dǎo)出文件上傳到linux-node1機(jī)器上,然后在linux-node1機(jī)器上導(dǎo)入 [root@linux-node1 ~] # docker load < /opt/centos.tar.gz |
鏡像的刪除(rmi后面可以跟多個id,用空格隔開)
docker rmi container_id
[root@linux-node2 ~]# docker rmi 813e3731b203
首次創(chuàng)建一個簡單的容器
[root@linux-node2 ~]# docker run centos /bin/echo "hehe"hehe
命令解讀:使用centos鏡像,run執(zhí)行命令,使用echo命令輸出hehe
查看容器狀態(tài)
可以使用docker ps只能看見存活的容器,docker ps -a 查看全部的容器,結(jié)果信息表示:
容器ID、使用的鏡像、執(zhí)行的命令、創(chuàng)建的時間、狀態(tài)、端口、名稱(如果不指定,自動生成)
[root@linux-node2 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESdaeb4d7f7aab centos "/bin/echo hehe" About a minute ago Exited (0) About a minute ago insane_einstein
創(chuàng)建容器
--name:指定容器名稱
-t :分配一個tty終端
-i :容器的標(biāo)準(zhǔn)輸保持打開的狀態(tài)
[root@linux-node2 ~]# docker run --name mydocker -t -i centos /bin/bash[root@94ab7a046f7c /]# ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.1 11772 1872 ? Ss 03:42 0:00 /bin/bashroot 14 0.0 0.0 35888 1472 ? R+ 03:43 0:00 ps aux
這種方式創(chuàng)建自動進(jìn)入容器,開啟的容器只執(zhí)行/bin/bash;
在容器中查看主機(jī)名
[root@94ab7a046f7c /]# hostname94ab7a046f7c[root@94ab7a046f7c /]# exit
啟動、停止容器
[root@linux-node2 ~]# docker stop ID
[root@linux-node2 ~]# docker start ID
進(jìn)入容器
[root@linux-node2 ~]# docker attach 94ab7a046f7c
[root@94ab7a046f7c /]#
刪除容器
[root@linux-node2 ~]# docker rm ID/名稱加-f 強(qiáng)制刪除,包括正在運(yùn)行中的容器
映射
隨機(jī)映射
端口的映射是系統(tǒng)自動分配的?
[root@linux-node2 ~]# docker run -d -P nginx90316d97ee975b4e62e1927a9fb31f20703556b1a3ea07880d0c68dcb5bbd3bb[root@linux-node2 ~]# docker ps -lCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES90316d97ee97 nginx "nginx -g 'daemon off" 25 seconds ago Up 23 seconds 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp ecstatic_almeida
指定映射
指定端口的映射
[root@linux-node2 ~]# docker run -d -p 81:80 nginx0294a8f5b4fc81ba31383a8eb98ec62b136826eba92360c84afd87bf1bf819fc[root@linux-node2 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES0294a8f5b4fc nginx "nginx -g 'daemon off" 11 seconds ago Up 10 seconds 443/tcp, 0.0.0.0:81->80/tcp admiring_ramanujan
查看日志
[root@linux-node2 ~]# docker log +ID
數(shù)據(jù)管理
數(shù)據(jù)卷
默認(rèn)掛載目錄
創(chuàng)建一個數(shù)據(jù)卷,名稱是volume-test1,掛載到data下默認(rèn)掛載目錄
[root@linux-node2 ~]# docker run -it --name volume-test1 -v /data centos [root@1768d6414cfc /]# ls -l /data/total 0
打開一個新的窗口
列出容器的所有信息,查看mounts模塊
[root@linux-node2 ~]# docker inspect 1768d6414cfc "Mounts": [ { "Name": "55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167", "Source": "/var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data", "Destination": "/data", "Driver": "local", "Mode": "", "RW": true } ],
查找掛載點(diǎn)并進(jìn)入
查看掛載的位置[root@linux-node2 ~]# ll /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data總用量 0進(jìn)入到掛載點(diǎn)[root@linux-node2 ~]# cd /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data
創(chuàng)建一個cgt測試,并重新回到容器中查看
[root@linux-node2 _data]# mkdir cgt去容器中查看[root@1768d6414cfc /]# ls -l /data/total 4drwxr-xr-x 2 root root 4096 Jan 4 14:04 cgt
指定掛載目錄
將/opt掛載到/opt目錄下[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt centos
指定權(quán)限
只需要在掛載后面加上權(quán)限即可。
加讀寫rw;只讀ro
[root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt:rw centos
掛載單個文件
記錄歷史記錄
[root@linux-node2 ~]# docker run -it -v ~/.bash_history:/.bash_history centos
數(shù)據(jù)卷容器
讓一個容器可以訪問另一個容器的數(shù)據(jù)卷
啟動兩個容器
啟動nfs容器,掛在一個卷,使用-d直接在后臺執(zhí)行[root@linux-node2 ~]# docker run -d --name nfs -v /data centos 209bc89b365ad6bc1eeae693ada01c04c2d08e9ee2b8816e624882944c116126啟動test1容器,掛載到nfs的數(shù)據(jù)卷容器上,[root@linux-node2 ~]# docker run -it --name test1 --volumes-from nfs centos[root@5e399198d6a8 /]# ls /data/查看沒內(nèi)容
找到nfs容器的掛載點(diǎn)
(可以使用名稱,不僅僅是ID)
找到nfs容器的ID[root@linux-node2 opt]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES209bc89b365a centos "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago nfs找到nfs容器的掛載點(diǎn)
[root@linux-node2 _data]# docker inspect nfs[root@linux-node2 opt]# cd /var/lib/docker/volumes/3938c9b1143d41340e148a4c7bc12d13b53966b15380c5b958a9e035897450d5/_data[root@linux-node2 _data]# touch cgt
在test1上查看
到test1上查看[root@5e399198d6a8 /]# ls /data/cgt
注意:數(shù)據(jù)卷容器不論停止還是開啟,不影響其他容器掛載使用
如何制作鏡像
方式一:手動構(gòu)建容器
1)創(chuàng)建一個容器mynginx,使用centos鏡像
[root@linux-node2 ~]# docker run --name mynginx -it centos[root@f9c7dfb6f552 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm[root@f9c7dfb6f552 /]# yum -y install nginx[root@f9c7dfb6f552 /]# exit exit
2)基于mynginx容器做一個鏡像mynginx:v1
[root@linux-node2 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf9c7dfb6f552 centos "/bin/bash" 3 minutes ago Exited (0) 15 seconds ago mynginx基于mynginx這個容器做一個鏡像[root@linux-node2 ~]# docker commit -m "my nginx" f9c7dfb6f552 cgt/mynginx:v13f3adc859b77b2b47c3631229761bee6c7066f1c708bc01c5173c2ef5c0adce8提交鏡像,同時打一個標(biāo)簽叫mynginx:v1,cgt相當(dāng)于你向github上提交的用戶名查看鏡像[root@linux-node2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEcgt/mynginx v1 3f3adc859b77 About a minute ago 326.4 MB
3)基于mynginx:v1創(chuàng)建一個容器mynginxv1
目的是修改nginx不讓其在后臺運(yùn)行
[root@linux-node2 ~]# docker run -it --name nginxv1 cgt/mynginx:v1[root@ea64c5855006 /]# vi /etc/nginx/nginx.confdaemon off; # 不再后臺運(yùn)行[root@ea64c5855006 /]# exit exit[root@linux-node2 ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESea64c5855006 cgt/mynginx:v1 "/bin/bash" 2 minutes ago Exited (0) 42 seconds ago nginxv1
4)基于mynginxv1提交mynginxv2版本
重新提交V2版本[root@linux-node2 ~]# docker commit -m "my nginx" ea64c5855006 cgt/mynginx:v2a480cdf9055ec4e640c65df6404c6ba42903ea77198a26cec75eef0e4965fe67查看V2鏡像[root@linux-node2 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZEcgt/mynginx v2 a480cdf9055e 25 seconds ago
5)基于mynginxv2鏡像,創(chuàng)建mynginxv2容器
啟動容器,-d后臺運(yùn)行,-p指定端口 在后面是鏡像,最后是命令(因為是yum安裝的,可以直接寫nginx,如果不是yum,那要寫絕對路徑)[root@linux-node2 ~]# docker run -d -p 82:80 cgt/mynginx:v2 nginx4eaf8a19034a673100f9355504628fad45e6ecbab91615afd6cb4e7a18b82171[root@linux-node2 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES4eaf8a19034a cgt/mynginx:v2 "nginx" 15 seconds ago Up 14 seconds 0.0.0.0:82->80/tcp elegant_leakey可以在瀏覽器訪問82端口
方式二:Dockerfile
1)Dockerfile包含的信息
基礎(chǔ)鏡像信息
維護(hù)者信息
鏡像操作指令
容器啟動時執(zhí)行指令
2)文件的編寫
[root@linux-node2 ~]# mkdir /opt/dockerfile/nginx/ -p[root@linux-node2 ~]# cd /opt/dockerfile/nginx/將index.html上傳到此處[root@linux-node2 nginx]# vim Dockerfile# This is docker file# version v1# Author wangshibo# Base image(基礎(chǔ)鏡像)FROM centos# Maintainer(維護(hù)者信息)MAINTAINER wangshibo 2134728394@qq.com# Commands(執(zhí)行命令)RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpmRUN yum -y install nginx# Add(添加文件)ADD index.html /usr/share/nginx/html/index.html # index.html是自己編寫的文件,放在后面的目錄中,因為yum安裝后Documentroot是在這里RUN echo "daemon off;" >>/etc/nginx/nginx.confEXPOSE 80 # 對外的端口CMD ['nginx'] # 執(zhí)行的命令
3)構(gòu)建容器,并運(yùn)行
1 2 3 4 | 建立newnginx容器,-t:標(biāo)簽,執(zhí)行 /opt/dockerfile/nginx/ 下面的默認(rèn)的Dockerfile文件 [root@linux-node2 nginx] # docker build -t cgt/mynginx:v3 /opt/dockerfile/nginx/ [root@linux-node2 nginx] # docker run -d -p 83:80 cgt/mynginx:v3 |
-------------------------------------------------------------------------------------------------------------------------------
Docker是一個開源的應(yīng)用容器引擎,讓開發(fā)者可以打包他們的應(yīng)用以及依賴包到一個可移植的容器中,然后發(fā)布到任何流行的Linux機(jī)器上,也可以實現(xiàn)虛擬化。當(dāng)你真正投入容器Docker的懷抱,不但可以發(fā)現(xiàn)它能解決很多問題,而且還具有眾多的優(yōu)點(diǎn):
1 2 3 | 1)它是不可變的-操作系統(tǒng),庫版本,配置,文件夾和應(yīng)用都是一樣的。您可以使用通過相同QA測試的鏡像,使產(chǎn)品具有相同的表現(xiàn)。 2)它是輕量級的-容器的內(nèi)存占用非常小。不需要幾百幾千MB,它只要對主進(jìn)程分配內(nèi)存再加上幾十MB。 3)它很快速-啟動一個容器與啟動一個單進(jìn)程一樣快。不需要幾分鐘,您可以在幾秒鐘內(nèi)啟動一個全新的容器。 |
但是,許多用戶依然像對待典型的虛擬機(jī)那樣對待容器,似乎都忘記了除了與虛擬機(jī)相似的部分,容器還有一個很大的優(yōu)點(diǎn):它是一次性的?! ?br>這個“特性”本身促使用戶改變他們關(guān)于使用和管理容器的習(xí)慣;下面將會說明下在容器中不應(yīng)該做這些事,以確保最大地發(fā)揮容器的作用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1)不要在容器中存儲數(shù)據(jù) – 容器可能被停止,銷毀,或替換。一個運(yùn)行在容器中的程序版本1.0,應(yīng)該很容易被1.1的版本替換且不影響或損失數(shù)據(jù)。有鑒于此,如果你需要存儲數(shù)據(jù),請存在卷中,并且注意如果兩個容器在同一個卷上寫數(shù)據(jù)會導(dǎo)致崩潰。確保你的應(yīng)用被設(shè)計成在共享數(shù)據(jù)存儲上寫入。 2)不要將你的應(yīng)用發(fā)布兩份 – 一些人將容器視為虛擬機(jī)。他們中的大多數(shù)傾向于認(rèn)為他們應(yīng)該在現(xiàn)有的運(yùn)行容器里發(fā)布自己的應(yīng)用。在開發(fā)階段這樣是對的,此時你需要不斷地部署與調(diào)試;但對于質(zhì)量保證與生產(chǎn)中的一個連續(xù)部署的管道,你的應(yīng)用本該成為鏡像的一部分。記住:容器應(yīng)該保持不變。 3)不要創(chuàng)建超大鏡像 – 一個超大鏡像只會難以分發(fā)。確保你僅有運(yùn)行你應(yīng)用/進(jìn)程的必需的文件和庫。不要安裝不必要的包或在創(chuàng)建中運(yùn)行更新(yum更新)。 4)不要使用單層鏡像 – 要對分層文件系統(tǒng)有更合理的使用,始終為你的操作系統(tǒng)創(chuàng)建你自己的基礎(chǔ)鏡像層,另外一層為安全和用戶定義,一層為庫的安裝,一層為配置,最后一層為應(yīng)用。這將易于重建和管理一個鏡像,也易于分發(fā)。 5)不要為運(yùn)行中的容器創(chuàng)建鏡像 – 換言之,不要使用“docker commit”命令來創(chuàng)建鏡像。這種創(chuàng)建鏡像的方法是不可重現(xiàn)的也不能版本化,應(yīng)該徹底避免。始終使用Dockerfile或任何其他的可完全重現(xiàn)的S2I(源至鏡像)方法。 6)不要只使用“最新”標(biāo)簽 – 最新標(biāo)簽就像Maven用戶的“快照”。標(biāo)簽是被鼓勵使用的,尤其是當(dāng)你有一個分層的文件系統(tǒng)。你總不希望當(dāng)你2個月之后創(chuàng)建鏡像時,驚訝地發(fā)現(xiàn)你的應(yīng)用無法運(yùn)行,因為最頂?shù)姆謱颖环窍蚝蠹嫒莸男掳姹咎鎿Q,或者創(chuàng)建緩存中有一個錯誤的“最新”版本。在生產(chǎn)中部署容器時應(yīng)避免使用最新。 7)不要在單一容器中運(yùn)行超過一個進(jìn)程-容器能完美地運(yùn)行單個進(jìn)程(http守護(hù)進(jìn)程,應(yīng)用服務(wù)器,數(shù)據(jù)庫),但是如果你不止有一個進(jìn)程,管理、獲取日志、獨(dú)立更新都會遇到麻煩。 8)不要在鏡像中存儲憑據(jù)。使用環(huán)境變量 –不要將鏡像中的任何用戶名/密碼寫死。使用環(huán)境變量來從容器外部獲取此信息。 9)使用非root用戶運(yùn)行進(jìn)程 – “docker容器默認(rèn)以root運(yùn)行。(…)隨著docker的成熟,更多的安全默認(rèn)選項變得可用?,F(xiàn)如今,請求root對于其他人是危險的,可能無法在所有環(huán)境中可用。你的鏡像應(yīng)該使用USER指令來指令容器的一個非root用戶來運(yùn)行?!?/code> 10)不要依賴IP地址 – 每個容器都有自己的內(nèi)部IP地址,如果你啟動并停止它地址可能會變化。如果你的應(yīng)用或微服務(wù)需要與其他容器通訊,使用任何命名與(或者)環(huán)境變量來從一個容器傳遞合適信息到另一個。 |