docker 相關(guān)梳理
下載安裝
安裝文檔手冊 - 環(huán)境 centos7
具體步驟
1. 卸載舊版本
sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2. 使用存儲庫安裝
sudo yum install -y yum-utils sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo
3. 安裝Docker引擎
sudo yum install docker-ce docker-ce-cli containerd.io
4. 啟動 docker
sudo systemctl start docker
開機自啟且馬上啟動
sudo systemctl enable docker --now
5. 驗證 docker 安裝成功
sudo docker run hello-world
ps:
如果安裝過程存在 404 問題, 需進行源的更換
cd /etc/yum.repos.d rm -rf docker-ce.repo rm -rf mirrors.ustc.edu.cn_docker-ce_linux_centos_docker-ce.repo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
用戶增加 docker 權(quán)限

每次執(zhí)行 docker 的命令都要加 sudo 有點麻煩
直接把用戶加入到 docker 組里面, 默認這個組會自動創(chuàng)建, 也可以手動創(chuàng)建一遍驗證下
設(shè)置完之后要對 docker 重啟一下, 然后 ssh 重連即可
sudo groupadd docker sudo gpasswd -a vagrant docker sudo service docker restart
docker 命令分類
docker 的命令分為兩類, management commands 是對一些具體分類的配置的前綴, 比如 image , container 等

其后的命令則是一些基礎(chǔ)的不需要指定分類或者一些默認分類的簡寫

比如對于 container 的操作
docker container rm xxxx 可以簡寫為 docker rm xxx
docker container ls 可以簡寫為 docker ps
docker container stop xxxx 可以簡寫為 docker kill xxxx 等
比如對于 image 的操作
docker image ls 可以簡寫為 docker images
docker image rm xxxx 可以簡寫為 docker irm xxx
docker machine
用于創(chuàng)建安裝好了 docker 的虛擬機
基礎(chǔ)命令
驗證安裝版本
默認隨著 docker 安裝的時候一起安裝
docker-machine version

安裝生成虛擬機
docker-machine create demo

整個過程類似 vagrant up 創(chuàng)建新的虛擬機, 也是從本地或者遠程的鏡像開始創(chuàng)建
查看當(dāng)前存在虛機列表
docker-machine ls

啟動當(dāng)前存在的虛機
docker-machine start demo

鏈接當(dāng)前存在虛機列表
操作依舊類似 vagrant ssh
docker-machine ssh demo

退出當(dāng)前鏈接虛機
退出的依舊是
exit
所有支持命令
docke-mechine 后進行追加

stop 停止指定虛機, rm 刪除等等
本地指定 server
docker-machine env demo

打印的最后一行執(zhí)行后, 則將 demo 這臺虛擬的 docker 作為 server 環(huán)境
eval $(docker-machine env demo)

云上指定 server 創(chuàng)建虛機
在遠程云上進行操作的話需要 Driver 的支持目前可支持的官方指定的 driver 如下 , 官方鏈接

docker image
image 簡述


如圖 image-4 就是在 image-2 的基礎(chǔ)上的mage, 他們都使用的同一份 centos 的基底
image 查看
docker image ls

也可以簡寫
docker images
通過 docker history 21dbf9672881 后面的數(shù)字要查看的 image 的 ID 可以查看具體的分層情況

image 的獲取
方式 一 - Dockerfile
創(chuàng)建 dockefile 制定步驟進行創(chuàng)建

輸出內(nèi)容, 根據(jù)Dockerfile 的每一行的步驟進行創(chuàng)建層, 然后順序執(zhí)行

方式 二 - Registry
命令 : docker pull [鏡像名:指定版本]
若未指定版本則默認拉去最新的版本

很多的包可以存在第三方的同名, 若未指定前面的簽名則默認拉取官方
也可以制定簽名者進行其他包的拉取 如

docker container
container 簡述


container 的創(chuàng)建
container 是基于 image 創(chuàng)建的, 只需要指定 image 則可以進行創(chuàng)建
docker run hello-world

創(chuàng)建的時候如果不指定 容器的內(nèi)存或者 cpu 的使用, 容器會按照當(dāng)前實體機的規(guī)格作為自己的上限
對 container 的內(nèi)存做限制
docker run --memory=200M [image name]
可選的內(nèi)存相關(guān)的限制參數(shù)

容器的運行內(nèi)存=memory--swap+memory ,沒有設(shè)置memory--swap 則默認和memory的值一致
對 container 的cpu使用做限制
docker run --cpu-shares=10 --name=demo1 [image name] --cpu 1
可選的內(nèi)存相關(guān)的限制參數(shù)

--cpu-shares 是制定相對權(quán)重, 如果有兩個不同的 container, 分別設(shè)置為 10, 5, 則 第一個就會是第二個的 兩倍的使用度
這樣設(shè)置可以區(qū)分container 之間的資源分配優(yōu)先級
查看 container
docker container ls / docker ps 可以進行簡寫
不帶參數(shù)默認查詢的是當(dāng)前運行的 container

加參數(shù) -a 可以查看所有的包括未運行的 container
交互式運行 container
可以看到 centos 這個 image 創(chuàng)建的 container 只是進行了一次 /bin/bash 的操作 , 這樣的程序是一次執(zhí)行后就退出結(jié)束生命周期

可以在創(chuàng)建 container 的時候 指定參數(shù) -it 可以交互式進行, 比如這里的 centos 相當(dāng)于又進入了這個 container 的系統(tǒng)內(nèi)部

使用 -d 則可以讓 container 在后臺運行
重新打開一個窗口就可以看到 當(dāng)前系統(tǒng)存在一個正在運行的 container 了, 同理如果那邊 exit 退出之后則表示生命周期結(jié)束

exec 進入 container 內(nèi)操作
exec 可以隨時進入一個當(dāng)前執(zhí)行中的 container 內(nèi)進行查看和操作, -it 也是用于持續(xù)保持
docker exec -it e7b22628acd2 /bin/bash

container 詳細信息展示
docker inspect
后跟 id 或者 name 即可查看這個 container 的全部詳細信息
以下為一個示例
[ { "Id": "e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a", "Created": "2021-05-11T05:03:14.64470952Z", "Path": "/bin/sh", "Args": [ "-c", "python /app/app.py" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 2400, "ExitCode": 0, "Error": "", "StartedAt": "2021-05-11T05:03:14.942143837Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:9339dd625ab4637f29ea98c9be4c4d586123b0dcc60fa8464e3e349b8ec566b8", "ResolvConfPath": "/var/lib/docker/containers/e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a/resolv.conf", "HostnamePath": "/var/lib/docker/containers/e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a/hostname", "HostsPath": "/var/lib/docker/containers/e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a/hosts", "LogPath": "/var/lib/docker/containers/e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a/e7b22628acd28a931f158892f299441da2fa74ec082bbc6a3089429a3d88e41a-json.log", "Name": "/nifty_agnesi", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": {}, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "CgroupnsMode": "host", "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "private", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DeviceRequests": null, "KernelMemory": 0, "KernelMemoryTCP": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": null, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0, "MaskedPaths": [ "/proc/asound", "/proc/acpi", "/proc/kcore", "/proc/keys", "/proc/latency_stats", "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", "/proc/scsi", "/sys/firmware" ], "ReadonlyPaths": [ "/proc/bus", "/proc/fs", "/proc/irq", "/proc/sys", "/proc/sysrq-trigger" ] }, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/b2fe85b06cba35f07dada165c0d726a7e1d2967cb0b987edfc010443bbf7537c-init/diff:/var/lib/docker/overlay2/b4f32e951c191781da8ce154c4d9fbf7387a0c2a6165accf558ff38a74ddc818/diff:/var/lib/docker/overlay2/b9b75b332dcc32fec8cde2caff58b22d2efd9860161091a34e5d6cec209a20de/diff:/var/lib/docker/overlay2/d7d0542c16ee817f6f37d40bf8e48c7427be4ffc88d8d12917d9e22fadac4b98/diff:/var/lib/docker/overlay2/852ff91ff2a5ea103cf33aaa66a8a0aea50de02483ee0d79cf815a14864d169b/diff:/var/lib/docker/overlay2/01e459322da852f4fa9f1e55ea2565c970777bac6abbdd2d44d13c26ab1439a1/diff:/var/lib/docker/overlay2/e201060f1281463a9a60118bb990d4eb4380beb79e46ace2a52872d1d5d9d35c/diff:/var/lib/docker/overlay2/b221351a67540f85dbc32029f3809131776c841ce4ee23ac5b0dfe6f4a34ed23/diff:/var/lib/docker/overlay2/63431ac14ac31c0f40d007260dfc2e429acf04dc528ab5da76f355db227f23a8/diff:/var/lib/docker/overlay2/d974506712f38f7b5f8a8e00597f5757ddc8eea5535f0900affdc0521385e183/diff:/var/lib/docker/overlay2/11b916dadec26cc098257f4371be564d624f38fe5c282ffb3fc04f82e18a2355/diff:/var/lib/docker/overlay2/1bf38d6429e330c9b91d8636ebe2cb000486fdc86aec7ee0a683c982f254d2e4/diff", "MergedDir": "/var/lib/docker/overlay2/b2fe85b06cba35f07dada165c0d726a7e1d2967cb0b987edfc010443bbf7537c/merged", "UpperDir": "/var/lib/docker/overlay2/b2fe85b06cba35f07dada165c0d726a7e1d2967cb0b987edfc010443bbf7537c/diff", "WorkDir": "/var/lib/docker/overlay2/b2fe85b06cba35f07dada165c0d726a7e1d2967cb0b987edfc010443bbf7537c/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "e7b22628acd2", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": true, "AttachStderr": true, "ExposedPorts": { "5000/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LANG=C.UTF-8", "PYTHONIOENCODING=UTF-8", "GPG_KEY=C01E1CAD5EA2C4F0B8E3571504C367C218ADD4FF", "PYTHON_VERSION=2.7.18", "PYTHON_PIP_VERSION=20.0.2", "PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/d59197a3c169cef378a22428a3fa99d33e080a5d/get-pip.py", "PYTHON_GET_PIP_SHA256=421ac1d44c0cf9730a088e337867d974b91bdce4ea2636099275071878cc189e" ], "Cmd": [ "/bin/sh", "-c", "python /app/app.py" ], "Image": "9339dd625ab4", "Volumes": null, "WorkingDir": "/app", "Entrypoint": null, "OnBuild": null, "Labels": { "maintainer": "yangtuo_tuo@126.com" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "04d5be4fe62e7621d852dd020044ec6645214f734b4c9af1eed5c5b9532737d1", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "5000/tcp": null }, "SandboxKey": "/var/run/docker/netns/04d5be4fe62e", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "2ed90014d1ffff21581a9f0f0c4319a1e586ede6e18df0d3eb38a96dfb2945ef", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "8518b740c12f8a55dfd01e68fdad18d1f5b626b731abb0bbb178bd605c071c18", "EndpointID": "2ed90014d1ffff21581a9f0f0c4319a1e586ede6e18df0d3eb38a96dfb2945ef", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
container 日志
docker logs
對于可以打印的內(nèi)容會被 docker 以日志的形式記錄下來

container 清理相關(guān)命令的實用簡寫
使用以下命令可以進行 container 的清理 (不刪除會一直占用空間)
docker container rm xxx docker rm xxxx
對于大批量 container 的清理的時候, 如果只使用 rm 這樣一個一個 id 刪除是非常辛苦的
可以使用 -q 參數(shù)可以只拿出 id, 作為要被刪除的 id 列表

-f 參數(shù)可以過濾, 支持自動提示, 可以進行過濾要刪除的 id

通過 $(要刪除的 id) 可以進行披露刪除
以上結(jié)合起來一起使用比如 刪除所有退出的 container

簡單粗暴的刪掉所有的 container
docker rm $(docker ps -aq)
image container 間的交互
container 是 基于 image 進行創(chuàng)建的
但是因為 image 存在不可寫入的原因. 因此 container 相關(guān)的讀寫如果想要覆蓋到原有的 image 上
則需要進行這部分修改的提交
應(yīng)用場景
比如這里我在 centos 的這個 image 創(chuàng)建的 container 里面新增了一個文件 a.py

我希望將這個 a.py 的文件永遠應(yīng)用到 centos 這個 image 上
從而以后在基于此 image 創(chuàng)建的 container 都擁有 a.py
或者我希望我以后的 container 都里面安裝了 vim 等等

命令詳解
以上述事例作為參考
退出交互式操作后, 在 ps 里面找到 剛剛退掉的 container

使用命令
docker commit

其中參數(shù) container 的部分用 剛剛退出的 name , 后面跟上命名的 tag

可以看到新的 image 就生成了

其實這個新建的和之前原有的內(nèi)部還是使用了一些相同的 layer

驗證總結(jié)

新創(chuàng)建的 container 確實保持了之前的操作結(jié)果
但是這樣操作會將中間的一些敏感信息泄露到 image 上, 這樣別人使用此 image 的時候就可以拿到這些信息
不提倡此操作, 更為安全的方式則是使用 Dockerfile 進行創(chuàng)建, 從而避免這些問題
Dockerfile build image
還是以上的場景
但是將這個操作移到 Dockerfile 中進行

在使用以下命令進行創(chuàng)建 container
docker build -t yangtuo/centos-vim-a .
由此創(chuàng)建的 container 是在 原有的 image 未發(fā)生改變的基礎(chǔ)上實現(xiàn)的
這樣敏感的信息文件都是在 Dockerfile 中, 而不會隨image 被傳播
Dockerfile 相關(guān)語法以及最佳實踐
關(guān)鍵字
FROM
指定要創(chuàng)建所使用的的 base image

最佳實踐建議:
盡量使用官方的 image 來作為 base image
LABLE
用于一些幫助描述信息的展示

RUN
主要用于一些命令的執(zhí)行

最佳實踐:
image 本身作為不可讀, 而 container 的生成過程中是層層相疊的
一次 RUN 的執(zhí)行就會生成一層, 因此盡量將命令使用 && (系統(tǒng)換行符號) 將多個命令進行合并
如果dockerfile 的一行過長不夠直觀, 可以使用 \ 反斜線用來文件換行優(yōu)化顯示
CMD

ENTRYPOINT

最佳實踐建議:
將entrypoint 信息寫在一個腳本中執(zhí)行

RUN / CMD / ENTRYPOINT


Exec 格式的時候, 如果不指定 bin/bash , 則 env 的常量無法被識別
特殊常見操作組合
可以利用 entrypoint + cmd 的形式組合成一個命令
如下圖, entrypoint 使用 exec 的形式指定要執(zhí)行的對象, 然后 CMD 為空等待 container 創(chuàng)建的時候傳入?yún)?shù)
從而實現(xiàn)讓 container 根據(jù)初始傳入的參數(shù)不同執(zhí)行不同的命令效果

WORKDIR
用于設(shè)定當(dāng)前工作目錄, 如果目錄不存在會進行相應(yīng)的創(chuàng)建

最佳實踐建議:
RUN cd 是可以達到 和 WORKDIR 相同的效果的
但是不推薦前者, 同時盡量使用絕對路勁, 從而避免還需要上下文去查找, 也更容易出錯
ADD / COPY
ADD 和 COPY 的唯一區(qū)別就是 ADD 會對文件進行解壓縮操作, COPY 是不會的
這兩個關(guān)鍵字的作用都是將文件添加到指定的路勁位置上

最佳實踐建議:

這兩個命令經(jīng)常會和 WORKDIR 組合操作, 是會受到 WORKDIR 的指定當(dāng)前目錄影響的
如果使用相對路勁則要注意不要出錯
大部分情況下, copy 比 add 更優(yōu)先去使用
這兩個命令都是對本地文件的操作無法操作遠程文件, 添加遠程文件或者目錄, 使用 curl 或者 wegt
ENV
設(shè)置常量

最佳實踐建議:
盡量使用ENV 從而減少代碼的維護成本
VOLUME
用于持久化

EXPOSE
用于暴露端口號讓外部可以訪問這個端口
Dockerfile 的共享和發(fā)布
docker-hub 是類似于 github 的一個共享網(wǎng)站
對于如果只是使用別人的鏡像或者Dockerfile是不需要進行登錄的
但是如果想將自己的進行上傳則需要注冊登錄
相關(guān)操作
docker login 進行登錄

登錄后進行 push, 注意 push 的時候的 image 的 tag 必須和自己的用戶名一樣 (不能push 別人的倉庫里面去)

本地拉取元辰倉庫則直接 docker pull 即可, 本地如果不存在就會在遠程找
還是不推薦使用這種 image 修改的方式進行
推薦使用Dockerfile 進行更新, docke-hub 會和 github 進行關(guān)聯(lián)
從而 在 github 上更新 Dockerfile 即可保持對image 的后續(xù)維護
Docker 私有 docker-hub
以上的操作不是在 docker-hub 就是在 github , 不論怎么說都是開源的
對于一些敏感信息的公司或者個人信息也可以選擇使用私有的 docker-hub
使用此命令即可在任意一臺裝了 docker 的服務(wù)器上啟動

啟動服務(wù)的端口需要確保可達

同時再次進行 push 的時候的 tag 要指定格式為遠程服務(wù)器的ip家端口

這里會提示 這個不可信任, 因此還需要做一些信任的配置操作
在 etc/docker 下創(chuàng)建一個 daemon.json 里面存入一行配置

然后修改
sudo vim /lib/system/docker.service
在 這里加入一行在這個位置
EnvironmentFile=-/etc/docker/daemon.json

然后還是重啟服務(wù)
sudo service docker restart
私有 docker-hub 的 api
私有的 docker-hub 是沒有圖形界面的
但是官方也提供了一些基礎(chǔ)的 api 可以進行查詢 倉庫的相關(guān)內(nèi)容

綜合實踐 打包一個 python flask 的簡單程序
創(chuàng)建一個簡單的 flask 的 web 程序

代碼如下
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'hello docker&flask' if __name__ == '__main__': app.run(debug=True)
然后就編寫 Dockerfile
FROM python:2.7 LAbEL maintainer="yangtuo_tuo@126.com" RUN pip install flask COPY app.py /app/ WORKDIR /app EXPOSE 5000 CMD python /app/app.py
利用 docker build -t 直接生成 image , base image 的 python 2.7 image 大概 200 多兆, 首次下載需要些時間

可以看到每一步驟都會生成 layer 的 container, 這些 id 都是可以進入的

查看下新創(chuàng)建的 image , 然后用 id 的形式直接創(chuàng)建 container 進行執(zhí)行

也可以使用 -d 讓這種持續(xù)占用頁面的操作放在后臺執(zhí)行

docker 網(wǎng)絡(luò)
驗證展示
不同的 container 之間的網(wǎng)絡(luò)是互相隔離的, 同時單機之間又是互通
下圖可以看出兩個的 ip 地址不同, 但是可達

同理對外網(wǎng)的訪問也是一樣

相關(guān)命令支持
查看當(dāng)前的容器網(wǎng)絡(luò)情況
docker network ls

其中 name 這里區(qū)分 bridge / host (完全使用宿主機的網(wǎng)絡(luò)空間) / none (沒有網(wǎng)絡(luò)配置的單機下線容器) , 后兩者用法很少 host 還容易出現(xiàn)端口沖突的場景
bridge 表示本機的物理網(wǎng)卡, 在本機的 ip a 中可以看到 docker0就是這個
而下面的 vth 則是docker0用于和容器相連的接口

原理如圖

inspect 可以查看 具體的網(wǎng)絡(luò)信息
docker network inspect bridge
其中在 Containers 中可以看到具體的容器的網(wǎng)絡(luò)信息

link
link 的使用場景
比如 程序在 test1, 數(shù)據(jù)庫在 test2
如果 test1 想在 test2 拿數(shù)據(jù), 但是 test2容器的 ip 是不定的
容器創(chuàng)建的時候分配的地址是無法確認的
因此需要一種手段將 test1 可以準(zhǔn)確的拿到 test2 上去
因此test1 只需要記錄下 test2 的名字就一樣可以找到test2
命令使用
創(chuàng)建 docker container 的時候使用參數(shù) --link 指定
在知道對方的 ip 下肯定沒問題

在不知道 ip 的時候用 link 的 name 直接代替 ip 的使用也可以達成 , 相當(dāng)于用 link 設(shè)置了一個 dns 的記錄

但是這里需要注意方向, --link 是單向的.
test2 --link test1 , 在 test2 上 ping test1 么問題
但是反過來則不行, 還是只能用 ip
ps:
這種方式其實用的場景并不多, 可以使用其他的方式來處理這種場景
比如自建的 bridge 就會吧鏈接到這個 bridge 上的 container 都建立好 link
這樣所有的 container 之間都可以直接用名字來互通
自建 bridge
默認的 container 創(chuàng)建的網(wǎng)絡(luò)都是鏈接到docker0 的默認的 bridge 上
所有鏈接到 docker0 上的 containers 彼此是不帶有 link 需要自行手動指定
因此存在不方便, 自建 bridge 則不會有這個問題
創(chuàng)建命令
創(chuàng)建時使用 -d 指定要創(chuàng)建的 driver 類型, 后面跟起個名字
docker network create -d bridge tuo-bridge
\
鏈接 bridge
鏈接方式有兩種, 創(chuàng)建的時候進行使用 --network 進行指定
![]()
或者將已有現(xiàn)在運行的 container 新建一個鏈接過來
docker network connect tuo-bridge test2
后面跟兩個參數(shù)分別是 bridge 以及要切換的 container

驗證
創(chuàng)建指定的 test3 , 和切換過來的 test2 都可以在 inspect 中這里看到

而且 test2 之前有鏈接到 docker0 上, 所有 test2 兩個網(wǎng)段都能互通

測試這兩個之間也都是可以互通的

docker 端口映射
創(chuàng)建的時候通過指定 -p 參數(shù)設(shè)定本機與 container 之間的端口映射
docker run --name web -d -p 80:80 nginx
設(shè)置了端口映射之后容器的 端口就乎映射到本機的端口一致
從而本機的訪問即可訪問到容器內(nèi), 以下示例為 nginx 的一個示例

docker 持久化
應(yīng)用場景
docker 的 container 停止后的數(shù)據(jù)是無法保存的
比如一個數(shù)據(jù)庫的 container 結(jié)束后希望這中間的結(jié)果都可以保存在數(shù)據(jù)庫中
則需要指定持久化的存儲進行保存
方式一: Data Volume
volume 在 docker中是同 image / container 一樣的一個分類的子命令
其中的大部分命令也喝 image / container 類似比如 ls, rm, inspect 等
此命令用于查看持久化的任務(wù)列表
docker volume ls

docker volume rm xxxx
刪除則 ls 換成 rm
![]()
查看具體的信息
docker volume inspect xxxx

如果不指定別名默認生成的 volume 識別上很不友好, 可以在創(chuàng)建 container 的時候 通過 -v 進行指定別名
指定格式后面跟上路徑表示存放位置
docker run -v xxxx:xxx/xxx/

通過 -v 參數(shù)指定了持久化存放的地點, 多個container 可以同時使用此 volume 進行操作存儲
方式一: Bind Mounting
![]()
不同于 Data Volume
此方式的完全的文件映射, 這樣在對 home/aaa 目錄進行修改的時候 root/aaa 目錄也會發(fā)生相應(yīng)的改變
非常方便開發(fā)中的代碼同步
多容器管理 - Docker Compose
使用背景
多個容器的互相配合使用的時候較為繁瑣
每個 image 要進行拉取或者 build , container 要分別創(chuàng)建還要進行管理啟動停止刪除等
Docker Compose 介紹

Docker Compose 安裝
mac / windows 在安裝 docker 的時候回附帶一起自己安裝

但是 linux 則需要自行安裝 相關(guān)的官方鏈接
步驟 1 : 下載文件
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
步驟2: 給予可執(zhí)行權(quán)限
sudo chmod +x /usr/local/bin/docker-compose
docker-compose.yml 文件編寫
Services / Networks / Volumes 作為 docker compose 的三大概念
Services

如圖 db 這個服務(wù)是以 posegres:9.4 的 image 進行拉取創(chuàng)建

通過 Dockerfile 創(chuàng)建則是這種形式

Volumes
在 Service 定義的時候的 volumes 也是需要聲明創(chuàng)建的

Networks

完整示例
build 的的指定位置以及 Dcokerfile 的文件名字

image 的則直接指定 image 即可

docker-compose 命令
docker-compose 的命令大部分要基于 yml 的文件來操作
啟動操作
docker-compose up

默認的 yml 文件為 docker-compose.yml
使用的時候默認使用的就是 docker-compose.yml 進行啟動
通過 -f 可以自行指定要啟動的 yml 文件
通過 -d 也可以指定后臺執(zhí)行, 不后臺執(zhí)行會占用當(dāng)前窗口退出也是同 ctrl+c
本地調(diào)試的時候如果為了 debug 看日志的時候則可以不用
容器進程查看

容器進程停止 / 啟動
stop / down 兩個命令可以進行停止. 但是 down 會將 容器移除 (但不會刪除 image, 只會刪除 container)
start 則可以讓 被停止的開啟, 但是 down 的則無法開啟

容器鏡像查看
images

容器命令執(zhí)行
exec 用法類似 docker 的 exec, 也是指定了 container (sevices) 之后后面具體命令

容器擴展
在 up 的時候進行此參數(shù)的指定--scale 可以允許容器進行擴展

但是注意端口如果存在 -p 映射本地的時候, 分配的情況下擴展會出現(xiàn)端口被占用沖突的場景從而無法啟動

基于此原理再加一個 HAProxy 進行分流讓 多個擴展的容器均衡, 可以扛起來更多的并發(fā)訪問量

容器編排 Swarm

單機環(huán)境下都是直接本地 cli 里面進行操作即可
多容器的之間如果需要部署在非單機環(huán)境, 而是在集群中部署則很多的問題需要進行考慮, 比如

Swarm 則是 docker 官方自帶的容器編排系統(tǒng)用于解決此類問題
此工具屬于內(nèi)置, 不需要任何的額外安裝下載

Swarm 節(jié)點角色

Manager
作為集群的首腦. 用于控制整個集群
Manager 作為控制中心必須存在多個才可以互相依持避免出現(xiàn)單點故障
而彼此之間的數(shù)據(jù)狀態(tài)同步則需要依靠 Raft 協(xié)議進行, 通過一個分布式的存儲數(shù)據(jù)庫進行實現(xiàn)
Worker
Worker 則進行具體的項目部署承載, 彼此之間的數(shù)據(jù)同步也會通過 Cossip 網(wǎng)絡(luò)進行同步
Swarm 服務(wù)和擴展

Service
概念類似 docker-compose 中的 service, 其實本質(zhì)也就是 container 容器
Replicas
service 進行橫向擴展的時候, manager 則需要進行決策調(diào)度具體在哪一個節(jié)點上進行創(chuàng)建
具體的服務(wù)創(chuàng)建和調(diào)度的算法基于 Raft 進行判定

Swarm 命令

init 初始化 manager

--advertise-addr 宣告 manager 節(jié)點地址
docker swarm init --advertise-addr=192.168.205.10
如果宣告成功之后會有打印一個行命令, 可以用于 worker 進行認證 manager 時使用
里面攜帶 manager 的 token 等信息

worker join
manager 返回的信息在 要被指定的 worker 上執(zhí)行, 可以將此設(shè)備指定為 manger 的worker

node 查看
在manager 上可以通過此命令查看當(dāng)前的鏈接節(jié)點信息

service
作為子命令很多地方類似 .

create 創(chuàng)建一個 container

ls 查看, 這里的 REPLICAS 表示可以擴展的數(shù)量

更詳細的情況可以使用 ps 指定名字進行查看, 本身就是個 container 也可以 直接 docker ps 查看
可以看到 create 創(chuàng)建的指定的名字是 services 的名字, 而不是 container 的名字

scale 擴展

擴展之后 ls 就可以看打 變成 5/5 了, 表示 5個ready , 總數(shù) 5個

可以看到這 5個的分配情況

這時如果我再 worker 2 上將這個強制刪除

再回到?jīng)Q策機上可以看到 5個數(shù)量是保持的2 上刪除了也會在其他的機器上重新開一個保證運行

rm 進行刪除, 在決策機上刪除之后. 后臺會通過一系列復(fù)雜的機制去worker 上也進行相關(guān)的刪除, 可能速度還是會有些慢一點


Swarm 網(wǎng)絡(luò)

![]()
對于 swarm 的多機互聯(lián)網(wǎng)絡(luò)內(nèi)部存在 DNS 服務(wù)發(fā)現(xiàn) 機制
從而可以將 worker 于 manager 在同一個網(wǎng)絡(luò)中互通, 從而對某一個服務(wù)可以用 servicesname進行直接訪問
注意這里的 dns 轉(zhuǎn)換的時候是使用的 vip, 如果使用真實 ip 是存在有變動的可能性從而不穩(wěn)定, 而使用 vip 則可以保持不變.

![]()
對于綁定了端口的 服務(wù),端口會暴露到所有的節(jié)點, 因此整個swarm網(wǎng)絡(luò)都可以直接通過該端口進行訪問, 同時建庫負載均衡
負載相關(guān)的底層基礎(chǔ)是 IPVS 來實現(xiàn) , 具體的數(shù)據(jù)包走向較為復(fù)雜

DNS 服務(wù)發(fā)現(xiàn)具體示例驗證
在決策機上創(chuàng)建兩個服務(wù), 分別是 whoami 的服務(wù), 建立在 決策機器上

第二個服務(wù)是 busybox 創(chuàng)建在worker1 上, 這兩個服務(wù)都是建立在 overlay 的網(wǎng)絡(luò)上
![]()

兩個服務(wù)起來之后, 到 worker1 上對 manager 上的 whoami 進行 ping

可以看到 ping 通. 同時 ping 的是 10.0.0.7 這個虛擬地址

繼續(xù)講 whoami 的服務(wù)進行擴展, 拓展后的第二個是在 worker2 上

此時在繼續(xù) ping 操作可以看到 vip 沒有發(fā)生變化, 同理 對這個服務(wù)的遷移, 關(guān)閉, 等操作都不會影響到這個 vip

docker stack 部署
依舊是使用 docker-compose 的 yml 文件進行編寫, 但是執(zhí)行的時候使用 docker 的命令進行
docker stack

示例

deploy 相關(guān)參數(shù)詳解
yml 總新增了一個對這方面各項配置的支持子命令 doploy
官方文檔 中對 deploy 的相關(guān)的參數(shù)

mode 設(shè)置 global 表示不可擴展, 只能全局只有一個, 默認是 replicated 可進行擴展

placement 做一些限制條件, 比如這里 node.role 可以限制只能在 manager 上建立

replicas 指定擴展的大小, 這樣一開始部署的時候就可以直接部署6個

resources 主要是做資源的限制 limit , 或者預(yù)留 reservations

restart_policy 重啟的條件相關(guān)的參數(shù)

update_config 更新相關(guān)的配置, 這里 parallelism 表示同時更新的數(shù)量, delay 表示更新建個的時間
docker secret 管理

對于一系列不想暴露的信息進行加密傳遞
原理


相關(guān)命令

創(chuàng)建 secret 有兩種方式
docker secret create my-pw password

通過文件的形式進行創(chuàng)建, 最好創(chuàng)建完之后就刪除文件, 文件內(nèi)容直接就是一行密碼信息即可.

也可以通過命令行的方式直接創(chuàng)建, 這樣更加簡單
創(chuàng)建之后的 secret 的使用則是在創(chuàng)建 container 的時候通過 --secret 進行指定即可, 指定多個就加多個 --sercet

在創(chuàng)建的 container 里面查閱已有的 secret 則使用 cd /runsecrets 然后 cat 即可

其他的地方在使用此環(huán)節(jié)變量的時候則可以通過文件的形式讀取即可
![]()
在 stack 里面使用

這個 my-pw 如果直接是當(dāng)前已存在的則可以直接使用
如果不存在也可以這樣指定, 但是這樣不安全, 還保留了一個 password的文件

最推薦的方式還是自己創(chuàng)建一個 secret 然后直接使用
---------------------施工中請繞行 - orz
本文來自博客園,作者:羊駝之歌,轉(zhuǎn)載請注明原文鏈接:http://www.rzrgm.cn/shijieli/p/14746025.html

浙公網(wǎng)安備 33010602011771號