1.docker的技術原理
1.1docker 新一代的PAAS平臺
新一代的云應用平臺技術則實現全方位的應用生命周期管理,關注開放性、應用的可移植性和云間相互操作性, 其代表者包括Cloud Foundry, OpenShift, Docker, Heroku, MoPaaS等PaaS技術或服務,除了在第一代PaaS 技術對用戶在實現應用交付的加速所提供的功能外,具備以下大多數特征: 多語言和框架:支持多語言和框架以及語言框架的擴展機制 多服務:開放的核心服務以及服務的擴展機制 多云和多IaaS技術:支持多種IaaS技術和多云的部署,包括公有云和私有云
Docker也被稱之為第三代Paas平臺 Docker 究竟是什么?
dotCloud 不僅支持諸如 PHP、MySql 等傳統技術框架,還包括 Node.js、MongoDB 等新興技術。基于 dotCloud 提供 的開發工具和技術框架,你可以直接使用 dotCloud 的 SDK 編寫代碼和構建業務服務,并在聯網的時候把這些代碼 推送到云端,實現自動部署和測試。
1.2.Docker的技術原理介紹
Docker就是虛擬化的一種輕量級替代技術。Docker的容器技術不依賴任何語言、框架或系統,可以將App變成一種 標準化的、可移植的、自管理的組件,并脫離服務器硬件在任何主流系統中開發、調試和運行
簡單的說就是,在 Linux 系統上迅速創建一個容器(類似虛擬機)并在容器上部署和運行應用程序,并通過配置文件 可以輕松實現應用程序的自動化安裝、部署和升級,非常方便。因為使用了容器,所以可以很方便的把生產環境和開 發環境分開,互不影響,這是 docker 最普遍的一個玩法。
1.3.Docker相關的核心技術
1.4.Docker相關的核心技術之cgroups
Linux系統中經常有個需求就是希望能限制某個或者某些進程的分配資源。于是就出現了cgroups的概念, cgroup就是controller group ,在這個group中,有分配好的特定比例的cpu時間,IO時間,可用內存大小等。 cgroups是將任意進程進行分組化管理的Linux內核功能。最初由google的工程師提出,后來被整合進Linux內 核中。
cgroups中的 重要概念是“子系統”,也就是資源控制器,每種子系統就是一個資源的分配器,比如cpu子系 統是控制cpu時間分配的。首先掛載子系統,然后才有control group的。比如先掛載memory子系統,然后在 memory子系統中創建一個cgroup節點,在這個節點中,將需要控制的進程id寫入,并且將控制的屬性寫入, 這就完成了內存的資源限制。
cgroups 被Linux內核支持,有得天獨厚的性能優勢,發展勢頭迅猛。在很多領域可以取代虛擬化技術分割資源。 cgroup默認有諸多資源組,可以限制幾乎所有服務器上的資源:cpu mem iops,iobandwide,net,device acess等
1.5.Docker相關的核心技術之LXC
LXC是Linux containers的簡稱,是一種基于容器的操作系統層級的虛擬化技術。借助于namespace的隔離機制 和cgroup限額功能,LXC提供了一套統一的API和工具來建立和管理container。LXC跟其他操作系統層次的虛 擬化技術相比,最大的優勢在于LXC被整合進內核,不用單獨為內核打補丁
LXC 旨在提供一個共享kernel的 OS 級虛擬化方法,在執行時不用重復加載Kernel, 且container的kernel與host 共享,因此可以大大加快container的 啟動過程,并顯著減少內存消耗,容器在提供隔離的同時,還通過共享這 些資源節省開銷,這意味著容器比真正的虛擬化的開銷要小得多。 在實際測試中,基于LXC的虛擬化方法的IO和 CPU性能幾乎接近 baremetal 的性能。
雖然容器所使用的這種類型的隔離總的來說非常強大,然而是不是像運行在hypervisor上的虛擬機那么強壯仍具有 爭議性。如果內核停止,那么所有的容器就會停止運行。
? 性能方面:LXC>>KVM>>XEN ? 內存利用率:LXC>>KVM>>XEN ? 隔離程度: XEN>>KVM>>LXC
1.6. Docker相關的核心技術之AUFS
什么是AUFS? AuFS是一個能透明覆蓋一或多個現有文件系統的層狀文件系統。 支持將不同目錄掛載到同一 個虛擬文件系統下,可以把不同的目錄聯合在一起,組成一個單一的目錄。這種是一種虛擬的文件系統,文 件系統不用格式化,直接掛載即可。
Docker一直在用AuFS作為容器的文件系統。當一個進程需要修改一個文件時,AuFS創建該文件的一個副本。 AuFS可以把多層合并成文件系統的單層表示。這個過程稱為寫入復制( copy on write )。
AuFS允許Docker把某些鏡像作為容器的基礎。例如,你可能有一個可以作為很多不同容器的基礎的CentOS 系統鏡像。多虧AuFS,只要一個CentOS鏡像的副本就夠了,這樣既節省了存儲和內存,也保證更快速的容器部署。
使用AuFS的另一個好處是Docker的版本容器鏡像能力。每個新版本都是一個與之前版本的簡單差異改動, 有效地保持鏡像文件最小化。但,這也意味著你總是要有一個記錄該容器從一個版本到另一個版本改動的審計跟蹤。
1.7.Docker原理之App打包
LXC的基礎上, Docker額外提供的Feature包括:標準統一的 打包部署運行方案
為了最大化重用Image,加快運行速度,減少內存和磁盤 footprint, Docker container運行時所構造的運行環境,實際 上是由具有依賴關系的多個Layer組成的。例如一個apache 的運行環境可能是在基礎的rootfs image的基礎上,疊加了 包含例如Emacs等各種工具的image,再疊加包含apache及 其相關依賴library的image,這些image由AUFS文件系統加載 合并到統一路徑中,以只讀的方式存在,最后再疊加加載 一層可寫的空白的Layer用作記錄對當前運行環境所作的修 改。
有了層級化的Image做基礎,理想中,不同的APP就可以既 可能的共用底層文件系統,相關依賴工具等,同一個APP的 不同實例也可以實現共用絕大多數數據,進而以copy on write的形式維護自己的那一份修改過的數據等
1.8. Docker全生命周期開發模式
2.Docker的基本概念
2.1.Docker Image
Docker Image是一個極度精簡版的Linux程序運行環境,比如vi這種基本 的工具沒有,官網的Java鏡像包括的東西更少,除非是鏡像疊加方式的, 如Centos+Java7 ? Docker Image是需要定制化Build的一個“安裝包”,包括基礎鏡像+應 用的二進制部署包
Docker Image內不建議有運行期需要修改的配置文件
Dockerfile用來創建一個自定義的image,包含了用戶指定的軟件依賴等。 當前目錄下包含Dockerfile,使用命令build來創建新的image
Docker Image的最佳實踐之一是盡量重用和使用網上公開的基礎鏡像
2.2.Docker Container
Docker Container是Image的實例,共享內核
Docker Container里可以運行不同Os的Image,比如Ubuntu的或者 Centos
Docker Container不建議內部開啟一個SSHD服務,1.3版本后新增了 docker exec命令進入容器排查問題。
Docker Container沒有IP地址,通常不會有服務端口暴露,是一個封閉的 “盒子/沙箱”
2.3.Docker Container的生命周期
2.4.Docker Daemon
Docker Daemon是創建和運行Container的Linux守護進程,也是Docker 最主要的核心組件
Docker Daemon 可以理解為Docker Container的Container
Docker Daemon可以綁定本地端口并提供Rest API服務,用來遠程訪問 和控制
2.5.Docker Registry/Hub
- Docker之所以這么吸引人,除了它的新穎的技術外,圍繞官方Registry(Docker Hub)的生態圈也是相當吸引人眼球的地方。在Docker Hub上你可以很輕松下載 到大量已經容器化好的應用鏡像,即拉即用。這些鏡像中,有些是Docker官方維 護的,更多的是眾多開發者自發上傳分享的。而且 你還可以在Docker Hub中綁定 你的代碼托管系統(目前支持Github和Bitbucket)配置自動生成鏡像功能,這樣 Docker Hub會在你代碼更新時自動生成對應的Docker鏡像。
問題點: Docker Hub是dotCloud公司私有的 國內曾有公司試圖提供鏡像服務,但被禁止 目前國內只有一個DaoCloud提供代理緩存服務
- Docker Hub - our SaaS service for sharing and managing your application stacks.
2.6.Docker 核心組件的關系
3. docker的基本操作命令
3.1.拉取鏡像
docker pull NAME[:TAG]
如果不顯示的指定TAG,則默認會選擇latest標簽,即下載倉庫中最新版本的鏡像
[圖片上傳失敗...(image-123eaa-1590976102508)]
repository: 來自于哪個倉庫,比如ubuntu倉庫
TAG: 鏡像的標簽,比如16.4
IMAGE ID : 鏡像的ID 號(唯一)
CREATE: 創建時間
SIZE: 鏡像大小
使用docker inspect 命令可以獲取鏡像的詳細信息.
docker inspect 61325bfc4914
[圖片上傳失敗...(image-31c1de-1590976102508)]
docker inspect 返回的是一個json格式的消息,如果只需要其中的一項內容時,可以使用-f參數指定.例如獲取鏡像的Created信息.
docker inspect -f {{".Created"}} 613
[圖片上傳失敗...(image-e8e919-1590976102508)]
3.2 查找鏡像
docker search 命令可以搜索到遠程倉庫中共享的鏡像,默認搜索docker hub 官網倉庫中的鏡像
docker serach TERM
-- automated= false 僅顯示自動創建的鏡像
-- no -trunc=false 輸出信息不截斷顯示
-- s ,--stars =0 指定僅顯示評價為指定星級以上的鏡像
3.3 docker 容器鏡像刪除
先停止容器,然后再刪除
docker stop $(docker ps -a -q)
如果想要刪除所有container的話再加一個指令:
docker rm $(docker ps -a -q)
3.4 查看當前有些什么images
docker images
3.5 刪除images
- 刪除images, 通過image的tags 來指定
docker rmi <image tags>
例如 dl.dockerpool.com:5000/ubuntu:latest 鏡像,可以使用如下命令:
sudo docker rmi dl.dockerpool.com:5000/ubuntu
當同一個鏡像有多個標簽的時候,docker rmi 只是刪除了該鏡像多個標簽中的指定標簽而已,并不影響鏡像文件.但是當鏡像只剩下一個標簽的時候就要小心了,此時再使用docker rmi 命令會徹底刪除該鏡像.
- 刪除images,通過image的id來指定刪除誰
docker rmi <image id>
- 想要刪除untagged images,也就是那些id為<None>的image的話可以用
docker rmi $(docker images | grep "^<none>" | awk "{print $3}")
- 要刪除全部image的話
docker rmi $(docker images -q)
- 強制刪除鏡像.強制刪除一個存在容器依賴的鏡像,會造成遺留問題,使用docker images 查看本地的鏡像列表時,原來被強制刪除的鏡像換了新的的ID 繼續存在系統中.正確的做法是先刪除依賴該鏡像的所有容器,然后在刪除該鏡像.
docker rmi -f ubuntu
3.6 終止容器運行
docker stop [NAME]/[CONTAINER ID]:將容器退出
docker kill [NAME]/[CONTAINER ID]:強制停止一個容器。
3.7 docker 批量刪除無用的容器或鏡像
# 刪除異常停止的docker容器
docker rm `docker ps -a | grep Exited | awk '{print $1}'`
# 刪除名稱或標簽為none的鏡像
docker rmi -f `docker images | grep '<none>' | awk '{print $3}'`
3.8 創建鏡像
3.8.1 基于已有鏡像的容器創建
該方法主要是使用docker commit 命令,其命令格式是 docker commit [options] container [repository:[tag]] ,主要包括:
-a , -- author ="" 作者信息
-m, --message =“” 提交信息
-m, --message =“” 提交時暫停容器運行
下面將演示如何使用該命令創建一個新鏡像。 首先啟動一個鏡像,并在其中修改操作,例如創建一個test 文件,之后退出。
$sudo docker run -ti unbutu:14.04 /bin/bash
root@a132s232md0:/# touch test
root@a132s232md0:/# exit
該容器已經和鏡像不同了,使用commit 操作創建鏡像
sudo docker commit -m "add file" -a "author" a132s232md0 test
查看本地鏡像,可以看到新的鏡像。
sudo docker images
3.8.2 使用dockerfile 創建鏡像
- FROM
格式為 FROM <image> 或者FROM <image>:<tag>
- MAINTAINER
格式為MAINTAINER <name> ,指定維護者的信息。
- RUN
格式為 RUN <command> 或 RUN <"excute", "param1" ,"param2">
- CMD
三種使用方式
- CMD <"excute", "param1" ,"param2"> ,使用exec 執行,推薦方式。
- CMD command param1 param2 在bin/sh 中執行,提供給需要交互的應用
- CMD ["param1" ,"param2"] 提供ENTRYPOINT 的默認參數
- EXPOSE
格式為 EXPOSE <port> [<port>....]
例如
EXPOSE 22 80 8080
docker 容器可以暴露的端口號, 可以-p 映射端口。
- ENV
格式為ENV <key> <value> 。 指定一個環境變量,會被后續RUN 指令使用,并在容器運行時保持。
- ADD
格式為ADD <src> <dest>
該命令將復制指定的<src> 到容器中的<dest>。 其中<src> 可以是dockerfile 所在目錄的一個相對路徑(文件或目錄);也可以是一個URL;還可以是一個tar文件(自動解壓為目錄)
- COPY
格式為COPY <src> <dest>
復制本地主機的<src> (為Dockerfile 所在目錄的相對路徑,文件或者目錄)為容器中的dest。目錄路徑不存在時,會自動創建。
當使用本地目錄為源目錄時,推薦使用COPY。
- ENTRYPOINT
有兩種格式:
ENTRYPOINT ["executable","param1","param2"]
ENTRYPOINT command param1 param2(shell 中執行)
配置容器啟動后執行的命令,并且不可被docker run 提供的參數覆蓋。
每個dockerfile 中只有一個ENTRYPOINT,當指定多個ENTRYPOINT 時,只有最后一個生效。
- VOLUME
格式為VOLUME ["/data"]
創建一個可以從本地或其他容器掛載的掛載點,一般用來存放數據庫和需要持久化的數據等。
- USER
格式為USER deamon
指定運行容器時的用戶或者UID,后續的RUN也會使用指定用戶。當服務不需要管理員權限時,可以通過該命令指定運行的用戶。并且可以在之前創建需要的用戶
例如: RUN groupadd -r postgres && useradd -r -g postgres postgres。 要臨時獲取管理員權限可以使用gosu,而不推薦sudo。
3.9 上傳鏡像
先在dockerhub 上注冊賬號,docker 默認上傳到dockerhub 倉庫。上傳命令:docker push name[:tag]
sudo docker tag test:latest user/test:latest
sudo docker push user/test:latest
會提示輸入賬號密碼
4. 創建和使用私有鏡像倉庫
4.1 通過官方提供的resigtry 鏡像簡單搭建一個私有的倉庫
sudo docker run -d -p 5000:5000 registry
默認情況下,會將倉庫創建在容器的/tmp/registry目錄下。可以通過-v 參數來指定本地存儲路徑。
sudo docker run -d -p 5000:5000 registry -v /opt/data/registry:/tmp/registry registry
本地會啟動一個私有倉庫,監聽端口為5000.
4.2 管理私有倉庫
比如本地已有的私有鏡像倉庫的地址為192.168.1.5:5000,標記本地鏡像為192.168.1.5:5000/nginx
sudo docker tag nginx:latest 192.168.1.5:5000/nginx
sudo docker push 192.168.1.5:5000/nginx
查看鏡像
curl http://192.168.1.5:5000/v1/search