【docker】Docker入門到實踐 筆記

Hua Zhu發表於2019-03-17

Docker入門到實踐 筆記

基本概念

  • 映象(Image)
  • 容器(Container)
  • 倉庫(Repository)

映象

  • 特殊的檔案系統
  • 不包含任何動態的資料
  • 採用Union FS技術,設計分層架構

容器

  • 映象和容器就像“類”和“例項”的區別
  • 容器的實質是程式
  • 容器也是分層結構,存在容器儲存層,為容器執行時讀寫而準備,生命週期和容器同步

倉庫

  • Docker Registry(註冊伺服器):集中的儲存、分發映象的服務
  • 一個registry多個repository(倉庫)
  • 一個repository(倉庫)多個tag(標籤)
  • 一個tag(標籤)一個image(映象)

常用操作

映象

獲取映象

docker pull --help

執行映象獲得容器

docker run --help

列出映象

docker image ls

虛懸映象

docker image prune #刪除虛懸映象

中間層映象

docker image ls -a #可以檢視到

列出部分映象

docker image ls [repo:tag]

列出映象id

docker image ls -q

刪除本地映象

docker image rm --help  #刪除tag是本質

映象執行容器定製

docker run  --name webserver -d -p 81:80 nginx 
//用nginx映象啟動一個容器命名為webserver,並對映80埠,用http://localhost:81可直接訪問(-p 宿主機埠:容器埠)
//進入容器 docker exec -it webserver bash
//退出容器 exit
//檢視容器變動 docker diff webserver
//儲存容器修改到映象(容器儲存層資料儲存)docker commit

定製映象

docker commit --help
//儲存容器修改到映象(容器儲存層資料儲存修)

檢視映象歷史

docker history [repo:tag]

容器

啟動容器

兩種方式

  • 基於映象新建容器
  • 將終止狀態的容器重新啟動

新建並啟動

docker run ubuntu:18.04 /bin/echo 'Hello world'
//命令輸出一個 “Hello World”,之後終止容器。

docker run -t -i ubuntu:18.04 /bin/bash
//-t 選項讓Docker分配一個偽終端(pseudo-tty)並繫結到容器的標準輸入上
//-i 則讓容器的標準輸入保持開啟。

docker run的後臺邏輯

  • 檢查本地是否存在指定的映象,不存在就從公有倉庫下載
  • 利用映象建立並啟動一個容器
  • 分配一個檔案系統,並在只讀的映象層外面掛載一層可讀寫層
  • 從宿主主機配置的網橋介面中橋接一個虛擬介面到容器中去
  • 從地址池配置一個 ip 地址給容器
  • 執行使用者指定的應用程式
  • 執行完畢後容器被終止

啟動已終止容器

docker container start

後臺執行

  • -d引數決定
  • 啟用後輸出結果不在列印到宿主機上,可以在docker logs中檢視
  • 返回唯一的id,可以通過docker container ls 檢視
  • 檢視輸出資訊 docker container logs
  • 容器是否會長久執行,是和 docker run 指定的命令有關,和 -d 引數無 關。
#宿主機上輸出
docker run ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

#-d 後臺執行,在docker logs中
docker run -d ubuntu:18.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"

終止容器

  • docker container stop 終止執行中的容器
  • docker容器中指定的應用終結時,容器自動終止。
  • 只啟動了一個終端的容器呼叫exit,ctrl+d退出終端時,容器即終止。
#檢視容器
docker container ls -a
#終止執行中的容器
docker container stop 
#終止狀態容器重啟 
docker container start
#執行狀態容器重啟 
docker container restart

進入容器

#attach方法
docker run -dit ubuntu
docker attach xxx //此時從stdin中exit,會導致容器停止。

#exec方法
docker run -dit ubuntu
docker exec -it 69d1 bash //從這個 stdin 中 exit,不會導致容器的停止

#更多方法
docker exec --help

匯入匯出容器

匯出容器

#匯出容器快照到本地檔案
docker export 7691a814370e > ubuntu.tar

匯入容器快照

#使用docker import 從容器快照檔案中再匯入為映象
cat ubuntu.tar | docker import - test/ubuntu:v1.0
docker image ls

#也可以通過指定 URL 或者某個目錄來匯入
docker import http://example.com/exampleimage.tgz example/imagerepo

  • docker load 來匯入映象儲存檔案到本地映象庫
  • docker import 來匯入一個容器快照到本地映象庫

這兩者的區別在於:

  • 容器快照檔案將丟棄所有的歷史記錄和後設資料資訊(即僅儲存容器當時的快照狀態)
  • 映象儲存檔案將儲存完整記錄,體積也要大。
  • 從容器快照檔案匯入時可以重新指定標籤等後設資料資訊。

刪除和清理容器

#刪除一個處於終止狀態的容器
docker container rm trusting_newton

#刪除一個處於執行中的容器
docker container rm -f xxxx //docker會傳送SIGKILL訊號給容器。

#清理所有處於終止狀態的容器
docker container prune

倉庫

  • 倉庫( Repository )是集中存放映象的地方。
  • 註冊伺服器( Registry )是管理倉庫的具體伺服器,每個伺服器上可以有多個倉庫,而每個倉庫下面有多個映象。
  • 倉庫可以被認為是一個具體的專案或目錄
  • 在dl.dockerpool.com/ubuntu 中dl.dockerpool.com 是註冊伺服器地址,ubuntu是倉庫名。

Docker Hub

Docker 官方維護了一個公共倉庫 Docker Hub,其中已經包括了數量超過 15,000 的映象

常用命令

docker search //查詢官方倉庫中的映象
docker pull //下載到本地
docker push //將自己的映象推送到 Docker Hub

自動建立

自動建立(Automated Builds)功能對於需要經常升級映象內程式來說,十分方 便。

私有倉庫

  • 工具docker-registry

資料管理

容器中管理資料兩種途徑

  • 資料卷(Volumes)
  • 掛載主機目錄(Bind mounts)

資料卷

  • 是一個可供一個或多個容器使用的特殊目錄,它繞過UFS可以提供很多 有用的特性
  • 資料卷 可以在容器之間共享和重用
  • 對 資料卷 的修改會立馬生效
  • 對 資料卷 的更新,不會影響映象
  • 資料卷 預設會一直存在,即使容器被刪除

資料卷 的使用,類似於 Linux 下對目錄或檔案進行 mount,映象中的 被指定為掛載點的目錄中的檔案會隱藏掉,能顯示看的是掛載的 資料卷 。

常用操作

#建立一個資料卷 my-vol
docker volume create my-vol

#檢視所有的 資料卷
docker volume ls

#在主機裡使用以下命令可以檢視指定 資料卷 的資訊
docker volume inspect my-vol

#啟動一個掛載資料卷的容器
#建立一個名為 web 的容器,並載入一個 資料卷 到容器的 /webapp 目錄。
docker run -d -P --name web --mount source=my-vol,target=/webapp \ training/webapp \ 
python app.pyc
在一次 docker run 中可以掛載多個 資料卷

#檢視資料卷的具體資訊
#主機裡使用以下命令可以檢視 web 容器的資訊
docker inspect web   //資料卷 資訊在 "Mounts" Key 下面

#刪除資料卷
docker volume rm my-vol

#清理資料卷
docker volume prune

  • 資料卷 是被設計用來持久化資料的,它的生命週期獨立於容器,Docker 不會在容器被刪除後自動刪除 資料卷
  • 並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的 資料卷
  • 如果需要在刪除容器的同時移除資料卷。可以在刪除容器的時候使用 docker rm -v 這個命令

掛載主機目錄

掛載一個主機目錄作為資料卷, --mount標記可以指定掛載一個本地主機的目錄到容器中去

#載入主機的 /src/webapp 目錄到容器的 /opt/webapp 目錄
docker run -d -P --name web --mount type=bind,source=/src/webapp,target=/opt/webapp \
training/webapp \
python app.py

# read only只讀
docker run -d -P --name web --mount type=bind,source=/src/webapp,target=/opt/webapp,read
only \
training/webapp \
python app.py

#檢視 web 容器的資訊
docker inspect web

掛載一個本地主機檔案作為資料卷

--mount 標記也可以從主機掛載單個檔案到容器中

docker run --rm -it --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
ubuntu:18.04 \
bash
#這樣就可以記錄在容器輸入過的命令了

網路功能

Docker 允許通過外部訪問容器或容器互聯的方式來提供網路服務。

外部訪問容器

-P(大寫)對映

  • -P (大寫p)Docker 會隨機對映一個 49000~49900 的埠到內部容器開放的網路埠。
  • docker container ls可以檢視對映關係
#隨機埠對映
docker run -d -P training/webapp python app.py

#檢視對映關係
docker container ls -l

#檢視應用資訊
docker logs -f nostalgic_morse

-p(小寫)對映

  • -p (小寫)則可以指定要對映的埠,並且,在一個指定埠上只可以繫結一個容器。
  • 支援的格式有 ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort 。
#對映所有介面地址
#hostPort:containerPort 格式本地的 5000 埠對映到容器的 5000 埠
docker run -d -p 5000:5000 training/webapp python app.py
#此時預設會繫結本地所有介面上的所有地址。

#對映到指定地址的指定埠
#ip:hostPort:containerPort 格式指定對映使用一個特定地址,比如
localhost 地址 127.0.0.1
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

#對映到指定地址的任意埠
#ip::containerPort 繫結 localhost 的任意埠到容器的 5000 埠,本地
主機會自動分配一個埠。
docker run -d -p 127.0.0.1::5000 training/webapp python app.py

#指定埠對映協議
#用udp 標記來指定 udp 埠
docker run -d -p 127.0.0.1:5000:5000/udp training/webapp pytho
n app.py

檢視埠配置

使用 docker port 來檢視當前對映的埠配置,也可以檢視到繫結的地址

docker port nostalgic_morse 5000

檢視容器內部網路配置

  • 容器有自己的內部網路和 ip 地址
  • 使用 docker inspect 可以獲取所有的變數
  • Docker 還可以有一個可變的網路配置

繫結多個埠

docker run -d \
-p 5000:5000 \
-p 3000:80 \
training/webapp \
python app.py

容器互聯

新建網路

docker network create -d bridge my-net
#-d 引數指定 Docker 網路型別有 bridge overlay 
#其中 overlay 網路型別用於 Swarm mode

連結容器

#容器busybox1, 映象源busybox, 網路my-net
docker run -it --rm --name busybox1 --network my-net busybox sh

#容器busybox2, 映象源busybox, 網路my-net
docker run -it --rm --name busybox2 --network my-net busybox sh

#檢視狀態
docker container ls

#通訊驗證,在busybox1中ping busybox2
ping busybox2

Docker Compose

如果你有多個容器之間需要互相連線,推薦使用 Docker Compose。

配置 DNS(Domain Name System)

配置容器的主機名和DNS,Docker 利用虛擬檔案來掛載容器的 3 個相關配置檔案來實現,在容器中執行mount可以獲得相關掛載資訊

$ mount
/dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ...
/dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ...
tmpfs on /etc/resolv.conf type tmpfs ...
#該機制可以讓宿主主機 DNS 資訊發生更新後,所有 Docker 容器的 DNS 配置通過 /etc/resolv.conf 檔案立刻得到更新。

配置所有容器的DNS

可以在 /etc/docker/daemon.json 檔案中增加以下內容來設定。

{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
#每次啟動的容器 DNS 自動配置為 114.114.114.114 和 8.8.8.8
#使用以下命令來證明其已經生效。
docker run -it --rm ubuntu:18.04 cat etc/resolv.conf

手動指定容器配置

可以在使用 docker run 命令啟動容器時加入如下引數:

  • -h HOSTNAME 或者 --hostname=HOSTNAME 設定容器的主機名,
  • 它會被寫到容器內的 /etc/hostname 和 /etc/hosts 。
  • 但它在容器外部看不到,既不會在docker container ls中顯示,也不會在其他的容器的 /etc/hosts 看到。
  • --dns=IP_ADDRESS 新增 DNS 伺服器到容器的 /etc/resolv.conf 中
  • 讓容器用這個伺服器來解析所有不在 /etc/hosts 中的主機名。
  • --dns-search=DOMAIN 設定容器的搜尋域
  • 當設定搜尋域為 .example.com時,在搜尋一個名為 host 的主機時,DNS 不僅搜尋 host,還會搜尋host.example.com 。

注意:如果在容器啟動時沒有指定最後兩個引數,Docker 會預設用主機上的/etc/resolv.conf 來配置容器。

相關文章