Docker容器之旅

一、前言

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個方面;

  1. 磁盤佔用空間小,因爲docker鏡像採用了分層技術,構建的鏡像大小,只有自身的大小,不包含父鏡像的大小
  2. 內存消耗少,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 會查看到所有的容器列表

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章