摘要:使用推出的語言開發(fā)實(shí)現(xiàn),基于內(nèi)核的,,以及等技術(shù)。初步了解容器與虛擬機(jī)的區(qū)別原理不同上圖是關(guān)于和傳統(tǒng)虛擬機(jī)區(qū)別的截圖。從而實(shí)現(xiàn)模擬更改鏡像的作用。下面的實(shí)踐以為例,。指令讓外界能通過容器的端口進(jìn)行網(wǎng)絡(luò)通信。使用可以啟動關(guān)閉容器。
Docker 是一個能讓程序跑在一個它無法感知的、用于隔絕外界環(huán)境里的容器的工具。Docker 簡介
最初是 dotCloud 公司創(chuàng)始人 Solomon Hykes 發(fā)起的一個公司內(nèi)部項(xiàng)目,并于 2013 年 3 月以 Apache 2.0 授權(quán)協(xié)議開源,代碼主要在 GitHub 上進(jìn)行維護(hù)。Docker 項(xiàng)目后來還加入了 Linux 基金會,并成立推動 開放容器聯(lián)盟(OCI)。
Docker 使用 Google 推出的 Go 語言開發(fā)實(shí)現(xiàn),基于 Linux 內(nèi)核的 cgroup,namespace,以及 UnionFS 等技術(shù)。最初實(shí)現(xiàn)基于 LXC,從 0.7 版本后去除 LXC,轉(zhuǎn)而開始使用自行開發(fā)的 libcontainer,從 1.11 開始,則進(jìn)一步演進(jìn)為使用 runC 和 containerd。
在 2017 年 4 月 21 日 Pull Request #32691 將原有的 Docker 項(xiàng)目更名為 Moby,由 Moby 構(gòu)建出 Docker CE(社區(qū)版),而新的 Docker 項(xiàng)目則構(gòu)建出 Docker EE(企業(yè)版本)。
Docker 初步了解 Docker 容器與虛擬機(jī)的區(qū)別 原理不同上圖是 Docker Doc 關(guān)于 Docker 和傳統(tǒng)虛擬機(jī)區(qū)別的截圖。
Docker 利用了 Linux 內(nèi)核的 cgroup 和 namespace 為程序的執(zhí)行創(chuàng)造一個隔離的環(huán)境,使得程序感知不到外界的存在,其本身仍然是跑在原有的內(nèi)核上的;而虛擬機(jī)則是通過 Hypervisor 模擬了一整套系統(tǒng)環(huán)境,虛擬機(jī)里的程序是跑在虛擬機(jī)內(nèi)核上的。由于虛擬機(jī)需要模擬一整套操作系統(tǒng)環(huán)境,因此開銷比 Docker 容器要高很多很多。
你可以把跑在容器里的程序想象成楚門(楚門的世界男主),他并不知道自己生活在一個精心布置的超大影棚里,但是他仍然是活在現(xiàn)實(shí)世界里的,呼吸著現(xiàn)實(shí)世界中的空氣,吃著和我們差不多的食物;跑在虛擬機(jī)里的程序就好像活在動畫片里的小豬佩奇,他的一切都是虛擬的,雖然小豬佩奇并不知道自己活在動畫片里,但是很顯然的是它和我們完全不在一個世界(不是同一個系統(tǒng)內(nèi)核)。
性能差異特性 | 容器 | 虛擬機(jī) |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為 MB | 一般為 GB |
性能 | 接近原生 | 弱于 |
系統(tǒng)支持量 | 單機(jī)上千個容器 | 一般幾十個 |
鏡像 是一個包含操作系統(tǒng)完整 root 文件系統(tǒng) 的、只讀的,由多層文件系統(tǒng)聯(lián)合而成的打包文件。
Docker 為了讓應(yīng)用無感知的跑在容器中,提供了一套完整的 root 文件系統(tǒng),比如官方鏡像 library/ubuntu 就包含了一整套 root 文件系統(tǒng)。像 apache、nginx 都是基于該鏡像構(gòu)建的,由于 library/ubuntu 本身很大,所以 Docker 采用了分層存儲的方式。
本文假裝你已經(jīng)安裝了 Docker,上圖通過 docker pull nginx 從 官方 Registry(下面會提到這是啥)拉取 nginx 鏡像,拉取 nginx 相當(dāng)于 library/nginx:latest,library 表示 nginx 是官方鏡像,因此可以省略,:latest 表示拉取標(biāo)簽為 latest 的鏡像。拉取后可以看到存在兩個鏡像,因?yàn)?nginx 鏡像本身就是基于 library:ubuntu:16.04 鏡像的。
上圖通過 docker pull httpd 拉取了 apache 鏡像,由于 ubuntu:16.04 鏡像已經(jīng)在本地存在了,因此拉取的時候不會重復(fù)拉取。從而節(jié)約拉取時間。這就是 Docker 分層存儲的意義。
鏡像的只讀可以理解成以前的光盤 CD,是不可更改的。為了模擬實(shí)現(xiàn)對光盤 CD 的寫的功能,會建立兩層文件系統(tǒng),一層是光盤 CD 的只讀文件系統(tǒng);另外一層是存放更改數(shù)據(jù)的可寫的文件系統(tǒng)。從而實(shí)現(xiàn)模擬更改鏡像的作用。Docker 也是采用這種類似的分層的方式。
如圖,可以看出 ubuntu:15.04 是由很多層文件系統(tǒng)(鏡像)堆疊形成的,最底層是 root 文件系統(tǒng)(d3a1f33e8a5a)。這幾層文件系統(tǒng)都被設(shè)置成只讀的。多層文件系統(tǒng)利用了上面提到的 UnionFS、AUFS、OverlayFS,這是一類文件系統(tǒng),這種聯(lián)合掛載文件系統(tǒng)最早就是用于解決 CD 這種只讀文件系統(tǒng)的修改問題,Docker 之前使用 AUFS,但是由于 AUFS 不被 linus 喜歡(被 linus 評價為稠密、不可讀,無注釋)導(dǎo)致 AUFS 一直沒有被合并到 Linux 的主分支中。Docker 在 1.12 以后已經(jīng)將默認(rèn)的文件系統(tǒng)從 AUFS 替換成 OverlayFS2。因?yàn)?OverlayFS2 已經(jīng)被合并進(jìn)了 Linux 的主干分支中。
容器上面我們拉取了 nginx 鏡像到本地,我們可以使用 docker container start nginx(省略了 latest 標(biāo)簽)來運(yùn)行這個鏡像。運(yùn)行之前會先創(chuàng)建一個容器(其實(shí)本質(zhì)就是創(chuàng)建了一層可讀寫的文件系統(tǒng),以提供程序運(yùn)行時的讀寫支持),然后就會啟動程序,讓程序跑在一個隔離環(huán)境(不是虛擬環(huán)境)里。你還可以通過 docker container commit>來對當(dāng)前層進(jìn)行提交(就好像 Git 提交一樣),從而形成一個新的鏡像,但是這種方式是不推薦的;這是因?yàn)樵诔绦蜻\(yùn)行過程中可能會產(chǎn)生一些垃圾文件,而如果這些垃圾文件被提交后,新的鏡像又是不可修改的,只會增大鏡像的體積。具體怎么創(chuàng)建鏡像會在下面說到。
可以看到上圖中在創(chuàng)建容器的時候其實(shí)就是創(chuàng)建了一個容器可讀寫層。你還可以通過 docker container stop
鏡像構(gòu)建完成后,可以很容易的在宿主機(jī)器上運(yùn)行,但是如果其他機(jī)器要使用這個鏡像,我們就需要一個集中存儲、分發(fā)鏡像的服務(wù),Docker Registry 就是這樣的服務(wù)。一個 Docker Registry 可以包含多個倉庫,每個倉庫可以包含多個標(biāo)簽,每個標(biāo)簽對應(yīng)一個鏡像。
就拿上面的 library/nginx:latest 舉例,library 表示這個鏡像是官方鏡像,如果不是官方鏡像,這里一般填注冊在 Docker Registry 的用戶名;library/nginx 是倉庫的名字,latest 是該倉庫一個標(biāo)簽。
誠然,官方的 Docker Registry 是世界上最大的鏡像分發(fā)服務(wù),官方還提供了 Docker Registry 鏡像 用于搭建私有鏡像分發(fā)服務(wù)。而且 DockerHub 和社區(qū)一起制作了大量的、高質(zhì)量的鏡像,使得我們構(gòu)建鏡像更為方便。
Docker 簡單實(shí)踐 Docker 單個鏡像前面提到可以通過 docker commit 生成新的鏡像,但是這種方式并不推薦(原因已經(jīng)說明),所以我們一般還是采用 Dockerfile 的方式。下面的實(shí)踐以 github-issue-rss 為例,demonstate how to containerization a normal project。
首先創(chuàng)建一個 Dockerfile 文件,內(nèi)容如下:
FROM node:9-alpine MAINTAINER mrcode "mrcodehang@outlook.com" WORKDIR /src # 表示容器內(nèi)的程序運(yùn)行時的當(dāng)前目錄 COPY . /src # 把構(gòu)建 Dockerfile 文件目錄下的文件全部復(fù)制到鏡像的 /src 目錄下 RUN npm install -g yarn && yarn install # 構(gòu)建時執(zhí)行 EXPOSE 3000 # 暴露容器的 3000 端口到外面 ENTRYPOINT ["npm", "start"] # 執(zhí)行 docker start時就會執(zhí)行 npm start
Dockerfile 里的每一行開頭的大寫字母單詞叫做 Dockerfile 指令。每執(zhí)行一條指令就會增加一層鏡像(本質(zhì)是執(zhí)行了一次 docker commit,而 AUFS 最大的層數(shù)是 127 層,因此 Dockerfile 里的層數(shù)最好不要太多!
FROM 表示基于哪一個鏡像構(gòu)建,node:9-alpine 表示基于官方的 node 鏡像構(gòu)建,標(biāo)簽 9-alpine 表示這是一個 node 9 的鏡像,同時該 node9 鏡像是基于 alpine 鏡像構(gòu)建的,alpine 是 Linux 的一個精簡發(fā)行版,大小只有 5MB 左右,而 Ubuntu 鏡像大小接近 200MB。
RUN 指令會在構(gòu)建鏡像時執(zhí)行,使用 && 符號是為了減少 RUN 命令的使用次數(shù),減少最終鏡像的層數(shù)。
EXPOSE 指令讓外界能通過容器的 3000 端口進(jìn)行網(wǎng)絡(luò)通信。
ENTRYPOINT 表示執(zhí)行 docker start
圖中執(zhí)行命令最后有一個 ".",這是將當(dāng)前目錄作為上下文傳遞給 Docker daemon;Docker 的工作方式是基于 C-S 架構(gòu)的,你需要將構(gòu)建的所在目錄傳給 docker daemon,這也是上面的 Dockerfile 文件的 COPY 指令的當(dāng)前目錄。
接下來創(chuàng)建容器,一個鏡像可以創(chuàng)建多個容器(其實(shí)就是創(chuàng)建多個在同一層的讀寫層)。
docker run 會拉取遠(yuǎn)程的鏡像(如果本地沒有的話),接著它會創(chuàng)建一個容器,基于 mrcode/github-issue-rss:test 鏡像(只有 latest 標(biāo)簽可以省略);-v 會創(chuàng)建一個數(shù)據(jù)卷(volume),表示當(dāng)容器對 /var/log/github-issue-rss/ 寫入數(shù)據(jù)時相當(dāng)于寫在了宿主機(jī)的 ~/github-issue-rss/log 目錄上,從而維持容器的無狀態(tài)特性(無狀態(tài)特性是指容器在運(yùn)行時盡量不要將重要數(shù)據(jù)存儲在容器所在的讀寫層里,雖然那是一層讀寫層,但是是用來存放程序運(yùn)行時產(chǎn)生的臨時文件的,不應(yīng)將重要數(shù)據(jù)放在里面);-d 表示 daemon 執(zhí)行程序,否則的話容器進(jìn)程會掛載在當(dāng)前 shell 上,一般通過 -d 掛載到 docker daemon 進(jìn)程上;—rm 表示容器退出后自動刪除容器,這是推薦的用法,也是容器的無狀態(tài)特性的體現(xiàn)。
容器進(jìn)程具有和容器內(nèi)程序本身進(jìn)程相同的生命周期,容器進(jìn)程用來啟動容器內(nèi)程序,相當(dāng)于 Linux 內(nèi)的 init 進(jìn)程;當(dāng)容器內(nèi)程序被 docker stop殺掉時,容器就會退出,留下一個已創(chuàng)建的讀寫層文件系統(tǒng),這也是容器存在的標(biāo)志。
由于創(chuàng)建容器僅僅是創(chuàng)建了一個可讀寫的文件系統(tǒng),所以容器的存在是非常非常輕量級的。即便對一個鏡像創(chuàng)建多個容器,鏡像本身是不會被重新拷貝的,而是最大程度的復(fù)用,這是因?yàn)殓R像內(nèi)的多層文件系統(tǒng)的每一層都被設(shè)置成只讀的。
你可以通過 docker container ls 查看當(dāng)前正在運(yùn)行的所有容器,如果還想查看已退出的容器,加上一個 -a 參數(shù)。使用 docker container start/stop 可以啟動/關(guān)閉容器。
最后可以通過 docker push mrcode/github-issue-rss:test 發(fā)布到 DockerHub 上,分享到社區(qū)。
Docker 多個鏡像github-issue-rssis a tool converts the issues on GitHub to RSS.
這個工具需要用到了 mysql,為了以后方便數(shù)據(jù)遷移,我決定使用 mysql 鏡像,mysql 鏡像可以把所有狀態(tài)存放在宿主機(jī)的一個文件夾下。那我現(xiàn)在不僅需要啟動 mysql 和 github-issue-rss 鏡像,還需要建立他們之間的網(wǎng)絡(luò)連接關(guān)系,事情變得麻煩了。有一個工具叫 docker-compose (本文假裝你已經(jīng)安裝了這個工具)可以把這一切自動化。下面是項(xiàng)目根目錄的一個 docker-compose.yml 文件:
version: "3" services: db: image: mysql:5.7 volumes: - ~/.github-issue-rss/mysql:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: rootroot MYSQL_DATABASE: rss MYSQL_USER: mrcode MYSQL_PASSWORD: github-issue-rss github-issue-rss: image: mrcode/github-issue-rss:v0.1.0 depends_on: - db ports: - "3000:3000" restart: always environment: MYSQL_PORT: 3306 MYSQL_HOST: db MYSQL_SCHEMA: rss MYSQL_USERNAME: mrcode MYSQL_PASSWORD: github-issue-rss LOG_FILE: /var/log/github-issue-rss/ volumes: - ~/.github-issue-rss/log/:/var/log/github-issue-rss/
在 docker-compose 的世界里沒有容器,只有服務(wù)。它認(rèn)為它啟動了兩服務(wù) db 和 github-issue-rss。沒有哪個是主服務(wù),所有服務(wù)都是平等的。
在 db service 中,設(shè)置了 volumes,將 mysql 的數(shù)據(jù)存儲在 ~/.github-issue-rss/mysql/ 里,還可以設(shè)置更多的 volume。restart 表示只要服務(wù)執(zhí)行失敗就重啟,防止依賴的 service 還沒有啟動完成時導(dǎo)致的錯誤引發(fā)連鎖反應(yīng)。給兩個 service 配置的 environment 來建立兩者的數(shù)據(jù)連接,github-issue-rss 代碼會讀取這個環(huán)境變量,然后連接到 db 服務(wù),可以看到 github-issue-rss 里的環(huán)境變量 MYSQL_HOST 設(shè)置為 db,這是因?yàn)?docker-compose 會在啟動的服務(wù)配置里建立這個 DNS 映射關(guān)系。
還可以通過 docker-compose down 來停止并且刪除服務(wù)對應(yīng)的容器。
現(xiàn)在你只需要克隆倉庫到本地,然后執(zhí)行 docker-compose up 就可以啟動 github-issue-rss 了,因?yàn)?github-issue-rss 鏡像本身已經(jīng)構(gòu)建并發(fā)布到 Docker Hub 了。
Docker 的應(yīng)用 持續(xù)集成和持續(xù)交付使用 Docker 可以通過定制應(yīng)用鏡像來實(shí)現(xiàn)持續(xù)集成、持續(xù)交付、部署。開發(fā)人員通過 Dockerfile 進(jìn)行鏡像構(gòu)建,結(jié)合持續(xù)集成系統(tǒng)進(jìn)行集成測試,而運(yùn)維人員則可以在生產(chǎn)環(huán)境中快速部署該鏡像。甚至結(jié)合持續(xù)部署進(jìn)行自動部署。
而且使用 Dockerfile 使鏡像的構(gòu)建透明化,不僅可以幫助開發(fā)人員理解應(yīng)用運(yùn)行環(huán)境,也方便運(yùn)維團(tuán)隊(duì)理解應(yīng)用運(yùn)行所需條件,幫助更好的生產(chǎn)環(huán)境中部署該鏡像。
微服務(wù)Docker 和微服務(wù)架構(gòu)簡直就是渾然天成,站在 Docker 的角度,軟件本質(zhì)是容器的組合:業(yè)務(wù)邏輯容器、數(shù)據(jù)庫容器、存儲容器、隊(duì)列容器……Docker 使得軟件拆分成若干的標(biāo)準(zhǔn)化容器,然后像積木一樣的搭建起來。這正是微服務(wù)的思想:軟件把任務(wù)外包出去,讓各種外部服務(wù)完成這些任務(wù),軟件本身只是底層服務(wù)的調(diào)用中心和組裝層。
參考文章http://www.ruanyifeng.com/blo... by 阮一峰
https://github.com/yeasy/dock... by Baohua Yang
https://docs.docker.com by Docker Doc
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/27279.html
摘要:編程書籍的整理和收集最近一直在學(xué)習(xí)深度學(xué)習(xí)和機(jī)器學(xué)習(xí)的東西,發(fā)現(xiàn)深入地去學(xué)習(xí)就需要不斷的去提高自己算法和高數(shù)的能力然后也找了很多的書和文章,隨著不斷的學(xué)習(xí),也整理了下自己的學(xué)習(xí)筆記準(zhǔn)備分享出來給大家后續(xù)的文章和總結(jié)會繼續(xù)分享,先分享一部分的 編程書籍的整理和收集 最近一直在學(xué)習(xí)deep learning深度學(xué)習(xí)和機(jī)器學(xué)習(xí)的東西,發(fā)現(xiàn)深入地去學(xué)習(xí)就需要不斷的去提高自己算法和高數(shù)的能力然后...
摘要:感謝參考本文內(nèi)容還是相對很淺的,中關(guān)于分布式,集群的內(nèi)容沒有涉及,所以本文推薦前端同學(xué)看一看,后端同學(xué)就不推薦了。本文中所有命令都是針對,拷貝粘貼時請注意。這一篇文章有些復(fù)讀機(jī) showImg(https://segmentfault.com/img/remote/1460000019424971); 感謝 & 參考 本文內(nèi)容還是相對很淺的,Docker中關(guān)于分布式,集群的內(nèi)容沒有涉及...
摘要:感謝參考本文內(nèi)容還是相對很淺的,中關(guān)于分布式,集群的內(nèi)容沒有涉及,所以本文推薦前端同學(xué)看一看,后端同學(xué)就不推薦了。本文中所有命令都是針對,拷貝粘貼時請注意。這一篇文章有些復(fù)讀機(jī)showImg(https://user-gold-cdn.xitu.io/2019/5/22/16adf8cacec9db2d); 感謝 & 參考 本文內(nèi)容還是相對很淺的,Docker中關(guān)于分布式,集群的內(nèi)容沒有涉及...
閱讀 1876·2021-09-24 09:48
閱讀 3220·2021-08-26 14:14
閱讀 1674·2021-08-20 09:36
閱讀 1461·2019-08-30 15:55
閱讀 3628·2019-08-26 17:15
閱讀 1426·2019-08-26 12:09
閱讀 607·2019-08-26 11:59
閱讀 3324·2019-08-26 11:57