docker的學習(七)-docker深入學習
技術標籤:docker
四、docker高階知識
4.1 執行一個 web 應用
前面我們執行的容器並沒有一些什麼特別的用處。
接下來讓我們嘗試使用 docker 構建一個 web 應用程式。
我們將在docker容器中執行一個 Python Flask 應用來執行一個web應用。
[[email protected] ~]# docker pull training/webapp # 載入映象 [[email protected] ~]# docker run -d -d -P training/webapp python app.py WARNING: IPv4 forwarding is disabled. Networking will not work. 11c153984caa26e8dce7973e4ea79f6db6126689222a180c0a06593bf2594187
-
-d:讓容器在後臺執行。
-
-P:將容器內部使用的網路埠隨機對映到我們使用的主機上。
4.1.1 檢視 WEB 應用容器
使用 docker ps 來檢視我們正在執行的容器:
[[email protected] ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11c153984caa training/webapp "python app.py" 11 seconds ago Up 9 seconds 0.0.0.0:49154->5000/tcp magical_saha
PORTS
多了埠資訊。
0.0.0.0:49154->5000/tcp
Docker 開放了 5000 埠(預設 Python Flask 埠)對映到主機埠 49154上。
4.1.2 訪問驗證
在訪問驗證之前先調整一下配置,不然可能會出現無法訪問的問題
檢視ip轉發是否開啟
sysctl net.ipv4.ip_forward
顯示net.ipv4.ip_forward=0則表示未開啟。
開啟方式
vim /etc/sysctl.conf
# 增加一行
net.ipv4.ip_forward = 1
# 儲存檔案 shift ZZ
# 重新載入
# sysctl -p
這時我們可以通過瀏覽器訪問WEB應用
如果還不行,關閉防火牆試試
# 檢視防火牆狀態,runing為啟動
systemctl status firewalld.server
# 關閉防火牆
systemctl stop firewalld.server
# 禁用防火牆
systemctl stop firewalld.server
4.1.3 網路埠的快捷方式
通過 docker ps 命令可以檢視到容器的埠對映
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
724961f8f2ab training/webapp "python app.py" 6 minutes ago Up 6 minutes 0.0.0.0:5000->5000/tcp nervous_carson
docker 還提供了另一個快捷方式 docker port
- 使用 docker port 可以檢視指定 (ID 或者名字)容器的某個確定埠對映到宿主機的埠號。
上面我們建立的 web 應用容器 ID 為 724961f8f2ab 的name為 nervous_carson
可以使用 docker port bf08b7f2cd89
或docker port wizardly_chandrasekhar
來檢視容器埠的對映情況。
[[email protected] ~]# docker port 724961f8f2ab
5000/tcp -> 0.0.0.0:5000
[[email protected] ~]# docker port nervous_carson
5000/tcp -> 0.0.0.0:5000
4.1.4 檢視 WEB 應用程式日誌
docker logs [ID或者名字] 可以檢視容器內部的標準輸出。
[[email protected] ~]# docker logs -f 724
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.88.163 - - [18/Jan/2021 06:02:05] "GET / HTTP/1.1" 200 -
192.168.88.163 - - [18/Jan/2021 06:02:06] "GET /favicon.ico HTTP/1.1" 404 -
-f
: 讓 docker logs 像使用 tail -f 一樣來輸出容器內部的標準輸出。
從上面,我們可以看到應用程式使用的是 5000 埠並且能夠檢視到應用程式的訪問日誌。
4.1.5 檢視WEB應用程式容器的程序
我們還可以使用 docker top 來檢視容器內部執行的程序
[[email protected] ~]# docker top 72496
UID PID PPID C STIME TTY TIME CMD
root 25038 25018 0 00:55 ? 00:00:00 python app.py
4.1.6 檢查 WEB 應用程式
使用 docker inspect 來檢視 Docker 的底層資訊。它會返回一個 JSON 檔案記錄著 Docker 容器的配置和狀態資訊。包括容器id、內部網路和ip地址等
[[email protected] ~]# docker inspect 724
[
{
"Id": "724961f8f2ab3c7266abdf5ceff2cf55673520afced2b7affbac945dbc650c39",
"Created": "2021-01-18T05:55:12.264342106Z",
"Path": "python",
"Args": [
"app.py"
],
"State": {
"Status": "running",
"Running": true,
此處省略......
4.2 Docker 容器連線
前面我們實現了通過網路埠來訪問執行在 docker 容器內的服務。
容器中可以執行一些網路應用,要讓外部也可以訪問這些應用,可以通過 -P 或 -p 引數來指定埠對映。
並且已經通過埠連線到一個 docker 容器,下面學習一下其他的連線方式
4.2.1 網路埠對映
在前面我們已經建立了一個 python 應用的容器。
[[email protected] ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
training/webapp latest 6fae60ef3446 5 years ago 349MB
並且使用-P
引數建立一個容器,通過 docker ps 可以看到容器埠 5000 繫結主機埠 49154。
我們也可以使用 -p
標識來指定容器埠繫結到主機埠。
兩種方式的區別是:
- -P :是容器內部埠
隨機對映
到主機的高階口。 - -p : 是容器內部埠
繫結到指定
的主機埠。
例:容器內部的 5000 埠對映到我們本地主機的 5000 埠上。
[[email protected] ~]# docker run -d -p 5000:5000 training/webapp python app.py
68a8bf0a9b978e58904049da5bb9801ba7e73b0e8441367c036a86098964a879
docker: Error response from daemon: driver failed programming external connectivity on endpoint goofy_visvesvaraya (e0c75e5ad3794ea85e2f4f3d04b5dba69a7819b7b6ecf428fe7e07c23c15612b): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 5000 -j DNAT --to-destination 172.17.0.2:5000 ! -i docker0: iptables: No chain/target/match by that name.
(exit status 1)).
報錯了,重啟一下docker服務就行
[[email protected] ~]# systemctl restart docker
[[email protected] ~]# docker run -d -p 5000:5000 training/webapp python app.py
724961f8f2ab3c7266abdf5ceff2cf55673520afced2b7affbac945dbc650c39
我們可以指定容器繫結的網路地址,比如繫結 127.0.0.1。
[[email protected] ~]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
e9ba94ff43f74ccd49bf005caad6765ebc770d08a6e7c11c41a64e31448e7c6e
$ curl http://127.0.0.1:5001/ ##訪問通過
$ curl http://localhost:5001/ ##訪問通過
$ curl http://192.168.88.84:5001/ ##訪問拒絕
curl: (7) Failed connect to 192.168.88.84:5001; 拒絕連線
從上面的測試中可以知道,要訪問容器中的應用只能通過127.0.0.1這個ip訪問容器的 5000 埠
接下來是繫結本機的任意埠到容器的80埠,docker會隨機分配一個埠
[[email protected] ~]# docker run -d -p 127.0.0.1::80 training/webapp python app.py
dee8072509d19728d0f4d850105c02ceb947e389344dd1ab7ea1f3b08c75a963
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dee8072509d1 training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp, 127.0.0.1:49153->80/tcp frosty_wilbur
e9ba94ff43f7 training/webapp "python app.py" 7 minutes ago Up 7 minutes 127.0.0.1:5001->5000/tcp flamboyant_feynman
[[email protected] ~]# curl http://127.0.0.1:49153/
curl: (56) Recv failure: Connection reset by peer
失敗的原因可能是 Python Flask 程式本身的問題, Python Flask 預設為5000 埠,
[[email protected] ~]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py
3bdc7439068faec51b2817930df49b7f0e4bdace3aa1bd70457188946b4ccd65
[[email protected] ~]# docker port 3bdc
5000/tcp -> 127.0.0.1:49154
[[email protected] ~]# curl 127.0.0.1:49154
Hello world!
還可以指定通訊協議,上面的例子中,預設都是繫結 tcp 埠,如果要繫結 UDP 埠,可以在埠後面加上 /udp
[[email protected] ~]# docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
f029e7235829a093b3db44d2d07ef0a56a4e88de87d63cca5fe28f78d358a578
[[email protected] ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f029e7235829 training/webapp "python app.py" About a minute ago Up About a minute 5000/tcp, 127.0.0.1:5000->5000/udp focused_galileo
修改已有Docker的埠對映
查詢要修改容器的容器Id
[[email protected] centos-test]# docker inspect 7e06 | grep Id
"Id": "7e06bef1c5a72b251a702810c3b739f09333cfc1521407f8c1937bba5742514d",
進到/var/lib/docker/containers 目錄下找到與 Id 相同的目錄,修改 hostconfig.json 和 config.v2.json檔案:
[[email protected] centos-test]# cd /var/lib/docker/containers/7e06bef1c5a72b251a702810c3b739f09333cfc1521407f8c1937bba5742514d/
若該容器還在執行,先停掉docker stop 容器ID
停掉docker服務systemctl stop docker
修改hostconfig.json
找到"PortBindings":{}
項,新增埠繫結"8888/tcp": [{"HostIp": "","HostPort": "8888"}]
,表示繫結埠8888
"PortBindings":{"20/tcp": [{"HostIp": "","HostPort": "20"}],"21/tcp": [{"HostIp": "","HostPort": "21"}],"80/tcp": [{"HostIp": "","HostPort": "80"}],"443/tcp": [{"HostIp": "","HostPort": "443"}],"888/tcp": [{"HostIp": "","HostPort": "888"}],"8888/tcp": [{"HostIp": "","HostPort": "8888"}]},
修改config.v2.json
Hostname的找到ExposedPorts項(若沒有就手動新增一個),加上要暴露的埠"8888/tcp":{}
,即8888
{"Hostname":"7e06bef1c5a7","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"20/tcp":{},"21/tcp":{},"80/tcp":{},"443/tcp":{},"888/tcp":{},"8888/tcp":{}},
啟動容器服務
systemctl start docker
啟動容器
docker start 7e
檢視埠
[[email protected] ~]# docker port 7e
80/tcp -> 0.0.0.0:80
888/tcp -> 0.0.0.0:888
8888/tcp -> 0.0.0.0:8888
20/tcp -> 0.0.0.0:20
21/tcp -> 0.0.0.0:21
443/tcp -> 0.0.0.0:443
4.2.2 Docker 容器互聯
埠對映並不是唯一把 docker 連線到另一個容器的方法。
docker 有一個連線系統允許將多個容器連線在一起,共享連線資訊。
docker 連線會建立一個父子關係,其中父容器可以看到子容器的資訊。
4.2.2.1 新建網路
下面先建立一個新的 Docker 網路。
[[email protected] ~]# docker network create -d bridge test-net
4ebeed8954c7f2de25ea86e09e583b33ae1f7fe529021e97f8681efad49f3215
先檢視下docker網路,發現添加了一個test-net網路
[[email protected] ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2b4ba552df71 bridge bridge local
492a3147f7fc host host local
4e9c3ec7cede none null local
4ebeed8954c7 test-net bridge local
引數說明:
- -d:引數指定 Docker 網路型別,有 bridge、overlay。
其中 overlay 網路型別用於 Swarm mode,在本小節中你可以忽略它。
4.2.2.2 連線容器
執行一個容器並連線到新建的 test-net 網路:
[[email protected] ~]# docker run -itd --name test1 --network test-net centos /bin/bash
8bb60b1c46b8e225d9d97c167e9fd715a93506add95b0708850a59260e04ee0a
開啟新的終端,再執行一個容器並加入到 test-net 網路:
[[email protected] ~]# docker run -itd --name test2 --network test-net centos /bin/bash
550d72f553e508d77a9ab0836d566d9b3e71fb9fe9fbb9c0b8763b87a3123ead
下面通過 ping 來證明 test1 容器和 test2 容器建立了互聯關係。
[[email protected] ~]# docker exec -it test1 /bin/bash
[[email protected] /]# ping test2
PING test2 (172.18.0.3) 56(84) bytes of data.
64 bytes from test2.test-net (172.18.0.3): icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from test2.test-net (172.18.0.3): icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from test2.test-net (172.18.0.3): icmp_seq=3 ttl=64 time=0.086 ms
這樣,test1 容器和 test2 容器建立了互聯關係。
如果你有多個容器之間需要互相連線,推薦使用Docker Compose
4.2.2.3 配置 DNS
如果在容器啟動時沒有指定 --dns 和 --dns-search,Docker 會預設用宿主主機上的 /etc/resolv.conf 來配置容器的 DNS。
全域性dns配置
我們可以在宿主機的 /etc/docker/daemon.json 檔案中增加以下內容來設定全部容器的 DNS:
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
設定後,啟動容器的 DNS 會自動配置為 114.114.114.114 和 8.8.8.8。
配置完,需要重啟 docker 才能生效。
檢視容器的 DNS 是否生效可以使用以下命令,它會輸出容器的 DNS 資訊:
[[email protected] ~]# docker run -it --rm centos cat /etc/resolv.conf
nameserver 114.114.114.114
nameserver 8.8.8.8
手動指定容器的配置
如果只想在指定的容器設定 DNS,則可以使用以下命令:
$ docker run -it --rm -h host_centos --dns=114.114.114.114 --dns-search=test.com centos
引數說明:
- –rm:容器退出時自動清理容器內部的檔案系統。
- -h HOSTNAME 或者 --hostname=HOSTNAME: 設定容器的主機名,它會被寫到容器內的 /etc/hostname 和 /etc/hosts。
- –dns=IP_ADDRESS: 新增 DNS 伺服器到容器的 /etc/resolv.conf 中,讓容器用這個伺服器來解析所有不在 /etc/hosts 中的主機名。
- –dns-search=DOMAIN: 設定容器的搜尋域,當設定搜尋域為 .example.com 時,在搜尋一個名為 host 的主機時,DNS 不僅搜尋 host,還會搜尋 host.example.com。
4.3 dockerfile學習
關於dockerfile的基本使用在 3.1.5.2 使用Dockerfile建立映象 已經學過了,就不再寫了
4.3.1 dockerfile的指令詳解
4.4 docker實踐應用
寶塔
使用dockerfile構建一個寶塔面板映象
# This my first nginx Dockerfile
# Version 1.0
# Base images 基礎映象
FROM centos
#MAINTAINER 維護者資訊
MAINTAINER test-1
#RUN 執行以下命令
Run yum install -y git
Run yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh -y
# 執行命令
CMD ["bt","default"]
emm~~~ 安裝失敗,因為寶塔安裝的時候還要手動輸入一個y
,但在容器外輸入的時候容器無法接收到
Step 5/5 : RUN yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
---> Running in 1f6536ea5a61
Last metadata expiration check: 19:38:53 ago on Tue Jan 19 06:00:31 2021.
Package wget-1.19.5-10.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!
--2021-01-20 01:39:25-- http://download.bt.cn/install/install_6.0.sh
Resolving download.bt.cn (download.bt.cn)... 123.129.198.197, 240e:ff:9000:1100:0:3:0:36
Connecting to download.bt.cn (download.bt.cn)|123.129.198.197|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25386 (25K) [application/octet-stream]
Saving to: 'install.sh'
0K .......... .......... .... 100% 2.49M=0.01s
2021-01-20 01:39:25 (2.49 MB/s) - 'install.sh' saved [25386/25386]
+----------------------------------------------------------------------
| Bt-WebPanel FOR CentOS/Ubuntu/Debian
+----------------------------------------------------------------------
| Copyright © 2015-2099 BT-SOFT(http://www.bt.cn) All rights reserved.
+----------------------------------------------------------------------
| The WebPanel URL will be http://SERVER_IP:8888 when installed.
+----------------------------------------------------------------------
y
y
^C
研究了一會,煩了,就用普通方式建立一個吧
[[email protected] centos-test]# docker run -itd --name bt_centos centos /bin/bash
7e06bef1c5a72b251a702810c3b739f09333cfc1521407f8c1937bba5742514d
[[email protected] centos-test]# docker exec -it 7e06 /bin/bash
[[email protected] /]# yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh
[[email protected] /]# exit
exit
[[email protected] centos-test]# docker commit -m "add a new bt" -a "silentgrass" 7e06 silentgrass/btcebtos:v1
sha256:6b99547dee16fd78177501af2efd73a95932b544ff72984c1f86f376ce56b934
[[email protected] centos-test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
silentgrass/btcebtos v1 6b99547dee16 About a minute ago 869MB
忘記指定埠了怎麼啟動呢
1.根據新封裝的映象建立寶塔容器
docker run -i -t -d --name baota -p 20:20 -p 21:21 -p 80:80 -p 443:443 -p 888:888 -p 8888:8888 --privileged=true -v /home/www:/www silentgrass/btcebtos
2.修改要埠對映的容器的配置檔案 點此跳轉
- - - 高階應用over - - -
感謝
Docker埠對映外部無法訪問問題
docker埠對映或啟動容器時報錯Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen
Docker容器繫結外部IP和埠
docker容器新增對外對映埠
修改已有Docker的埠對映