Docker解決什么問題
大型企業(yè)級服務器內存(32G..more),CPU(8核...more),對單個應用來說是富足有余的,所以為了更好的利用服務器,傳統(tǒng)的做法是安裝多個虛擬機來部署更多的應用,但是虛擬機缺點是占用內存很大、部署麻煩,而Docker恰恰很大的解決了這兩個問題。
什么是Docker
Docker使用Go語言開發(fā),基于Linux內核cgroup,namespace,以及AUFS類的Union FS等技術,對進程進行封裝隔離,屬于操作系統(tǒng)層面的虛擬化技術。
由于隔離的進程獨立于宿主和其它隔離的進程,因此也稱其為容器。(具有獨立的文件等系統(tǒng)...仿佛一個小型獨立的系統(tǒng))
Docker在容器的基礎上,進行了進一步的封裝,從文件系統(tǒng)、網絡互連到進程隔離等等,極大的簡化了容器的創(chuàng)建和維護。
Docker和傳統(tǒng)虛擬機不同:
傳統(tǒng)虛擬機技術是在虛擬出一套硬件后,在其上運行一個完整的操作系統(tǒng),在該系統(tǒng)上再運行所需的應用進程。
而容器的應用進程直接運行于宿主的內核,容器沒有自己的內核,而且也沒有進行硬件虛擬。容器比傳統(tǒng)虛擬機更為輕便。
Docker優(yōu)點
- 更高效的利用系統(tǒng)資源(比傳統(tǒng)虛擬機技術更高效:減少不必要的內存占用,不需要建立新的系統(tǒng)...)
- 更快的啟動時間(s級別,傳統(tǒng)虛擬機m級別)
- 一致的運行環(huán)境:Docker鏡像提供了除內核外完整的運行時環(huán)境,確保了運行環(huán)境的一致性(非常重要的特性,避免了不同系統(tǒng)之間表現(xiàn)不同)。
- 持續(xù)交付和部署
使用 Docker 可以通過定制應用鏡像來實現(xiàn)持續(xù)集成、持續(xù)交付、部署。開發(fā)人員可以通過 Dockerfile 來進行鏡像構建,并結合 持續(xù)集成(Continuous Integration) 系統(tǒng)進行集成測試,而運維人員則可以直接在生產環(huán)境中快速部署該鏡像,甚至結合 持續(xù)部署(Continuous Delivery/Deployment) 系統(tǒng)進行自動部署。
- 更輕松的遷移(不需要進行環(huán)境配置等操作)
- 更輕松的維護和擴展
Docker 使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基于基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質量的官方鏡像,既可以直接在生產環(huán)境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。
和傳統(tǒng)虛擬機比較:
特性 | 容器 | 虛擬機 |
---|---|---|
啟動 | 秒級 | 分鐘級 |
硬盤使用 | 一般為 MB | 一般為 GB |
性能 | 接近原生 | 弱于 |
系統(tǒng)支持量 | 單機支持上千個容器 | 一般幾十個 |
安裝
Mac下載地址(下載安裝即可):
https://store.docker.com/editions/community/docker-ce-desktop-mac?tab=description
Docker Store:國內下載鏡像比較慢,參照docker 配置國內鏡像源 設置即可。
Docker概念
鏡像(Image)
是一個特殊的文件系統(tǒng),除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。鏡像不包含任何動態(tài)數(shù)據,其內容在構建之后也不會被改變。
容器(Container)
鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的類和實例一樣,鏡像是靜態(tài)的定義,容器是鏡像運行時的實體。容器可以被創(chuàng)建、啟動、停止、刪除、暫停等。
容器的實質是進程,但與直接在宿主執(zhí)行的進程不同,容器進程運行于屬于自己的獨立的 命名空間。因此容器可以擁有自己的 root 文件系統(tǒng)、自己的網絡配置、自己的進程空間,甚至自己的用戶 ID 空間。容器內的進程是運行在一個隔離的環(huán)境里,使用起來,就好像是在一個獨立于宿主的系統(tǒng)下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。也因為這種隔離的特性,很多人初學 Docker 時常常會把容器和虛擬機搞混。
按照 Docker 最佳實踐的要求,容器不應該向其存儲層內寫入任何數(shù)據,容器存儲層要保持無狀態(tài)化。所有的文件寫入操作,都應該使用 數(shù)據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發(fā)生讀寫,其性能和穩(wěn)定性更高。
數(shù)據卷的生存周期獨立于容器,容器消亡,數(shù)據卷不會消亡。因此,使用數(shù)據卷后,容器可以隨意刪除、重新 run,數(shù)據卻不會丟失。
倉庫(Repository)
鏡像構建完成后,可以很容易的在當前宿主上運行,但是,如果需要在其它服務器上使用這個鏡像,我們就需要一個集中的存儲、分發(fā)鏡像的服務,Docker Registry 就是這樣的服務。
一個 Docker Registry 中可以包含多個倉庫(Repository);每個倉庫可以包含多個標簽(Tag);每個標簽對應一個鏡像。
通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標簽就常用于對應該軟件的各個版本。我們可以通過 <倉庫名>:<標簽> 的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標簽,將以 latest 作為默認標簽。
以 Ubuntu 鏡像 為例,ubuntu 是倉庫的名字,其內包含有不同的版本標簽,如,14.04, 16.04。我們可以通過 ubuntu:14.04,或者 ubuntu:16.04 來具體指定所需哪個版本的鏡像。如果忽略了標簽,比如 ubuntu,那將視為 ubuntu:latest。
倉庫名經常以 兩段式路徑 形式出現(xiàn),比如 jwilder/nginx-proxy,前者往往意味著 Docker Registry 多用戶環(huán)境下的用戶名,后者則往往是對應的軟件名。但這并非絕對,取決于所使用的具體 Docker Registry 的軟件或服務。
常用命令
docker images # 查看docker鏡像 -a 列出所有鏡像
docker pull xxx # 拉取一個鏡像 docker pull ubuntu
docker search xxx # 搜索某個鏡像
docker rmi xxx # 移除docker鏡像
docker run xxx # 啟動某個容器 -d 容器在后臺運行 -P 容器內部使用端口號映射到主機上 -p 1000:1000 容器和主機端口映射 -i 交互式操作 -t 終端 --rm 容器退出后刪除