《每天5分鐘,玩轉Docker容器技術》筆記

文|Seraph

01 | 容器生態環境概覽

容器生態環境

  1. 安裝(Ubuntu)
  • 安裝docker依賴包:apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
  • 添加docker的官方GPG祕鑰:curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • 將docker源(穩定版本)添加到/etc/apt/sources.llistadd-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  • 更新apt包引用:apt-get update
  • 安裝Docker Engine-Community 和 containerd :apt-get install docker-ce docker-ce-cli containerd.io
  1. 由於Docker Hub在國外,下載鏡像會比較慢,DaoCloud提供國內鏡像服務。
    註冊賬戶並登陸後,點擊右上角的小火箭打開加速器
    加速器
    拷貝下面的鏈接在相應的系統下執行即可。
    加速指令
    然後使用systemctl restart docker.service重啓Docker deamon。

  2. 基本docker命令

命令 含義
docker run 運行容器
docker pull 拉取鏡像
docker images 查看鏡像
docker commit 提交容器更新至新的鏡像,添加--no-cache參數表示不是用緩存。
docker build 構建鏡像
docker history 查看鏡像構建歷史
docker tag 給鏡像打標籤
docker login 登錄docker hub
docker push 上傳image至docker hub
docker search 搜索Docker Hub中的鏡像
docker rmi 刪除Docker Host上的鏡像
docker rm 刪除容器
docker ps 查詢Docker Host上運行的容器,加上-a查詢所有的容器(包含停止的)
docker stop 停止容器
docker attch 直接進入容器啓動命令的終端,不會打開新的終端
docker exec 在容器打開新的終端
docker logs 查看容器輸出
docker start 啓動容器
docker restart 重啓容器
docker kill 終止容器
docker pause 暫停容器
docker uppause 恢復暫停的容器
docker create 創建容器
docker info 查看docker相關信息
docker inspect 查看容器信息
docker volume 查看容器掛載信息
docker cp 容器與host數據拷貝
docker top 查詢容器內運行進程情況
docker stats 監控容器資源使用情況
docker save/load 導出/導入鏡像
docker export/import 導出/導入容器

02 | 容器技術

  1. 容器由共享主機的內核系統,這個是與虛擬機最本質的區別。
    容器一般由兩部分組成:應用程序本身、依賴(庫等)。
    所以容器可以看成一個個相互隔離的進程。佔用的體積也小。
  2. 容器最關鍵的特性是:可移植性。解決了不同環境下部署難得問題。
  3. Docker核心組件
    Docker核心組件

查詢docker運行狀態:systemctl status docker.service

  1. 修改遠程登陸功能(應用場景應該很低)
  • 修改/etc/systemd/system/multi-user.target.wants/docker.service文件,在ExecStart後面添加-H tcp://0.0.0.0
  • 重啓Docker daemon
systemctl daemon-reload
systemctl restart docker.service
  1. Docker鏡像
    以Dockerfile構建而來,Dockerfile構建過程中,又是利用docker commit進行構建。

  2. docker run命令 = docker pull + 啓動

03 | Docker鏡像

一、 Dockerfile
  1. 指令
指令 含義
FROM 指定基礎鏡像
MAINTAINER 設置鏡像作者
CMD 容器啓動時運行指定的命令,只有最有一個CMD會生效,同事CMD會被docker run 之後的參數替換
RUN 運行指定指令
COPY 從build context複製文件到容器中
ADD 與COPY類似,但是src文件爲歸檔文件(tar\zip\tgz等),會被自動解壓
ENV 設置環境變量,環境變量可被後面的指令使用
EXPOSE 指定容器中的進程監聽某個端口
VOLUME 將文件或目錄聲明爲volume
WORKDIR 設置工作目錄
ENTRYPOINT 設置容器啓動時運行的命令,只有最後一個會生效,且CMD或docker run值後的運行參數會被當作參數傳遞給ENTRYPOINT
  1. 兩種運行格式Shell和Exec格式:
    Shell格式(默認調用/bin/sh -c):<instruction> <command>
    Exec格式:<instruction> ["executable", "param1", "param2", ...]

  2. 由於每一層都會創建鏡像層,當有些由於不同時間執行可能受影響的指令,需要和其他執行搭配在一樣進行執行。
    比如apt update,不能單獨佔一行,否則會使用之前的鏡像層。

  3. 當CMD與ENTRYPOINT配合使用時,CMD提供參數,ENTRYPOINT必須使用Exec格式。

二、原理
  1. 容器維護的是rootfs(用戶空間),內核空間都是使用主機的Kernel,所以在容器內查詢Kernel,都和主機一樣。
    所以當容器本身應用對內核版本有要求的時候,不建議使用容器,推薦使用虛擬機。
三、構建鏡像
  1. 一般能用官方或者別人創建穩定的鏡像,一定要先用。沒有才考慮自己構建容器。
    推薦使用Dockerfile方式構建鏡像,不推薦使用docker commit方式創建。
    由於不能複用,再者使用者也不知道是創建出來的,無法對鏡像進行審計。

  2. 每執行一條指令,對容器修改後,都會使用類似docker commit操作,新建鏡像層。這樣的話,如果其中某個指令執行失敗,也能得到前一個指令執行後構建出來的鏡像。

  3. 鏡像是分層結構的,同時我們在容器中的修改只會保存在容器層。
    Copy-on-Write
    添加文件:在容器中創建文件,新文件被添加到容器層。
    讀取文件:從容器層往下,再到鏡像層,查找文件。
    修改文件:先如讀取文件時一樣查找文件,然後將文件複製到容器層進行修改。
    刪除文件:先如讀取文件時一樣查找文件,在容器層中記錄此刪除操作。(實際上不刪除文件)

四、分發鏡像
  1. 每個repository可以有多個tag,所以當發新版本的時候,可以使用tag管理版本關係。
    我們可以把tag看成linux下的鏈接,爲了我們用通用的名字使用特定的版本。
    Image的ID是唯一,如果使用docker images查詢ID相同,說明是同一份鏡像,只不過tag不一樣而已。

  2. 搭建本地Registry
    docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2
    repository的完整格式是:[registry-host]:[post]/[username],只不過Docker Hub可以省略。
    私人庫其實就是在我們機器上啓動一個Registry容器,使用上僅是要加上repostitory完整格式指明是哪個私人庫,其它和訪問Docker Hub一樣。

04 | 容器

一、Run容器
  1. 當進程退出時(或OOM),Docker會根據--restart策略判斷是否要重啓容器。
  • 當加--restart=always參數時,表示無論容器什麼原因退出,都會重啓容器。
  • 當加--restart==on-failure:3參數時,表示容器退出非0時,則重啓容器。
  1. 內存限制
  • -m:內存限制
  • --memory-swap:設置內存+swap的使用限制
  • -vm:啓動內存工作線程數
  • -vm-bytes:每個線程分配內存數
  1. CPU限制
  • -c:CPU優先級,數字越大,佔比越高。
  • --cpu:CPU數量
  1. block IO帶寬限額
  • --blkio-weight:block IO權重。
  • --device-read-bps:限制讀某個設備的bps
  • --device-write-bps:限制寫某個設備的bps
  • --device-read-iops:限制讀某個設備的iops
  • --device-write-iops:限制寫某個設備的iops
    其中bps表示每秒讀取多少byte。
    iops表示每秒IO的次數。

測試例子:
<1> 創建限制寫/dev/sda的速率30M/s:docker run -it --device-write-bps /dev/sda:30MB ubuntu
<2> 在容器中運行dd測試:time dd if=/dev/zero of=test.out bs=1M count=800 oflag=direct
progrium/stress壓力測試鏡像。

二、刪除容器
  1. 刪除所有停止的容器docker rm -v $(docker ps -qf status=exited)
三、實現容器的底層技術
  1. cgroup實現資源限額。
    cgroup的主目錄爲:/sys/fs/cgroup
    按cpu、memory、blkio等區分的多個子目錄:
    每個容器的限額會在相應的子目錄下的docker目錄下新建一個以容器ID爲名的目錄。其中保存着該容器的限額信息。

  2. namespace實現資源隔離。
    隔離的資源有:Mount、UTS(hostname)、IPC(共享內存和信號量)、PID、Network、User。

04 | Docker網絡

Docker容器安裝時會自動在host上新建三個網絡,用docker network ls可以查詢到。
docker網絡run參數:--network

一、 none網絡

none網絡表示在這個網絡下的容器除了lo外,沒有其他任何網卡。適用於需要網絡隔離的場景

二、host 網絡

host網絡表示共享Docker host的網絡棧。
使用host網絡的有點是網絡性能最好。但因爲是和host共享網絡棧,所以需要避免端口衝突。

三、bridge網絡

Docker安裝時會創建一個命名爲docker0的linux bridge。我們新建的容器默認網絡模式爲bridge,所以會掛載到docker0上。不過虛擬網卡是成對的,一個在host上,與docker0連接;一個在容器內。

  1. 通過docker network inspect bridge命令可以查看網橋設置。
  2. brctl show查看網橋信息。
四、user-defined網絡
  1. 可以使用docker network create創建網絡
  • --driver:網絡驅動,bridge、overlay和macvlan。
  • --subnet:指定子網。
  • --gateway:指定網關。
  • --ip:指定ip(前提已經使用–subnet指定了子網)
    eg. docker network create --driver bridge --subnet 172.22.16.0/24 --gatway 172.22.16.1 my_net2
  1. 使用docker network connect可以給容器添加網絡。
    建立在同一個網絡上的容器才能IP通信,所以當兩個容器需要IP通信時,可以讓其中一個容器添加另一個容器的網絡即可。
五、容器間通信

容器間可通過IP、Docker DNS Server或joined容器三種方式通信。

  1. 建立在同一個網絡上的容器即能IP通信。但是僅能通過靜態IP。
  2. Docker DNS Server通信,可以給容器主機命名,通過對方的主機名與在一個user-defined網絡(其它網絡不行)上進行通信。
  3. joined容器,我們可以通過joined容器的形式與容器共享網絡棧:docker run -it --network=container:容器名
六、與外部網絡連接
  1. 我們默認以bridge模式建立的容器是能與外部網絡連接的。其主要是docker0通過NAT方式與外部連接。
  2. 外部網絡訪問容器,通常是根據容器映射到host上的端口。
    每一個映射的端口,host都會啓動一個docker-proxy進程來處理。

06 | Docker 存儲

一、storage driver
  1. storage driver實現了多層數據的堆疊。docker支持多種storage driver實現,優先使用系統本身默認的storage driver,這個樣穩定性更好。
二、Data Volume

對於需要持久化的數據(即使容器刪除,數據也保留),需要使用Data Volume來處理。
有兩種方式:bind mount、docker managed volume。

  1. bind mount
  • 使用方式:在docker run加入-v <host path>:<container path>[:讀寫屬性]即可。
    其實就是目錄映射。
  • Data Volume默認是可讀可寫,可以指定添加:ro只讀
  • 缺點:需要指定目錄,移植後如發現host沒有指定目錄會出錯。
  1. docker managed volume
  • 使用方式:在docker run加入-v <container path>即可。docker會爲容器自動生成host共享目錄。
  • 當移植時,不會自動打包數據,只會生成相應的掛載目錄。
  1. 另一種數據共享方式:volume container
    volume container的意識是專門爲其它容器提供volume,其容器只需被create就行,不用run。
  • 新建volume容器示例:docker create --name vc_data -v ~/htdocs:/usr/local/apache2/htdocs -v /other/useful/tools busybox
  • 其它容器使用volume容器示例:docker run --name web1 -d -p 80 --volumes-from vc_data httpd
  1. 在Dockerfile文件中使用VOLUME、ADD添加共享文件或volume。(自包含的)
  2. volume刪除
  • 刪除容器是加上-v參數可以將容器使用到的volume也刪除,但前提是沒有其它容器也使用了。
  • 可以使用docker volume ls查詢volume的情況。如果刪除容器時,沒有加-v參數,docker volume ls還是能查找volume存在的。
    如要繼續刪除,可以使用docker volume rm
  • 刪除所有孤兒volume指令:docker volume rm $(docker volume ls -1)

07 | 多主機管理

docker machine,目前沒有實際環境,後面再試。

99 | 問題解決
  1. 在ubuntu下使用--memory-swap會彈出Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
    解決:嘗試在aliyun服務器改動過配置文件,然後服務器就起不來了。。。。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章