通過docker末盔,我們交付的東西不再只是代碼、配置文件座慰、數(shù)據(jù)庫定義等陨舱,而是整個應(yīng)用程序運行環(huán)境:“OS+各種中間件、 類庫+應(yīng)用程序代碼”版仔。它所需的全部環(huán)境只是一臺僅僅安裝了兼容版本的Linux內(nèi)核和二進制文件最小化的宿主機游盲。主要特點是:
- 原生的Linux容器格式
- 使用Linux內(nèi)核的namespace,能夠隔離文件系統(tǒng)蛮粮、進程益缎、網(wǎng)絡(luò)
- 文件系統(tǒng)隔離。每個容器有自己的root文件系統(tǒng)
- 網(wǎng)絡(luò)隔離然想。不同容器間的網(wǎng)絡(luò)默認是互相隔離的
- 資源隔離莺奔。使用Linux內(nèi)核的Cgroup實現(xiàn)硬件資源分配
- 寫時復(fù)制。提升了文件系統(tǒng)性能
- 日志变泄。STDOUT令哟、STDERR、STDIN都會記錄日志
- 交互式shell妨蛹。給容器提供了shell
docker run
- -i 交互模式運行容器屏富,通常是-it一起使用
- -t 給容器分配輸入終端,通常是-it一起使用
- 單獨使用-d 會讓容器在后臺運行并馬上退出控制臺滑燃,同時返回容器id役听,docker run默認的cmd參數(shù)是/bin/bash,執(zhí)行完此cmd參數(shù)后就關(guān)閉了〉溆瑁可以讓cmd參數(shù)是一個 駐留在進程中長期運行的命令(例如tail -f /dev/null )甜滨,或者使用-itd解決啟動失敗的問題
- -p 主機端口:容器內(nèi)端口
- --name 指定容器名,唯一瘤袖,用來替代容器id
- -e 指定環(huán)境變量
- --env-file 可以是單個文件衣摩,也可以是多個文件
- --rm 一般用在開發(fā)調(diào)試過程中短期運行,等價于在容器推出后執(zhí)行docker rm -v捂敌,即在退出容器時自動清理容器和掛載卷艾扮,所以與-d選項互斥
- -v
- --mount type=bind,source=宿主目錄,target=容器目錄
docker ps
- docker ps 顯示所有正在運行的容器
- docker ps -a 顯示所有容器,包括未運行的
- docker ps -l 顯示最近創(chuàng)建的容器
- docker ps -a -q 此參數(shù)表示只顯示容器ID
docker exec
docker attach可以attach到一個已經(jīng)運行的容器的stdin占婉,然后進行命令執(zhí)行的動作泡嘴。要注意從這個stdin中exit,會導(dǎo)致容器的停止
- d 表示只在內(nèi)部執(zhí)行某個命令逆济,而不進入酌予,例如
docker exec -d demo touch /etc/new_config_file
表示在此容器內(nèi)創(chuàng)建文件 - exit退出容器
docker logs
- -f 實時查看內(nèi)部日志
- -f --tail 10 實時打印最新10條
- -ft 同時打印時間
- Ctrl + c 退出日志
- 結(jié)合日志驅(qū)動實現(xiàn)自定義的日志打印
鏡像類型
dangling類型:Repository和tag都為空
docker image ls -f dangling=true
查看
docker image prune
清空
更多常用命令
指令 | 描述 | eg |
---|---|---|
search | 從鏡像倉庫搜索鏡像 | docker search nginx |
pull | 從鏡像倉庫拉取 | docker pull nginx:latest |
ls | 查看本地鏡像 | docker image list |
images | 和list一樣,不過后面跟鏡像名奖慌,可以篩選 | docker images |
rmi | 從本地刪除鏡像(指定IMAGE ID) | docker rmi -f $(docker images -q) |
build | 從Dockerfile構(gòu)建鏡像 | docker build -t imageName:tagName dockerfileDir |
history | 查看鏡像分層 | docker image history nginx |
push | 推送 | - |
prune | 移除未使用抛虫、未引用的鏡像 | - |
tag | 標記目標鏡像生成新版本的鏡像 | docker tag nginx:1.11 nginx:v1 |
export | 導(dǎo)出容器為tar | docker export 容器id > nginx.tar |
import | 導(dǎo)入tar為容器 | docker image import nginx.tar nginx:1.11 |
save | 保存鏡像為tar | docker image save nginx:1.11 > nginx1.11.tar |
load | 加載tar為鏡像 | docker load < nginx1.11.tar |
run | 啟動鏡像為容器 | docker container run -itd --cpus 1 --name nginx02 (使用一個核) docker container run -itd --memory 512m --name nginx02(限制512m內(nèi)存) |
ps | 列出容器, -a表示包括未運行的 | docker ps -a |
start | 啟動容器 | docker start 容器名或id |
stop | 關(guān)閉容器 | docker stop 容器名或id |
restart | 重啟容器 | docker start 容器名或id |
rm | 移除容器,示例命令表示移除所有容器 | docker rm -f $(docker ps -q -a) |
inspect | 查看容器詳情 | docker inspect 容器名或id或鏡像名:標簽 |
exec | 進入容器 | docker exec -it 容器名或id bash |
logs | 查看內(nèi)部日志 | docker logs 容器名或id |
kill | 殺掉運行中的容器 | docker kill $(docker ps -a -q) |
top | 查看某運行容器中的進程简僧,不進入容器內(nèi)部即可查出 | docker top demo |
stats | 查看某運行容器中的資源統(tǒng)計信息 | docker stats demo |
volume數(shù)據(jù)卷掛載容災(zāi)
保證數(shù)據(jù)存在于數(shù)據(jù)卷而不是容器中建椰。在容器中的掛載點保存文件時,宿主機也能看到對應(yīng)的映射文件
ls /var/lib/docker 查看image岛马,containers棉姐,image存儲位置
有兩種掛載模式,第一種volume(推薦)
docker run -it -v my-volume:/mydata alpine sh
若不指定-v蛛枚,則自動在/var/lib/docker/volumes創(chuàng)建一個掛載點(掛載點的名稱沒有可讀性)谅海。上述命名了一個掛載點脸哀,容器內(nèi)的/mydata目錄掛載在了/var/lib/docker/volumes/my-volume/_data目錄蹦浦。如果主機是空的而container中的目錄有內(nèi)容,那么docker會將container目錄中的內(nèi)容拷貝到主機中撞蜂,但是如果主機中已經(jīng)有內(nèi)容盲镶,則會將container中的目錄覆蓋
第二種bind mount
host機器的目錄路徑必須為全路徑,如果主機上的目錄不存在蝌诡,docker會自動創(chuàng)建該目錄溉贿,如果container中的目錄不存在,docker會自動創(chuàng)建該目錄浦旱,無論container是否有數(shù)據(jù)被掛載的目錄都會被host上的目錄覆蓋掉
ls /var/lib/docker/volumes/
docker volume ls
docker volume create nginx-vol
docker volume inspect nginx-vol
docker run -itd --privileged --name=nginx-test --mount src=nginx-vol,dst=/usr/share/nginx/html nginx
此時/usr/share/nginx/html中的文件夾與宿主主機cd /var/lib/docker/volumes/nginx-vol/_data文件夾相同宇色。可在Dockerfile中使用VOLUME指令來給鏡像添加一個或多個數(shù)據(jù)卷。--privileged表示容器擁有root權(quán)限
docker volume inspect my-volume #查看掛載目錄和類型
四種網(wǎng)絡(luò)模式
使用docker network ls查看所有網(wǎng)絡(luò)
Host:使用host模式的容器可以直接使用宿主機的IP地址與外界通信宣蠕,容器內(nèi)部的服務(wù)端口也可以使用宿主機的端口例隆,不需要進行NAT,host最大的優(yōu)勢就是網(wǎng)絡(luò)性能比較好抢蚀,但是docker host上已經(jīng)使用的端口就不能再用了镀层,網(wǎng)絡(luò)的隔離性不好
Container: 通過為一個容器指定--net container:otherContainerName來依賴于另一個容器的網(wǎng)絡(luò),可以在被依賴的容器的網(wǎng)絡(luò)中使用netstat -antp看到依賴的容器的端口詳情
None: 基本用不上
Bridge: 依賴docker0這個網(wǎng)絡(luò)接口皿曲,Docker默認使用bridge網(wǎng)絡(luò)模式唱逢,每次啟動鏡像,它的容器的IP地址會變化屋休。docker network create --subnet=172.20.0.0/16 --gateway 172.20.0.1 extnetwork
創(chuàng)建自定義的網(wǎng)絡(luò)模式坞古,然后docker run時指定--net extnetwork --ip 172.20.0.2即可分配自定義的網(wǎng)絡(luò),推薦使用自定義網(wǎng)絡(luò)自動分配網(wǎng)絡(luò)ip劫樟,例如docker network create extnetwork
绸贡。使用docker network rm extnetwork
刪除。如果不指定網(wǎng)絡(luò)模式毅哗,那么容器默認使用bridge模式的bridge網(wǎng)絡(luò)听怕,如果多個容器處于不同的bridge網(wǎng)絡(luò)中,需要解決多個bridge網(wǎng)絡(luò)之間的互連問題虑绵。一開始使用--link來連接網(wǎng)絡(luò)尿瞭,后來使用docker network connect sub_net_a1 sub_net_b2
解決,使用docker exec sub_net_a1 ping sub_net_b2
看是否可以連通
重要的點
不同容器間的訪問翅睛,還可以通過宿主機的IP進行連接声搁,注意不能是127.0.0.1,因為在容器中的127.0.0.1指的是本身所處的網(wǎng)絡(luò)而不是宿主機的網(wǎng)絡(luò)
例子
創(chuàng)建網(wǎng)絡(luò)捕发,例如lnmp處于同一個網(wǎng)絡(luò)下
docker network create lnmp
注意數(shù)據(jù)庫主機名就是數(shù)據(jù)庫容器名
https://www.bilibili.com/video/av49731612?p=10
docker desktop
掛載時先到setting -> resources -> file sharing里勾上盤符疏旨,否則會"Unhandled exception: Drive has not been shared"
Dockerfile
解決項目依賴。bulid時把Dockerfile文件所處目錄下的文件全都打包成鏡像扎酷,Dockerfile每行命令生成1個臨時鏡像檐涝,放入緩存中(不需要緩存使用--no-cache),層層推進法挨,最后生成一個最終的鏡像谁榜。每個指令都使用大寫。#表示注釋
指令 | 作用 | eg |
---|---|---|
FROM | 依賴的鏡像凡纳,第1個指令必須為FROM | - |
RUN | 構(gòu)建鏡像時需要內(nèi)部執(zhí)行的命令窃植,默認使用bash模式(適合shell變量語法時),否則使用數(shù)組模式(不支持shell變量語法)例如RUN [ "apt-get", " install", "-y", "nginx" ] | RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME' |
EXPOSE | 運行容器后對外暴露的端口號 | - |
WORKDIR | 進入容器后的默認工作目錄荐糜,ENTRYPOINT和/或CMD指定的程序會在這個目錄下執(zhí)行 | - |
ENV | 設(shè)置容器的環(huán)境變量巷怜,容器內(nèi)使用env查看 | ENV RVM_PATH=/home/rvm RVM_ARCHFLAGS="-arch i386" |
COPY | build時拷貝宿主機的文件到鏡像里 | - |
ADD | 和COPY類似葛超。多了下載鏈接和自動解壓tar包的功能 | - |
VOLUME | 指定容器內(nèi)某些目錄文件能被掛載到宿主機 | - |
CMD | 容器啟動時內(nèi)部執(zhí)行的命令,和RUN的語法一樣延塑,注意CMD的命令會被docker run之后的指定參數(shù)全部替換 | |
ENTRYPOINT | 和CMD類似巩掺,此命令作為命令前綴,可用于接收docker run指定的要執(zhí)行的命令參數(shù)或CMD中的命令參數(shù)页畦,例如docker run指定了-g "daemon off;"胖替,若ENTRYPOINT 是/usr/sbin/nginx ,則會拼接為["/usr/sbin/nginx", "-g", "daemon off;"] |
|
LABEL | 為鏡像添加元數(shù)據(jù)豫缨,通過docker inspect查看鏡像中的標簽信息 | LABEL location="New York" type="Data Center" role="Web Server" |
多階段構(gòu)建最小化鏡像
基礎(chǔ)鏡像選擇:
①scratch独令,這個版本是空鏡像,當你的dockerfile文件里面不需要任何命令時使用
②Alpine好芭,只有5M燃箭,但這個版本使用的標準庫與大多數(shù)發(fā)行版不同,它使用的是 musl libc舍败,這個庫相比于 glibc 更小招狸、更簡單、更安全邻薯,但是與大家常用的標準庫 glibc 并不兼容裙戏。有些官方會給出Alpine版本的基礎(chǔ)鏡像讓我們依賴,例如golang:alpine厕诡,可以依賴這個來BUILD累榜,然后用空鏡像來RUN。對于沒有alpine基礎(chǔ)鏡像的灵嫌,需要使用諸如RUN apk add build-base
這樣的命令保證編譯環(huán)境不存在問題
docker build
例如本地構(gòu)建
docker build -t="jamtur01/static_web:v1" .
git倉庫構(gòu)建(Dockerfile的目錄要對應(yīng)好壹罚,最好放在項目根目錄)
docker build -t="jamtur01/static_web:v1" \ git@github.com:jamtur01/docker-static_web
構(gòu)建失敗調(diào)試
因為構(gòu)建過程每個步驟都返回了一個id,可以用docker run命令來基于這次構(gòu)建到目前為止已經(jīng)成功的最后一步創(chuàng)建一個容器寿羞,然后執(zhí)行失敗步驟的命令來查看錯誤
docker push
同樣猖凛,鏡像倉庫也支持從github等倉庫導(dǎo)入,需要綁定绪穆,且需要倉庫有Dockerfile文件
docker-compose
docker-compose的容器編排使得內(nèi)部有關(guān)的容器都在同一個network下辨泳,所以可以互相通信,如果外部的容器需要訪問霞幅,則需要指定-net為同一個network漠吻,注意如果不通過量瓜,默認在當前目錄下識別docker-compose.yml的文件司恳。如果是自定義路徑,可以用以下方式啟動
docker-compose -f "$COMPOSE_FILE_PATH" config &&
docker-compose --env-file="$ENV_FILE_PATH" -f "$COMPOSE_FILE_PATH" up
進入其中的一個容器使用以下方式
docker-compose -f "$COMPOSE_FILE_PATH" exec mongodb bash
只啟動其中一個容器
docker-compose -f "$COMPOSE_FILE_PATH" up -d mongodb