Docker 疑難雜癥匯總(二)
在下方公眾號(hào)后臺(tái)回復(fù):JGNB,可獲取杰哥原創(chuàng)的 PDF 手冊(cè)。
1. Docker 服務(wù)啟動(dòng)串臺(tái)
使用 docker-compose 命令各自啟動(dòng)兩組服務(wù),發(fā)現(xiàn)服務(wù)會(huì)串臺(tái)!
[問題起因] 在兩個(gè)不同名稱的目錄目錄下面,使用 docker-compose 來啟動(dòng)服務(wù),發(fā)現(xiàn)當(dāng) A 組服務(wù)啟動(dòng)完畢之后,再啟動(dòng) B 組服務(wù)的時(shí)候,發(fā)現(xiàn) A 組當(dāng)中對(duì)應(yīng)的一部分服務(wù)又重新啟動(dòng)了一次,這就非常奇怪了!因?yàn)檫@個(gè)問題的存在會(huì)導(dǎo)致,A 組服務(wù)和 B 組服務(wù)無法同時(shí)啟動(dòng)。之前還以為是工具的 Bug,后來請(qǐng)教了 “上峰”,才知道了原因,恍然大悟。
#?服務(wù)目錄結(jié)構(gòu)如下所示
A:?/data1/app/docker-compose.yml
B:?/data2/app/docker-compose.yml
[解決方法] 發(fā)現(xiàn) A 和 B 兩組服務(wù)會(huì)串臺(tái)的原因,原來是 docker-compose 會(huì)給啟動(dòng)的容器加 label 標(biāo)簽,然后根據(jù)這些 label 標(biāo)簽來識(shí)別和判斷對(duì)應(yīng)的容器服務(wù)是由誰啟動(dòng)的、誰來管理的,等等。而這里,我們需要關(guān)注的 label 變量是 com.docker.compose.project,其對(duì)應(yīng)的值是使用啟動(dòng)配置文件的目錄的最底層子目錄名稱,即上面的 app 就是對(duì)應(yīng)的值。我們可以發(fā)現(xiàn), A 和 B 兩組服務(wù)對(duì)應(yīng)的值都是 app,所以啟動(dòng)的時(shí)候被認(rèn)為是同一個(gè),這就出現(xiàn)了上述的問題。如果需要深入了解的話,可以去看對(duì)應(yīng)源代碼。

#?可以將目錄結(jié)構(gòu)調(diào)整為如下所示
A:?/data/app1/docker-compose.yml
B:?/data/app2/docker-compose.yml
A:?/data1/app-old/docker-compose.yml
B:?/data2/app-new/docker-compose.yml
或者使用 docker-compose 命令提供的參數(shù) -p 手動(dòng)指定標(biāo)簽,來規(guī)避該問題的發(fā)生。
#?指定項(xiàng)目項(xiàng)目名稱
$?docker-compose?-f?./docker-compose.yml?-p?app1?up?-d
2.Docker 命令調(diào)用報(bào)錯(cuò)
在編寫腳本的時(shí)候常常會(huì)執(zhí)行 docker 相關(guān)的命令,但是需要注意使用細(xì)節(jié)!
[問題起因] CI 更新環(huán)境執(zhí)行了一個(gè)腳本,但是腳本執(zhí)行過程中報(bào)錯(cuò)了,如下所示。通過對(duì)應(yīng)的輸出信息,可以看到提示說正在執(zhí)行的設(shè)備不是一個(gè) tty。

隨即,查看了腳本發(fā)現(xiàn)報(bào)錯(cuò)地方是執(zhí)行了一個(gè) exec 的 docker 命令,大致如下所示。很奇怪的是,手動(dòng)執(zhí)行或直接調(diào)腳本的時(shí)候,怎么都是沒有問題的,但是等到 CI 調(diào)用的時(shí)候怎么都是有問題。后來好好看下,下面這個(gè)命令,注意到 -it 這個(gè)參數(shù)了。
#?腳本調(diào)用docker命令
docker?exec?-it??psql?-Upostgres?......
我們可以一起看下 exec 命令的這兩個(gè)參數(shù),自然就差不多理解了。
| 編號(hào) | 參數(shù) | 解釋說明 |
|---|---|---|
| 1 | -i/-interactive | 即使沒有附加也保持 STDIN 打開;如果你需要執(zhí)行命令則需要開啟這個(gè)選項(xiàng) |
| 2 | -t/–tty | 分配一個(gè)偽終端進(jìn)行執(zhí)行;一個(gè)連接用戶的終端與容器 stdin 和 stdout 的橋梁 |
[解決方法] docker exec 的參數(shù) -t 是指 Allocate a pseudo-TTY 的意思,而 CI 在執(zhí)行 job 的時(shí)候并不是在 TTY 終端中執(zhí)行,所以 -t 這個(gè)參數(shù)會(huì)報(bào)錯(cuò)。

3.Docker 定時(shí)任務(wù)異常
在 Crontab 定時(shí)任務(wù)中也存在 Docker 命令執(zhí)行異常的情況!
[問題起因] 今天發(fā)現(xiàn)了一個(gè)問題,就是在備份 Mysql 數(shù)據(jù)庫的時(shí)候,使用 docker 容器進(jìn)行備份,然后使用 Crontab 定時(shí)任務(wù)來觸發(fā)備份。但是發(fā)現(xiàn)備份的 MySQL 數(shù)據(jù)庫居然是空的,但是手動(dòng)執(zhí)行對(duì)應(yīng)命令切是好的,很奇怪。
#?Crontab定時(shí)任務(wù)
0?*/6?*?*?*?\
????docker?exec?-it??sh?-c?\
????????'exec?mysqldump?--all-databases?-uroot?-ppassword?......'
[解決方法] 后來發(fā)現(xiàn)是因?yàn)閳?zhí)行的 docker 命令多個(gè) -i 導(dǎo)致的。因?yàn)?Crontab 命令執(zhí)行的時(shí)候,并不是交互式的,所以需要把這個(gè)去掉才可以??偨Y(jié)就是,如果你需要回顯的話則需要 -t 選項(xiàng),如果需要交互式會(huì)話則需要 -i 選項(xiàng)。
| 編號(hào) | 參數(shù) | 解釋說明 |
|---|---|---|
| 1 | -i/-interactive | 即使沒有附加也保持 STDIN 打開;如果你需要執(zhí)行命令則需要開啟這個(gè)選項(xiàng) |
| 2 | -t/–tty | 分配一個(gè)偽終端進(jìn)行執(zhí)行;一個(gè)連接用戶的終端與容器 stdin 和 stdout 的橋梁 |
4.Docker 變量使用引號(hào)
compose 里邊環(huán)境變量帶不帶引號(hào)的問題!
[問題起因] 使用過 compose 的朋友可能都遇到過,在編寫啟服務(wù)啟動(dòng)配置文件的時(shí)候,添加環(huán)境變量時(shí)到底是使用單引號(hào)、雙引號(hào)還是不使用引號(hào)的問題?時(shí)間長了,我們可能會(huì)將三者混用,認(rèn)為其效果是一樣的。但是后來,發(fā)現(xiàn)的坑越來越多,才發(fā)現(xiàn)其越來越隱晦。
反正我是遇到過很多問題,都是因?yàn)樘砑右?hào)導(dǎo)致的服務(wù)啟動(dòng)異常的,后來得出的結(jié)論就是一律不使引號(hào)。裸奔,體驗(yàn)前所未有的爽快!直到現(xiàn)在看到了 Github 中對(duì)應(yīng)的 issus 之后,才終于破案了。
#?在Compose中進(jìn)行引用TEST_VAR變量,無法找到
TEST_VAR="test"
#?在Compose中進(jìn)行引用TEST_VAR變量,可以找到
TEST_VAR=test
#?后來發(fā)現(xiàn)docker本身其實(shí)已經(jīng)正確地處理了引號(hào)的使用
docker?run?-it?--rm?-e?TEST_VAR="test"?test:latest
[解決方法] 得到的結(jié)論就是,因?yàn)?Compose 解析 yaml 配置文件,發(fā)現(xiàn)引號(hào)也進(jìn)行了解釋包裝。這就導(dǎo)致原本的 TEST_VAR="test" 被解析成了 'TEST_VAR="test"',所以我們?cè)谝玫臅r(shí)候就無法獲取到對(duì)應(yīng)的值?,F(xiàn)在解決方法就是,不管是我們直接在配置文件添加環(huán)境變量或者使用 env_file 配置文件,能不使用引號(hào)就不適用引號(hào)。
需要注意的是環(huán)境變量配置的是日志格式的話(2022-01-01),如果使用的是 Python 的 yaml.load 模塊的話,會(huì)被當(dāng)做是 date 類型的,這是如果希望保持原樣信息的話,可以使用 '/" 引起來將其變成字符串格式的。
5.Docker 刪除鏡像報(bào)錯(cuò)
無法刪除鏡像,歸根到底還是有地方用到了!
[問題起因] 清理服器磁盤空間的時(shí)候,刪除某個(gè)鏡像的時(shí)候提示如下信息。提示需要強(qiáng)制刪除,但是發(fā)現(xiàn)及時(shí)執(zhí)行了強(qiáng)制刪除依舊沒有效果。
#?刪除鏡像
$?docker?rmi?3ccxxxx2e862
Error?response?from?daemon:?conflict:?unable?to?delete?3ccxxxx2e862?(cannot?be?forced)?-?image?has?dependent?child?images
#?強(qiáng)制刪除
$?dcoker?rmi?-f?3ccxxxx2e862
Error?response?from?daemon:?conflict:?unable?to?delete?3ccxxxx2e862?(cannot?be?forced)?-?image?has?dependent?child?images
[解決方法] 后來才發(fā)現(xiàn),出現(xiàn)這個(gè)原因主要是因?yàn)?TAG,即存在其他鏡像引用了這個(gè)鏡像。這里我們可以使用如下命令查看對(duì)應(yīng)鏡像文件的依賴關(guān)系,然后根據(jù)對(duì)應(yīng) TAG 來刪除鏡像。
#?查詢依賴?-?image_id表示鏡像名稱
$?docker?image?inspect?--format='{{.RepoTags}}?{{.Id}}?{{.Parent}}'?$(docker?image?ls?-q?--filter?since=)
#?根據(jù)TAG刪除鏡像
$?docker?rmi?-f?c565xxxxc87f
#?刪除懸空鏡像
$?docker?rmi?$(docker?images?--filter?"dangling=true"?-q?--no-trunc)
6.Docker 普通用戶切換
切換 Docker 啟動(dòng)用戶的話,還是需要注意下權(quán)限問題的!
[問題起因] 我們知道在 Docker 容器里面使用 root 用戶的話,是不安全的,很容易出現(xiàn)越權(quán)的安全問題,所以一般情況下,我們都會(huì)使用普通用戶來代替 root 進(jìn)行服務(wù)的啟動(dòng)和管理的。今天給一個(gè)服務(wù)切換用戶的時(shí)候,發(fā)現(xiàn) Nginx 服務(wù)一直無法啟動(dòng),提示如下權(quán)限問題。因?yàn)閷?duì)應(yīng)的配置文件也沒有配置 var 相關(guān)的目錄,無奈 ???♀ !?
#?Nginx報(bào)錯(cuò)信息
nginx:?[alert]?could?not?open?error?log?file:?open()?"/var/log/nginx/error.log"?failed?(13:?Permission?denied)
2020/11/12?15:25:47?[emerg]?23#23:?mkdir()?"/var/cache/nginx/client_temp"?failed?(13:?Permission?denied)
[解決方法] 后來發(fā)現(xiàn)還是 nginx.conf 配置文件,配置的有問題,需要將 Nginx 服務(wù)啟動(dòng)時(shí)候需要的文件都配置到一個(gè)無權(quán)限的目錄,即可解決。
user??www-data;
worker_processes??1;
error_log??/data/logs/master_error.log?warn;
pid????????/dev/shm/nginx.pid;
events?{
????worker_connections??1024;
}
http?{
????include???????/etc/nginx/mime.types;
????default_type??application/octet-stream;
????gzip???????????????on;
????sendfile???????????on;
????tcp_nopush?????????on;
????keepalive_timeout??65;
????client_body_temp_path??/tmp/client_body;
????fastcgi_temp_path??????/tmp/fastcgi_temp;
????proxy_temp_path????????/tmp/proxy_temp;
????scgi_temp_path?????????/tmp/scgi_temp;
????uwsgi_temp_path????????/tmp/uwsgi_temp;
????include?/etc/nginx/conf.d/*.conf;
}
7.Docker 綁定到 IPv6 上
Docker 服務(wù)在啟動(dòng)的時(shí)候,將地址綁定到 IPv6 地址上面了,提示報(bào)錯(cuò)信息!
[問題起因] 物理機(jī)器更新了對(duì)應(yīng)補(bǔ)丁之后,重啟了服務(wù),導(dǎo)致原本可以正常啟動(dòng)的 docker-compose 服務(wù)提示如下報(bào)錯(cuò)信息。不清楚是否修改了操作系統(tǒng)的相關(guān)配置,還是對(duì)應(yīng) docker 進(jìn)行的其他方面的配置,比如修改 /etc/docker/daemon.json 或者 docker 的 service 啟動(dòng)文件。
#?Docker的報(bào)錯(cuò)信息
docker?run?-p?80:80?nginx:alpine?succeeds.?Previously,?this?was?failing?with?Error?\
starting?userland?proxy:?listen?tcp6?[::]:80:?socket:?address?family?not?supported?by?protocol.
[解決方法] 通過如上所示的報(bào)錯(cuò)信息,可以看到服務(wù)的啟動(dòng)端口綁定到了 tcp6 上面了,但是對(duì)應(yīng)的 socket 發(fā)現(xiàn)系統(tǒng)本身并不支持。這時(shí),我們一看下對(duì)應(yīng)的操作系統(tǒng) ipv6 的設(shè)置,發(fā)現(xiàn)系統(tǒng)禁用了,所有的 ipv6 地址。
#?操作系統(tǒng)配置
$?cat?/etc/sysctl.conf?|?grep?ipv6
net.ipv6.conf.all.disable_ipv6=1
[方法一] 最為簡單的解決方法,就是在 docker-compose.yml 文件中,手動(dòng)指定將對(duì)應(yīng)服務(wù)的端口綁定到 ipv4 上面,如下所示。
version:?"3"
services:
??app:
????restart:?on-failure
????container_name:?app_web
????image:?app:latest
????ports:
??????-?"0.0.0.0:80:80/tcp"
????volumes:
??????-?"./app_web:/data"
????networks:
??????-?app_network
networks:
??app_network:
[方法二] 或者修改 /etc/docker/daemon.json 文件,在配置中,阻止 Docker 錯(cuò)誤的將端口映射到 IPv6 上,即可達(dá)到同樣的效果,且不用再次修改多個(gè)服務(wù)的啟動(dòng)配置文件了。
#?修改配置
$?vim?/etc/docker/daemon.json
{
??"ipv6":?false,
??"fixed-cidr-v6":?"2001:db8:1::/64"
}
#?重啟服務(wù)
$?systemctl?reload?docker
[方法三] Docker 默認(rèn)情況下會(huì)同時(shí)將端口映射于 IPv4 與 IPv6 兩者上,而且有的時(shí)候會(huì)出現(xiàn)只綁定到了 IPv6,導(dǎo)致服務(wù)無法正常訪問的情況?,F(xiàn)在通用的始終還是 IPv4 地址,因此最簡單的做法就是關(guān)閉 IPv6 地址。
#?修改系統(tǒng)配置
echo?'1'?>?/proc/sys/net/ipv6/conf/lo/disable_ipv6
echo?'1'?>?/proc/sys/net/ipv6/conf/lo/disable_ipv6
echo?'1'?>?/proc/sys/net/ipv6/conf/all/disable_ipv6
echo?'1'?>?/proc/sys/net/ipv6/conf/default/disable_ipv6
#?重啟網(wǎng)絡(luò)
$?/etc/init.d/networking?restart
#?最后檢測(cè)是否已關(guān)閉IPv6
ip?addr?show?|?grep?net6
8.Docker 容器啟動(dòng)超時(shí)
Docker 服務(wù)在啟動(dòng)的時(shí)候,提示超時(shí),被直接終止了!
[問題起因] 使用 docker-compose 啟動(dòng)容器的時(shí)候,等待了很久的時(shí)候(大約 2-3 分鐘左右),之后提示如下信息。通過閱讀信息內(nèi)容,可以看到是因?yàn)槌瑫r(shí)導(dǎo)致的,提示可以通過設(shè)置環(huán)境變量,加大超時(shí)的時(shí)間。
$?docker-compose?up?-d
ERROR:?for?xxx??UnixHTTPConnectionPool(host='localhost',?port=None):?Read?timed?out.?(read?timeout=70)
ERROR:?An?HTTP?request?took?too?long?to?complete.?Retry?with?--verbose?to?obtain?debug?information.
If?you?encounter?this?issue?regularly?because?of?slow?network?conditions,?consider?setting?COMPOSE_HTTP_TIMEOUT?to?a?higher?value?(current?value:?60).
[解決方法] 按照提示設(shè)置的環(huán)境變量之后,再次啟動(dòng)發(fā)現(xiàn)確實(shí)可以正常啟動(dòng)了,但是還是能夠感覺到有些慢。
$?sudo?vim?/etc/profile
export?COMPOSE_HTTP_TIMEOUT=500
export?DOCKER_CLIENT_TIMEOUT=500
排除了下啟動(dòng)流程,因?yàn)槿萜鲉?dòng)有映射目錄到容器里面且目錄大小比較大,所以懷疑是因?yàn)?i/o 導(dǎo)致的。隨即使用 iotop 命令查看服務(wù)器目前的 i/o 情況,發(fā)現(xiàn)存在很多個(gè) rg 命令,且都處于 100% 左右。查了下,發(fā)現(xiàn)是 vscode 遠(yuǎn)程服務(wù)器啟動(dòng)的搜索目錄結(jié)構(gòu)的進(jìn)程,西八,有些坑呀!
$?sudo?iotop
?4269?be/4?escape?????15.64?K/s????0.00?B/s??0.00?%?98.36?%?rg?--files?--hidden
?4270?be/4?escape?????28.15?K/s????0.00?B/s??0.00?%?97.46?%?rg?--files?--hidden
?4272?be/4?escape?????31.27?K/s????0.00?B/s??0.00?%?97.39?%?rg?--files?--hidden
?4276?be/4?escape?????34.40?K/s????0.00?B/s??0.00?%?96.98?%?rg?--files?--hidden
9.Docker 端口網(wǎng)絡(luò)限制
如果發(fā)現(xiàn)服務(wù)都一切正常,但是無法無法訪問的話,則多為網(wǎng)絡(luò)問題!
[問題起因] 啟用服務(wù)之后,登錄跳轉(zhuǎn)發(fā)現(xiàn)直接 502 報(bào)錯(cuò)了。排除了配置等相關(guān)原因都沒有任何問題(做過相關(guān)測(cè)試),這就非常奇怪了!
#?部署服務(wù)架構(gòu)
nginx(80)?->?web1(8080)
??????????->?web2(8081)
#?報(bào)錯(cuò)信息如下所示
nginx?connect()?failed?(113:?No?route?to?host)?while?connecting?to?upstream
[解決方法] 根據(jù)錯(cuò)誤信息可知,是因?yàn)闆]有路由到指定的 host 導(dǎo)致了,隨即看了下防火墻是開著的,看了日志發(fā)現(xiàn)被過濾掉了,西八!問題找到了,現(xiàn)在需要做的就是,要么添加防火墻規(guī)則,要么關(guān)閉防火墻。
#?檢查開放的端口
$?sudo?firewall-cmd?--permanent?--zone=public?--list-ports
#?開啟需要路由的端口
$?sudo?firewall-cmd?--permanent?--zone=public?--add-port=8080/tcp
$?sudo?firewall-cmd?--permanent?--zone=public?--add-port=8081/tcp
#?配置立即生效
firewall-cmd?--reload
#?關(guān)閉防火墻
$?sudo?systemctl?stop?firewalld.service
#?禁用自啟動(dòng)
$?sudo?systemctl?disable?firewalld.service
10.Docker 無法獲取鏡像
新初始化的機(jī)器,無法獲取私有倉庫的鏡像文件!
[問題起因] 機(jī)器初始化之后,使用如下命令登錄私有 docker 倉庫,發(fā)現(xiàn)提示無法獲取對(duì)應(yīng)鏡像,但是在其他機(jī)器上面獲取該鏡像就可以執(zhí)行成功,這就非常奇怪了!
#?登錄私有倉庫
$?echo?'123456'?|?docker?login?-u?escape?--password-stdin?docker.escapelife.site
#?異常信息提示
$?sudo?docker?pull?docker.escapelife.site/app:0.10
Error?response?from?daemon:?manifest?for?docker.escapelife.site/app:0.10?not?found:?manifest?unknown:?manifest?unknown
[解決方法] 太坑了,我還以為我發(fā)現(xiàn)某個(gè)隱藏的 bug 了,可勁的排查,最后發(fā)現(xiàn),原來是自己鏡像包名字寫錯(cuò)了,應(yīng)該寫成 0.0.10 的,自己卻寫成了 0.10。這里,紀(jì)念一下,以后碰到上述報(bào)錯(cuò),那肯定是鏡像不存在的。
#?登錄私有倉庫之后會(huì)在用戶家目錄下生成一個(gè)docker配置
#?其用來記錄docker私有倉庫的登錄認(rèn)證信息(是加密過的信息但不安全)?=>?base64
$?cat?.docker/config.json
{
????"auths":?{
????????"docker.escapelife.site":?{
????????????"auth":?"d00u11Fu22B3355VG2xasE12w=="
????????}
????}
}
11.Docker 使容器不退出
如何使使用 docker-compose 啟動(dòng)的容器服務(wù) hang 住而不退出
[問題起因] 有時(shí)候我們啟動(dòng)的服務(wù),因?yàn)槟承﹩栴}(bug)導(dǎo)致服務(wù)無法正常啟動(dòng),就會(huì)出現(xiàn)容器無限重啟(restart: on-failure)的情況,這時(shí)就很不利于排除問題。
??docker?ps?-a
4e6xxx9a4???app:latest???"/xxx/…"???26?seconds?ago???Restarting?(1)?2?seconds?ago
[解決方法] 這時(shí)我們就需要根據(jù),服務(wù)構(gòu)建使用命令來決定是用什么命令來 hang 住服務(wù)。卡住的原理,就類似于使用 /bin/bash 進(jìn)入容器是一樣的,這里我就不過多解釋了。
#?類似原理
docker?run?-it?--rm?--entrypoint=/bin/bash?xxx/app:latest
#?使用Command命令
tty:?true
command:?tail?-f?/dev/null
#?使用Entrypoint命令
tty:?true
entrypoint:?tail?-f?/dev/null
同理,我們?cè)谑褂?docker-compose 或者 k8s 平臺(tái)部署服務(wù)的時(shí)候,也有時(shí)會(huì)因?yàn)閱?dòng)問題需要,使啟動(dòng)的服務(wù)不直接退出,來手動(dòng)調(diào)試和排查問題原因。所以,我這里記錄下其不同部署方式的,暫停方式。
#?Compose
version:?"3"
services:
??app:
????image:?ubuntu:latest
????tty:?true
????entrypoint:?/usr/bin/tail
????command:?"-f?/dev/null"
#?K8S
apiVersion:?v1
kind:?Pod
metadata:
??name:?ubuntu
spec:
??containers:
????-?name:?ubuntu
??????image:?ubuntu:latest
??????command:?["/bin/bash",?"-c",?"--"]
??????args:?["while?true;?do?sleep?30;?done;"]
??????#?command:?["sleep"]
??????#?args:?["infinity"]
12.Docker 不使用默認(rèn)網(wǎng)段
有些情況,內(nèi)部規(guī)劃的網(wǎng)段和可能和 Dockerd 默認(rèn)的網(wǎng)段有沖突,導(dǎo)致異常出現(xiàn)!
[問題起因] 今天在新機(jī)器上面,部署了一整套服務(wù)(多臺(tái)機(jī)器),服務(wù)部署完畢之后,通過前置 Nginx 服務(wù)發(fā)現(xiàn)并不能訪問,后置機(jī)器開放的端口,發(fā)現(xiàn)發(fā)到對(duì)應(yīng)端口的請(qǐng)求都沒有轉(zhuǎn)發(fā)出去。這就比較奇怪了,因?yàn)槎丝诳刂剖且呀?jīng)開通了的,不應(yīng)該出現(xiàn)不通的情況。
??nc?-v?172.16.100.12?8000
nc:?connect?to?172.16.100.12?port?8000?(tcp)?failed:?Connection?refused
[解決方法] 發(fā)現(xiàn)服務(wù)器端口不通,我這里懷疑可能是 dockerd 服務(wù)啟動(dòng)導(dǎo)致的,所以我先將服務(wù)都停掉,直接在機(jī)器上面啟動(dòng)了 Python 的服務(wù)端程序(Linux 機(jī)器自帶 Python2.7.x 的版本),然后在前置 Nginx 服務(wù)發(fā)現(xiàn),端口確實(shí)是通的。后來,排除發(fā)現(xiàn)是內(nèi)部服務(wù)默認(rèn)網(wǎng)段和 dockerd 服務(wù)啟動(dòng)的默認(rèn)網(wǎng)段是沖突的,導(dǎo)致重寫了機(jī)器的防火墻規(guī)則,導(dǎo)致出現(xiàn)上述異常的。
$?python?-m?SimpleHTTPServer?8000
Serving?HTTP?on?0.0.0.0?port?8000?...
??nc?-v?172.16.100.12?8000
Connection?to?172.16.100.12?8000?port?[tcp/*]?succeeded!
既然問題已經(jīng)知道了,現(xiàn)在需要做的就是非常簡單了:不適用默認(rèn)網(wǎng)段!通過 『mirantis』 里面,我們可以選擇進(jìn)行設(shè)置,然后重啟服務(wù) dockerd 服務(wù),即可。
#?修改配置
$?sudo?cat?/etc/docker/daemon.json
{
??"default-address-pools":[{"base":"192.168.100.0/20","size":24}]
}
#?重啟服務(wù)
$?sudo?systemctl?restart?docker
#?啟動(dòng)服務(wù)驗(yàn)證是否生效
$?ip?a
$?docker?network?inspect?app?|?grep?Subnet

這時(shí),就到了考驗(yàn)我們網(wǎng)絡(luò)的子網(wǎng)劃分的能力了:如何在給定的網(wǎng)段下面合理且高效的進(jìn)行劃分呢?咳咳,確實(shí)難倒我了,這時(shí)我們可以再這個(gè)在線網(wǎng)站上面 JSON 在線解析 進(jìn)行劃分,然后選定合理的 base 和 size 就可以了。
#?報(bào)錯(cuò)信息
Error?response?from?daemon:?could?not?find?an?available,?non-overlapping?IPv4?address?pool?among?the?defaults?to?assign?to?the?network
#?按照下圖我們可以對(duì)?pool?進(jìn)行合理劃分
#?給定?10.210.200.0?+?255.255.255.0?的網(wǎng)段來劃分子網(wǎng)
$?sudo?cat?/etc/docker/daemon.json
{
??"default-address-pools":[{"base":"10.210.200.0/24","size":28}]
}
其中,base 告訴我們劃分子網(wǎng)的網(wǎng)段是什么(從來開始),是從前兩位(/16)開始,還是第三位開始(/24)呢?而 size 則告訴我們劃分的每個(gè)子網(wǎng)有多少 IP 地址可以使用呢?從 "10.210.200.0/24" 我們可以知道,該網(wǎng)絡(luò)下面只有 254 個(gè)可用的 IP 地址(直接使用肯定不夠),然后我們需要給 docker 使用,劃分每個(gè)子網(wǎng)可用 16 個(gè) IP 地址,所以子網(wǎng)就應(yīng)該寫成 28 了。

13.Docker 添加私有倉庫
有些情況,我們服務(wù)器上面需要使用內(nèi)部私有的容器鏡像地址!
[問題起因] 如果新機(jī)器上面需要使用私有倉庫的話,但是又沒有配置,再獲取鏡像的時(shí)候就會(huì)出現(xiàn)如下報(bào)錯(cuò)信息。
#?拉取/登陸私庫時(shí)提示
$?docker?pull?192.168.31.191:5000/nginx:latest
x509:?certificate?signed?by?unknown?authority
[解決方法] 該問題的處理方式很簡單,如下所示,配置一下倉庫地址,重啟服務(wù)并登陸私有倉庫就可以了。
#?添加配置
$?sudo?cat?/etc/docker/daemon.json
{
????"insecure-registries":?["192.168.31.191:5000"]
}
#?重啟docker
$?sudo?systemctl?restart?docker
#?重新登錄即可
$?docker?login?私庫地址?-u?用戶名?-p?密碼
14.Docker 解決時(shí)間同步
解決 Docker 容器時(shí)間時(shí)區(qū)和宿主機(jī)不同步的問題!
[問題起因] 有時(shí)間我們會(huì)遇到新創(chuàng)建的容器,容器內(nèi)部和外部時(shí)間不一致,這就導(dǎo)致服務(wù)的日志、定時(shí)任務(wù)等不能按照我們既定的時(shí)間觸發(fā),非常麻煩。
#?容器內(nèi)部時(shí)間(CST?-?東八區(qū)?-?北京時(shí)間)
[root@server?~]#?date
Fri?Apr?27?22:49:47?CST?2022
#?容器外部時(shí)間(UTC?-?格林尼治?-?標(biāo)準(zhǔn)時(shí)間)
[root@server?~]#?docker?run?--rm?nginx?date
Fri?Apr?27?14:49:51?UTC?2022
[解決方法] 宿主機(jī)設(shè)置了時(shí)區(qū),而 Docker 容器并沒有設(shè)置,導(dǎo)致兩者相差 8 小時(shí)。
#?以?docker?run?方式啟動(dòng)
$?docker?run?-d?--name?'app'?\
????-v?/etc/localtime:/etc/localtime?\
????escape/nginx:v1
#?以?Dockerfile?構(gòu)建
ENV?TimeZone=Asia/Shanghai
RUN?ln?-sf?/usr/share/zoneinfo/Asia/Shanghai?/etc/localtime
#?以?docker-compose?方式啟動(dòng)
environment:
??TZ:?Asia/Shanghai
作者:escape?
來源:https://www.escapelife.site/posts/43a2bb9b.html
推薦閱讀:

