一、前言
Docker是軟件工業上的集裝箱技術
回顧,在沒有集裝箱出現以前,傳統運輸行業中,會存在這些問題:
在運輸過程中,貨物損壞
裝卸、運輸貨物,效率低下
運輸手續繁多及運輸環節多
勞動強度大,及船舶週轉慢
在集裝箱出現後,完全改變了這種狀況,是由於集裝箱:
規則標準化,大大減少了包裝費用
大大提升了貨物裝卸效率、及運輸效率
不同種運輸工具之間轉換更容易
所以,集裝箱出現是傳統行業中的一次重大變革
傳統軟件行業中存在的問題
軟件更新發布低效
業務無法敏捷
環境一致性,難於保證
不同環境之間遷移成本太高
軟件開發商,交付實施週期長—成本高
有了Docker,以上問題在很大程度上可以得到解決
二、Docker介紹
Docker最初是dotCloud公司創始人Solomon Hykes在法國期間發起的一個公司內部項目,它是基於dotCloud公司多年雲服務技術的一次革新,並於2013年3月以Apache 2.0授權協議開源,主要項目代碼在GitHub上進行維護。Docker項目後來還加入了Linux基金會併成立推動開放容器聯盟(OCI)
Docker使用Google公司推出的Go語言進行開發實現,基於Linux內核的cgroup,namespace,以及AUFS類的UnionFS等技術,對進程進行封裝隔離,屬於操作系統層面的虛擬化技術。由於隔離的進程獨立於宿主和其它的隔離的進程,因此也稱其爲容器
Docker在容器的基礎上,進行了進一步的封裝,從文件系統、網絡互聯到進程隔離等等,極大的簡化了容器的創建和維護。使得Docker技術比虛擬機技術更爲輕便、快捷
與傳統虛擬機相比
傳統虛擬機
傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操作系統,在該系統上再運行所需應用進程
Docker
而容器內的應用進程直接運行於宿主的內核,容器內沒有自己的內核,而且也沒有進行硬件虛擬。因此容器要比傳統虛擬機更爲輕便
Docker的優勢
- 更高效的利用系統資源
- 更快速的啓動時間
- 一致的運行環境
- 持續交付和部署
- 更輕鬆的遷移
- 更輕鬆的維護和擴展
對比傳統虛擬機總結
特性 | 容器 | 虛擬機 |
---|---|---|
啓動 | 秒級 | 分鐘級 |
硬盤使用 | 一般爲MB | 一般爲GB |
性能 | 接近原生 | 較弱 |
系統支持量 | 單機支持上千個容器 | 一般幾十個 |
Docker包括三個基本概念:
鏡像(Image)、容器(Container)、倉庫(Repository)
理解了這三個概念,就理解了Docker的整個生命週期
鏡像(Image)
我們都知道,操作系統分爲內核和用戶空間。對於Linux而言,內核啓動後,會掛載root文件系統爲其提供用戶空間支持。而Docker鏡像(lmage),就相當於是一個root文件系統。比如官方鏡像centos:7.6就包含了完整的一套centos7,6最小系統的root文件系統。
Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建之後也不會被改變
容器(Container)
鏡像(Image)和容器(Container)的關係,就像Java中的類和實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啓動、停止、刪除、暫停等
前面講過鏡像使用的是分層存儲,容器也是如此。每一個容器運行時,是以鏡像爲基礎層,在其上創建一個當前容器的存儲層,我們可以稱這個爲容器運行時讀寫而準備的存儲層爲容器存儲層
容器存儲層的生存週期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存於容器存儲層的信息都會隨容器刪除而丟失
三、Registry
Registry在構建自動化平臺,起着非常重要的作用!
倉庫(Repository)
鏡像構建完成後,可以很容易的在當前宿主機上運行,但是,如果需要在其它服務器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,DockerRegistry就是這樣的服務
一個DockerRegistry中可以包含多個倉庫(Repository);每個倉庫可以包含多個標籤(Tag);每個標籤對應一個鏡像
通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標籤就常用於對應該軟件的各個版本。我們可以通過<倉庫名>:<標籤>的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標籤,將以latest作爲默認標籤
以centos鏡像爲例,centos是倉庫的名字,其內包含有不同的版本標籤,如,6.9、7.5。我們可以通過centos:6.9,或者centos:7.5來具體指定所需哪個版本的鏡像。如果忽略了標籤,比如centos,那將視爲centos:latest
倉庫名經常以兩段式路徑形式出現,比如study/ngin,前者往往意味着Docker Registry多用戶環境下的用戶名,後者則往往是對應的賴件名。但這並非絕對,取決於所使用的具體Docker Registry的軟件或服務
Docker Registry 公開倉庫
常用的Registry是官方的DockerHub,這也是默認的Registry。除此以外,還有CoreOS的Quay.io,CoreOS相關的鏡像存儲在這裏;Google的Google Container Registry,Kubernetes的鏡像使用用的就是這個服務
國內的一些雲服務商提供了針對Docker Hub的鏡像服務,這些鏡像服務被稱爲加速器。常見的有阿里雲加速器、DaoCloud加速器等。使用加速器會直接從國內的地址下載DockerHub的鏡像,比直接從DockerHub下載速度會提高很多
國內也有一些雲服務商提供類似於DockerHub的公開服務。比如網易雲鏡像服務、DaoCloud鏡像市場丶阿里雲鏡像庫等。
私有Docker Registry
除了使用公開服務外,用戶還可以在本地搭建私有DockerRegistryoDocker官方提供了DockerRegistry鏡像,可以直接使用做爲私有Registry服務
開源的DockerRegistry鏡像只提供了Docker Registry API的服務端實現,足以支持docker命令,不影響使用。但不包含圖形界面,以及鏡像維護、用戶管理、訪問控制等高級功能。在官方的商業化版本DockerTrustedRegistry中,提供了這些高級功能
除了官方的DockerRegistry外,還有第三方軟件實現了DockerRegistryAPl,甚至提供了用戶界面以及一些高級功能。比如,VMWare Harbor和Sonatype Nexus
Docker容器啓動速度非常快,體現在2個方面;
- 磁盤佔用空間小,因爲docker鏡像採用了分層技術,構建的鏡像大小,只有自身的大小,不包含父鏡像的大小
- 內存消耗少,docker容器共享的宿主機的內核,沒有操作的進程消耗
什麼是Dockerfile?
Dockerfile是自動構建docker鏡像的配置文件,Dockerfile中的命令非常類似linux shell下的命令
Dockerfile,可以讓用戶自定義構建docker鏡像,支持以 # 開頭的註釋行
一般,Dockerfile分爲4部分
基礎鏡像(父鏡像)信息
維護者信息
鏡像操作命令
容器啓動命令
當把Dockerfile存放到git倉庫中,併爲每個項目創建git倉庫,這樣操作通過自動化平臺,可以自動構建docker鏡像
dockerfile示例
###基礎鏡像csphere/centos:7.1
#
# MAINTAINER liao
# DOCKER-VERSION 1.6.2
#
# Dockerizing CentOS7: Dockerfile for building CentOS images
#
FROM centos:centos7.1.1503
MAINTAINER liao
ENV TZ "Asia/Shanghai"
ENV TERM xterm
ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo
ADD aliyun-epel.repo /etc/yum.repos.d/epel.repo
RUN yum install -y curl wget tar bzip2 unzip vim-enhanced passwd sudo yum-utils hostname net-tools rsync man && \
yum install -y gcc gcc-c++ git make automake cmake patch logrotate python-devel libpng-devel libjpeg-devel && \
yum install -y --enablerepo=epel pwgen python-pip && \
yum clean all
RUN pip install supervisor
ADD supervisord.conf /etc/supervisord.conf
RUN mkdir -p /etc/supervisor.conf.d && \
mkdir -p /var/log/supervisor
EXPOSE 22
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
Dockerfile解釋
FROM centos:centos7.1.1503
基於父鏡像構建其他docker鏡像,父鏡像:可以通過docker pull 命令獲得,也可以自己製作
MAINTAINER liao
Dockerfile 維護者
ENV TZ "Asia/Shanghai"
ENV(environment)設置環境變量,一個Dockerfile中可以寫多個。以上例子是:設置docker容器的時區爲Shanghai
Dockerfile中有2條指令可以拷貝文件
ADD aliyun-mirror.repo /etc/yum.repos.d/CentOS-Base.repo
拷貝本地文件到docker容器裏,還可以拷貝URL鏈接地址下的文件,ADD還具有解壓軟件包的功能(支持gzip, bzip2 or xz)
COPY test /mydir
拷貝本地文件到docker容器
RUN yum install -y curl wget....
RUN命令,非常類似linux下的shell命令 (the command is run in a shell - /bin/sh -c - shell form)
在Dockerfile中每執行一條指令(ENV、ADD、RUN等命令),都會生成一個docker image layer
RUN pip install supervisor
supervisor進程管理系統,推薦使用
ADD supervisord.conf /etc/supervisord.conf
添加supervisor的主配置文件,到docker容器裏
RUN mkdir -p /etc/supervisor.conf.d
創建存放啓動其他服務"supervisor.conf"的目錄,此目錄下的所有以.conf結尾的文件,在啓動docker容器的時候會被加載
EXPOSE 22
端口映射 EXPOSE <host_port>:<container_port>
推薦使用docker run -p <host_port>:<container_port> 來固化端口
ENTRYPOINT ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
一個Dockerfile中只有最後一條ENTRYPOINT生效,並且每次啓動docker容器,都會執行ENTRYPOINT
以上文件就是用來生成第一個docker鏡像的Dockerfile,通過docker build指令來生成docker鏡像
docker build -t csphere/centos:7.1 .
如果Dockerfile在當前目錄下,輸入點.就可以進行加載當前目錄下的Dockerfile
如果不在當前目錄下需要運行docker build -t csphere/centos:7.1 <Dockerfile_dir>加載相對路徑下的Dockerfile
docker鏡像的命名規則 registry_url/namespace/image_name:tag 默認tag是latest
在構建Docker鏡像時,如果有自己內部的yum源,替換成自己內部的yum源地址,可以加快構建速度。
如果第一次構建失敗,會有部分鏡像layer生成,第二次構建會基於第一次構建所生成的layer(use cache),繼續構建
Step 10 : EXPOSE 22
—> Running in 0ed1c5479ebc
—> c57a5bac41c8
Removing intermediate container 0ed1c5479ebc
Step 11 : ENTRYPOINT /usr/bin/supervisord -n -c /etc/supervisord.conf
—> Running in e16c7ac2fd45
—> 185ef7b101a8
Removing intermediate container e16c7ac2fd45
Successfully built 185ef7b101a8
可以看到每執行一條Dockerfile的指令都會生成一個鏡像的layerc57a5bac41c8 185ef7b101a8 最後185ef7b101a8這個是docker鏡像的ID,185ef7b101a8是由c57a5bac41c8 185ef7b101a8…layers疊加而成,體現了docker鏡像是分層的
docker images # 查看當前主機本地有哪些docker鏡像
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
csphere/centos 7.1 185ef7b101a8 40 minutes ago 451.9 MB
通過docker鏡像生成一個docker容器
docker help run #查看docker run命令的使用方法
介紹日常工作中經常用到的參數:
docker run -it #啓動docker容器在前端 docker run -d #啓動docker容器在後臺
docker run -p docker run -P
在Dockerfile中有一條指令是EXPOSE 22,如果使用-P,宿主機會隨機選擇一個沒有被使用的端口和docker容器的22端口做端口映射,如果docker主機或者容器重啓後,宿主機又會隨機選擇一個沒有被使用的端口和docker容器的22端口做端口映射,這樣端口會發生變化
如果使用-p,比如2222:22,這樣不管是docker主機或者容器重啓後,2222:22端口都是這樣來映射,不會發生改變
生成docker容器
docker run -d -p 2222:22 --name base csphere/centos:7.1
>>>37ac69acf47d501ffc61d8883ae2ba362a132d11e46897212a92b1936e0a0593
參數說明:
-d 後臺運行
-it 前臺交互式運行
-P 22 將宿主機的一個未使用的隨機端口映射到容器的22端口
-p 2222:22 將宿主機的2222端口映射到容器的22端口
–name base 給容器命名爲base
csphere/centos:7.1 使用這個鏡像鏡像創建docker容器
查看Docker容器
docker ps
ps默認只會顯示容器在“running”的狀態的,容器列表
docker ps -a
ps -a 會查看到所有的容器列表