Docker學習筆記

image.png

Docker 誕生的背景

主機時代比拼的是單個服務器物理性能(如CPU主頻和內存)的強弱,那麼在雲時代,最爲看重的則是憑藉虛擬化技術所構建的集羣處理能力。 虛擬化的概念早已經普遍應用到各類關鍵場景中。從20世紀60年代IBM推出的大型主機虛擬化,到後來以Xen、KVM爲表明的虛擬機虛擬化,再到如今以Docker爲表明的容器技術,虛擬化技術自身也在不斷進行創新和突破。 虛擬化既能夠經過硬件模擬來實現,也能夠經過操做系統軟件來實現。而容器技術則更爲優雅,它充分利用了操做系統自己已有的機制和特性,能夠實現遠超傳統虛擬機的輕量級虛擬化。所以,有人甚至把它稱爲「新一代的虛擬化」技術,並將基於容器打造的雲平臺親切地稱爲「容器雲」,Docker正是衆多容器技術中的佼佼者python

初始Docker容器

Docker是基於Go語言實現的開源容器項目。它誕生於2013年年初,最初發起者是dotCloud公司(如今已經改成Docker )。Docker項目已加入Linux基金會,並遵循Apache 2.0協議。mysql

Linux容器技術

與大部分新興技術的誕生同樣,Docker也並不是「從石頭縫裏蹦出來的」,而是站在前人的肩膀上,就是Linux容器(Linux Containers, LXC)技術。IBM 開發者網站關於容器技術的描述十分準確:「容器有效地將由單個操做系統管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有衝突的資源使用需求。與虛擬化相比,這樣既不須要指令級模擬,也不須要即時編譯。容器能夠在覈心CPU本地運行指令,而不須要任何專門的解釋機制。此外,也避免了準虛擬化(para-virtualization)和系統調用替換中的複雜性。LXC也經歷了長期的演化,最先能夠追溯到1982年Unix系列操做系統上的chroot工具。linux

從Linux容器到Docker

在LXC的基礎上,Docker進一步優化了容器的使用體驗,首先,Docker提供了各類容器管理工具(如分發、版本、移植等),讓用戶無須關注底層的操做,更加簡單明瞭地管理和使用容器;其次,Docker經過引入分層文件系統構建和高效的鏡像機制,下降了遷移難度,極大地改善了用戶體驗。用戶操做Docker容器就像操做應用自身同樣簡單。 早期的Docker代碼實現是直接基於LXC的。自0.9版本開始,Docker開發了libcon-tainer項目做爲更普遍的容器驅動實現,從而替換掉了LXC的實現。目前,Docker還積極推進成立了runC標準項目,並貢獻給開放容器聯盟,試圖讓容器的支持再也不侷限於Linux操做系統,而是更安全、更開放、更具擴展性。簡單地講。 Docker容器理解爲一種輕量級的沙盒(sandbox)。每一個容器內運行着一個或多個應用,不一樣的容器相互隔離,容器之間也能夠經過網絡互相通訊。容器的建立和中止十分快速,幾乎跟建立和終止原生應用一致;另外,容器自身對系統資源的額外需求也十分有限,遠遠低於傳統虛擬機。不少時候,甚至直接把容器看成應用自己也沒有任何問題。nginx

Docker的目標

Docker的構想是要實現「Build, Ship and Run Any App, Anywhere」,即經過對應用的封裝(Packaging)、分發(Distribution)、部署(Deployment)、運行(Runtime)全生命週期進行管理,達到應用組件級別的「一次封裝,處處運行」。這裏的應用組件,既能夠是一個Web應用、一個編譯環境,也能夠是一套數據庫平臺服務,甚至是一個操做系統或集羣。c++

Docker引擎的認識

Docker 引擎由以下主要的組件構成: Docker 客戶端(Docker Client) Docker 守護進程(Docker daemon) containerd 以及 runc。它們共同負責容器的建立和運行 最新的架構示意圖:git

image.png

核心概念與安裝配置

介紹Docker的三大核心概念:❑ 鏡像(Image)❑ 容器(Container)❑ 倉庫(Repository)只有理解了這三個核心概念,才能順利地理解Docker容器的整個生命週期。web

鏡像

Docker鏡像相似於虛擬機鏡像,能夠將它理解爲一個只讀的模板。例如,一個鏡像能夠包含一個基本的操做系統環境,裏面僅安裝了Apache應用程序(或用戶須要的其餘軟件)。能夠把它稱爲一個Apache鏡像。鏡像是建立Docker容器的基礎。經過版本管理和增量的文件系統,Docker提供了一套十分簡單的機制來建立和更新現有的鏡像,用戶甚至能夠從網上下載一個已經作好的應用鏡像,並直接使用。鏡像能夠理解成源代碼。sql

容器

Docker容器相似於一個輕量級的沙箱,Docker利用容器來運行和隔離應用。容器是從鏡像建立的應用運行實例。它能夠啓動、開始、中止、刪除,而這些容器都是彼此相互隔離、互不可見的。能夠把容器看做一個簡易版的Linux系統環境(包括root用戶權限、進程空間、用戶空間和網絡空間等)以及運行在其中的應用程序打包而成的盒子。容器能夠理解成從鏡像編譯運行的應用程序。docker

倉庫

鏡像倉庫,則是指存放鏡像文件的地方,能夠理解成源代碼倉庫,列如GitHub,或者GitLab。 每一個倉庫集中存放某一類鏡像,每每包括多個鏡像文件,經過不一樣的標籤(tag)來進行區分。例如存放Ubuntu操做系統鏡像的倉庫,被稱爲Ubuntu倉庫,其中可能包括16.0四、18.04等不一樣版本的鏡像。 目前,最大的公開倉庫是官方提供的Docker Hub,其中存放着數量龐大的鏡像供用戶下載。國內很多雲服務提供商阿里雲倉庫也提供了倉庫的本地源,能夠提供穩定的國內訪問。shell

Docker的安裝

Docker引擎目前分爲兩個版本:社區版本(Community Edition, CE)和企業版本(Enterprise Edition, EE對於windows和 Mac 版本的Docker 都是社區提供的,在生產環境中不建議使用。因此重點學習在其Linux系統的上面的使用,以centos8爲例安裝學習:

#!/bin/bash
echo -e  '卸載舊版本的docker'
yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
echo -e '安裝經常使用軟件包'
yum install yum-utils device-mapper-persistent-data lvm2 -y
echo -e '添加 阿里Docker源'
yum-config-manager  --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
echo '更新並安裝Docker-CE'
sudo yum makecache fast
echo -e '安裝docker-ce'
yum install -y docker-ce docker-ce-cli containerd.io
echo -e '設置Docker開機自啓動'
systemctl enable docker
echo -e '啓動docker'
systemctl start docker
echo -e '查看docker版本'
docker --version
echo -e '給docker換阿里源'
cat <<EOF > /etc/docker/daemon.json
{
"registry-mirrors": ["https://fl791z1h.mirror.aliyuncs.com"]
}
EOF
echo -e '重啓docker服務'
systemctl restart docker

echo -e '查看docker信息'
docker info
exit
複製代碼

安裝過程出現的可能出現的問題排查: 因爲最新的docker 依賴的container 的版本變化引發的安裝問題

[root@localhost ~]# yum -y install docker-ce
上次元數據過時檢查:0:00:32 前,執行於 2021年01月07日 星期四 08時07分56秒。
錯誤:
 問題: package docker-ce-3:20.10.2-3.el7.x86_64 requires containerd.io >= 1.4.1, but none of the providers can be installed
  - cannot install the best candidate for the job
  - package containerd.io-1.4.3-3.1.el7.x86_64 is filtered out by modular filtering
 # 出現上面的錯誤信息的時候 ,打開下面的連接 找到對應的 centos 版本,而後點進去找到繼續找 下圖所
https://mirrors.aliyun.com/docker-ce/linux/centos/

wget https://mirrors.aliyun.com/docker-ce/linux/centos/8/x86_64/stable/Packages/containerd.io-1.4.3-3.1.el8.x86_64.rpm

yum install containerd.io-1.4.3-3.1.el8.x86_64.rpm
 # 在繼續
yum -y install docker-ce 
複製代碼

image.png

鏡像 image

docker image pull 或者 docker pull

鏡像是運行容器的前提,可使用docker [image] pull命令直接從Docker Hub鏡像源來下載鏡像。該命令的格式爲 docker [image] pull NAME[:TAG] NAME是鏡像倉庫名稱(用來區分鏡像), TAG是鏡像的標籤(每每用來表示版本信息)。一般狀況下,描述一個鏡像須要包括「名稱+標籤」信息

[root@localhost ~]# docker pull centos   獲取一個鏡像,不加 tag 標籤的時候 默認拉去的 tag是latest
Using default tag: latest
latest: Pulling from library/centos
7a0437f04f83: Pull complete
Digest: sha256:5528e8b1b1719d34604c87e11dcd1c0a20bedf46e83b5632cdeac91b8c04efc1
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
複製代碼

下載過程當中能夠看出,鏡像文件通常由若干層(layer)組成,7a0437f04f83這樣的串是層的惟一id(實際上完整的id包括256比特,64個十六進制字符組成)。使用docker pull命令下載中會獲取並輸出鏡像的各層信息。當不一樣的鏡像包括相同的層時,本地僅存儲了層的一分內容,減少了存儲空間

docker images命令能夠列出本地主機上已有鏡像的基本信息

[root@localhost ~]# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
nginx                 latest    ae2feff98a0c   3 weeks ago     133MB
centos                latest    300e315adb2f   4 weeks ago     209MB
portainer/portainer   latest    62771b0b9b09   5 months ago    79.1MB
複製代碼

能夠看到幾個字段信息: ❑ 來自於哪一個倉庫,好比centos表示centos系列的基礎鏡像; ❑ 鏡像的標籤信息,好比latest表示不一樣的版本信息。標籤只是標記,並不能標識鏡像內容; ❑ 鏡像的ID(惟一標識鏡像),若是兩個鏡像的ID相同,說明它們實際上指向了同一個鏡像,只是具備不一樣標籤名稱而已; ❑ 建立時間,說明鏡像最後的更新時間; ❑ 鏡像大小,優秀的鏡像每每體積都較小

docker[image]inspect 鏡像名稱/鏡像ID 命令能夠獲取該鏡像的詳細信息,包括製做者、適應架構、各層的數字摘要等

docker history 鏡像名稱/鏡像ID命令查看鏡像歷史

docker search 鏡像名稱 命令能夠搜索Docker Hub官方倉庫中的鏡像

docker rmi 鏡像名稱/鏡像ID docker image rm 鏡像名稱/鏡像ID命令刪除鏡像

docker image prune命令來進行清理鏡像

使用Docker一段時間後,系統中可能會遺留一些臨時的鏡像文件,以及一些沒有被使用的鏡像可使用上述的命令清理掉 支持選項包括: ❑ -a, -all:刪除全部無用鏡像,不光是臨時鏡像 ❑ -filter filter:只清理符合給定過濾器的鏡像 ❑ -f, -force:強制刪除鏡像,而不進行提示確認

docker [container] commit 命令基於已有容器建立鏡像

命令格式爲 docker [container] commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 主要選項包括:OPTIONS ❑ -a, --author="":做者信息 ❑ -c, --change=[]:提交的時候執行Dockerfile指令,包括CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等 ❑ -m, --message="":提交消息 ❑ -p, --pause=true:提交時暫停容器運行

docker [container] import 從模板文件導入一個鏡像

命令格式爲 docker [image] import [OPTIONS]file|URL|-[REPOSITORY [:TAG]]

基於Dockerfile建立鏡像

docker [image] save 導出鏡像到本地文件

該命令支持-o、-output string參數,導出鏡像到指定的文件中,就能夠經過複製處處的文件給別人使用

// 保存當前的centos 鏡像爲centos_letest.tar 文件
docker save -o centon_letest.tar centos:latest  

複製代碼

docker [image] load將導出的tar文件再導入到本地鏡像庫

支持-i、-input string選項,從指定文件中讀入鏡像內容

docker load -i centon_letest.tar
複製代碼

docker [image] push 命令上傳鏡像到倉庫

默認上傳到Docker Hub官方倉庫,相似 git push

容器 container

容器是Docker的另外一個核心概念。簡單來講,容器是鏡像的一個運行實例。所不一樣的是,鏡像是靜態的只讀文件,而容器帶有運行時須要的可寫文件層,同時,容器中的應用進程處於運行狀態。

建立容器

docker [container] create命令新建一個容器

使用docker [container] create命令新建的容器處於中止狀態,可使用 docker[container] start命令來啓動它。

[root@localhost ~]# docker create -it centos:latest
27a89a80a2cb4e5c5fe0e24ef86cb2dac451219beeee3f11ac916fe2143f369a
複製代碼

docker [container] start啓動容器

[root@localhost ~]# docker start 27a89a80a2c
27a89a80a2c
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS      NAMES
27a89a80a2cb   centos:latest         "/bin/bash"              6 minutes ago   Up 4 seconds              objective_lederberg
複製代碼

docker [container] run 新建並啓動容器

等價於先執行docker [container]create命令,再執行docker [container] start命令 當利用docker [container] run來建立並啓動容器時,Docker在後臺運行的標準操做包括: ❑ 檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載 ❑ 利用鏡像建立一個容器,並啓動該容器 ❑ 分配一個文件系統給容器,並在只讀的鏡像層外面掛載一層可讀寫層 ❑ 從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中去 ❑ 從網橋的地址池配置一個IP地址給容器 ❑ 執行用戶指定的應用程序 ❑ 執行完畢後容器被自動終止

[root@localhost ~]# docker run -it --name centos-test  centos:latest /bin/bash
[root@d078291e042a /]#
複製代碼

經常使用選項

  • -t選項讓Docker分配一個僞終端(pseudo-tty)並綁定到容器的標準輸入上,
  • -i則讓容器的標準輸入保持打開
  • --name 給這個啓動的容器起一個名稱
  • -d 須要讓Docker容器在後臺以守護態(Daemonized)形式運行
  • 更多的命令選項能夠經過 docker run --help命令來查看

docker [container] logs 查看容器輸出日誌

中止容器

docker [container] pause 命令來暫停一個運行中的容器

處於paused狀態的容器,可使用docker [container] unpause CONTAINER[CONTAINER...]命令來恢復到運行狀態

docker [container] unpause命令來恢復到運行狀態

docker [container] stop來終止一個運行中的容器

該命令會首先向容器發送SIGTERM信號,等待一段超時時間後(默認爲10秒),再發送SIGKILL信號來終止容器,處於終止狀態的容器,能夠經過docker [container] start命令來從新啓動

docker [container] kill直接發送SIGKILL信號來強行終止容器

docker [container] restart命令會將一個運行態的容器先終止,而後再從新啓動

進入容器

docker [container] attach 鏈接到正在運行中的容器

docker [container] exec 更加方便的工具exec命令,能夠在運行中容器內直接執行任意命令

docker exec -it 容器名稱/容器ID /bin/bash
複製代碼

刪除容器

docker [container] rm命令來刪除處於終止或退出狀態的容器

主要支持的選項包括:
❑ -f, --force=false:是否強行終止並刪除一個運行中的容器
❑ -l, --link=false:刪除容器的鏈接,但保留容器
❑ -v, --volumes=false:刪除容器掛載的數據卷

導入和導出容器

docker [container] export

導出容器是指,導出一個已經建立的容器到一個文件,無論此時這個容器是否處於運行狀態

docker export -o export_centos.tar 容器ID/容器名稱
// -o 導出的文件名
複製代碼

docker [container] import命令導入變成鏡像

docker container inspect 查看容器詳情

docker [container] top 查看容器內進程

docker [container] stats 查看統計信息

docker [container] cp 命令支持在容器和主機之間複製文件

本地的路徑data複製到test容器的/tmp路徑下 docker cp data test:/tmp

docker [container] diff 查看容器內文件系統的變動

docker [container] port 命令能夠查看容器的端口映射狀況

docker [container] update 命令能夠更新容器的一些運行時配置,主要是一些資源限制份額

支持的選項包括:
❑ -blkio-weight uint16:更新塊IO限制,10~1000,默認值爲0,表明着無限制
❑ -cpu-period int:限制CPU調度器CFS(Completely Fair Scheduler)使用時間,單位爲微秒,最小1000
❑ -cpu-quota int:限制CPU調度器CFS配額,單位爲微秒,最小1000
❑ -cpu-rt-period int:限制CPU調度器的實時週期,單位爲微秒
❑ -cpu-rt-runtime int:限制CPU調度器的實時運行時,單位爲微秒
❑ -c, -cpu-shares int:限制CPU使用份額;
❑ -cpus decimal:限制CPU個數;
❑ -cpuset-cpus string:容許使用的CPU核,如0-3,0,1
❑ -cpuset-mems string:容許使用的內存塊,如0-3,0,1
❑ -kernel-memory bytes:限制使用的內核內存;
❑ -m, -memory bytes:限制使用的內存
❑ -memory-reservation bytes:內存軟限制
❑ -memory-swap bytes:內存加上緩存區的限制,-1表示爲對緩衝區無限制
❑ -restart string:容器退出後的重啓策略

Docker數據管理

在生產環境中使用Docker,每每須要對數據進行持久化,或者須要在多個容器之間進行數據共享,這必然涉及容器的數據管理操做。 容器中的管理數據主要有兩種方式: ❑ 數據卷(Data Volumes):容器內數據直接映射到本地主機環境; ❑ 數據卷容器(Data Volume Containers):使用特定容器維護數據卷。 首先介紹如何在容器內建立數據卷,而且把本地的目錄或文件掛載到容器內的數據卷中。其次介紹如何使用數據卷容器在容器和主機、容器和容器之間共享數據,並實現數據的備份和恢復。

數據卷

數據卷(Data Volumes)是一個可供容器使用的特殊目錄,它將主機操做系統目錄直接映射進容器,相似於Linux中的mount行爲 數據卷能夠提供不少有用的特性: ❑ 數據卷能夠在容器之間共享和重用,容器間傳遞數據將變得高效與方便 ❑ 對數據卷內數據的修改會立馬生效,不管是容器內操做仍是本地操做 ❑ 對數據卷的更新不會影響鏡像,解耦開應用和數據 ❑ 卷會一直存在,直到沒有容器使用,能夠安全地卸載它

建立數據卷

docker volume create 建立數據卷

Docker提供了volume子命令來管理數據卷,以下命令能夠快速在本地建立一個數據卷:

docker volume create -d local test-vol 建立一個本地的數據卷
// 
/var/lib/docker/volumes路徑下,會發現所建立的數據卷 test-vol
複製代碼

docker volume inspect(查看詳細信息)

[root@localhost volumes]# docker volume inspect test-vol
[
    {
        "CreatedAt": "2021-01-07T16:36:32-05:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
        "Name": "test-vol",
        "Options": {},
        "Scope": "local"
    }
]
複製代碼

docker volume ``ls 列出已有數據卷

docker volume prune 清理無用數據卷

docker volume rm 刪除數據卷

綁定數據卷

除了使用volume子命令來管理數據卷外,還能夠在建立容器時將主機本地的任意路徑掛載到容器內做爲數據卷,這種形式建立的數據卷稱爲綁定數據卷 docker [container] run命令的時候,可使用 -mount 選項來使用數據卷。
-mount type選項支持三種類型的數據卷,包括:
❑ volume:普通數據卷,映射到主機/var/lib/docker/volumes路徑下;
❑ bind:綁定數據卷,映射到主機指定路徑下;
❑ tmpfs:臨時數據卷,只存在於內存中

source:主機目錄路徑
destination:容器目錄路徑

type=bind,source=/path/on/host,destination=/path/in/container

type=volume,source=my-volume,destination=/path/in/container,volume-label="color=red",volume-label="shape=round"

type=tmpfs,tmpfs-size=512M,destination=/path/in/container
複製代碼
docker run -itd --name centos-test --mount type=bind,source=/www,destination=/cen_www centos:latest
// 上面的命令至關下面
docker run -itd --name centos-test  -v /www:/cen_www centos:latest
複製代碼

Docker掛載數據卷的默認權限是讀寫(rw),用戶也能夠經過ro指定爲只讀:

docker run -itd --name centos-test  -v /www:/cen_www:ro centos:latest
複製代碼

數據卷容器

若是須要在多個容器之間共享一些持續更新的數據,最簡單的方式是使用數據卷容器。數據卷容器也是一個容器,可是它的目的是專門提供數據卷給其餘容器掛載 首先,建立一個數據卷容器dbcontainer,並在其中建立一個數據卷掛載到/dbcontainer, 而後,能夠在其餘容器中使用 --volumes-from 來掛載dbcontainer容器中的數據卷,例如建立db1和db2兩個容器,並從dbcontainer容器掛載數據卷:

docker run -itd --name dbcontainer -v /db_host:/dbdata centos:latest
docker run -itd --name db1  --volumes-from   dbcontainer centos:latest
docker run -itd --name  db2  --volumes-from  dbcontainer centos:latest
複製代碼

此時,容器db1和db2都掛載同一個數據捲到相同的/dbdata目錄,三個容器任何一方在該目錄下的寫入,其餘容器均可以看到 能夠屢次使用 --volumes-from 參數來從多個容器掛載多個數據卷,還能夠從其餘已經掛載了容器卷的容器來掛載數據卷

端口映射與容器互聯

Docker除了經過網絡訪問外,還提供了兩個很方便的功能來知足服務訪問的基本需求:一個是容許映射容器內應用的服務端口到本地宿主主機;另外一個是互聯機制實現多個容器間經過容器名來快速訪問

從外部訪問容器應用

當容器中運行一些網絡應用,要讓外部訪問這些應用時,能夠經過-P或-p參數來指定端口映射。 當使用-P(大寫的)標記時,Docker會隨機映射一個49000~49900的端口到內部容器開放的網絡端口 -p(小寫的)則能夠指定要映射的端口,而且,在一個指定端口上只能夠綁定一個容器。 支持的格式有

  • 映射全部接口地址

HostPort:ContainerPort eg:80 8080:8080

  • 映射到指定地址的指定端口

    IP:HostPort:ContainerPort eg:127.0.0.1:5000:5000

  • 映射到指定地址的任意端口

IP::ContainerPort eg:127.0.0.1::5000 使用IP::ContainerPort綁定localhost的任意端口到容器的5000端口,本地主機會自動分配一個端口

  • 指定udp端口

IP:ContainerPort/udp eg:127.0.0.1:5000/udp

容器互聯

使用--link參數可讓容器之間安全地進行交互 ,--link參數的格式爲--link name:alias,其中name是要連接的容器的名稱,alias是別名

// 先建立一個容器
docker run -it --rm --name centos-1 centos:latest
// 在建立一個容器
docker run -itd --name centos-2 --link centos-1:centos-1 centos:latest
複製代碼

Docker至關於在兩個互聯的容器之間建立了一個虛機通道,並且不用映射它們的端口到宿主主機上。
在啓動容器的時候並無使用-p和-P標記,從而避免了暴露數據庫服務端口到外部網絡上。
Docker經過兩種方式爲容器公開鏈接信息:
更新環境變量 查看容器的環境變量 : docker exec centos-1 env 使用env命令來查看容器的環境變量 ❑ 更新/etc/hosts文件

使用Dockerfile建立鏡像

Dockerfile是一個文本格式的配置文件,用戶可使用Dockerfile來快速建立自定義的鏡像。 Dockerfile由一行行命令語句組成,而且支持以#開頭的註釋行。 通常而言,Dockerfile主體內容分爲四部分:基礎鏡像信息、維護者信息、鏡像操做指令和容器啓動時執行指令

配置指令說明

Dockerfile中指令的通常格式爲 INSTRUCTION arguments,包括「配置指令」(配置鏡像信息)和「操做指令

ARG     		定義建立鏡像過程當中使用的變量 惟一一個能夠在FROM指令以前
FROM    		指定基礎鏡像,必須爲第一個命令(在沒有ARG)
LABEL LABEL指令能夠爲生成的鏡像添加元數據標籤信息。這些信息能夠用來輔助過濾出特定鏡像
EXPOSE 			聲明鏡像內服務監聽的端口
ENV    			指定環境變量,在鏡像生成過程當中會被後續RUN指令使用,在鏡像啓動的容器中也會存在
ENTRYPOINT 指定鏡像的默認入口命令,該入口命令會在啓動容器時做爲根命令執行,全部傳入值做爲該命令的參數
VOLUME 建立一個數據卷掛載點
USER				指定運行容器時的用戶名或UID,後續的RUN等指令也會使用指定的用戶身份
WORKDIR 爲後續的RUN、CMD、ENTRYPOINT指令配置工做目錄
ONBUILD 		指定當基於所生成鏡像建立子鏡像時,自動執行的操做指令
STOPSIGNAL 	指定所建立鏡像啓動的容器接收退出的信號值
HEALTHCHECK 配置所啓動容器如何進行健康檢查
SHELL 指定其餘命令使用shell時的默認shell類型
複製代碼

操做指令

RUN 運行指定命令
CMD 用來指定啓動容器時默認執行的命令
ADD 添加內容到鏡像
COPY 複製內容到鏡像
複製代碼

經常使用指令

ARG : 定義建立鏡像過程當中使用的變量

惟一一個能夠在FROM指令以前的指令,ARG指令定義的參數,在docker build命令中以--build-arg a_name=a_value形式賦值。若是docker build命令傳遞的參數,在Dockerfile中沒有對應的參數,將警告

# 格式:
    ARG <name>[=<default value>]
# 示例:
    ARG VERSION="7.0"
    FROM centos:${VERSION}
複製代碼

FROM : 指定所建立鏡像的基礎鏡像

tag或digest是可選的,若是不使用這兩個值時,會使用latest版本的基礎鏡像

# 格式:
    FROM <image>
    FROM <image>:<tag>
    FROM <image>@<digest>
 #示例:  
    FROM mysql:5.6
複製代碼

 LABEL : 指令能夠爲生成的鏡像添加元數據標籤信息

使用LABEL指定元數據時,一條LABEL指定能夠指定一或多條元數據,指定多條元數據時不一樣元數據之間經過空格分隔。推薦將全部的元數據經過一條LABEL指令指定,以避免生成過多的中間鏡像

# 格式:
    LABEL <key>=<value> <key>=<value> <key>=<value> ...
# 示例:
    LABEL version="1.0" description="這是一個Web服務器" by="IT筆錄"
    LABEL author="sun@qq.com" data="2021-1-1"
複製代碼

EXPOSE : 聲明鏡像內服務監聽的端口

EXPOSE並不會讓容器的端口訪問到主機。要使其可訪問,須要在docker run運行容器時經過-p來發布這些端口,或經過-P參數來發布EXPOSE導出的全部端口

# 格式:
    EXPOSE <port> [<port>...]
# 示例:
    EXPOSE 80 443
    EXPOSE 8080    EXPOSE 11211/tcp 11211/udp
複製代碼

ENV : 指定環境變量

指令指定的環境變量在運行時能夠被覆蓋掉,如 docker run --env <key>=<value> built_image

#格式:
    ENV <key> <value>  #<key>以後的全部內容均會被視爲其<value>的組成部分,所以,一次只能設置一個變量
    ENV <key>=<value> ...  #能夠設置多個變量,每一個變量爲一個"<key>=<value>"的鍵值對,若是<key>中包含空格,可使用\來進行轉義,也能夠經過""來進行標示;另外,反斜線也能夠用於續行
# 示例:
    ENV myName John Doe
    ENV myDog Rex The Dog
    ENV myCat=fluffy
複製代碼

ENTRYPOINT : 指定鏡像的默認入口命令

注ENTRYPOINT與CMD很是相似,不一樣的是經過docker run執行的命令不會覆蓋ENTRYPOINT,而docker run命令中指定的任何參數,都會被當作參數再次傳遞給ENTRYPOINT。Dockerfile中只容許有一個ENTRYPOINT命令,多指定時會覆蓋前面的設置,而只執行最後的ENTRYPOINT指令,在運行時,能夠被--entrypoint參數覆蓋掉,如 docker run --entrypoint

#格式:
    ENTRYPOINT ["executable", "param1", "param2"] (可執行文件, 優先)
    ENTRYPOINT command param1 param2 (shell內部命令)
示例:
    FROM ubuntu
    ENTRYPOINT ["top", "-b"]
    CMD ["-c"]
複製代碼

VOLUME :建立一個數據卷掛載點

# 格式:
    VOLUME ["/path/to/dir"]
# 示例:
    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"

注:一個卷能夠存在於一個或多個容器的指定目錄,該目錄能夠繞過聯合文件系統,並具備如下功能:
1 卷能夠容器間共享和重用
2 容器並不必定要和其它容器共享卷
3 修改卷後會當即生效
4 對卷的修改不會對鏡像產生影響
5 卷會一直存在,直到沒有任何容器在使用它
複製代碼

USER : 指定運行容器時的用戶名或UID

# 格式:  
    USER user  
    USER user:group  
    USER uid  
    USER uid:gid  
    USER user:gid  
    USER uid:group 
# 示例:   
		USER www 
# 注:使用USER指定用戶後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT都將使用該用戶。鏡像構建完成後,經過docker run運行容器時,能夠經過-u參數來覆蓋所指定的用戶。
複製代碼

WORKDIR 爲後續的RUN、CMD、ENTRYPOINT指令配置工做目錄,經過WORKDIR設置工做目錄後,Dockerfile中其後的命令RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都會在該目錄下執行。在使用** docker run -w ****運行容器時,能夠經過-w參數覆蓋構建時所設置的工做目錄 **

# 格式:
    WORKDIR /path/to/workdir
# 示例:
    WORKDIR /a (這時工做目錄爲/a)
    WORKDIR b (這時工做目錄爲/a/b)
    WORKDIR c (這時工做目錄爲/a/b/c)
複製代碼

ONBUILD : 指定當基於所生成鏡像建立子鏡像時,自動執行的操做指令

#格式: 
   ONBUILD [INSTRUCTION]
#示例:
  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src
# 注:當所構建的鏡像被用作其它鏡像的基礎鏡像,該鏡像中的觸發器將會被鑰觸發
複製代碼

RUN : 運行指定命令

RUN用於在鏡像容器中執行命令,其有如下兩種命令執行方式:
shell執行
格式:
    RUN <command>
    
exec執行
格式:
    RUN ["executable", "param1", "param2"]
    
示例:
    RUN ["executable", "param1", "param2"]
    RUN apk update
    RUN ["/etc/execfile", "arg1", "arg1"]
注:RUN指令建立的中間鏡像會被緩存,並會在下次構建中使用。若是不想使用這些緩存鏡像,能夠在構建時指定--no-cache參數,如:docker build --no-cache
複製代碼

CMD : 指令用來指定啓動容器時默認執行的命令

格式:
    CMD ["executable","param1","param2"] (執行可執行文件,優先)
    CMD ["param1","param2"] (設置了ENTRYPOINT,則直接調用ENTRYPOINT添加參數)
    CMD command param1 param2 (執行shell內部命令)
示例:
    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]
    
 注: CMD不一樣於RUN,CMD用於指定在容器啓動時所要執行的命令,而RUN用於指定鏡像構建時所要執行的命令。
複製代碼

ADD:添加內容到鏡像

格式:
    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"] 用於支持包含空格的路徑
示例:
    ADD hom* /mydir/ # 添加全部以"hom"開頭的文件
    ADD hom?.txt /mydir/ # ? 替代一個單字符,例如:"home.txt"
    ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
    ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
   
複製代碼

COPY:複製內容到鏡像

COPY與ADD指令功能相似,可是是不會自動解壓文件,也不能訪問網絡資源,當使用本地目錄爲源目錄時,推薦使用COPY

下載 nginx-1.18.0.tar.gz ,epel-release-latest-7.noarch.rpm 文件在同一目錄之下 而且在當前目錄下 新建 Dockerfile 文件

# This nginx Dockerfile
# Version 1.0

# Base images 基礎鏡像
FROM centos

#MAINTAINER 維護者信息
MAINTAINER xxxxx 

#ENV 設置環境變量
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD 文件放在當前目錄下,拷過去會自動解壓
ADD ./nginx-1.18.0.tar.gz /usr/local/ 
ADD ./epel-release-latest-7.noarch.rpm /usr/local/ 

#RUN 執行如下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 至關於cd
WORKDIR /usr/local/nginx-1.8.0 

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 映射端口
EXPOSE 80

#CMD 運行如下命令
CMD ["nginx"]
複製代碼

Dockerfile構建鏡像

docker build -t Name:Tag -f Dockerfile . 構建鏡像

--add-host list 添加自定義Host到ip的映射(主機:ip)
--build-arg list 設置構建時的變量
--cache-from strings 將鏡像視爲緩存源
--cgroup-parent string 可選的容器父cgroup
--compress 使用gzip工具壓縮構建的上下文
--console  顯示控制檯輸出,僅使用 buildkit,參數有:true、false、auto(默認爲 auto)
--cpu-period int 限制CPU CFS(徹底公平的調度)的週期
--cpu-quota int 限制CPU CFS(徹底公平的調度)的限額
-c, --cpu-shares int 設置CUP的共享權重
--cpuset-cpus string 容許執行的cpu個數 (0-3,0,1)
--cpuset-mems string 容許執行的MEM個數 (0-3,0,1)
--disable-content-trust 跳過鏡像的驗證(默認爲 true)
-f, --file string 構建的Dockerfile的名稱(默認爲 ‘PATH/Dockerfile’)
--force-rm 老是移除中間容器
--iidfile string 將鏡像ID寫入到指定文件
--isolation string 容器隔離技術
--label list 爲鏡像設置元數據
-m, --memory bytes 內存限額
--memory-swap bytes 若是啓用無限交換,則交換限制等於內存加上交換:'-1'便可
--network string 在構建期間爲 RUN 指令設置網絡模式(默認爲 「default」)
--no-cache 在構建映像時不使用緩存(設定後,每次都會從新去拉取,默認使用緩存的)
--platform string 若是服務器具備多平臺能力,則設置該平臺
--pull 老是嘗試拉取該鏡像的新版本
-q, --quiet 鏡像構建成功後禁止生成輸出和打印鏡像的ID
--rm 構建成功後刪除中間容器(默認爲 true)
--security-opt strings 安全選項
--shm-size bytes 設定/dev/shm的大小
--squash 將新建的鏡像層壓縮成一個新的鏡像層
--stream 將流附加到服務器以協商構建上下文
-t, --tag list 名稱和可選的標籤(格式爲 'name:tag' )
--target string 設置須要構建的目標構建階段
--ulimit ulimit U 限制項 (默認爲 [])

Docker 網絡

默認狀況下容器與容器、容器與宿主機的網絡是隔離開來的,docker 網絡須要解決的就是 容器於容器的之間的互通。

網絡模式

Docker網絡模式 配置 說明
host模式 --net=host 容器和宿主機共享Network namespace
container模式 --net=container:NAME_or_ID 容器和另一個容器共享Network namespace,kubernetes中的pod就是多個容器共享一個Network namespace
none模式 --net=none 容器有獨立的Network namespace但並無對其進行任何網絡設置,如分配veth pair 和網橋鏈接,配置IP等
bridge模式 --net=bridge (默認爲該模式) 網絡橋接模式,將自動生成獨有的Network namespace 
自定義模式 --net=自定義網絡名稱 --

host模式

原理:若是啓動容器的時候使用host模式,那麼這個容器將不會得到一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace容器將不會虛擬出本身的網卡,配置本身的IP等,而是使用宿主機的IP和端口。可是,容器的其餘方面,如文件系統、進程列表等仍是和宿主機隔離的。 使用host模式的容器能夠直接使用宿主機的IP地址與外界通訊,容器內部的服務端口也可使用宿主機的端口,不須要進行NAThost最大的優點就是網絡性能比較好,可是docker host上已經使用的端口就不能再用了,網絡的隔離性很差。 ** image.png **

container模式

這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和宿主機共享。新建立的容器不會建立本身的網卡,配置本身的 IP,而是和一個指定的容器共享 IP、端口範圍等。一樣,兩個容器除了網絡方面,其餘的如文件系統、進程列表等仍是隔離的。兩個容器的進程能夠經過 lo 網卡設備通訊

image.png

none模式

使用none模式,Docker容器擁有本身的Network Namespace,可是,並不爲Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。須要咱們本身爲Docker容器添加網卡、配置IP等。 這種網絡模式下容器只有lo迴環網絡,沒有其餘網卡。none模式能夠在容器建立時經過--network=none來指定。這種類型的網絡沒有辦法聯網,封閉的網絡能很好的保證容器的安全性 image.png

bridge模式

當Docker進程啓動時,會在主機上建立一個名爲docker0的虛擬網橋,此主機上啓動的Docker容器會鏈接到這個虛擬網橋上。虛擬網橋的工做方式和物理交換機相似,這樣主機上的全部容器就經過交換機連在了一個二層網絡中 從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址爲容器的默認網關。在主機上建立一對虛擬網卡veth pair設備,Docker將veth pair設備的一端放在新建立的容器中,並命名爲eth0(容器的網卡),另外一端放在主機中,以vethxxx這樣相似的名字命名,並將這個網絡設備加入到docker0網橋中。能夠經過brctl show命令查看 bridge模式是docker的默認網絡模式,不寫--net參數,就是bridge模式。使用docker run -p時,docker實際是在iptables作了NAT規則,實現端口轉發功能。可使用iptables -t nat -vnL查看

veth-pair 就是一對的虛擬設備接口,它都是成對出現的。一端連着協議棧,一端彼此相連着

image.png

bridge模存在的問題

按照如下方式建立了兩個容器,在經過名稱互聯訪問時候,鏈接不用

docker run -itd  --name centos-bdg-01 centos:latest
docker run -itd  --name centos-bdg-02 centos:latest

// 會出現如下問題
docker exec -it centos-bdg-01 ping centos-bdg-02
ping: centos-bdg-02: Name or service not known
複製代碼

自定義模式

docker network ls 列出本地網絡模式

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
63d9493bce38   bridge    bridge    local      # 橋接模式
de1105dfa5a8   host      host      local			# host模式
87441a7540aa   none      null      local 			# none模式
複製代碼

docker network create      建立一個網絡模式

  • --driver 鏈接的網絡模式
  •  --subnet 子網掩碼 192.168.0.0/16
  • --gateway 192.168.1.0 網關
docker network create --driver bridge  --subnet 192.168.0.0/16  --gateway 192.168.1.0 mynet

336cdb202d7a5d7f1fb3f8dc087d5d6e1b7aa46b3513186c8cb35bc1125a0784
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
63d9493bce38   bridge    bridge    local
de1105dfa5a8   host      host      local
336cdb202d7a   mynet     bridge    local
87441a7540aa   none      null      local


建立自定義模式的docker容器
docker run -itd  --name centos-net-01 --network mynet centos:latest
docker run -itd  --name centos-net-02 --network mynet centos:latest

再次執行 能夠發現容器之間是互通的
docker exec -it centos-net-01 ping centos-net-02
PING centos-net-02 (192.168.0.2) 56(84) bytes of data.
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.162 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.160 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.181 ms
64 bytes from centos-net-02.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.158 ms
複製代碼

docker network inspect    顯示一個或多個網絡上的詳細信息

docker network connect  將容器鏈接到網絡

docker network connect [OPTIONS] NETWORK CONTAINER 目前環境中有一下幾個容器 centos-bdg-xx 走原始的橋接模式的 docker0 網卡 網段實在 172.17.0.0/16 centos-net-xx 走的是自定義的mynet模式的 mynet網卡 網段 在 192.168.0.0/16

怎麼實現 centos-bdg-xx 到 centos-net-- 的通訊

docker ps
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
1573b7088604   centos:latest   "/bin/bash"   6 minutes ago    Up 6 minutes              centos-net-02
22a4f34fb7b8   centos:latest   "/bin/bash"   6 minutes ago    Up 6 minutes              centos-net-01
22844f330ba3   centos:latest   "/bin/bash"   25 minutes ago   Up 25 minutes             centos-bdg-02
8f7ae3be00e3   centos:latest   "/bin/bash"   25 minutes ago   Up 25 minutes             centos-bdg-01


docker network connect mynet centos-bdg-01
docker exec -it centos-bdg-01  ping centos-net-01
PING centos-net-01 (192.168.0.1) 56(84) bytes of data.
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=2 ttl=64 time=0.161 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=3 ttl=64 time=0.202 ms
64 bytes from centos-net-01.mynet (192.168.0.1): icmp_seq=4 ttl=64 time=0.153 ms


docker network inspect mynet
····
"Containers": {
      "1573b70886040ce5922a0366e866bd6c5ac91acd851dd53dd43b2c2fbc388389": {
      "Name": "centos-net-02",
      "EndpointID": "968dd40f23362c3066df4092a2be6955c8681eaf38e07e505344492bc383a8c9",
      "MacAddress": "02:42:c0:a8:00:02",
      "IPv4Address": "192.168.0.2/16",
      "IPv6Address": ""
      },
      "22a4f34fb7b8becd82719d16cecf84c54ca48bc184964042aecec74d18d1c931": {
      "Name": "centos-net-01",
      "EndpointID": "b2c7cf4d66fdeeea5559bd81fd3166bf78e0e3064e5016e71e51ba5543c5ded4",
      "MacAddress": "02:42:c0:a8:00:01",
      "IPv4Address": "192.168.0.1/16",
      "IPv6Address": ""
      },
      // 容器鏈接到自定義網卡中
      "8f7ae3be00e349005326d1fd4ff57fd0e19867b66a23bbc73c9568c9467b7c6f": {
      "Name": "centos-bdg-01",
      "EndpointID": "22427d81dc7386d04c7502ae90c99b812503e8514a13c1e89207435a2ec9ebb4",
      "MacAddress": "02:42:c0:a8:00:03",
      "IPv4Address": "192.168.0.3/16",
      "IPv6Address": ""
      }
}
複製代碼

image.png

docker network rm   移除一個網絡模式

docker network prune 刪除全部未使用的網絡

**

Docker 可視化管理

docker run -itd --restart always --name portainer-web -p 9000:9000  -v /var/run/docker.sock:/var/run/docker.sock  portainer/portainer
複製代碼
相關文章
相關標籤/搜索