1. 程式人生 > 程式設計 >docker 基礎總結

docker 基礎總結

docker 是什麼

Docker是一個開源的容器引擎,它基於 LXC 容器技術,使用 Go 語言開發。原始碼託管在 Github 上,並遵從 Apache2.0 協議。 Docker採用 C/S 架構,其可以輕鬆的為任何應用建立一個輕量級的、可移植的、自給自足的容器。 簡單來說: Docker 就是一種快速解決生產問題的一種技術手段。

docker 官網: www.docker.com/

理解 docker 的理念

  • 構建: 龍珠裡的膠囊,將你需要的場景構建好,裝在一個小膠囊裡
  • 運輸: 隨身攜帶著房子、車子等,非常方便
  • 執行: 只需要你輕輕按一下膠囊,找個合適的地方一放,就ok了

優缺點

優點 :

  • 多: 使用場景多
  • 快: 環境部署快、更新快
  • 好: 好多人在用,東西好
  • 省: 省錢省力省人工。

缺點:

  • 依賴作業系統;
  • 依賴網路;
  • 銀行 U 盾等場景不能用。

docker 的安裝

根據不用的作業系統可以輕鬆在網上查詢到很多安裝教程,之前寫過一個: blog.csdn.net/Enjolras_fu… 這裡不再贅述。

測試已安裝:

docker version 
複製程式碼

網路卡區別:

在安裝前,只有 ens33 和 lo 網路卡 在安裝後,docker 啟動後,多出了 docker0 網路卡,網路卡地址是 172.17.0.1

docker 的基本目錄

  • /etc/docker/ 是 docker 的認證目錄

  • /var/lib/docker/ 是 docker 的應用目錄

配置 docker 加速器

這部分網上也有較多文章去具體講解,這裡就不再贅述。 blog.csdn.net/Enjolras_fu…

docker 映象簡介

docker 映象相當於一個只讀的檔案,就類似於我們安裝作業系統的時候所需要的各種iso 光碟映象,我們通過執行這個映象來完成各種應用的部署。

可以理解映象就是一個能被 docker 執行起來的一個程式。

映象相關命令

查詢映象:

docker search ubuntu 
複製程式碼

獲取映象:

docker pull ubuntu 
複製程式碼

獲取的映象存放在哪裡? /var/lib/docker 目錄下。

檢視映象:

docker images [image_name] 
複製程式碼

這裡是 docker images ubuntu:latest

映象的 ID 唯一標識了映象,如果 ID 相同,就說明是同一映象。TAG 資訊來區分不同的發行版本,如果不指定具體的標記,就預設使用 latest 來標記資訊。

列出全部映象:

docker image ls (當前存在的映象) 
複製程式碼

或者 docker images -a (包含已經刪除的映象記錄)

這兩個命令列出的結果略有不同。

檢視映象歷史:

docker history [image_name]
複製程式碼

我們獲取到一個映象,想知道他預設啟動了哪些命令或者封裝了哪些系統層,就可以使用 docker history 來獲取。

映象重新命名:

docker tag [old_image]:[old_version] [new_image]:[new_version]
複製程式碼

演示: docker tag nginx:latest sswang-nginx:v1.0

刪除映象:

docker rmi [image_id/image_name:image_version]
複製程式碼

注意 如果一個 image_id 對應多個名稱,要使用 name:tag 的格式刪除映象。

清除狀態為 dangling 的映象:

docker image prune 
複製程式碼

清除所有未被使用的映象:

docker image prune  -a  
複製程式碼

按照條件刪除部分映象:

docker image prune -a  --filter "until=24h"
複製程式碼

我們可以將已經下載好的映象匯出到本地,以備後用。

匯出映象:

docker save -o [包檔案][映象]

docker save [映象1] ... [映象n] > [包檔案]
複製程式碼

docker save 會儲存映象的全部歷史記錄和元資料資訊。

舉例: docker save -o nginx.tar sswang-nginx

匯入映象:

docker load < [image.tar_name]
docker load --input [image.tar_name]
複製程式碼

舉例: docker load < nginx.tar

容器

容器是什麼? 容器類似於我們執行起來的一個作業系統,而且這個作業系統啟動了某些服務。 這裡的容器指的是一個執行起來的 docker 映象。

檢視正在執行的容器:

docker ps  
複製程式碼

檢視所有容器,包括已經不執行的容器:

docker ps -a  
複製程式碼

啟動已經終止的容器:

docker start [container_id]
複製程式碼

在生產過程中,常常會出現執行和不執行的容器,我們使用 start 命令開起一個已經關閉的容器。

關閉某個容器:

docker stop [container_id]
複製程式碼

在生產過程中,我們會因為臨時情況, 要關閉某些容器,我們使用 stop 命令來關閉容器。

刪除已經關閉的容器:

docker rm [container_id]  
docker container prune
複製程式碼

刪除符合條件的部分容器:

docker container prune --filter "until=24h"
複製程式碼

強制刪除執行的容器:

docker rm -f [container_id]
複製程式碼

批量關閉並且刪除容器:

docker rm -f $(docker ps -a -q)
複製程式碼

建立並且進入容器:

docker run --name [container_name] -it [docker_image] /bin/bash 
複製程式碼

  • --name 給容器定義一個名稱
  • -i 讓容器的標準輸入保持開啟
  • -t 讓 docker 分配一個偽終端,並且繫結到容器的標準輸入上
  • /bin/bash 執行一個終端命令

退出容器:

method1: exit
method2: Ctrl+D
複製程式碼

進入一個容器:

docker exec -it [container_id] /bin/bash 
複製程式碼

基於容器建立映象

docker commit -m '改動資訊' -a '作者資訊' [container_id] [new_image:tag]
複製程式碼

舉例: 進入一個容器,建立檔案之後退出。

$ docker exec -it 7f551fd3c017 /bin/bash
root@7f551fd3c017:/# mkdir /furuiyang
root@7f551fd3c017:/# exit
exit
複製程式碼

基於該容器建立一個映象:

$ docker commit -m 'mkdir /furuiyang' -a 'furuiyang' 7f551fd3c017 ry-nginx:v0.0.1
sha256:e0aa3ce6ace3bc8e38de40ab31a88b3901ba09c366511a280ba75b0719963c98
複製程式碼

檢視映象:

$ docker image ls -a
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
ry-nginx              v0.0.1              e0aa3ce6ace3        14 seconds ago      126MB
複製程式碼

基於新映象啟動一個容器:

$ docker run --name d3 -itd ry-nginx:v0.0.1 /bin/bash
6d2e0f2cf48569b44eed1af2ca9871bb56a58b561695266112f7650e84546ead
複製程式碼

進入容器進行檢視:

$ docker exec -it 6d2e0f2cf48 /bin/bash
root@6d2e0f2cf485:/# ls
bin  boot  dev	etc  furuiyang	home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
複製程式碼

檢視容器的執行日誌:

docker logs [container_id]
複製程式碼

檢視容器的詳細資訊:

docker inspect [container_id]
複製程式碼

在詳細資訊中過濾出容器的網路資訊:

docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' [container_id]
複製程式碼

倉庫管理

什麼是倉庫?

倉庫就類似於我們在網上搜索作業系統光碟的一個映象站。 這裡的倉庫指的是 Docker 映象儲存的地方。

Docker 倉庫分類

  • 共有倉庫: Docker hub、 Docker cloud 等
  • 私有倉庫: register、 harbor 等
  • 本地倉庫: 在當前的主機儲存映象的地方

倉庫相關命令

  • 登入倉庫: docker login [倉庫名稱]
  • 在倉庫中 pull 映象: docker pull [映象名稱]
  • 推送映象: docker push [映象名稱]
  • 查詢映象: docker search [映象名稱]

部署一個私有倉庫

部署流程:

  1. 根據 registry 映象建立容器
  2. 配置倉庫許可權
  3. 提交映象到私有倉庫
  4. 測試

實施方案: 下載 regisstry 映象:

docker pull registry:latest
複製程式碼

啟動倉庫容器:

docker run -d -p 5000:5000 registry:latest
複製程式碼

檢查容器效果:

curl 127.0.0.1:5000/v2/_catalog
複製程式碼

配置容器許可權:

vim /etc/docker/daemin.json
{"registry-mirrors": ["http://74f21445.m.daocloud.io"],"insecure-registries": ["172.18.222.137:5000"]}
複製程式碼

注意私有倉庫的 ip 地址是宿主機的 ip 地址,並且 ip 地址的兩側有引號。

重啟 docker 服務:

systemctl restart docker 
systemctl status docker 
複製程式碼

效果檢視: 啟動倉庫服務的容器: (在重啟 docker 服務的過程中關閉了執行中的全部容器)

docker start 6492f6a098c6 
複製程式碼

標記要提交的映象:

docker tag ry-nginx:v0.0.1  172.18.222.137:5000/ry-nginx:v0.0.1
複製程式碼

推送映象:

docker push 172.18.222.137:5000/ry-nginx:v0.0.1
複製程式碼

拉取映象:

docker pull 172.18.222.137:5000/ry-nginx:v0.0.1
複製程式碼

docker 資料管理

docker 的映象是隻讀的,雖然可以根據映象建立的容器可以進行操作,但是我們不能將資料儲存在容器裡面,因為容器會隨時關閉和開啟,那麼應該如何將 資料儲存下來呢?

答案就是資料卷和資料卷容器。

什麼是資料卷

就是講宿主機的某個目錄,對映到容器中,作為資料儲存的目錄,我們就可以在宿主機對資料進行儲存。

缺點: 太單一了。

我們可使用 docker run 來建立容器,在 docker run 命令時新增 -v 引數,就可以建立並且掛載一個到多個資料捲到當前執行的容器中。

-v 引數的作用是將宿主機的一個目錄作為容器的資料卷掛載到docker容器中,使宿主機和容器之間可以共享一個 目錄,如果本地路徑不存在,Docker也會自動建立。 -v 宿主機檔案:容器檔案

關於資料卷的管理我們從兩個方面來說: 1、目錄 2、普通檔案

資料卷之目錄

命令格式:

docker run -itd --name [container_name] -v [宿主機目錄]:[容器目錄] [映象名稱] [命令[可選]]
複製程式碼

命令演示: 建立測試檔案:

echo 'hello ruiyang' > /tmp/file1.txt
複製程式碼

啟動一個容器,掛載資料卷

docker run -itd --name test1 -v /tmp:/test1 nginx 
複製程式碼

進入容器檢視:

docker exec -it 3733303ee /bin/bash
cat /test1/file1.txt
複製程式碼

資料卷之檔案

命令格式:

docker run -itd --name [container_name] -v [宿主機檔案]:[容器檔案] [映象名稱][命令[可選]]
複製程式碼

命令演示: 建立測試檔案:

echo 'file1' > /tmp/file1.txt
複製程式碼

啟動一個容器,掛載資料卷

docker run -itd --name test2 -v /temp/file1.txt:/nihao/nihao.sh nginx
複製程式碼

這時候直接建立資料夾 nihao.sh ...

  • 檢視全部的資料卷: docker volume ls
  • 刪除某個資料卷: docker volume rm [VOLUME NAME]
  • 清除無用的資料卷: docker volume prune

資料卷容器

將宿主機的某個目錄,使用容器的方式來表示,然後其他的應用容器將資料儲存在這個容器裡面,達到大批量應用資料同時儲存的目的。

如果我們使用資料卷容器,在多個容器之間共享資料,並永久保留這些資料,需要有一個規範的流程才能做得到。 1、 建立資料卷容器 2、 其他容器掛載資料卷容器 注意: 資料卷容器不啟動

資料卷容器實踐:

建立一個資料卷容器:

docker create -v [容器資料卷目錄] --name [容器名字] [映象名稱]:[命令[可選]]

docker create -v /data --name v-test nginx 
複製程式碼

建立兩個容器同時掛載資料卷容器:

docker run --volumes-from  e7dd7d04c9 -itd --name t1 nginx /bin/bash 

docker run --volumes-from  e7dd7d04c9 -itd --name t2 nginx /bin/bash 
複製程式碼

進入 t1 操作資料卷容器:

docker exec -it 7dc224 /bin/bash
cd /data
touch reach.py
複製程式碼

進入 t2 確認資料卷是否有改動:

docker exec -it dc17055491 /bin/bash
cd /data
ls
複製程式碼

回到宿主機檢視 /data 目錄,不存在上述目錄。

容器之間可以共享資料卷迷你容器,不過資料是儲存在資料卷裡面的,並沒有儲存到宿主機的檔案目錄中。

網路管理概述

docker 以上的內容都依賴於網路才能工作,我們從兩個方面來學習網路:

  • 埠對映
  • 網路模式

埠對映概述

預設情況下,容器和宿主機之間網路是隔離的,我們可以通過埠對映的方式,將容器中的埠,對映到宿主機的某個埠上。這樣我們就可以通過 宿主機的ip+port的方式來訪問容器裡的內容。

埠對映種類
  • 隨機對映 -P(大寫)
  • 指定對映 -p 宿主機埠:容器埠

注意: 在生產場景一般不使用隨機對映,但是隨機對映的好處就是由docker分配,埠不會衝突,不管哪種對映都會影響效能,因為涉及到對映。

隨機對映實踐

隨機對映我們從兩個方面來學習:

  • 預設隨機對映
  • 指定主機隨機對映

預設隨機對映

docker run -d -P [映象名稱]
複製程式碼

啟動一個 nginx 映象:

檢視效果:

我們可以看到宿主機的 32768 埠被對映到容器裡面的 80 埠。 -P 可以做到自動繫結所有對外提供服務的容器埠,對映的埠將會從沒有使用過的埠池中自動隨機選擇,但是如果連續繫結多個容器的話,則下一個容器的埠預設是當前容器佔用埠號+1.

這時候我們在瀏覽器裡面訪問本地的 32768 埠,效果如下:

指定主機隨機對映

命令格式:

docker run -d -p [宿主機ip]::[容器埠] --name [容器名稱] [映象名稱]
複製程式碼

比如:

檢視效果:

指定對映實踐

命令格式:

docker run -d -p [宿主機ip]:[宿主機埠]:[容器埠] --name [容器名字] [映象名字]
複製程式碼

注意:

  • 如果不指定宿主機的ip,預設是使用 0.0.0.0
  • 容器埠必須清楚,而且必須寫出來

命令實踐: 現在我們在啟動容器的時候,給容器指定一個訪問的埠是 1199:

docker run -d -p 172.18.222.137:1199:80 --name n3 nginx 
複製程式碼

檢視新容器的 ip:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' c64c7cdc052cc57961
複製程式碼

檢視容器的埠對映: (接著上次寫的嗎,所以截圖時間是 42 小時之前)

檢視宿主機開啟的埠:

netstat -tnulp | grep docker-proxy 
複製程式碼

我們可以在瀏覽器訪問指定的埠 http://172.18.222.137:32768 檢視效果. 在這裡,我直接使用 httpie 的命令去訪問:

多埠對映的方法

命令格式:

docker run -d -p [宿主機埠1]:[容器埠1] -p [宿主機埠2]:[容器埠2] --name [容器名稱] [映象名稱]
複製程式碼

開啟多埠對映實踐:

docker run -d -p 520:443 -p 6666:80 --name n3 nginx
複製程式碼

檢視容器程式:

網路管理

docker 網路命令

docker network --help

docker 的網路模式

bridge 模式

docker 的預設模式,會在 docker 啟動的時候,自動配置好自己的網路資訊。同一個宿主機的所有容器都在一個網路下,彼此之間可以通訊,類似於 vmware 虛擬機器器的 nat 模式。 在這種模式下,利用宿主機的網路卡進行通訊,因為涉及到網路轉換,所以會造成資源浪費,網路效率會低。 示意圖:

擷取一段提問方便之後覆盤:

host 模式

簡單來說,就是鳩佔鵲巢,用著宿主機的東西,幹著自己的事情。容器使用宿主機的 ip 地址進行通訊。 特點: 容器和宿主機共享網路。 示意圖:

開啟小灰與大黃模式:

container 模式

新建立的容器之間適應已經建立的容器網路,類似於一個區域網。 特點: 容器和容器之間共享網路。 示意圖:

提問時間:

none 模式

這種模式最為純粹,不會幫你做任何的配置,可以最大限度的定製化。

overlay 模式

容器之間不是在同一網路,但是能互相通行。

提問時間:

嗯,交學費了 ... 找了一篇參考: blog.csdn.net/sqzhao/arti… 有待繼續深入

bridge 實踐

其實在埠對映部分做的實踐就是 bridge 的簡單演示了,因為他們使用的是預設 bridge 模式,現在我們來自定義橋接網路。 這一部分從三個方面來演示:

  • 建立橋接網路
  • 使用自定義網路建立容器
  • 容器的斷開和連線

建立網路

命令格式:

docker network create --driver [網路型別][網路名稱]
複製程式碼

命令演示:

docker network create --driver bridge bridge-test 
複製程式碼

檢視主機網路型別:

docker network ls
複製程式碼

檢視新建的網路的網路資訊:

docker network inspect bridge-test
複製程式碼

檢視宿主機的網路卡: 可以看到宿主機多出一個網路卡裝置:

在自定義的網路中建立容器

命令格式:

docker run --net=[網路名稱] -itd --name=[容器名稱] [映象名稱]
複製程式碼

使用效果:

docker run --net=bridge-test -itd --name=n_bri nginx
複製程式碼

檢視該容器的 ip 資訊:

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' n_bri 
複製程式碼

注意:使使用者預設的橋接模型的容器是可以直接聯網的,但是使用自定義的橋接模型不可以直接聯網,但是可以通過埠對映來實現聯網。

容器斷開網路

命令格式:

docker network disconnect [網路名] [容器名]
複製程式碼

命令演示:

docker network disconnect bridge-test n_bri 
複製程式碼

效果展示:

容器連線網路

命令格式:

docker network connect [網路名] [容器名]
複製程式碼

命令演示:

docker network connect bridge-test n_bri 
複製程式碼

效果展示:

host 模型實踐

我們從命令講解 以及 host 特點兩個方面來學習。

命令講解

在host模型下,容器使用宿主機的 ip 地址進行對外提供服務,本身沒有 ip 地址。

命令格式:

docker run --net=host -itd --name [容器名稱] [映象名稱]
複製程式碼

命令示例: 建立容器使用 host 模式:

docker run --net=host -itd --name nginx-1 nginx 
複製程式碼

一般這時我們 netstat -at 檢視宿主機埠,就可以看到 80 被使用。

如果不能啟動 ,說明本機的 80 已經被佔用

host 的特點: host 模型比較適合於,一臺宿主機跑一個固定的容器,比較穩定。或者是一個宿主機跑幾個佔用不同埠容器的應用場景,他的網路效能是很高的。 host 模型啟動的容器不會有任何地址,他其實是使用了宿主機的所有資訊。