Docker學習筆記


一、關於Docker

1、什么是Docker?

(摘自Wikipedia)

Docker 是一個開放源代碼軟件,是一個開放平台,用於開發應用、交付(shipping)應用、運行應用。 Docker允許用戶將基礎設施(Infrastructure)中的應用單獨分割出來,形成更小的顆粒(容器),從而提高交付軟件的速度。[1]

Docker容器與虛擬機類似,但二者在原理上不同。容器是將操作系統層虛擬化,虛擬機則是虛擬化硬件,因此容器更具有便攜性、高效地利用服務器。 容器更多的用於表示 軟件的一個標准化單元。由於容器的標准化,因此它可以無視基礎設施(Infrastructure)的差異,部署到任何一個地方。另外,Docker也為容器提供更強的業界的隔離兼容。[2]

Docker 利用Linux核心中的資源分離機制,例如cgroups,以及Linux核心名字空間(namespaces),來創建獨立的容器(containers)。這可以在單一Linux實體下運作,避免啟動一個虛擬機造成的額外負擔[3]。Linux核心對名字空間的支持完全隔離了工作環境中應用程序的視野,包括行程樹、網絡、用戶ID與掛載文件系統,而核心的cgroup提供資源隔離,包括CPU存儲器、block I/O與網絡。從0.9版本起,Dockers在使用抽象虛擬是經由libvirtLXC與systemd - nspawn提供界面的基礎上,開始包括libcontainer庫做為以自己的方式開始直接使用由Linux核心提供的虛擬化的設施,

依據行業分析公司“451研究”:“Dockers是有能力打包應用程序及其虛擬容器,可以在任何Linux服務器上執行的依賴性工具,這有助於實現靈活性和便攜性,應用程序在任何地方都可以執行,無論是公用雲端服務器私有雲端服務器、單機等。” [4]

2、為什么使用Docker?

更高效的利用系統資源
  由於容器不需要進行硬件虛擬以及運行完整操作系統等額外開銷,Docker 對系統資源的利用率更高。無論是應用執行速度、內存損耗或者文件存儲速度,都要比傳統虛擬機技術更高效。因此,相比虛擬機技術,一個相同配置的主機,往往可以運行更多數量的應用。
更快速的啟動時間
  傳統的虛擬機技術啟動應用服務往往需要數分鍾,而 Docker 容器應用,由於直接運行於宿主內核,無需啟動完整的操作系統,因此可以做到秒級、甚至毫秒級的啟動時間。大大的節約了開發、測試、部署的時間。
一致的運行環境
  開發過程中一個常見的問題是環境一致性問題。由於開發環境、測試環境、生產環境不一致,導致有些 bug 並未在開發過程中被發現。而 Docker 的鏡像提供了除內核外完整的運行時環境,確保了應用運行環境一致性,從而不會再出現 「這段代碼在我機器上沒問題啊」 這類問題。
持續交付和部署
  對開發和運維(DevOps)人員來說,最希望的就是一次創建或配置,可以在任意地方正常運行。
使用 Docker 可以通過定制應用鏡像來實現持續集成、持續交付、部署。開發人員可以通過 Dockerfile 來進行鏡像構建,並結合 持續集成(Continuous Integration) 系統進行集成測試,而運維人員則可以直接在生產環境中快速部署該鏡像,甚至結合 持續部署(Continuous Delivery/Deployment) 系統進行自動部署。
而且使用 Dockerfile 使鏡像構建透明化,不僅僅開發團隊可以理解應用運行環境,也方便運維團隊理解應用運行所需條件,幫助更好的生產環境中部署該鏡像。
更輕松的遷移
  由於 Docker 確保了執行環境的一致性,使得應用的遷移更加容易。Docker 可以在很多平台上運行,無論是物理機、虛擬機、公有雲、私有雲,甚至是筆記本,其運行結果是一致的。因此用戶可以很輕易的將在一個平台上運行的應用,遷移到另一個平台上,而不用擔心運行環境的變化導致應用無法正常運行的情況。
更輕松的維護和擴展
  Docker 使用的分層存儲以及鏡像的技術,使得應用重復部分的復用更為容易,也使得應用的維護更新更加簡單,基於基礎鏡像進一步擴展鏡像也變得非常簡單。此外,Docker 團隊同各個開源項目團隊一起維護了一大批高質量的 官方鏡像,既可以直接在生產環境使用,又可以作為基礎進一步定制,大大的降低了應用服務的鏡像制作成本。

3、與傳統虛擬機的對比

二、Docker的安裝

Linux:

在未安裝過Docker的機器上,root權限執行如下命令即可一鍵安裝最新版Docker:

curl -s https://get.docker.com/ | sh 

如果已經安裝過老版本Docker(且不是用這個一鍵安裝腳本安裝的),請先卸載Docker:

相關命令例如:

sudo apt purge --autoremove docker.io

如果不想使用這種方式安裝Docker,也可以使用系統自帶的包管理工具來安裝,比如在Ubuntu下:

sudo apt install docker.io

但包管理工具安裝的Docker版本一般較老。

輸入以下命令檢驗是否安裝成功:

docker info
docker version

此外,Docker 需要用戶具有 sudo 權限,為了避免每次命令都輸入sudo,可以把用戶加入 Docker 用戶組:

sudo usermod -aG docker $USER

Docker 是服務器----客戶端架構。命令行運行docker命令的時候,需要本機有 Docker 服務。如果這項服務沒有啟動,可以用下面的命令啟動。

# service 命令的用法
$ sudo service docker start
# 設置開機自動啟動
$ sudo systemctl enable docker

如果使用一鍵安裝工具安裝的docker,則docker會自動啟動。

Windows:

進入官網下載即可:

https://www.docker.com/products/docker-desktop

安裝完成后的圖形化界面:

 利用Ubuntu20.04 LTS檢驗安裝結果:

三、鏡像

1、概述

Docker鏡像(Image)類似於虛擬機鏡像,可以理解為一個面向Docker引擎的只讀模板,包含了文件系統。
例如,一個鏡像可以包含一個完整的 Ubuntu 操作系統環境,可以理解為一個Ubuntu鏡像。
image 是二進制文件。實際開發中,一個 image 文件往往通過繼承另一個 image 文件,加上一些個性化設置而生成。舉例來說,你可以在 Ubuntu 的 image 基礎上,往里面加入 Apache 服務器,形成你的 image。
Docker運行容器前需要本地存在對應的鏡像,如果不存在本地,Docker會先嘗試從默認鏡像倉庫下載(默認使用Docker Hub公共注冊服務器中的倉庫),用戶也可以通過配置,使用自定義的鏡像倉庫。

2、獲取鏡像

鏡像是Docker運行容器的前提。

使用docker pull命令從網絡上下載鏡像。

命令格式:

docker pull NAME[:TAG]

如果不顯式地指定TAG,則默認選擇latest標簽,即下在倉庫中最新版本的鏡像。

示例:

從Docker Hub的 Ubuntu 倉庫下載一個最新的Ubuntu操作系統的鏡像:

docker pull ubuntu
docker pull ubuntu:14.04

也可以選在從其他注冊服務器的倉庫下載。此時需要在倉庫名稱前指定完整的倉庫注冊服務器地址:

docker pull xxx.com:port/ubuntu

3、查看鏡像信息

使用docker images 命令可以列出本地主機上已有的鏡像

命令:

docker images

圖中的字段信息:

  • REPOSITORY:來自於哪個倉庫,比如ubuntu倉庫;
  • TAG:鏡像的標簽信息,比如latest;
  • IMAGE ID:鏡像的ID(唯一);
  • CREATED:創建時間;
  • SIZE:鏡像大小

使用docker tag 命令可以為本地鏡像添加新的標簽:

docker tag ubuntu:14.04 ubuntu:xiaojian

不難發現,不同標簽的鏡像的ID是完全一致的,說明它們實際上指向了同一個鏡像文件,只是別名不一樣。標簽可以理解為起到了引用或快捷方式的作用。

使用docker inspect命令可以獲取該鏡像的詳細信息:

docker inspect

docker inspect 命令返回的是一個JSON格式的下次,如果只需要查看其中一項內容,可以使用 -f 參數進行指定:

例如:獲取鏡像的Architecture信息:

 命令:

docker inspect -f {{".Architecture"}}  13b66

4、搜尋鏡像

使用docker search 命令可以搜索遠端倉庫中共享的鏡像,默認搜索Docker Hub官方倉庫中的鏡像。

命令:

docker search TERM

參數如下:

  • -- automated=false:僅顯示自動創建的鏡像;
  • -- no-trunc=false:輸出信息不截斷顯示;
  • -s, --stars=0:指定僅顯示評價為指定星級以上的鏡像;

例如,搜索帶有 mysql 關鍵字的鏡像:

返回信息中包括鏡像名字,描述,星級,是否官方創建,是否自動創建等字段信息。

默認的輸出結果將按照星級評價進行排序。

官方的鏡像說明是官方項目組創建和維護的,automated資源則允許用戶驗證鏡像的來源和內容。

5、刪除鏡像

命令:

docker rmi IMAGE [IMAGE...]
# IMAGE可以為標簽或ID

示例1:刪除 TAG 為 14.04 的鏡像:

docker rmi ubuntu

示例2:使用鏡像ID刪除鏡像:

當使用docker rmi 命令 + 鏡像ID時,會先嘗試刪除所有指向該鏡像的標簽,然后刪除該鏡像文件本身。

當有該鏡像創建的容器存在時,鏡像文件默認是無法刪除的,例如:

先利用 ubuntu 鏡像創建一個簡單的容器,輸出典中典的一句話“Hello World!”:

docker run ubuntu:14.04 echo 'Hello, World!'

使用docker ps -a 命令查看本機上存在的所有容器:

docker ps -a

此時則不允許刪除該鏡像。

若要強制刪除,可以使用 -f 參數:

在此之前如果沒有刪除該鏡像下的容器,則會導師查看本地鏡像列表時,出現一個標簽為<none>的臨時鏡像,原來被強制刪除的鏡像換成了新的ID繼續存在系統中。

6、創建鏡像

創建鏡像的方法

  1. 基於已有鏡像的容器創建;
  2. 基於本地模板導入;
  3. 基於Dockerfile創建;

此處介紹前兩種,第三種篇幅過長,后續將詳細介紹。

基於已有鏡像的容器創建

命令:

docker commit [OPTIONS] CONTAINER [REPOSTTORY[:TAG]]

參數:

  • -a, --author="":作者信息;
  • -m, --message="":提交消息;
  • -p, --pause=true:提交時暫停容器運行;

示例:

  首先啟動一個鏡像,並在其中進行修改,例如創建一個test文件,之后退出:

docker run -ti ubuntu:14.04 /bin/bash touch test exit

該容器ID為 d338e2f51b50。

此時該容器與原來的ubuntu:14.04鏡像相比,已經發生了改變,使用docker commit 命令提交提交為一個新的鏡像。提交時可以使用ID或名稱來指定容器:

docker commit -m "南風知我意,吹夢到西洲" -a "s1mpl3" d338e2f51b50 test

成功創建的話會返回新的鏡像的ID信息:

查看本地鏡像列表:

基於本地模板導入

比如使用OpenVZ提供的模板,

https://download.openvz.org/template/precreated/

命令:

cat ubuntu-14.04-x86_64-minamal.tar.gz | docker import -ubuntu:14.04

7、存出鏡像

命令:

docker save

示例:存出本地的ubuntu:14.04 鏡像為文件ubuntu_14.04.gz

docker save -o ubuntu_14.04.tar ubuntu:14.04

8、載入鏡像

命令:

docker load

從存出的本地文件中再導入本地鏡像庫。

示例:從ubuntu_14.04.tar 導入鏡像到本地鏡像列表

docker load --input ubuntu_14.04.tar 或 docker load < ubuntu_14.04.tar

四、容器

1、概念

  容器是鏡像的一個運行實例。不同之處在於,它帶有額外的可寫文件層。

  鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的 實例 一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等。

  容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行於屬於自己的獨立的 命名空間。因此容器可以擁有自己的 root 文件系統、自己的網絡配置、自己的進程空間,甚至自己的用戶 ID 空間。容器內的進程是運行在一個隔離的環境里,使用起來,就好像是在一個獨立於宿主的系統下操作一樣。這種特性使得容器封裝的應用比直接在宿主運行更加安全。也因為這種隔離的特性,很多人初學 Docker 時常常會混淆容器和虛擬機。

2、創建容器

(1)新建容器

命令:

docker create

示例:

docker create -it ubuntu:latest

 使用該命令新建的容器處於停止狀態,使用docker start 命令啟動。

(2)新建並啟動容器

  啟動容器的方式有兩種:

  • 基於鏡像新建一個容器並啟動;
  • 將在終止態(stopped)的容器重新啟動;

命令:

docker run # 等價於1.docker create 2.docker start

示例:以下命令輸出一個“Hello World”,之后容器自動終止:

docker run ubuntu:14.04 /bin/echo 'Hello World'

  當利用 docker run 進行創建並啟動容器時,Docker在后台運行的標准操作如下:

  • 檢查本地是否存在指定的鏡像,若不存在就從公有倉庫下載;
  • 利用鏡像創建並啟動一個容器;
  • 分配一個文件系統,並在只讀的鏡像層外面掛載一層可讀寫層;
  • 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去;
  • 從地址池配置一個IP地址給容器;
  • 執行用戶指定的應用程序;
  • 執行完畢后容器被終止。

以下命令啟動一個bash終端,允許用戶進行交互:

docker run -ti ubuntu:14.04 /bin/bash

其中,-t 選項允許Docker分配一個偽終端(pseudo-tty)並綁定容器的標准輸入上;

   -i 選項則允許容器的標准輸入保持打開。

  輸入 exit 或 Ctrl+d 退出容器,退出之后,該容器就自動處於終止狀態。(即當運行的應用退出之后,容器就沒有運行的必要了)

3、終止容器

命令:

docker stop [-t | --time[ =10 ]]

該命令首先向容器發送SIGTERM信號,等待一段時間后(默認為10s),再發送SIGKILL信號終止容器。

注:docker kill 命令會直接發送SIGKILL信號來強行終止容器。

  使用docker ps -a -q 命令查看處於終止狀態的容器的ID信息:

   處於終止狀態的容器,通過docker start 命令重啟:

   使用docker restart 命令將一個運行態的容器終止,然后重啟:

4、進入容器

attach命令

docker attach 是Docker自帶的命令。

但當多個窗口同時attach 到同一個容器的時候,所有的窗口都會同步顯示。當某個窗口1因命令阻塞時,其他窗口也就無法執行操作了。

示例:

docker attach tender_mestorf

exec命令

  exec工具可以直接在容器內運行命令。

示例:

命令:

docker exec -ti c9ce /bin/bash

5、刪除容器

命令:

docker rm [OPTIONS] CONTAINER [CONTAINER...]

參數:

  • -f, --forece=false:強行終止並刪除一個運行中的容器;
  • -l, --link=false:刪除容器的連接,但保留容器;
  • -v, --volumes=false:刪除容器掛在的數據卷。

示例:

查看處於終止狀態的容器並刪除某容器:

6、導出容器

  導出容器是指導出一個已經創建的容器到一個文件,無論此時是否處於運行狀態,都可以使用 docker export 命令。

命令:

docker export CONTAINER

示例:

7、導入容器

命令:

docker import - image_name

示例:

注:

既可以使用 docker load 命令來導入鏡像存儲文件到本地的鏡像庫,又可以使用 docker import 命令來導入一個容器的快照到本地鏡像庫。

二者的區別:

  • 容器快照文件將丟棄所有的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也更大;
  • 從容器快照文件導入時可以重新指定標簽等元數據信息。

五、倉庫

1、概述

  倉庫(Repository)是集中存放鏡像的地方。

  容易與之混淆的概念是注冊服務器(Registry)。注冊服務器是存放倉庫的具體服務器,每個服務器上可以有多個倉庫,而每個倉庫下面有多個鏡像。可以說,倉庫被認為是一個具體的項目或目錄

  倉庫又分公共倉庫和私有倉庫。

  倉庫包括鏡像存儲系統和賬戶管理系統。前者通過 Docker 倉庫注冊服務(Registry)實現;而一個有實用價值的倉庫(如Docker Hub)都會有完善的賬戶管理系統。

  使用者注冊成為用戶之后,可以通過Login 命令登錄到倉庫服務,命令如下:

docker login -u <username> -p <password> -e <email> <registry domain>

2、上傳鏡像

命令:

docker push IMAGES

六、Vulhub靶場搭建

1、安裝Docker-compose

命令:

pip install -U docker-compose

查看版本:

docker-compose --version

 

 

2、下載Vulhub

命令:

git clone https://github.com/vulhub/vulhub.git

 

3、啟動靶場環境

進入vulhub選擇要復現的漏洞,如/flask/ssti:

對靶場進行編譯:

docker-compose build

注:

該命令是可選的

docker-compose up -d運行后,會自動查找當前目錄下的配置文件。

如果配置文件中包含的環境均已經存在,則不會再次編譯;如果配置文件中包含的環境不存在,則會自動進行編譯。

所以,其實docker-compose up -d命令是包含了docker-compose build的。

如果更新了配置文件,你可以手工執行docker-compose build來重新編譯靶場環境。

運行靶場:

docker-compose up -d

 

 

4、查看Docker容器的IP

命令:

docker ps

ifconfig

 

 

5、訪問

172.17.0.1:8000即可

如果要在物理機訪問,需要對路由進行配置。

七、參考

https://docs.docker.com/

https://vulhub.org/#/docs/install-docker-one-click/

https://yeasy.gitbook.io/docker_practice/

https://segmentfault.com/a/1190000038361706#item-5

https://www.ruanyifeng.com/blog/2018/02/docker-tutorial.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM