摘要:年月發布了內核對進行了重新設計。年發布了內核更加徹底的改造了,稱為,并且認可其已經穩定。集群工具,多宿主管理運行。通過的設置通過設置將設置上標簽。使用兩種方式傳遞給宿主其的主機位置,環境變量和文件。
https://www.youtube.com/watch?v=heBI7oQvHZU
http://v.qq.com/page/o/8/j/o03134mlm8j.html
基本介紹Docker 很像(但不是)一個輕量級的虛擬機,有自己的shell, namespace, network interface,可以以root運行東西,有自己的服務和軟件包
虛擬機有虛擬硬件層和一個運行其上的完整系統。而容器則是直接將進程運行于現有內核上。所以啟動Docker非常輕量級,啟動非常快速。
Docker組成部分,簡單來看,分為三個角色,客戶端、docker 主機、docker registry。
客戶端運行 docker run, build, pull等命令;
docker host 則有一個docker daemon 在運行,它維護著本地的container和image;
docker registry則是集中管理所有image的地方,docker host將從docker registry取得image。
Docker 文件系統是分層的,這是基于Union FS的概念,在Ubuntu上使用的是aufs,可以很自然的支持這種概念。而在CentOS/RHEL上則只能使用DeviceMapper去模擬,性能和穩定性以及一些功能會有問題。在 Linux 3.18 以后,可以使用 Overlay FS,這也是 Union FS 的實現。
Docker 文件系統分層,最底層是 bootfs(kernel),然后是鏡像中的各種層,最后是運行期的容器的層。容器的存儲層在容器停止后,即被廢棄。
嚴格來說并不是在容器停止后就被銷毀。容器停止后,其存儲層依然附屬于停止掉的容器。如果利用 docker start 將容器啟動后,會發現其內文件系統的變動依然存在。而這種容器存儲層被廢棄的概念則是指另一個層面的事情。
容器應當被視為 immutable 的,因此容器內部的變動應該可以隨時被拋棄,不希望丟失的變化部分應該存儲于掛載的數據卷中。
所以docker的工作流是 docker run, stop, rm, 再次run。每一次run都是從image建立的新鮮的container,所以里面的內容永遠是image的狀態,而沒有上一次container中的修改。所以從這個工作流程理解,container中的變動被廢棄了。
Docker 1.10 發布更新了Layer的ID問題,曾經使用的是隨機UUID,但是發生過沖突,而且很難判斷相同UUID的layer到底是哪個。所以從1.10開始,將其升級為密碼學 Hash 值,SHA256。這樣可以確保其內容統一,而且Image將會更小。在 1.10 以前,Image 和 Layer 基本是一個完整的東西,但是 1.10 之后,由于使用了 SHA256,Image 和 Layer 可以分開復用重復的Layer,這樣Image可以更小。由于這種變化,如果從 1.10 以前的版本過來,必須要升級所有 images。
Docker 容器文件層會在停止后被廢棄,那么數據應該存儲于掛載的卷中。而掛載卷可以是數據卷也可以是本地文件,注意是“本地”,不可以使用NFS, SMB之類的位置進行掛載,這樣Docker會認為其不安全。如果需要類似的云存儲,可以使用volume的driver,可以支持AWS S3之類的存儲。
docker run 一個容器,容器可以定義 EXPOSE 某些端口,而這些端口是容器之間可以訪問的,而不是從外部訪問,如果需要這些端口暴露于外部,那么應該用 -p 或 --publish,將該端口發布于宿主,可以映射不同端口。
Dockerfile, docker build, images, runDockerfile 是分步驟的,而每一步都會被緩存,所以重新構建非常快。
ENTRYPOINT 和 CMD 不同,一般 ENTRYPOINT 是要運行的命令,而 CMD 則是參數,docker run 后面所跟隨的實際上是 CMD,也就是參數。有些鏡像把 ENTRYPOINT 設為了 sh -c,這樣 CMD 可以跟 bash 命令和腳本,所以一些人誤以為 CMD 就是命令。其實它們只是作為參數送給了 ENTRYPOINT 中指定的 sh -c。
基本命令:build, run, stop, start, ps, ps -a, images, rmi
將鏡像push到registry,docker login, docker push
Docker 的歷史是和 Linux 內核發布歷史緊密相關的。
2007年 Linux 發布內核 2.6.24有個特性被添加進來,Control Groups(cgroups)。隨后,使用 cgroups 的 Linux Containers (lxc) 發布。cgroups 是今天 Docker 的基礎。
cgroups ,可以限制資源使用,設置優先級,會計,控制。
距演講者說,Linux 中的 nice,實際上就是使用 cgroups 中優先級的功能。
https://en.wikipedia.org/wiki/Nice_(Unix)
不過應該不是。
控制的部分包括freeze和restart。
(這部分的內容演講者講的有些錯誤,我查詢了一下,進行修正。)
2013年2月 Linux 發布了內核 3.8http://kernelnewbies.org/Linux_3.8#head-fc2604c967c200a26f336942caee2440a2a4099c
這次完整的實現了 namespace 的隔離,包括了 pid, network, hostname, mount pic, user 的namespace。
正是這次發布構成了Docker的基礎,同年3月份 Docker 項目正式成為開源項目。最開始基于 lxc,現在抽象出來了 libcontainer,統一接口,下面可以支持多種容器組合,默認使用的是 runC,不過可以換。
2014年8月 Linux 發布了內核 3.16對 cgroups 進行了重新設計。 http://lwn.net/Articles/601840/
Docker Networking 中的 overlay network 所依賴的就是這次內核的改進。
2014年12月 Linux發布了內核 3.18經過多年的努力,這次終于第一次在內核中加入了 Union FS的實現,這次是 Overlay fs。(Ubuntu中的aufs爭取了好多年,最后作者懶得爭取了,放棄了)。這樣對于紅帽系將來的服務器,也就終于有可能有Union FS可用了。以前只能湊合用 Device Mapper,而且本地loop還是不適合在生產環境使用的。所以要使用 overlay 存儲層,需要內核在 3.18 以上。
2015年4月 Linux發布了內核 4.0docker 1.12 中的 overlay2 存儲層就依賴的是這次的內核對 overlay 驅動的改進。
2016年 Linux 發布了內核 4.5更加徹底的改造了 cgroups,稱為 cgroups2,并且認可其已經穩定。
http://kernelnewbies.org/Linux_4.5#head-621383bcd8bc104aed825c9ebc08a0b986690f8a
非常容易擴展,由于所有東西都打包在一個容器里了,所以部署的時候不需要在服務器上進行安裝了,所以很適合擴展。
Docker 容器是 immutable 的,可以將其視為樂高積木,如果哪個壞了,扔了換個新的,而不是在舊的上面修修補補。
DevOps,開發人員(Dev)只需要考慮容器內的東西即可,而運營人員(Ops)則只需負責容器外部即可。
持續集成(Continuous Integration)確保所有環境完全一樣,不會出現“我的機器上沒問題啊”這種情況。運行、測試都在容器內。
編排(Orchestration)工具Compose, Machine, Swarm, Networking
Compose定義運行多容器應用,單機沒問題,多主機還在試驗中。
實例中,值得注意的是,他的目錄結構。docker-compose.yml 在項目根目錄,每個應用都有自己獨立目錄,以及其目錄下存在 Dockerfile。這種感覺更干凈。(或許在LNMP示例項目中,我不應該把conf都存在于同一個目錄下,而是應該分應用建立目錄,對應的配置放在各自目錄下。)
另外需要注意的是,在僅有幾臺的應用環境下,他依然定義了前端網絡和后端網絡,讓兩個網絡獨立。
在啟動示例的過程中,Tom Vereist 提到了這個例子寫的不好的一點,在 worker 項目中,它在容器里使用 maven 對項目進行了構建。這不是一個好的寫法,這會導致maven的安裝,編譯開發工具的安裝、依賴的安裝等等,會產生一個非常大的鏡像。建議的做法是可以在另一個容器中構建,把構建后的軟件包拿到運行的容器中安裝使用即可,避免運行時不需要的東西存在于容器中。
Machine用于創建、管理 docker host,可以支持多種云平臺,提供統一的訪問接口。
Swarmdocker 集群工具,多宿主管理運行。
可以定義 docker host 的 label。通過 docker daemon 的 --label 設置;通過 docker-machine --engine-label, --label 設置;將 docker host 設置上標簽。然后在運行的時候可以通過約束標簽,來決定該容器運行于那些 docker host 上。
可以定義過濾器,包括兩大類,節點(Node)或容器(Container)。節點可能是約束、健康程度等;容器可以是端口、依賴等。
Networking創建 Overlay network。替代 link (bridge),link 在一些動態環境下使用會有問題。比如一群容器啟動后,link的某一個節點掛了,重新運行,使用了新的ip,而還在運行的docker使用的還是舊的ip去聯系該節點,導致無法連接。所以只能夠把所有節點都down掉,然后重新運行。
嘗試了一下,兩個沒有link關系的容器,可以通過容器IP訪問對方。所以 link 是建立一種識別的辦法,而不是安全上的建立通道的概念。看了一下文檔,提到了 --icc=false 的參數來創建網絡隔離。
https://docs.docker.com/engine/userguide/networking/work-with-networks/#linking-containers-in-user-defined-networks
link (bridge)使用兩種方式傳遞給宿主其link的主機位置,環境變量和/etc/hosts文件。
https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#communication-across-links
而多宿主環境中,使用 docker network 創建 overlay network,使用link鏈接主機,則會有一個內置的DNS進行名字的動態維護,不再使用 /etc/hosts。
在Tom 演示 docker swarm 的時候,我發現他和我一樣建立了一個 bash 腳本來啟動建立 docker host。我覺得應該考慮做個工具使用 yaml 描述文件來建立 docker-machine,就像 docker-compose做的那樣。命令行中有太多的重復信息了。
腳本最后是使用 docker network 創建 overlay 網絡,Tom 提到一點,需要指定 --subnet ,否則將無法連通,特別是跨主機的時候,有的版本有bug,同一個網絡不一定使用同一段IP地址。不過現在這個bug已經修復了,不指定地址跨主機沒問題。
演示 swarm 的過程中碰到了和我碰到的一樣的問題。在單機環境中,在 docker compose 中可以使用 build 來構建鏡像。但是在 swarm 的多宿主環境中,這樣做的結果會導致所有的 service 會扔到同一個 docker host 中去,而如果打算使用多宿主環境(也是為什么要用swarm 的初衷),則必須使用 registry 中的 image。這樣宿主可以主動去 registry 下載 image。可以使用 docker hub 的服務,或者自己架設 registry。
并且不可以使用 link 了,而必須使用 自定義network。Tom 說這是由于一個 link 的bug,現在不知道是否已經解決了,需要試驗。
通過 environment:"constraint:type==frontend" 的形式來指定約束。
Tom 不推薦在生產環境中使用 compose + swarm,因為碰到了太多的問題,他甚至自己還報告了一個bug #2866。
其它工具 Docker Cloud (cloud.docker.com)創建 node clusters,可以選擇AWS, Digital Ocean, Azure,Softlayer等幾大云服務商。然后可以使用docker hub上的鏡像進行部署。建立 Stack 需要腳本,很像compose,其實他們應該支持compose腳本更合適,建立service。
Docker Cloud 適合小規模云的部署。
Kubernetes由 Google 開發,用 Go 語言寫的。Google 每周用這個運行2百萬個containers。
一個 kubernetes 集群由 master 和 minions 組成。master 含有 etcd、scheduler;而每個 minon 含有 kubelet,proxy 和一群 pod。
CoreOS不需要安裝 docker,它包含了 linux container。它也使用 etcd,所不同的是它每一個 host都運行etcd,這樣避免了單點故障。fleetd,很像是網絡多宿主環境下的 systemd,它負責開啟停止分布在宿主中的服務。
Lattice Flocker Docker Security Container Securitycontainer 本身很安全,由于 isolation,只使用必要的依賴。
可以使用 --security-opt sec comp:xxx.json,來指定安全策略。
Unikernel,可以非常靈活定制的內核,只選擇所必須的組件使用,其它的都拋棄,信任域更小。
現在 docker daemon 必須以 root 運行。現在的授權機制是 all or nothing,或者可以管理所有 docker,或者完全沒有權限管理。這點將來可能會改變。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26663.html
摘要:由于隔離的進程獨立于宿主和其它的隔離的進程,因此也稱其為容器。鏡像實際是由多層文件系統聯合組成。容器可以被創建啟動停止刪除暫停等。容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行于屬于自己的獨立的命名空間。 Docker簡介 Docker 使用 Google 公司推出的 Go 語言 進行開發實現,基于 Linux 內核的 cgroup,namespace,以及 AUFS ...
摘要:前言默認的為功能有限現在把它該歸它提供了豐富的查詢功能拉取使用啟動利用上節教程使所有添加至改用安裝請把環境變量都改為的實例化創建一些并交易 前言 默認的state DB為goleveldb,功能有限,現在把它該歸CouchDB.它提供了豐富的查詢功能 拉取coundb image docker pull hyperledger/fabric-couchdb:x86_64-1.0.5 d...
摘要:用對象字面量形式創建的對象,直接賦值給函數的原型對象,本質上完全重寫了其對象,因此屬性也就變成了新對象的屬性指向構造函數,不再指向函數。 【上一篇】:JavaScript對象內部屬性及其特性總結 showImg(https://segmentfault.com/img/bVbjYsc?w=839&h=489); 工廠模式(★★) 先在內部顯示地創建一個臨時對象,根據接收的參數來構建(賦...
摘要:解決的痛點免搭建后端開發環境。開發環境改變只需要改變鏡像就能同步更新。啟動這個新建的鏡像。 這篇文章是為了解決前后端開發沒有徹底分離的坑,因為我司用的是java,入職第一天就是搭建本地開發環境,看見了多年不見的eclipse的圖標出現我的電腦上,我是難過的。后來知道并不是我一個人有此感受。依稀記得有個同學整整一天項目都沒跑起來的崩潰感。為了解決這個問題我們嘗試了很多方案,但是大大小小都...
摘要:解決的痛點免搭建后端開發環境。開發環境改變只需要改變鏡像就能同步更新。啟動這個新建的鏡像。 這篇文章是為了解決前后端開發沒有徹底分離的坑,因為我司用的是java,入職第一天就是搭建本地開發環境,看見了多年不見的eclipse的圖標出現我的電腦上,我是難過的。后來知道并不是我一個人有此感受。依稀記得有個同學整整一天項目都沒跑起來的崩潰感。為了解決這個問題我們嘗試了很多方案,但是大大小小都...
閱讀 856·2021-10-11 10:59
閱讀 2792·2019-08-30 15:43
閱讀 2129·2019-08-30 11:08
閱讀 1647·2019-08-29 15:20
閱讀 1002·2019-08-29 13:53
閱讀 485·2019-08-26 13:24
閱讀 1632·2019-08-26 13:24
閱讀 2819·2019-08-26 12:08