日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Docker应用学习

發布時間:2024/1/8 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Docker应用学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Docker是什么?

在計算機技術日新月異的今天,?Docker?在國內發展的如火如荼,特別是在一線互聯網公司,?Docker?的使用是十分普遍的,甚至成為了一些企業面試的加分項。

?

對于我們而言,熟悉?docker?可以快速搭建?CTF環境,幫助我們快速提升自己。

市面上已經有很多優秀的教程,但是很多原理性的東西,筆者認為那些教程對初學者而言還是很難理解,感覺沒有說清楚(筆者自己都覺得挺懵逼的),為了讓初學者少走彎路,我將以我的學習經歷以及作為一個?CTF選手?的角度,編寫此套教程,來帶大家去了解并熟練運用?docker?,祝愿各位讀者朋友們學完此套教程后,在未來企業面試中能夠多一項加分的籌碼,能夠幫助到大家,我覺得就很值了。

既然說了這么多,?docker?到底是個什么東西呢?

我們在理解?docker?之前,首先我們得先區分清楚兩個概念,容器虛擬機

可能很多讀者朋友都用過虛擬機,而對容器這個概念比較的陌生。

我們用的傳統虛擬機如?VMware?,?VisualBox?之類的需要模擬整臺機器包括硬件,每臺虛擬機都需要有自己的操作系統,虛擬機一旦被開啟,預分配給它的資源將全部被占用。每一臺虛擬機包括應用,必要的二進制和庫,以及一個完整的用戶操作系統。

而容器技術是和我們的宿主機共享硬件資源及操作系統,可以實現資源的動態分配。容器包含應用和其所有的依賴包,但是與其他容器共享內核。容器在宿主機操作系統中,在用戶空間以分離的進程運行。

容器技術是實現操作系統虛擬化的一種途徑,可以讓您在資源受到隔離的進程中運行應用程序及其依賴關系。通過使用容器,我們可以輕松打包應用程序的代碼、配置和依賴關系,將其變成容易使用的構建塊,從而實現環境一致性、運營效率、開發人員生產力和版本控制等諸多目標。容器可以幫助保證應用程序快速、可靠、一致地部署,其間不受部署環境的影響。容器還賦予我們對資源更多的精細化控制能力,讓我們的基礎設施效率更高。通過下面這幅圖我們可以很直觀的反映出這兩者的區別所在。

Docker 屬于 Linux 容器的一種封裝,提供簡單易用的容器使用接口。它是目前最流行的?Linux?容器解決方案。

而?Linux?容器是?Linux?發展出了另一種虛擬化技術,簡單來講,?Linux?容器不是模擬一個完整的操作系統,而是對進程進行隔離,相當于是在正常進程的外面套了一個保護層。對于容器里面的進程來說,它接觸到的各種資源都是虛擬的,從而實現與底層系統的隔離。

Docker?將應用程序與該程序的依賴,打包在一個文件里面。運行這個文件,就會生成一個虛擬容器。程序在這個虛擬容器里運行,就好像在真實的物理機上運行一樣。有了?Docker?,就不用擔心環境問題。

總體來說,?Docker?的接口相當簡單,用戶可以方便地創建和使用容器,把自己的應用放入容器。容器還可以進行版本管理、復制、分享、修改,就像管理普通的代碼一樣。

Docker的優勢

Docker相比于傳統虛擬化方式具有更多的優勢:

  • docker?啟動快速屬于秒級別。虛擬機通常需要幾分鐘去啟動
  • docker?需要的資源更少,?docker?在操作系統級別進行虛擬化,?docker?容器和內核交互,幾乎沒有性能損耗,性能優于通過?Hypervisor?層與內核層的虛擬化
  • docker?更輕量,?docker?的架構可以共用一個內核與共享應用程序庫,所占內存極小。同樣的硬件環境,?Docker?運行的鏡像數遠多于虛擬機數量,對系統的利用率非常高
  • 與虛擬機相比,?docker?隔離性更弱,?docker?屬于進程之間的隔離,虛擬機可實現系統級別隔離
  • 安全性:?docker?的安全性也更弱。?Docker?的租戶?root?和宿主機?root?等同,一旦容器內的用戶從普通用戶權限提升為root權限,它就直接具備了宿主機的root權限,進而可進行無限制的操作。虛擬機租戶?root?權限和宿主機的?root?虛擬機權限是分離的,并且虛擬機利用如?Intel?的?VT-d?和?VT-x?的?ring-1?硬件隔離技術,這種隔離技術可以防止虛擬機突破和彼此交互,而容器至今還沒有任何形式的硬件隔離,這使得容器容易受到攻擊
  • 可管理性:?docker?的集中化管理工具還不算成熟。各種虛擬化技術都有成熟的管理工具,例如?VMware vCenter?提供完備的虛擬機管理能力
  • 高可用和可恢復性:?docker?對業務的高可用支持是通過快速重新部署實現的。虛擬化具備負載均衡,高可用,容錯,遷移和數據保護等經過生產實踐檢驗的成熟保障機制,?VMware?可承諾虛擬機?99.999%?高可用,保證業務連續性
  • 快速創建、刪除:虛擬化創建是分鐘級別的,?Docker?容器創建是秒級別的,?Docker?的快速迭代性,決定了無論是開發、測試、部署都可以節約大量時間
  • 交付、部署:虛擬機可以通過鏡像實現環境交付的一致性,但鏡像分發無法體系化。?Docker?在?Dockerfile?中記錄了容器構建過程,可在集群中實現快速分發和快速部署

我們可以從下面這張表格很清楚地看到容器相比于傳統虛擬機的特性的優勢所在:

特性容器虛擬機
啟動秒級分鐘級
硬盤使用一般為MB一般為GB
性能接近原生弱于
系統支持量單機支持上千個容器一般是幾十個

Docker的三個基本概念

從上圖我們可以看到,Docker?中包括三個基本的概念:

  • Image(鏡像)
  • Container(容器)
  • Repository(倉庫)

鏡像是?Docker?運行容器的前提,倉庫是存放鏡像的場所,可見鏡像更是?Docker?的核心。

Image (鏡像)

那么鏡像到底是什么呢?

Docker?鏡像可以看作是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建之后也不會被改變。

鏡像(Image)就是一堆只讀層(read-only layer)的統一視角,也許這個定義有些難以理解,下面的這張圖能夠幫助讀者理解鏡像的定義。

從左邊我們看到了多個只讀層,它們重疊在一起。除了最下面一層,其它層都會有一個指針指向下一層。這些層是Docker?內部的實現細節,并且能夠在主機的文件系統上訪問到。統一文件系統?(union file system)?技術能夠將不同的層整合成一個文件系統,為這些層提供了一個統一的視角,這樣就隱藏了多層的存在,在用戶的角度看來,只存在一個文件系統。我們可以在圖片的右邊看到這個視角的形式。

Container (容器)

容器?(container)?的定義和鏡像?(image)?幾乎一模一樣,也是一堆層的統一視角,唯一區別在于容器的最上面那一層是可讀可寫的。

由于容器的定義并沒有提及是否要運行容器,所以實際上,容器 = 鏡像 + 讀寫層。

Repository (倉庫)

Docker?倉庫是集中存放鏡像文件的場所。鏡像構建完成后,可以很容易的在當前宿主上運行,但是, 如果需要在其它服務器上使用這個鏡像,我們就需要一個集中的存儲、分發鏡像的服務,Docker Registry?(倉庫注冊服務器)就是這樣的服務。有時候會把倉庫?(Repository)?和倉庫注冊服務器?(Registry)?混為一談,并不嚴格區分。Docker?倉庫的概念跟?Git?類似,注冊服務器可以理解為?GitHub?這樣的托管服務。實際上,一個?Docker Registry?中可以包含多個倉庫?(Repository)?,每個倉庫可以包含多個標簽?(Tag),每個標簽對應著一個鏡像。所以說,鏡像倉庫是?Docker?用來集中存放鏡像文件的地方類似于我們之前常用的代碼倉庫。

通常,一個倉庫會包含同一個軟件不同版本的鏡像,而標簽就常用于對應該軟件的各個版本?。我們可以通過<倉庫名>:<標簽>的格式來指定具體是這個軟件哪個版本的鏡像。如果不給出標簽,將以?latest?作為默認標簽.。

倉庫又可以分為兩種形式:

  • public(公有倉庫)
  • private(私有倉庫)

Docker Registry?公有倉庫是開放給用戶使用、允許用戶管理鏡像的?Registry?服務。一般這類公開服務允許用戶免費上傳、下載公開的鏡像,并可能提供收費服務供用戶管理私有鏡像。

除了使用公開服務外,用戶還可以在本地搭建私有?Docker Registry?。Docker?官方提供了?Docker Registry?鏡像,可以直接使用做為私有?Registry?服務。當用戶創建了自己的鏡像之后就可以使用?push?命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機器上使用這個鏡像時候,只需要從倉庫上?pull?下來就可以了。

我們主要把?Docker?的一些常見概念如?Image?,?Container?,?Repository?做了詳細的闡述,也從傳統虛擬化方式的角度闡述了?docker?的優勢,我們從下圖可以直觀地看到?Docker?的架構:

Docker?使用?C/S?結構,即客戶端/服務器體系結構。?Docker?客戶端與?Docker?服務器進行交互,Docker服務端負責構建、運行和分發?Docker?鏡像。?Docker?客戶端和服務端可以運行在一臺機器上,也可以通過?RESTful?、?stock?或網絡接口與遠程?Docker?服務端進行通信。

這張圖展示了?Docker?客戶端、服務端和?Docker?倉庫(即?Docker Hub?和?Docker Cloud?),默認情況下Docker?會在?Docker?中央倉庫尋找鏡像文件,這種利用倉庫管理鏡像的設計理念類似于?Git?,當然這個倉庫是可以通過修改配置來指定的,甚至我們可以創建我們自己的私有倉庫。

Docker的安裝和使用

Docker?的安裝和使用有一些前提條件,主要體現在體系架構和內核的支持上。對于體系架構,除了?Docker?一開始就支持的?X86-64?,其他體系架構的支持則一直在不斷地完善和推進中。

Docker?分為?CE?和?EE?兩大版本。?CE?即社區版(免費,支持周期?7?個月),?EE?即企業版,強調安全,付費使用,支持周期?24?個月。

我們在安裝前可以參看官方文檔獲取最新的?Docker?支持情況,官方文檔在這里:

https://docs.docker.com/install/

Docker?對于內核支持的功能,即內核的配置選項也有一定的要求(比如必須開啟?Cgroup?和?Namespace?相關選項,以及其他的網絡和存儲驅動等),?Docker?源碼中提供了一個檢測腳本來檢測和指導內核的配置,腳本鏈接在這里:

https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh

在滿足前提條件后,安裝就變得非常的簡單了。

Docker CE?的安裝請參考官方文檔:

  • MacOS:https://docs.docker.com/docker-for-mac/install/
  • Windows:https://docs.docker.com/docker-for-windows/install/
  • Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/
  • Debian:https://docs.docker.com/install/linux/docker-ce/debian/
  • CentOS:https://docs.docker.com/install/linux/docker-ce/centos/
  • Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/
  • 其他?Linux?發行版:https://docs.docker.com/install/linux/docker-ce/binaries/

這里我們以?CentOS7?作為本文的演示。

環境準備

  • 阿里云服務器(1核2G,1M帶寬)
  • CentOS 7.4 64位

由于?Docker-CE?支持?64?位版本的?CentOS7?,并且要求內核版本不低于?3.10

首先我們需要卸載掉舊版本的?Docker

?

$ sudo yum remove docker \

docker-client \

docker-client-latest \

docker-common \

docker-latest \

docker-latest-logrotate \

docker-logrotate \

docker-selinux \

docker-engine-selinux \

docker-engine

我們執行以下安裝命令去安裝依賴包:

?

$ sudo yum install -y yum-utils \

device-mapper-persistent-data \

lvm2

這里我事先已經安裝過了,所以提示我已經安裝了最新版本

安裝Docker

Docker?軟件包已經包括在默認的?CentOS-Extras?軟件源里。因此想要安裝?docker,只需要運行下面的?yum?命令

$ sudo yum install docker

當然在測試或開發環境中?Docker?官方為了簡化安裝流程,提供了一套便捷的安裝腳本,CentOS?系統上可以使用這套腳本安裝:

?

curl -fsSL get.docker.com -o get-docker.sh

sh get-docker.sh

具體可以參看?docker-install?的腳本:

https://github.com/docker/docker-install

執行這個命令后,腳本就會自動的將一切準備工作做好,并且把?Docker CE?的?Edge?版本安裝在系統中。

安裝完成后,運行下面的命令,驗證是否安裝成功:

?

docker version

or

docker info

返回docker的版本相關信息,證明?docker?安裝成功

啟動Docker-CE

?

$ sudo systemctl enable docker

$ sudo systemctl start docker

Docker的簡單運用---Hello World

由于服務器日常崩潰了,?docker?出了點問題,所以以下案例的演示是基于?Kali Linux?環境下進行的。

我們通過最簡單的?image?文件?hello world,感受一下?Docker?的魅力吧!

我們直接運行下面的命令,將名為?hello-world?的?image?文件從倉庫抓取到本地。

docker pull library/hello-world

docker pull images?是抓取?image?文件,?library/hello-world?是?image?文件在倉庫里面的位置,其中?library?是?image?文件所在的組,?hello-world?是?image?文件的名字。

抓取成功以后,就可以在本機看到這個?image?文件了。

docker images

我們可以看到如下結果:

現在,我們可以運行?hello-world?這個?image?文件

docker run hello-world

我們可以看到如下結果:

輸出這段提示以后,hello world?就會停止運行,容器自動終止。有些容器不會自動終止,因為提供的是服務,比如Mysql鏡像等。

是不是很?easy?呢?我們從上面可以看出,?docker?的功能是十分強大的,除此之外,我們還可以拉去一些?Ubuntu?,?Apache等鏡像,在未來的教程中我們將會一一提到。

Docker?提供了一套簡單實用的命令來創建和更新鏡像,我們可以通過網絡直接下載一個已經創建好了的應用鏡像,并通過?Docker RUN?命令就可以直接使用。當鏡像通過?RUN?命令運行成功后,這個運行的鏡像就是一個?Docker?容器啦,容器可以理解為一個輕量級的沙箱,?Docker?利用容器來運行和隔離應用,容器是可以被啟動、停止、刪除的,這并不會影響?Docker?鏡像。

我們可以看看下面這幅圖:

Docker?客戶端是?Docker?用戶與?Docker?交互的主要方式。當您使用?docker?命令行運行命令時,?Docker?客戶端將這些命令發送給服務器端,服務端將執行這些命令。?docker?命令使用?docker API?。?Docker?客戶端可以與多個服務端進行通信。

我們將剖析一下?Docker?容器是如何工作的,學習好Docker容器工作的原理,我們就可以自己去管理我們的容器了。

Docker架構

在上面的學習中,我們簡單地講解了Docker的基本架構。了解到了Docker?使用的是?C/S?結構,即客戶端/服務器體系結構。明白了?Docker?客戶端與?Docker?服務器進行交互時,?Docker?服務端負責構建、運行和分發?Docker?鏡像。 也知道了Docker?客戶端和服務端可以運行在一臺機器上,可以通過?RESTful?、?stock?或網絡接口與遠程?Docker?服務端進行通信。

我們從下圖可以很直觀的了解到Docker的架構:

Docker?的核心組件包括:

  • Docker Client
  • Docker daemon
  • Docker Image
  • Docker Registry
  • Docker Container
  • Docker?采用的是?Client/Server?架構。客戶端向服務器發送請求,服務器負責構建、運行和分發容器。客戶端和服務器可以運行在同一個?Host?上,客戶端也可以通過?socket?或?REST API?與遠程的服務器通信。可能很多朋友暫時不太理解一些東西,比如?REST API?是什么東西等,不過沒關系,在后面的文章中會一一給大家講解清楚。

    Docker Client

    Docker Client?,也稱?Docker?客戶端。它其實就是?Docker?提供命令行界面?(CLI)?工具,是許多?Docker?用戶與?Docker?進行交互的主要方式。客戶端可以構建,運行和停止應用程序,還可以遠程與Docker_Host進行交互。最常用的?Docker客戶端就是?docker?命令,我們可以通過?docker?命令很方便地在?host?上構建和運行?docker?容器。

    Docker daemon

    Docker daemon?是服務器組件,以?Linux?后臺服務的方式運行,是?Docker?最核心的后臺進程,我們也把它稱為守護進程。它負責響應來自?Docker Client?的請求,然后將這些請求翻譯成系統調用完成容器管理操作。該進程會在后臺啟動一個?API Server?,負責接收由?Docker Client?發送的請求,接收到的請求將通過Docker daemon?內部的一個路由分發調度,由具體的函數來執行請求。

    我們大致可以將其分為以下三部分:

    • Docker Server
    • Engine
    • Job

    Docker Daemon的架構如下所示:

    Docker Daemon?可以認為是通過?Docker Server?模塊接受?Docker Client?的請求,并在?Engine?中處理請求,然后根據請求類型,創建出指定的?Job?并運行。?Docker Daemon?運行在?Docker host?上,負責創建、運行、監控容器,構建、存儲鏡像。

    運行過程的作用有以下幾種可能:

    • 向?Docker Registry?獲取鏡像
    • 通過?graphdriver?執行容器鏡像的本地化操作
    • 通過?networkdriver?執行容器網絡環境的配置
    • 通過?execdriver?執行容器內部運行的執行工作

    由于?Docker Daemon?和?Docker Client?的啟動都是通過可執行文件?docker?來完成的,因此兩者的啟動流程非常相似。?Docker?可執行文件運行時,運行代碼通過不同的命令行?flag?參數,區分兩者,并最終運行兩者各自相應的部分。

    啟動?Docker Daemon?時,一般可以使用以下命令來完成

    ?

    docker --daemon = true

    docker –d

    docker –d = true

    再由?docker?的?main()?函數來解析以上命令的相應?flag?參數,并最終完成?Docker Daemon?的啟動。

    下圖可以很直觀地看到?Docker Daemon?的啟動流程:

    默認配置下,?Docker daemon?只能響應來自本地?Host?的客戶端請求。如果要允許遠程客戶端請求,需要在配置文件中打開?TCP監聽。我們可以照著如下步驟進行配置:

    1、編輯配置文件?/etc/systemd/system/multi-user.target.wants/docker.service?,在環境變量?ExecStart?后面添加?-H tcp://0.0.0.0,允許來自任意 IP 的客戶端連接。

    2、重啟?Docker daemon

    ?

    systemctl daemon-reload

    systemctl restart docker.service

    3、我們通過以下命令即可實現與遠程服務器通信

    docker -H 服務器IP地址 info

    -H?是用來指定服務器主機,?info?子命令用于查看?Docker?服務器的信息

    Docker Image

    Docker?鏡像可以看作是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建之后也不會被改變。我們可將?Docker鏡像看成只讀模板,通過它可以創建?Docker?容器。

    鏡像有多種生成方法:

  • 從無到有開始創建鏡像
  • 下載并使用別人創建好的現成的鏡像
  • 在現有鏡像上創建新的鏡像
  • 我們可以將鏡像的內容和創建步驟描述在一個文本文件中,這個文件被稱作?Dockerfile?,通過執行?docker build <docker-file>?命令可以構建出 Docker 鏡像,在后續的教程中,我們會用一篇專門討論這個問題。

    Docker Registry

    Docker registry?是存儲?docker image?的倉庫,它在?docker?生態環境中的位置如下圖所示:

    運行docker push、docker pull、docker search時,實際上是通過?docker daemon?與?docker registry?通信。

    Docker Container

    Docker?容器就是?Docker?鏡像的運行實例,是真正運行項目程序、消耗系統資源、提供服務的地方。?Docker Container?提供了系統硬件環境,我們可以使用?Docker Images?這些制作好的系統盤,再加上我們所編寫好的項目代碼,?run?一下就可以提供服務啦。

    Docker組件是如何協作運行容器

    看到這里,我相信各位讀者朋友們應該已經對Docker基礎架構已經熟悉的差不多了,我們還記得運行的第一個容器嗎?現在我們再通過hello-world這個例子來體會一下?Docker?各個組件是如何協作的。

    容器啟動過程如下:

    • Docker?客戶端執行?docker run?命令
    • Docker daemon?發現本地沒有?hello-world?鏡像
    • daemon?從?Docker Hub?下載鏡像
    • 下載完成,鏡像?hello-world?被保存到本地
    • Docker daemon?啟動容器

    具體過程可以看如下這幅演示圖:

    我們可以通過docker images?可以查看到?hello-world?已經下載到本地

    我們可以通過docker ps?或者?docker container ls?顯示正在運行的容器,我們可以看到,?hello-world?在輸出提示信息以后就會停止運行,容器自動終止,所以我們在查看的時候沒有發現有容器在運行。

    我們把?Docker?容器的工作流程剖析的十分清楚了,我們大體可以知道?Docker?組件協作運行容器可以分為以下幾個過程:

  • Docker?客戶端執行?docker run?命令
  • Docker daemon?發現本地沒有我們需要的鏡像
  • daemon?從?Docker Hub?下載鏡像
  • 下載完成后,鏡像被保存到本地
  • Docker daemon?啟動容器
  • 了解了這些過程以后,我們再來理解這些命令就不會覺得很突兀了,下面我來給大家講講?Docker?常用的一些命令操作吧。

    Docker常用命令

    我們可以通過?docker -h?去查看命令的詳細的幫助文檔。在這里我只會講一些平常日常比賽或者生活中我們可能會用的比較多的一些命令。

    例如,我們需要拉取一個?docker?鏡像,我們可以用如下命令:

    docker pull image_name

    image_name?為鏡像的名稱,而如果我們想從?Docker Hub?上去下載某個鏡像,我們可以使用以下命令:

    docker pull centos:latest

    centos:lastest?是鏡像的名稱,?Docker daemon?發現本地沒有我們需要的鏡像,會自動去?Docker Hub?上去下載鏡像,下載完成后,該鏡像被默認保存到?/var/lib/docker?目錄下。

    接著我們如果想查看下主機下存在多少鏡像,我們可以用如下命令:

    docker images

    我們要想知道當前有哪些容器在運行,我們可以用如下命令:

    docker ps -a

    -a?是查看當前所有的容器,包括未運行的

    我們該如何去對一個容器進行啟動,重啟和停止呢?我們可以用如下命令:

    ?

    docker start container_name/container_id

    docker restart container_name/container_id

    docker stop container_name/container_id

    這個時候我們如果想進入到這個容器中,我們可以使用?attach?命令:

    docker attach container_name/container_id

    那如果我們想運行這個容器中的鏡像的話,并且調用鏡像里面的?bash?,我們可以使用如下命令:

    docker run -t -i container_name/container_id /bin/bash

    那如果這個時候,我們想刪除指定鏡像的話,由于?image?被某個?container?引用(拿來運行),如果不將這個引用的?container?銷毀(刪除),那?image?肯定是不能被刪除。我們首先得先去停止這個容器:

    ?

    docker ps

    docker stop container_name/container_id

    然后我們用如下命令去刪除這個容器:

    docker rm container_name/container_id

    然后這個時候我們再去刪除這個鏡像:

    docker rmi image_name

    此時,常用的?Docker?相關的命令就講到這里為止了,我們在后續的文章中還會反復地提到這些命令。

    Dockerfile是什么

    前面我們已經提到了?Docker?的一些基本概念。以?CTF?選手的角度來看,我們可以去使用?Dockerfile?定義鏡像,依賴鏡像來運行容器,可以去模擬出一個真實的漏洞場景。因此毫無疑問的說,?Dockerfile?是鏡像和容器的關鍵,并且?Dockerfile?還可以很輕易的去定義鏡像內容,說了這么多,那么?Dockerfile?到底是個什么東西呢?

    Dockerfile?是自動構建?docker?鏡像的配置文件, 用戶可以使用?Dockerfile?快速創建自定義的鏡像。Dockerfile?中的命令非常類似于?linux?下的?shell?命令。

    我們可以通過下面這幅圖來直觀地感受下 Docker 鏡像、容器和 Dockerfile 三者之間的關系。

    我們從上圖中可以看到,?Dockerfile?可以自定義鏡像,通過?Docker?命令去運行鏡像,從而達到啟動容器的目的。

    Dockerfile?是由一行行命令語句組成,并且支持已?#?開頭的注釋行。

    一般來說,我們可以將?Dockerfile?分為四個部分:

    • 基礎鏡像(父鏡像)信息指令?FROM
    • 維護者信息指令?MAINTAINER
    • 鏡像操作指令?RUN?、?EVN?、?ADD?和?WORKDIR?等
    • 容器啟動指令?CMD?、?ENTRYPOINT?和?USER?等

    下面是一段簡單的Dockerfile的例子:

    ?

    FROM python:2.7

    MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>

    COPY . /app

    WORKDIR /app

    RUN pip install -r requirements.txt

    EXPOSE 5000

    ENTRYPOINT ["python"]

    CMD ["app.py"]

    我們可以分析一下上面這個過程:

    • 1、從?Docker Hub?上?pull?下?python 2.7?的基礎鏡像
    • 2、顯示維護者的信息
    • 3、copy?當前目錄到容器中的?/app?目錄下 復制本地主機的?<src>?(?Dockerfile?所在目錄的相對路徑)到容器里?<dest>
    • 4、指定工作路徑為?/app
    • 5、安裝依賴包
    • 6、暴露?5000?端口
    • 7、啟動?app

    這個例子是啟動一個?python flask app?的?Dockerfile?(?flask?是?python?的一個輕量的?web?框架),相信大家從這個例子中能夠稍微理解了Dockfile的組成以及指令的編寫過程。

    Dockerfile常用的指令

    根據上面的例子,我們已經差不多知道了Dockerfile的組成以及指令的編寫過程,我們再來理解一下這些常用命令就會得心應手了。

    由于?Dockerfile?中所有的命令都是以下格式:INSTRUCTION argument?,指令?(INSTRUCTION)?不分大小寫,但是推薦大寫,和sql語句是不是很相似呢?下面我們正式來講解一下這些指令集吧。

    FROM

    FROM?是用于指定基礎的?images?,一般格式為?FROM <image>?or?FORM <image>:<tag>?,所有的?Dockerfile?都用該以?FROM?開頭,FROM?命令指明?Dockerfile?所創建的鏡像文件以什么鏡像為基礎,FROM?以后的所有指令都會在?FROM?的基礎上進行創建鏡像。可以在同一個?Dockerfile?中多次使用?FROM?命令用于創建多個鏡像。比如我們要指定?python 2.7?的基礎鏡像,我們可以像如下寫法一樣:

    FROM python:2.7

    MAINTAINER

    MAINTAINER 是用于指定鏡像創建者和聯系方式,一般格式為?MAINTAINER <name>?。這里我設置成我的?ID?和郵箱:

    MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>

    COPY

    COPY?是用于復制本地主機的?<src>?(為 Dockerfile 所在目錄的相對路徑)到容器中的?<dest>。

    當使用本地目錄為源目錄時,推薦使用?COPY?。一般格式為?COPY <src><dest>?。例如我們要拷貝當前目錄到容器中的?/app?目錄下,我們可以這樣操作:

    COPY . /app

    WORKDIR

    WORKDIR?用于配合?RUN,CMD,ENTRYPOINT?命令設置當前工作路徑。可以設置多次,如果是相對路徑,則相對前一個?WORKDIR?命令。默認路徑為/。一般格式為?WORKDIR /path/to/work/dir?。例如我們設置/app?路徑,我們可以進行如下操作:

    WORKDIR /app

    RUN

    RUN?用于容器內部執行命令。每個?RUN?命令相當于在原有的鏡像基礎上添加了一個改動層,原有的鏡像不會有變化。一般格式為?RUN <command>?。例如我們要安裝?python?依賴包,我們做法如下:

    RUN pip install -r requirements.txt

    EXPOSE

    EXPOSE?命令用來指定對外開放的端口。一般格式為?EXPOSE <port> [<port>...]

    例如上面那個例子,開放5000端口:

    EXPOSE 5000

    ENTRYPOINT

    ENTRYPOINT?可以讓你的容器表現得像一個可執行程序一樣。一個?Dockerfile?中只能有一個?ENTRYPOINT,如果有多個,則最后一個生效。

    ENTRYPOINT?命令也有兩種格式:

    • ENTRYPOINT ["executable", "param1", "param2"]?:推薦使用的?exec形式
    • ENTRYPOINT command param1 param2?:shell?形式

    例如下面這個,我們要將?python?鏡像變成可執行的程序,我們可以這樣去做:

    ENTRYPOINT ["python"]

    CMD

    CMD?命令用于啟動容器時默認執行的命令,CMD?命令可以包含可執行文件,也可以不包含可執行文件。不包含可執行文件的情況下就要用?ENTRYPOINT?指定一個,然后?CMD?命令的參數就會作為ENTRYPOINT的參數。

    CMD?命令有三種格式:

    • CMD ["executable","param1","param2"]:推薦使用的?exec?形式。
    • CMD ["param1","param2"]:無可執行程序形式
    • CMD command param1 param2:shell 形式。

    一個?Dockerfile?中只能有一個CMD,如果有多個,則最后一個生效。而?CMD?的?shell?形式默認調用?/bin/sh -c?執行命令。

    CMD?命令會被?Docker?命令行傳入的參數覆蓋:docker run busybox /bin/echo Hello?Docker?會把?CMD?里的命令覆蓋。

    例如我們要啟動?/app?,我們可以用如下命令實現:

    CMD ["app.py"]

    當然還有一些其他的命令,我們在用到的時候再去一一講解一下。

    構建Dockerfile

    我們大體已經把Dockerfile的寫法講述完畢,我們可以自己動手寫一個例子:

    ?

    mkdir static_web

    cd static_web

    touch Dockerfile

    然后 vi Dockerfile 開始編輯該文件

    輸入 i 開始編輯

    ?

    以下是我們構建的Dockerfile內容

    ``````````

    FROM nginx

    MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>

    RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

    ``````````

    編輯完后 按 esc 退出編輯

    然后 :wq 寫入 退出

    我們在?Dockerfile?文件所在目錄執行:

    docker build -t angelkitty/nginx_web:v1 .

    我們解釋一下,?-t?是為新鏡像設置倉庫和名稱,其中?angelkitty?為倉庫名,?nginx_web?為鏡像名,?:v1?為標簽(不添加為默認?latest?)

    我們構建完成之后,使用?docker images?命令查看所有鏡像,如果存在?REPOSITORY?為?nginx?和?TAG?是?v1?的信息,就表示構建成功。

    接下來使用?docker run?命令來啟動容器

    docker run --name nginx_web -d -p 8080:80 angelkitty/nginx_web:v1

    這條命令會用 nginx 鏡像啟動一個容器,命名為?nginx_web?,并且映射了 8080 端口,這樣我們可以用瀏覽器去訪問這個?nginx?服務器:http://localhost:8080/?或者 http://本機的IP地址:8080/,頁面返回信息:

    這樣一個簡單使用?Dockerfile?構建鏡像,運行容器的示例就完成了!

    本文引用轉載?https://www.cnblogs.com/ECJTUACM-873284962/p/9789130.html

    總結

    以上是生活随笔為你收集整理的Docker应用学习的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。