Hello Docker
官方安裝教程:https://docs.docker.com/install/linux/docker-ce/ubuntu/
進去選好對應系統/發行版, 照着命令複製-粘貼-運行。 就能夠安裝成功(根本不須要多餘操做)
Image(鏡像)
-
docker search
docker search python # 列出dockerhub 提供的 image
-
docker pull(下載)
docker pull python:3.7 # 從 dockerhub下載 image 冒號:數字 用來指定版本(不指定就是最新版本)
-
docker images(列出)
docker images # 列出本地鏡像 (或 docker image ls)
docker images py* # 也能夠經過名稱來篩選查看 image, 也可以使用通配符
-
docker rmi(刪除)
docker rmi "image名" 或 "imageID" # 刪除 image
docker rmi python -f # 強制刪除(當image內有容器運行沒法刪除時,可經過-f強制刪除)
若是兩個image有相同 "imageID",會刪除失敗, 這時能夠考慮用 "image名" 來刪除
若是兩個image有相同的 "image名", 那麼能夠考慮用 "image名:Tag" 來刪除
-
docker save(保存備份)
方式1:docker save python > python.tar # 可追加多個image來 把多個image打包保存
方式2: docker save python -o python.tar
python.tar文件 可分享傳輸,給別人還原加載使用
注: 上令爲例,若是有多個python版本, 那麼會將全部python images 都會打包在一塊兒保存
若是你有多個鏡像, 爲了不混淆,必定要指定一下版本號 docker save python:latest
-
docker load(還原)
方式1: docker load -i python.tar
方式2: docker load < python.tar
-
docker tag(更名,改版本號)
docker tag python:latest py:3.7 # 把 "python:latest" 改成 "py:3.7 "
注1: 若image名不爲<none>, 那麼首先會將 image 複製建立一份,而後更名
注2: 若原image名爲 <none> ,那麼 更名後,會直接在原有image上直接更名
-
docker inspect(查看詳細信息)
docker inspect python
-
docker history(查看分層歷史信息)
docker history mypython:3.7
Container(容器)
-
docker create(建立)
docker create --name py-con python:latest # --name後自定義名字, 最後指定哪個鏡像
docker create -it python:latest python # 建立帶有標準輸入環境的容器,並執行python命令
-t 爲了給容器建立一個 terminal
-i 爲了給容器提供一個 標準輸入流 (不然,容器終端裏沒法輸入)
注:建立默認是 created狀態, 須要下面 docker start 命令來啓動
-
docker start(開啓)
docker start -ai 容器ID # 以標標準環境開啓容器
-a 表明提供標準輸出
-i 同create -i ,提供標準輸入
-
docker run(建立+啓動, 推薦)
docker run -it python:latest python # 一套搞定 create+start 的繁雜過程, -it同上不解釋
# 命令防混淆解釋: 根據python:latest鏡像 ,建立並執行容器,同時執行 python命令
docker run -d -it python:latest python
# 其餘不變,多加一個 -d, 能夠建立並放入 "後臺" 執行 (不加-d , 默認"前臺")
docker run -dit --rm python:latest python
# --rm 參數表明 容器中止,即(exited狀態), 就會自動刪除。
docker run --network bridge -itd mypython:latest python
# --network 表明指定網絡(若不指定,默認也是bridge,見下面 網絡章節)
docker run -dit -p 6006:6379 redis
# 端口映射, 宿主機(6006):容器(6379) (-P表明容器內部全部端口 與宿主機隨即映射)
docker run --restart always
# --restart always 表明 docker服務重啓時, 裏面的容器也會跟着重啓
-
docker stop(終止,結束)
docker ps # 查看一下 "運行中容器ID"
docker stop 容器ID # 中止 "運行中" 的容器 ( 默認 10秒鐘後 才中止)
docker stop -t 0 374 # -t指定時間 0秒後, 即瞬間就能夠中止
擴展(中止全部正在運行的容器):
docker stop $(docker ps -q) # -q參數表明只顯示容器ID
-
docker restart(重啓)
docker restart -t 0 281 # 0秒重啓
-
docker pause(暫停)
docker pause 281 # 暫停容器內的全部進程, 注意是暫停, 不是終止
-
docker unpause(繼續)
docker unpause 281 # 把暫停的容器,繼續開啓
-
docker ps(查看)
docker ps # 列出全部 "運行中" 的容器
docker ps -a # 列出全部 容器
-
docker logs(查看輸出日誌)
docker logs 281 # 查看容器內部輸出日誌
docker logs -f 281 # -f 表明阻塞監控, (和 tail -f 一個道理)
-
docker rename(重命名)
docker rename 281 python # 把 281的容器 更名爲 python
-
docker inspect(查看容器詳細信息)
docker inspect 374 # 查看容器全部信息
-
docker rm(刪除)
docker rm 容器ID # 刪除已中止的容器
docker rm 容器ID -f # 強制刪除(運行中)等特殊狀況的容器
-
docker attach(進入到容器命令執行處)
docker run -itd python:latest python # 新建立容器,名執行 python命令
docker attach 281 # 直接進入281這個容器,並直接跳到 python控制檯內部
"注: 進入python控制檯後,再退出去,就意味着, 容器的退出。"
-
docker exec(執行命令)
docker exec -it 281 python # 在"容器外部", 執行"內部容器"的 python命令
"注: 與上一條attach不一樣的是,退出python控制檯後,容器依舊運行!(由於是在容器外面執行的python命令)"
Container and Images(容器與鏡像關聯)
-
docker commit (把容器"封裝"成一個新鏡像)
docker commit 4d mypython:3.7 # 把4d這個容器全部內容,封裝爲一個"名字:版本"叫"mypython:3.7"的鏡像
-
docker export (容器導出爲一個文件)
docker export fc8 -o mypython.tar # 把此容器導出爲一個.tar文件 ,和前面說過的 image的 save相似
-
docker import (把export導出的文件導出,並"生成"一個鏡像)
docker import mypython.tar mypython:latest
注: 把export導出的 mypython.tar文件導入 並 直接建立一個 mypython:latest 的 鏡像
-
docker commit & docker import區別
前面說過:
docker commit 是 直接把一個container 封裝爲一個image
docker import 是 把export導出的container.tar文件 再 導入進來,並從新生成一個 新 image
docker commit 是繼承封裝的,並建立具備分層歷史記錄 (docker history imageID 便可查看)
docker import 是直接生成的,不具備分層記錄 (docker history imageID 便可查看)
網絡
-
docker network ls (查看)
docker network ls
bridge(網橋):容器默認網絡模式
容器-容器網絡鏈接:
container1(etho0)--veth1--Docker(bridge)--veth2--container2(etho0)
容器-宿主機網絡鏈接:
container1(etho0)--veth1--Docker(bridge)--宿主機(etho0)
注: veth是建立網絡時,自動建立的,不須要手動管理
host(主機): 容器網絡和主機使用同一個網絡
容器-容器網絡鏈接:
container1(etho0)--宿主機--container2(etho0)
容器-宿主機網絡鏈接:
container1(etho0)--宿主機
容器網絡(特殊host):
container1--container2 # 就是 ‘每一個容器互相把對方認做爲 宿主機’ 這個意思
使用方法:
docker run -it --network container:24f1 mypython:latest ls
# container:24f1 的container是語法關鍵詞 24f1是鏈接的對方容器()
null(無網絡):全部容器無網絡
-
docker network create (建立)
docker network create -d bridge mybridge # 可建立多個bridge
docker network create -d host myhost # 只可建立一個host(默認就有一個,故沒法建立)
docker network create -d null mynull # 只可建立一個null(默認就有一個,故沒法建立)
-
docker network rm (刪除)
docker network rm ab5
注:默認自帶的網絡不能夠刪除(null host 和 自帶的一個 bridge)
-
docker network connect (給容器綁定網絡)
docker network connect mybridge 4c4 # 給4c4這個容器綁定一個 mybridge網絡(自定義的bridge)
docker inspect 4c4 # 查看一下容器信息,最下面就是網絡
注:一個container 能夠綁定 多個bridge 網絡,
-
docker network disconnect (給容器 解除綁定的網絡)
docker network disconnect mybridge 4c4 # 給容器解除綁定網絡mybridge
注: 一個container 中 bridge 和 none 網絡不能夠共存, (若衝突,則先disconnect再connect)
注2:host 網絡不能 connect 和 disconnect
數據卷 (volume)
-
docker volume create(建立數據卷)
docker volume create myvolume
注: myvolume爲數據卷名
-
docker volume ls(列出數據卷)
docker volume ls
注: 若數據卷未指定名字,當 使用docker run -v 方式時,則會新建數據卷ID,並以此ID命名。
-
docker volume prune(刪除未被容器使用的 全部 數據卷)
docker volume prune
注:容器佔用的數據卷,刪不了
-
docker volume rm (刪除 一個 或 多個 指定數據卷)
docker volume rm myvolume
注: 刪除 myvolume這個數據卷,固然也能夠連續參數,追加刪除多個數據卷
-
掛載數據卷
"""意義: 可讓 宿主機 與 容器 數據聯通共享"""
方式1 (-v參數)
-v使用方式1:(指定路徑映射掛載)
docker run -itd -v /root:/root mypython:latest python # -v 宿主機路徑:容器路徑
測試:
cd /root
touch aaa.txt # 宿主機建立文件 aaa.txt
docker exec -it cfb ls /root # 結果可看見容器裏面也有 aaa.txt 文件
-v使用方式2:(指定數據卷對象 映射掛載)
docker run -itd -v myvolume:/root mypython:latest python # 冒號前面 變成了myvolume
注1: 這個myvolume就是一個數據卷對象, 執行上面這條命令,就會爲咱們自動建立這個數據卷對象
注2: 因爲沒有宿主映射路徑,那麼映射的宿主路徑 是什麼呢??
docker volume inspect myvolume # 結果Mountpoint後面的就是,宿主機映射的 默認鉤子路徑
cd /var/lib/docker/volumes/myvolume11/_data # 此路徑和volume名有關
touch bbb.txt # 宿主機建立文件 bbb.txt
docker exec -it 916 ls /root # 打印結果可見,容器內部也有bbb.txt,說明成功共享。
方式2:(--mount參數,一樣包括 -v的兩種使用方式, 另外還新增另外一種 文件"緩存"掛載方式)
docker run -itd --mount type=volume,src=myvolume11,dst=/root mypython:latest python
注:
type: 指定類型(路徑映射: bind)或 (數據卷對象映射: volume) 或(內存映射:tmpfs)
src: 對應上面方式1(宿主機路徑) 或 對應上面方式2(數據卷名) 或 省略此項(對應新增)
dst: 容器路徑
逗號分隔,其餘沒變
docker run -itd --mount type=tmpfs,dst=/root mypython:latest python (tmpfs"緩存"掛載)
"綜上,可總結爲3種掛載選擇用途":
一. "宿主路徑 與 容器路徑" 映射掛載
二. "數據卷 與 容器路徑" 映射掛載
三. "宿主內存 與 容器路徑" 映射掛載
"綜上,可總結爲2種掛載參數使用":
1、 "-v 參數" 2種用途 (路徑映射 和 數據卷對象映射)
2、 "--mount 參數" 3種用途 (路徑映射 和 數據卷對象映射 和 內存映射)
-
容器之間共享數據
"""藉助已經擁有數據卷的容器 來 建立一個新容器"""
docker run -itd --volumes-from 6252 python:latest # 藉助6252容器建立新容器,來共享數據卷
驗證:
docker exec -it 97db touch /root/abc # 新容器 建立一個文件abc
docker exec -it 6252 ls /root # 舊容器查看 ,也有新文件abc,共享成功
-
細節注意事項
1、若將 "空數據卷" 掛載到 容器非空目錄中,則"此容器目錄下的內容 會copy一份到 數據卷中"
2、若將 "非空數據卷" 掛載到 容器任意目錄中,則"數據卷的數據 會copy到這個目錄中,並將此目錄原數據隱藏"
更通俗一點理解就是:
數據卷大哥說:"若是我這裏有數據, 你的容器來掛載,你的數據就會被我這裏面的數據覆蓋。。"
數據卷大哥又說:"若是我這裏是空的(沒有數據),那麼 你的容器來掛載, 你的數據就要提供一份給我"
DockerHub(倉庫)
無認證 私有倉庫
-
搭建倉庫
docker pull registry # 拉取 registry鏡像
docker run -itd \
--restart always \ # docker重啓時,此容器也跟着重啓
--name myregistry \ # 指定容器名
-p 6006:5000 \ # 端口映射 (registry服務默認爲5000端口,映射爲6006)
-v /root:/var/lib/registry \ # 綁定數據卷 (持久化存儲), 冒號後面的容器路徑時默認的
registry # 拉取的 registry鏡像
驗證:(一種web服務,因此經過固定Url訪問便可)
外部瀏覽器驗證: 瀏覽器輸入 服務器外網IP:6006/v2/_catalog 便可
服務器內部驗證: curl 127.0.0.1:6006/v2/_catalog
-
上傳鏡像
1、先把要上傳的鏡像更名
docker tag mypython:latest 127.0.0.1:6006/mython_hub
注: 目標名固定格式(需注意,必須此格式): IP:Port/新鏡像名
2、開始上傳
docker push 127.0.0.1:6006/mython_hub # docker push 鏡像名,注意這裏用ID很差使,必須用這名
3、驗證
同上面搭建倉庫時的驗證方法, 可看見結果 repositories列表中多了一個 剛剛上傳的鏡像
curl 127.0.0.1:6006/v2/_catalog
-
下載鏡像
docker pull 127.0.0.1:6006/mython_hub
注: 這個名就是上傳時候的 那個名, 同樣的
Dockerfile(配置文件式)
-
Dockerfile認知
Docker 與 docker命令的關係就至關於 shell編程 與 單條命令
主要就是把上面講的全部命令連起來,腳本式執行, 固然dockerfile也有本身的語法關鍵詞。
Dockerfile是基於緩存,因此裏面的文件內容(某條命令) "若是未發生改變,則不會從新執行(用的是緩存)"
Dockerfile機制:
1、若在結尾每"追加"一條新命令,從新構建Dockerfile時,"只會執行這個新命令,其餘舊命令都會使用緩存"
2、若新命令 是在"中間插入編寫的",則此條新命令"以前的命令用緩存", "以後"的命令都會從新執行一遍,
3、FROM 關鍵字是 Dockerfile的入口。
新命令只要不是 寫在 "FROM的下一條", 那麼全部新命令及其以後的命令都會在 構建Dockerfile時-->
觸發"層層封裝"機制 ,即每條"非緩存命令"運行一遍,都會commit封裝一層鏡像
-
Dockerfile構建
docker build /Dockerfile所在路徑 -t mypython:v2
注1: 指定Dockerfile所在路徑便可,build會自動幫咱們找到dockerfile文件
注2: 若是Dockerfile就在當前路徑下,那麼能夠用 . 來替代絕對路徑
注3: -t 給鏡像指定名字
Dockerfile語法
-
FROM
"下載鏡像,相似 docker pull"
FROM python:latest # 一樣能夠指定版本號
-
RUN | CMD | ENTRYPOINT
這三個 命令 都有共同的 2種書寫方式:
1、(exec)格式--當前進程執行
eg: python -V # 就是玩linux的命令正常寫
2、(shell) 格式--子進程執行
eg: ["python", "-V"] # 命令與做爲字符串列表來書寫, 和py的scrapy的shell相似
RUN:
"構建鏡像過程當中"執行的命令, 好比安裝東西之類的。。(可寫多個)
CMD:
啓動容器時 執行的命令, 就和 以前說過的 docker run 跟的命令是同樣的
"可是 docker run 要是指定了一個命令,那麼 這個CMD配置就會失效"
ENRTYPOINT:
和CMD相似, 不過 在docker run 指定新命令是, ENTRYPOINT的命令是不會被覆蓋的。都會執行
-
ADD | COPY
"""將宿主機文件 拷貝 到鏡像的某個目錄中"""
COPY aaa.txt /root # 將aaa.txt 拷貝到 鏡像的/root目錄中
ADD aaa.txt /root # 和COPY同樣,不過 ADD能夠將壓縮文件拷貝進去後,"自動解壓"
-
ENV
"""就至關於編程語言的 變量賦值"""
ENV name=python
ENV nickname=$name # $name 意爲取出 name變量的值
-
WORKDIR
"""切換目錄 相似cd命令"""
WORKDIR /root
-
VOLUME
"""添加數據卷"""
VOLUME /root # 就至關於前面說過的docker run -v /root, 即自動建立一個數據卷映射到 容器的/root
-
EXPOSE
"""暴露端口"""
EXPOSE 6379
EXPOSE 3306 # 能夠用多個 EXPOSE 暴露多個端口
注1: 暴露端口後,能夠經過 前面說的 docker run -P 來作自動端口映射
注2: 或者不暴露端口,直接使用手動映射-p,都是能夠的。
-
官方模板參考網址
官方文檔:https://docs.docker.com/engine/reference/builder/
各類開源Dockerfile模板:https://github.com/docker-library/docs/tree/master/
Docker Compose
-
Docker-Compose認知
1、Dockerfile 能夠看做是 Docker命令的組合
2、Docker-Compose 能夠看做是 Dockerfile的組合(也稱做 容器編排工具)
3、Docker-Compose 文件默認名爲 docoker-compose.yaml
4、docoker-compose.yaml 文件指令中間都有空格 eg: version: 3.7(3.7以前是有空格的)
5、docoker-compose.yaml 採用縮進對格式語法進行區分
-
Docker-Compose安裝
官方安裝教程:https://docs.docker.com/compose/install/
從上往下,命令複製-粘貼-運行。。。Easy略
-
Docker-Compose文件指令
version: "3.7" # 必有
# 此版本號與docker版本對應地址: https://docs.docker.com/compose/compose-file/
services: # services關鍵字,寫上就行, 必有
mypython: # mypython是我隨便起個名
build: . # Dockerfile的路徑位置, build是構建Dockerfile文件的
ports:
-"6006:3003" # 注意-後面是有空格的,markdown語法充衝突,我就沒寫空格
command: xxxx # 覆蓋Dockerfile中的 CMD
depends_on: # 依賴的服務, (被依賴的先執行,也就是myredis先執行)
-myredis # -後有空格
myredis: # 同理 myredis 也是我隨便起的名
image: redis # 指定一個成品鏡像 相似DockerfilE的 FROM指令
container_name: myredis # 指定容器名
networks: # 使用下面建立的mynet網絡
-mynet # (同-後有空格,避免markdown語法衝突)
volumes: # 使用下面建立的myvolume數據卷,並映射到容器的/root目錄
-myvolume:/root # -後有空格,(特別注意 :後面不容許有空格)
hostname: myredis
# 由於容器建立時IP可能動態改變,指定名稱,則可經過名稱來代替IP
# 若不指定 hostname, 則默認爲服務名, 即 myredis
networks: # 建立網絡
mynet: # 給網絡起名爲 mynet
driver: "bridge" # 指定爲橋接模式
volumes: # 建立數據卷
myvolume: # 給數據捲起名爲 myvolume
driver: "local" # 默認就是local,即數據卷存儲在宿主機的目錄下
-
預檢查docker-compose.yml文件語法格式是否有誤
docker-compose config
注:須要在 docker-compose.yml 所在目錄下執行
-
啓動/中止 docker comopse
docker-compose up # 前臺終端阻塞執行(就是執行以後,你不能在終端輸入東西了)
docker-compose up -d # 後臺終端非阻塞執行 (做爲服務同樣後臺執行)
docker-compose stop # 中止編排(即中止 全部 編排運行的容器)
END