Docker 系列簡(jiǎn)明教程1——基礎(chǔ)入門(mén)
# 分類(lèi)標(biāo)簽
- 運(yùn)維
- 后端開(kāi)發(fā)
# 前置知識(shí)
- Linux 基礎(chǔ)
# 思維導(dǎo)圖
一熏迹、簡(jiǎn)介
1.1 技術(shù)背景
每一項(xiàng)新技術(shù)的誕生伦腐,起初都是為了解決一個(gè)或多個(gè)問(wèn)題企锌。
Docker 也是如此甫煞。
環(huán)境配置的難題
軟件開(kāi)發(fā)最大的麻煩事之一壶笼,就是環(huán)境配置
虐沥。
軟件的運(yùn)行環(huán)境千差萬(wàn)別杨名,開(kāi)發(fā)環(huán)境脏榆、測(cè)試環(huán)境、生產(chǎn)環(huán)境……等等台谍。這臺(tái)機(jī)器可以跑须喂,那臺(tái)機(jī)器或許就跑不起來(lái)。用戶必須保證兩件事:操作系統(tǒng)的設(shè)置趁蕊,各種庫(kù)和組件的安裝坞生。只有它們都正確,軟件才能運(yùn)行起來(lái)掷伙。
如果某些老舊的模塊與當(dāng)前環(huán)境不兼容是己,那就更麻煩了。
環(huán)境配置是如此麻煩任柜,換一臺(tái)機(jī)器卒废,我們就要重來(lái)一次沛厨。很多人想,能不能從根本上解決問(wèn)題摔认,讓軟件可以帶環(huán)境安裝逆皮?
也就是說(shuō),安裝的時(shí)候参袱,把原始環(huán)境一模一樣地復(fù)制一份過(guò)來(lái)电谣。
當(dāng)然,答案是肯定的抹蚀。
解決方案
(1)虛擬機(jī)
虛擬機(jī)(virtual machine)就是帶環(huán)境安裝的一種解決方案辰企。它可以在一種操作系統(tǒng)里面運(yùn)行另一種操作系統(tǒng)。
應(yīng)用程序?qū)Υ撕翢o(wú)感知况鸣,因?yàn)樘摂M機(jī)看上去跟真實(shí)系統(tǒng)一模一樣牢贸。而對(duì)于底層系統(tǒng)來(lái)說(shuō),虛擬機(jī)就是一個(gè)普通文件镐捧,不需要了就刪掉潜索,對(duì)其他部分毫無(wú)影響。
雖然用戶可以通過(guò)虛擬機(jī)還原軟件的原始環(huán)境懂酱。但是竹习,這個(gè)方案也有幾個(gè)缺點(diǎn)。
(1)資源占用多
虛擬機(jī)會(huì)獨(dú)占一部分內(nèi)存和硬盤(pán)空間列牺。它運(yùn)行的時(shí)候整陌,其他程序就不能使用這些資源了。哪怕虛擬機(jī)里面的應(yīng)用程序瞎领,真正使用的內(nèi)存只有 1MB泌辫,虛擬機(jī)依然需要幾百 MB 的內(nèi)存才能運(yùn)行。
(2)冗余步驟多
虛擬機(jī)是完整的操作系統(tǒng)九默,一些系統(tǒng)級(jí)別的操作步驟震放,往往無(wú)法跳過(guò),比如用戶登錄驼修。
(3)啟動(dòng)慢
啟動(dòng)操作系統(tǒng)需要多久殿遂,啟動(dòng)虛擬機(jī)就需要多久∫腋鳎可能要等幾分鐘墨礁,應(yīng)用程序才能真正運(yùn)行。
(2)Linux 容器
由于虛擬機(jī)存在這些缺點(diǎn)耳峦,Linux 發(fā)展出了另一種虛擬化技術(shù):Linux 容器(Linux Containers恩静,縮寫(xiě)為 LXC)。
Linux 容器
不是模擬一個(gè)完整的操作系統(tǒng)妇萄,而是對(duì)進(jìn)程進(jìn)行隔離蜕企。或者說(shuō)冠句,在正常進(jìn)程的外面套了一個(gè)保護(hù)層轻掩。對(duì)于容器里面的進(jìn)程來(lái)說(shuō),它接觸到的各種資源都是虛擬的懦底,從而實(shí)現(xiàn)與底層系統(tǒng)的隔離唇牧。
由于容器是進(jìn)程級(jí)別的,相比虛擬機(jī)有很多優(yōu)勢(shì)聚唐。
(1)啟動(dòng)快
容器里面的應(yīng)用丐重,直接就是底層系統(tǒng)的一個(gè)進(jìn)程,而不是虛擬機(jī)內(nèi)部的進(jìn)程杆查。所以扮惦,啟動(dòng)容器相當(dāng)于啟動(dòng)本機(jī)的一個(gè)進(jìn)程,而不是啟動(dòng)一個(gè)操作系統(tǒng)亲桦,速度就快很多崖蜜。
(2)資源占用少
容器只占用需要的資源,不占用那些沒(méi)有用到的資源客峭;虛擬機(jī)由于是完整的操作系統(tǒng)豫领,不可避免要占用所有資源。另外舔琅,多個(gè)容器可以共享資源等恐,虛擬機(jī)都是獨(dú)享資源。
(3)體積小
容器只要包含用到的組件即可备蚓,而虛擬機(jī)是整個(gè)操作系統(tǒng)的打包课蔬,所以容器文件比虛擬機(jī)文件要小很多。
總之郊尝,容器有點(diǎn)像輕量級(jí)的虛擬機(jī)购笆,能夠提供虛擬化的環(huán)境,但是成本開(kāi)銷(xiāo)小得多虚循。
1.2 Docker 是什么
Docker 屬于 Linux 容器的一種封裝同欠,提供簡(jiǎn)單易用的容器使用接口『岬蓿基于 Go 語(yǔ)言铺遂,并遵從 Apache2.0 協(xié)議開(kāi)源,于2013年發(fā)布茎刚。它是目前最流行的 Linux 容器解決方案襟锐。
Docker 可以讓開(kāi)發(fā)者把他們的應(yīng)用以及依賴打包到一個(gè)文件里。運(yùn)行這個(gè)文件膛锭,就會(huì)生成一個(gè)輕量級(jí)粮坞、可移植的虛擬容器蚊荣。應(yīng)用程序在這個(gè)虛擬容器里運(yùn)行,就好像在真實(shí)的物理機(jī)上運(yùn)行一樣莫杈。
有了 Docker
互例,就不用擔(dān)心環(huán)境問(wèn)題。
1.3 Docker 的用途
Docker 的主要用途筝闹,目前主要有三大類(lèi)媳叨。
(1)提供一次性的環(huán)境。比如关顷,本地測(cè)試他人的軟件糊秆、持續(xù)集成的時(shí)候提供單元測(cè)試和構(gòu)建的環(huán)境。
(2)提供彈性的云服務(wù)议双。因?yàn)?Docker 容器可以隨開(kāi)隨關(guān)痘番,很適合動(dòng)態(tài)擴(kuò)容和縮容。
(3)組建微服務(wù)架構(gòu)平痰。通過(guò)多個(gè)容器夫偶,一臺(tái)機(jī)器可以跑多個(gè)服務(wù),因此在本機(jī)就可以模擬出微服務(wù)架構(gòu)觉增。
1.4 Docker 的版本
Docker 是一個(gè)開(kāi)源的商業(yè)產(chǎn)品兵拢,從 17.03 版本之后分為 CE(Community Edition: 社區(qū)版) 和 EE(Enterprise Edition: 企業(yè)版),企業(yè)版包含了一些收費(fèi)服務(wù)逾礁,個(gè)人開(kāi)發(fā)者一般用不到说铃。我們用社區(qū)版就可以了。
二嘹履、安裝
Docker CE 的安裝請(qǐng)參考官方文檔
腻扇。
- MacOS: https://docs.docker.com/docker-for-mac/install/
- Windows: https://docs.docker.com/docker-for-windows/install/
- CentOS: https://docs.docker.com/install/linux/docker-ce/centos/
- Ubuntu: https://docs.docker.com/install/linux/docker-ce/ubuntu/
- Debian: https://docs.docker.com/install/linux/docker-ce/debian/
- Fedora: https://docs.docker.com/install/linux/docker-ce/fedora/
- 其他Linux發(fā)行版:https://docs.docker.com/install/linux/docker-ce/binaries/
官方文檔是英文的,喜歡中文文檔的童鞋也可參考菜鳥(niǎo)教程的砾嫉。
- MacOS: https://www.runoob.com/docker/macos-docker-install.html
- Windows: https://www.runoob.com/docker/windows-docker-install.html
- CentOS: https://www.runoob.com/docker/centos-docker-install.html
- Ubuntu: https://www.runoob.com/docker/ubuntu-docker-install.html
- Debian: https://www.runoob.com/docker/debian-docker-install.html
安裝完成后幼苛,運(yùn)行下面的命令,驗(yàn)證是否安裝成功焕刮。
$ docker version
# 或者
$ docker info
Docker 需要用戶具有 sudo 權(quán)限
舶沿,為了避免每次命令都輸入sudo,可以把用戶加入 Docker 用戶組配并。
$ sudo usermod -aG docker $USER
Docker 是服務(wù)器/客戶端架構(gòu)括荡。命令行運(yùn)行docker命令的時(shí)候,需要本機(jī)有 Docker 服務(wù)
溉旋。如果這項(xiàng)服務(wù)沒(méi)有啟動(dòng)畸冲,可以用下面的命令啟動(dòng)。
# service 命令的用法
$ sudo service docker start
# systemctl 命令的用法
$ sudo systemctl start docker
# 換源
國(guó)內(nèi)從 DockerHub 拉取鏡像有時(shí)會(huì)遇到困難,此時(shí)可以配置鏡像加速
邑闲。Docker 官方和國(guó)內(nèi)很多云服務(wù)商都提供了國(guó)內(nèi)加速器服務(wù)算行,例如:
- 網(wǎng)易:https://hub-mirror.c.163.com/
- 阿里云:https://<你的ID>.mirror.aliyuncs.com
- 七牛云加速器:https://reg-mirror.qiniu.com
- Docker 官方加速: https://registry.docker-cn.com (現(xiàn)在好像已經(jīng)不能使用了)
當(dāng)配置某一個(gè)加速器地址之后,若發(fā)現(xiàn)拉取不到鏡像苫耸,請(qǐng)切換到另一個(gè)加速器地址州邢。國(guó)內(nèi)各大云服務(wù)商均提供了 Docker 鏡像加速服務(wù),建議根據(jù)運(yùn)行 Docker 的云平臺(tái)選擇對(duì)應(yīng)的鏡像加速服務(wù)鲸阔。
各平臺(tái)換源的操作步驟請(qǐng)參考官方文檔:https://www.docker.com/registry-mirror
或者菜鳥(niǎo)教程:https://www.runoob.com/docker/docker-mirror-acceleration.html
然后檢查加速器是否生效:
$ docker info
三偷霉、Docker 的架構(gòu)與核心概念
Docker 包括三個(gè)基本概念:
鏡像(Image):
Docker 鏡像(Image)迄委,就是一個(gè)二進(jìn)制文件
褐筛。Docker 把應(yīng)用程序及其依賴,打包
在 image 文件里面叙身。只有通過(guò)這個(gè)文件渔扎,才能生成 Docker 容器實(shí)例
,image 文件可以看作是容器的模板
信轿。同一個(gè) image 文件晃痴,可以生成多個(gè)
同時(shí)運(yùn)行的容器實(shí)例。實(shí)際開(kāi)發(fā)中财忽,一個(gè) image 文件往往通過(guò)繼承
另一個(gè) image 文件倘核,加上一些個(gè)性化設(shè)置
而生成。容器(Container):
Image 文件生成的容器實(shí)例
即彪,本身也是一個(gè)文件紧唱,稱為容器文件
。鏡像(Image)和容器(Container)的關(guān)系隶校,就像是面向?qū)ο蟪绦蛟O(shè)計(jì)中的類(lèi)和實(shí)例
一樣漏益,鏡像是靜態(tài)的定義,容器是鏡像運(yùn)行時(shí)的實(shí)體深胳。容器可以被創(chuàng)建绰疤、啟動(dòng)、停止舞终、刪除轻庆、暫停等。-
倉(cāng)庫(kù)(Repository):
倉(cāng)庫(kù)可看成一個(gè)代碼控制中心
敛劝,用來(lái)保存鏡像文件榨了。Docker 的官方倉(cāng)庫(kù) Docker Hub 是最重要、最常用的 image 倉(cāng)庫(kù)攘蔽。類(lèi)似于GitHub龙屉。一個(gè) Docker Registry 中可以包含多個(gè)倉(cāng)庫(kù)(Repository);每個(gè)倉(cāng)庫(kù)可以包含多個(gè)標(biāo)簽(Tag);每個(gè)標(biāo)簽對(duì)應(yīng)一個(gè)鏡像转捕。 通常作岖,一個(gè)倉(cāng)庫(kù)會(huì)包含同一個(gè)軟件不同版本的鏡像,而標(biāo)簽就常用于對(duì)應(yīng)該軟件的各個(gè)版本五芝。我們可以通過(guò) <倉(cāng)庫(kù)名>:<標(biāo)簽> 的格式來(lái)指定具體是這個(gè)軟件哪個(gè)版本的鏡像痘儡。如果不給出標(biāo)簽,將以 latest 作為默認(rèn)標(biāo)簽枢步。
Docker 鏡像和容器的關(guān)系:
Docker | 面向?qū)ο?/th> |
---|---|
容器 | 對(duì)象 |
鏡像 | 類(lèi) |
# Docker 架構(gòu)
Docker 使用客戶端-服務(wù)器 (C/S) 架構(gòu)模式
沉删,使用遠(yuǎn)程API來(lái)管理和創(chuàng)建Docker容器。
- Docker 客戶端通過(guò)命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 與 Docker 的守護(hù)進(jìn)程通信醉途。
- Docker 主機(jī)(Host):一個(gè)物理或者虛擬的機(jī)器用于執(zhí)行 Docker 守護(hù)進(jìn)程和容器矾瑰。
- Docker Machine:Docker Machine是一個(gè)簡(jiǎn)化Docker安裝的命令行工具,通過(guò)一個(gè)簡(jiǎn)單的命令行即可在相應(yīng)的平臺(tái)上安裝Docker隘擎,比如VirtualBox殴穴、 Digital Ocean、Microsoft Azure货葬。
四采幌、實(shí)例:HelloWorld
下面,我們通過(guò)最簡(jiǎn)單的 image 文件"hello world"(https://hub.docker.com/r/library/hello-world/)震桶,感受一下 Docker休傍。
首先,運(yùn)行下面的命令蹲姐,將 image 文件從倉(cāng)庫(kù)抓取到本地磨取。
$ docker image pull library/hello-world
查看本機(jī)image文件
$ docker image ls
運(yùn)行這個(gè)image文件
$ docker container run hello-world
查看運(yùn)行結(jié)果
Hello from Docker!
This message shows that your installation appears to be working correctly.
... ...
輸出這段提示以后,hello world就會(huì)停止運(yùn)行淤堵,容器自動(dòng)終止寝衫。
有些容器不會(huì)自動(dòng)終止,因?yàn)樘峁┑氖欠?wù)拐邪,需要一直運(yùn)行慰毅。加-d
參數(shù)后臺(tái)模式啟動(dòng),如docker run -d xxx
扎阶。默認(rèn)不會(huì)進(jìn)入容器汹胃,想要進(jìn)入容器需要使用指令 docker exec。
查看本機(jī)容器文件
# 列出本機(jī)正在運(yùn)行的容器
$ docker container ls
# 列出本機(jī)所有容器东臀,包括終止運(yùn)行的容器
$ docker container ls --all
# 或者
$ docker ps
手動(dòng)終止容器運(yùn)行
$ docker container kill [containID]
刪除容器文件
$ docker container rm [containerID]
刪除鏡像文件
$ docker image rm [imageName]
# 命令小結(jié)
-
docker image pull
:抓取 image 文件着饥。
library/hello-world是 image 文件在倉(cāng)庫(kù)里面的位置,其中l(wèi)ibrary是 image 文件所在的組惰赋,hello-world是 image 文件的名字宰掉。由于 Docker 官方提供的 image 文件呵哨,都放在library組里面,所以它的是默認(rèn)組轨奄,可以省略孟害。寫(xiě)成這樣docker image pull hello-world。 -
docker image ls
:查看本機(jī)image文件列表挪拟。 -
docker container run
:從 image 文件挨务,生成一個(gè)正在運(yùn)行的容器實(shí)例。
它還具有自動(dòng)抓取 image 文件的功能玉组。如果發(fā)現(xiàn)本地沒(méi)有指定的 image 文件谎柄,就會(huì)從倉(cāng)庫(kù)自動(dòng)抓取。 -
docker container ls
:列出本機(jī)正在運(yùn)行的容器列表惯雳。輸出結(jié)果之中朝巫,包括容器的 ID。很多地方都需要提供這個(gè) ID吨凑。 -
docker container kill
:終止容器運(yùn)行捍歪。 -
docker container rm
:刪除容器文件户辱。 -
docker image rm
:刪除鏡像文件鸵钝。
# 容器的狀態(tài)
- created(已創(chuàng)建)
- restarting(重啟中)
- running(運(yùn)行中)
- removing(遷移中)
- paused(暫停)
- exited(停止)
- dead(死亡)
五、制作鏡像(Image)文件
5.1 Dockerfile 文件
它是一個(gè)文本文件庐镐,用來(lái)配置 image恩商。Docker 根據(jù) 該文件生成二進(jìn)制的 image 文件。
5.2 實(shí)例:制作自己的 Docker 容器
下面我以 koa-demos 項(xiàng)目為例必逆,介紹怎么寫(xiě) Dockerfile 文件怠堪,實(shí)現(xiàn)讓用戶在 Docker 容器里面運(yùn)行 Koa 框架。
(1)首先名眉,下載源代碼
$ git clone https://github.com/ruanyf/koa-demos.git
$ cd koa-demos
(2)在項(xiàng)目的根目錄下粟矿,新建一個(gè)文本文件.dockerignore
# 表示這三個(gè)路徑要排除,不要打包進(jìn)入 image 文件损拢。如果你沒(méi)有路徑要排除陌粹,這個(gè)文件可以不新建。
.git
node_modules
npm-debug.log
(3)然后福压,在項(xiàng)目的根目錄下掏秩,新建一個(gè)文本文件 Dockerfile
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
CMD node demos/01.js
FROM node:8.4:該 image 文件繼承官方的 node image,冒號(hào)表示標(biāo)簽荆姆,這里標(biāo)簽是8.4蒙幻,即8.4版本的 node。 COPY . /app:將當(dāng)前目錄下的所有文件(除了.dockerignore排除的路徑)胆筒,都拷貝進(jìn)入 image 文件的/app目錄邮破。 WORKDIR /app:指定接下來(lái)的工作路徑為/app。 RUN npm install:在/app目錄下,運(yùn)行npm install命令安裝依賴抒和。注意队询,安裝后所有的依賴,都將打包進(jìn)入 image 文件构诚。 EXPOSE 3000:將容器 3000 端口暴露出來(lái)蚌斩, 允許外部連接這個(gè)端口。 CMD node demos/01.js:它表示容器啟動(dòng)后自動(dòng)執(zhí)行node demos/01.js范嘱,只能有一個(gè)CMD命令送膳。
(4)創(chuàng)建 image 文件
$ docker image build -t koa-demo .
# 或者
$ docker image build -t koa-demo:0.0.1 .
# 查看image文件
$ docker image ls
-t參數(shù)用來(lái)指定 image 文件的名字 冒號(hào)指定標(biāo)簽。如果不指定丑蛤,默認(rèn)的標(biāo)簽就是latest叠聋。 最后的那個(gè)點(diǎn)表示 Dockerfile 文件所在的路徑
(5)生成容器
$ docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
# 如果指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash)受裹,否則它會(huì)覆蓋CMD命令碌补。
$ docker container run --rm -p 8000:3000 -it koa-demo:0.0.1
-p參數(shù):容器的 3000 端口映射到本機(jī)的 8000 端口。 -it參數(shù):容器的 Shell 映射到當(dāng)前的 Shell棉饶,然后你在本機(jī)窗口輸入的命令厦章,就會(huì)傳入容器。exit命令或Ctrl+D退出交互照藻。 koa-demo:0.0.1:image 文件的名字(如果有標(biāo)簽袜啃,還需要提供標(biāo)簽,默認(rèn)是 latest 標(biāo)簽)幸缕。 /bin/bash:容器啟動(dòng)以后群发,內(nèi)部第一個(gè)執(zhí)行的命令。這里是啟動(dòng) Bash发乔,保證用戶可以使用 Shell熟妓。 --rm參數(shù):在容器終止運(yùn)行后自動(dòng)刪除容器文件。
(6)發(fā)布 image 文件
首先栏尚,去 hub.docker.com 或 cloud.docker.com 注冊(cè)一個(gè)賬戶起愈。然后,用下面的命令登錄抵栈。
$ docker login
接著告材,為本地的 image 標(biāo)注用戶名和版本。
$ docker image tag [imageName] [username]/[repository]:[tag]
# 實(shí)例
$ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1
也可以不標(biāo)注用戶名古劲,重新構(gòu)建一下 image 文件斥赋。
$ docker image build -t [username]/[repository]:[tag] .
最后,發(fā)布 image 文件产艾。
$ docker image push [username]/[repository]:[tag]
發(fā)布成功以后疤剑,登錄 hub.docker.com滑绒,就可以看到已經(jīng)發(fā)布的 image 文件。
六隘膘、其他常用命令
(1)docker container start
它用來(lái)啟動(dòng)已經(jīng)生成疑故、已經(jīng)停止運(yùn)行的容器文件,重復(fù)使用容器弯菊。docker container run命令是新建容器纵势。
$ docker container start [containerID]
(2)docker container stop
向容器里面的主進(jìn)程發(fā)出 SIGTERM 信號(hào),然后過(guò)一段時(shí)間再發(fā)出 SIGKILL 信號(hào)管钳。docker container kill命令終止容器運(yùn)行钦铁,發(fā)出 SIGKILL 信號(hào)。
這兩個(gè)信號(hào)的差別是才漆,應(yīng)用程序收到 SIGTERM 信號(hào)以后牛曹,可以自行進(jìn)行收尾清理工作,但也可以不理會(huì)這個(gè)信號(hào)醇滥。如果收到 SIGKILL 信號(hào)黎比,就會(huì)強(qiáng)行立即終止,那些正在進(jìn)行中的操作會(huì)全部丟失鸳玩。
$ bash container stop [containerID]
(3)docker container logs
用來(lái)查看 docker 容器的輸出阅虫,即容器里面 Shell 的標(biāo)準(zhǔn)輸出。如果docker run命令運(yùn)行容器的時(shí)候怀喉,沒(méi)有使用-it參數(shù)书妻,就要用這個(gè)命令查看輸出船响。
$ docker container logs [containerID]
(4)docker container exec
用于進(jìn)入一個(gè)正在運(yùn)行的 docker 容器躬拢。如果docker run命令運(yùn)行容器的時(shí)候,沒(méi)有使用-it參數(shù)见间,就要用這個(gè)命令進(jìn)入容器聊闯。一旦進(jìn)入了容器,就可以在容器的 Shell 執(zhí)行命令了米诉。
$ docker container exec -it [containerID] /bin/bash
(5)docker container cp
用于從正在運(yùn)行的 Docker 容器里面菱蔬,將文件拷貝到本機(jī)。下面是拷貝到當(dāng)前目錄的寫(xiě)法史侣。
$ docker container cp [containID]:[/path/to/file] .
(6)docker command --help
更深入的了解指定的 Docker 命令使用方法拴泌。
# 相關(guān)鏈接
Docker 官網(wǎng):https://www.docker.com
Github Docker 源碼:https://github.com/docker/docker-ce
http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html
http://www.ruanyifeng.com/blog/2018/02/docker-wordpress-tutorial.html