Linux學習 day11之docker續集
docker續集
使用 Docker 容器
建立容器
在
Docker
中,真正對外提供服務的還是容器,本小節我們們來建立一個容器。
建立容器的格式:docker run [option] image [cmd]
如:docker run -d --name nginx -p 80:80 nginx
容器啟動引數
-d
以守護程式方式執行
-p
指定對映埠
-P
隨機對映埠
-i
保持標準輸入開啟
-t
分配一個偽終端
-v
設定掛載檔案到主機上
--rm
當容器關閉時自動刪除
--name
為啟動的容器設定一個名字
--network
指定使用哪個網路
-e
設定容器中的環境變數
--link
連結到另一個容器
-h
指定容器內的主機名
停止容器
docker
終止容器是首先向容器傳送SIGTERM
訊號,等待一段時間超時後(預設10
秒),再傳送SIGKILL
訊號來終止容器。
語法:docker stop nginx
NGINX 容器被我們終止後。這個時候我們也可以重新啟動這個容器。
docker start nginx
進入容器
在使用容器的過程中,我們難免需要進入容器進行排查問題。下面我們就來介紹進入容器的集中方式。
attach
attach
是最早docker
官方推出的進入容器的命令了,不過使用該命令有一個問題。當多個視窗同時使用該命令進入該容器時,所有的視窗都會同步顯示。如果有一個視窗阻塞了,那麼其他視窗也無法再進行操作,當所有視窗退出時,容器結束。
`docker attach nginx`
127.0.0.1 - "GET / HTTP/1.1" 308 171 "-" "curl/7.59.0" 0.000 - .
exec
既
attach
之後,exec
是官方推出的有一個新的進入容器的命令,這個命令相當於在容器中執行一個命令
docker exec -it nginx /bin/bash
nginx [ / ]$
nginx [ / ]$
nsenter
需要配合
docker inspect
來使用(早期沒有exec
命令時,企業當中最長用的方式之一),Docker
是用golang
語言開發,所以它也支援 go 語言的摸版語法。
nsenter --target $( docker inspect -f {{.State.Pid}}nginxv1 ) --mount --uts --ipc --net --pid
mesg: ttyname failed: No such device
root@6f99ae8757f7:/#
ssh
在生產環境中排除了使用
docker attach
命令進入容器之後,相信大家第一個想到的就是ssh
。在映象(或容器)中安裝SSH Server
,這樣就能保證多人進入容器且相互之間不受干擾了,相信大家在當前的生產環境中(沒有使用Docker
的情況)也是這樣做的。但是使用了Docker
容器之後不建議使用ssh
進入到Docker
容器內。
總結
進入 docker container
中一般情況下有 4 種方式,最常用的是exec
和nsenter
這兩種。
Nsenter
和exec
之間的區別?
Exec
是docker
自帶的命令,Nsenter
是Linux
提供的命令。Exec
相當於在容器內執行一個命令,而Nsenter
是僅僅進入容器之中而已。
刪除容器
可以使用
docker rm
命令來刪除處於終止或退出狀態的容器,命令格式為:docker rm container
如:docker rm nginx
強制刪除
強制刪除一個正在執行的容器
docker rm -f nginx
匯入與匯出容器
某些時候,需要將容器從一個系統遷移到另外一個系統,此時可以使用
Docker
的導人和匯出功能,這也是Docker
自身提供的一個重要特性。
匯出容器
匯出容器是指,匯出一個已經建立的容器到一個檔案,不管此時這個容器是否處於執行狀態 可以使用
docker [container] export
命令,該命令格式為:
docker export daf9c3656be3 > nginx.tar
匯入容器
匯出的檔案又可以使用
docker [ container] import
命令導人變成映象,該命令格式為:
docker import nginx.tar test/nginx:v1
實際上,既可以使用
docker load
命令來匯入映象儲存檔案到本地映象庫,也可以使docker [container] import
命令來匯入一個容器快照到本地映象庫 這兩者的區別在於 容器快照檔案將丟棄所有的歷史記錄和後設資料資訊(即僅儲存容器當時的快照狀態),而映象儲存檔案將儲存完整記錄,體積更大 此外,從容器快照檔案導人時可以重新指定標籤等後設資料資訊。
檢視容器
檢視容器詳情可以使用
docker container inspect [OPTIONS] CONTAINER [CONTAINER . .. ]
子命令
[root@alvin-test-os ~]# docker inspect k8s
[
{
"Id": "726b695a337c63b2ba617ed282171dff82a3d51cc0bdc43194ce63beaf656c38",
"Created": "2020-11-16T04:05:53.271281122Z",
"Path": "docker-entrypoint.sh",
"Args":
[
"./start"
],
... 此處略去千百行
}
]
容器命令詳解
複製命令
複製命令類似於 Linux 系統中的scp
命令,是將宿主主機上的內容上傳到容器中,也可能是將容器中的檔案下載到宿主主機中。
# 將容器中的內容複製到宿主主機
[root@alvin-test-os ~]# docker cp 726b695a337c:/opt/start .
[root@alvin-test-os ~]# ls | grep start
Start
#將宿主主機中的檔案複製到容器中
[root@alvin-test-os ~]# docker cp start 726b695a337c:/root
[root@alvin-test-os ~]# docker exec 726b695a337c ls /root
start
Docker 網路
Docker
本身的技術依賴於 Linux 核心虛擬化技術的發展。所以Docker
對 Linux 核心的特性有很強的依賴。
本章主要介紹Docker
所使用的 Linux 網路技術。
網路基礎
其中 Docker 使用到的與 Linux 網路有關的技術分別有:網路名稱空間、Veth、Iptables、網橋、路由。
網路名稱空間
為了支援網路協議棧的多個例項,Linux 在網路協議棧中引入了網路
名稱空間(Network Namespace)
,這些獨立的協議棧被隔離到不同的名稱空間中。處於不同的名稱空間的網路協議棧是完全隔離的,彼此之間無法進行網路通訊,就好像兩個“平行宇宙”。通過這種對網路資源的隔離,就能在一個宿主機上虛擬多個不同的網路環境,而Docker
正是利用這種網路名稱空間的特性,實現了不同容器之間的網路隔離。在 Linux 的網路名稱空間內可以有自己獨立的Iptables
來轉發、NAT
及IP
包過濾等功能。
Linux 的網路協議棧是十分複雜的,為了支援獨立的協議棧,相關的這些全域性變數都必須修改為協議棧私有。最好的辦法就是讓這些全域性變數成為一個
Net Namespace
變數的成員,然後為了協議棧的函式呼叫加入一個Namespace
引數。這就是 Linux 網路名稱空間的核心。所以的網路裝置都只能屬於一個網路名稱空間。當然,通常的物理網路裝置只能關聯到root
這個名稱空間中。虛擬網路裝置則可以被建立並關聯到一個給定的名稱空間中,而且可以在這些名稱空間之間移動。
建立一個名稱空間
[root@alvin-test-os ~]# ip netns add test01
[root@alvin-test-os ~]# ip netns add test02
[root@alvin-test-os ~]# ip netns list
test02
test01
Veth
裝置
引入
Veth
裝置對是為了在不同的網路名稱空間之間進行通訊,利用它可以直接將兩個網路名稱空間連結起來。由於要連線的兩個網路名稱空間,所以Veth
裝置是成對出現的,很像一對乙太網卡,並且中間有一根直連的網線。既然是一對網路卡,那麼我們將其中一端稱為另一端的peer
。在Veth
裝置的一端傳送資料時,它會將資料直接傳送到另一端,並觸發另一端的接收操作。
Veth
裝置操作
建立Veth
裝置對
ip link add veth type veth peer name veth001
- 生成了兩個
veth
裝置, 互為對方的peer
繫結名稱空間
ip link set veth001 netns test01
ip link show | grep veth
已經檢視不到veth001
,當我們進入test01
名稱空間之後,就可以檢視到:
ip netns exec test01 bash
將Veth
分配IP
# 設定 IP
[root@alvin-test-os ~]# ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001
# 繫結
[root@alvin-test-os ~]# ip netns exec test01 ip link set dev veth001 up
# 檢視
[root@alvin-test-os ~]# ip netns exec test01 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
14: veth001@if15: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state
LOWERLAYERDOWN group default qlen 1000
link/ether 96:f1:a2:1d:1d:10 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.16.0.111/20 scope global veth001
valid_lft forever preferred_lft forever
- 這個時候雙方就通了。
檢視對端 Veth
裝置
ip netns exec test01 ethtool -S veth001
為對端Veth
裝置設定IP
[root@alvin-test-os ~]# ip addr add 172.16.0.112/20 dev veth
[root@alvin-test-os ~]# ip link set dev veth down
[root@alvin-test-os ~]# ip link set dev veth up
[root@alvin-test-os ~]# ping 172.16.0.111
PING 172.16.0.111 (172.16.0.111) 56(84) bytes of data.
64 bytes from 172.16.0.111: icmp_seq=1 ttl=64 time=0.126 ms
64 bytes from 172.16.0.111: icmp_seq=2 ttl=64 time=0.081 ms
^C
--- 172.16.0.111 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.081/0.103/0.126/0.024 ms
網橋
Linux 可以支援多個不同的網路,它們之間能夠相互通訊,就需要一個網橋。 網橋是二層的虛擬網路裝置,它是把若干個網路介面“連線”起來,從而報文能夠互相轉發。網橋能夠解析收發的報文,讀取目標
MAC
地址的資訊,和自己記錄的MAC
表結合,來決定報文的轉發目標網口。
網橋裝置
brO
繫結了eth0
、eth1
。對於網路協議械的上層來說,只看得到brO
。因為橋接是在資料鏈路層實現的 ,上層不需要關心橋接的細節,於是協議枝上層需要傳送的報文被送到brO
,網橋裝置的處理程式碼判斷報文該被轉發到ethO
還是ethl
,或者兩者皆轉發。反過來,從ethO
或從ethl
接收到的報文被提交給網橋的處理程式碼,在這裡會判斷報文應該被轉發、丟棄還是提交到協議枝上層。 而有時ethl
也可能會作為報文的源地址或目的地址 直接參與報文的傳送與接收,從而繞過網橋。
Iptables
我們知道, Linux 絡協議樵非常高效,同時比較複雜 如果我們希望在資料的處理過程中對關心的資料進行一些操作該怎麼做呢? Linux 提供了一套機制來為使用者實現自定義的資料包處理過程。在 Linux 網路協議棋中有一組回撥函式掛接點,通過這些掛接點掛接的鉤子函式可以在 Linux 網路棋處理資料包的過程中對資料包進行 些操作,例如過濾、修改、丟棄等 整個掛接點技術叫作
Netfilter lptablesNetfilter
負責在核心中執行各種掛接的規則,執行在核心模式中:而lptables
是在使用者模式下執行的程式,負責協助維護核心中Netfilter
的各種規則表 通過 者的配合來實現整個 Linux 網路協議戰中靈活的資料包處理機制。
總結
network namespace
主要提供了關於網路資源的隔離,包括網路裝置、IPv4 和
IPv6協議棧、IP 路由表、防火牆、
/proc/net目錄、
/sys/class/net目錄、埠(
socket)等。
linux Bridge
功能相當於物理交換機,為連在其上的裝置(容器)轉發資料幀。如docker0
網橋。
iptables
主要為容器提供NAT
以及容器網路安全。
veth pair
兩個虛擬網路卡組成的資料通道。在Docker
中,用於連線Docker
容器和Linux Bridge
。一端在容器中作為eth0
網路卡,另一端在Linux Bridge
中作為網橋的一個埠。
Docker 網路模式
Docker
使用 Linux 橋接的方式,在宿主機虛擬一個Docker
容器網橋(docker0),Docker
啟動一個容器時會根據Docker
網橋的網段分配給容器一個IP
地址,稱為Container-IP
,同時Docker
網橋是每個容器的預設閘道器。因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的Container-IP
直接通訊。
Docker
網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路是無法定址到的,這也意味著外部網路無法通過直接Container-IP
訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到宿主主機(埠對映),即docker run
建立容器時候通過-p
或-P
引數來啟用,訪問容器的時候就通過[宿主機 IP]:[容器埠]
訪問容器。
Docker 網路模型 | 配置 | 說明 |
---|---|---|
host 模式 | –-network=host | 容器和宿主機共享 Network namespace 。 |
containe 模式 | --network=container:ID | 容器和另外一個容器共享 Network namespace 。 kubernetes 中的 pod 就是多個容器共享一個 Network namespace 。 |
none 模式 | --network=none | 容器有獨立的 Network namespace ,但並沒有對其進行任何網路設定,如分配 veth pair 和網橋連線,配置IP 等。 |
bridge 模式 | --network=bridge | 當 Docker 程式啟動時,會在主機上建立一個名為 docker0 的虛擬網橋,此主機上啟動的Docker 容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。(預設為該模式) |
HOST
模式
如果啟動容器的時候使用 host 模式,那麼這個容器將不會獲得一個獨立的
Network Namespace
,而是和宿主機共用一個Network Namespace
。容器將不會虛擬出自己的網路卡,配置自己的 IP 等,而是使用宿主機的IP
和埠。但是,容器的其他方面,如檔案系統、程式列表等還是和宿主機隔離的。
使用
host
模式的容器可以直接使用宿主機的 IP 地址與外界通訊,容器內部的服務埠也可以使用宿主機的
埠,不需要進行NAT
,host
最大的優勢就是網路效能比較好,但是docker host
上已經使用的埠就不能再
用了,網路的隔離性不好。
[root@instance-gvpb80ao ~]# docker run -d --name my-web --network host nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
d121f8d1c412: Pull complete
ebd81fc8c071: Pull complete
655316c160af: Pull complete
d15953c0e0f8: Pull complete
2ee525c5c3cc: Pull complete
Digest: sha256:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0
Status: Downloaded newer image for nginx:latest
06941559a3f7e0c53cf228302dedc2040c10f2eb0b6e3d0f962c065b0e0419ce
[root@instance-gvpb80ao ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
06941559a3f7 nginx "/docker-entrypoint.…" 6 minutes ago
Up 6 minutes my-web
[root@instance-gvpb80ao ~]# curl 127.0.0.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Containe
模式
這個模式指定新建立的容器和已經存在的一個容器共享一個
Network Namespace
,而不是和宿主機共享。新建立的容器不會建立自己的網路卡,配置自己的IP
,而是和一個指定的容器共享IP
、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程式列表等還是隔離的。兩個容器的程式可以通過 lo 網路卡裝置通訊。
[root@instance-gvpb80ao ~]# docker run -itd --name test01 busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
df8698476c65: Pull complete
Digest: sha256:d366a4665ab44f0648d7a00ae3fae139d55e32f9712c67accd604bb55df9d05a
Status: Downloaded newer image for busybox:latest
dd99687d303d61d649364084ad353ec38b4e07149b0328301ec9691f18669951
[root@instance-gvpb80ao ~]# docker run -itd --name test02 --network
"container:test01" busybox
72adb0dcdb93b6adc7a62e1ad1ac274f64b8cec941d5f89da43fcd0757f99fa3
[root@instance-gvpb80ao ~]# docker exec -it test02 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:28 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2423 (2.3 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # exit
[root@instance-gvpb80ao ~]# docker exec -it test01 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:29 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2493 (2.4 KiB) TX bytes:0 (0.0 B)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ #
none
模式
使用
none
模式,Docker
容器擁有自己的Network Namespace
,但是,並不為Docker
容器進行任何網路配置。也就是說,這個Docker
容器沒有網路卡、IP
、路由等資訊。需要我們自己為Docker
容器新增網路卡、配置IP
等。
這種網路模式下容器只有
lo
迴環網路,沒有其他網路卡。none
模式可以在容器建立時通過--network=none
來指定。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。
[root@instance-gvpb80ao ~]# docker run -itd --name test03 --network none busybox
b9dde79754bc110314be4aecde1251dcdd6ce28fdf43102ae184b79c6e7414bc
[root@instance-gvpb80ao ~]# docker exec -it test03 sh
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
bridge
模式
當
Docker
程式啟動時,會在主機上建立一個名為docker0
的虛擬網橋,此主機上啟動的Docker
容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。
從
docker0
子網中分配一個IP
給容器使用,並設定docker0
的IP
地址為容器的預設閘道器。在主機上建立
一對虛擬網路卡veth pair
裝置,Docker
將veth pair
裝置的一端放在新建立的容器中,並命名為eth0
(容器的網
卡),另一端放在主機中,以vethxxx
這樣類似的名字命名,並將這個網路裝置加入到docker0
網橋中。可以
通過brctl show
命令檢視。
bridge
模式是docker
的預設網路模式,不寫--net
引數,就是bridge
模式。使用docker run -p
時,docker
實際是在iptables
做了DNAT
規則,實現埠轉發功能。可以使用iptables -t nat -vnL
檢視。
[root@instance-gvpb80ao ~]# docker run -itd --name test04 busybox
dd17d863b2957a29df44b2552365eb0cfc01552fd4ec6b8b63e28dfd0d61472e
[root@instance-gvpb80ao ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default
qlen 1000
link/ether fa:16:3e:4a:9c:c7 brd ff:ff:ff:ff:ff:ff
inet 172.16.0.4/20 brd 172.16.15.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::f816:3eff:fe4a:9cc7/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42:ab:42:6a:8a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:abff:fe42:6a8a/64 scope link
valid_lft forever preferred_lft forever
5: veth870d996@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master
docker0 state UP group default
link/ether ae:36:24:dc:11:6d brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::ac36:24ff:fedc:116d/64 scope link
valid_lft forever preferred_lft forever
7: veth6acb18a@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master
docker0 state UP group default
link/ether 4e:03:b1:5e:40:91 brd ff:ff:ff:ff:ff:ff link-netnsid 1
inet6 fe80::4c03:b1ff:fe5e:4091/64 scope link
valid_lft forever preferred_lft forever
[root@instance-gvpb80ao ~]# docker exec -it test04 bash
/ # ping 172.16.0.4
PING 172.16.0.4 (172.16.0.4): 56 data bytes
64 bytes from 172.16.0.4: seq=0 ttl=64 time=0.113 ms
64 bytes from 172.16.0.4: seq=1 ttl=64 time=0.101 ms
^C
--- 172.16.0.4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.101/0.107/0.113 ms
Dockerfile 構建映象
Dockerfile
由一行行命令語句組成, 並且支援以#開頭的註釋行。一般而言,Dockerfile
主體內容分為四部分:基礎映象資訊、 維護者資訊、 映象操作指令和容器啟動時執行指令。
Docker
以從上到下的順序執行Dockerfile
的指令。為了指定基本映像,第一條指令必須是FROM
。一個宣告以#字元開頭則被視為註釋。可以在Docker
檔案中使用RUN
,CMD
,FROM
,EXPOSE
,ENV
等指令。
FROM
:指定基礎映象,必須為第一個命令
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
示例: FROM mysql:5.6
注: tag 或 digest 是可選的,如果不使用這兩個值時,會使用 latest 版本的基礎映象
MAINTAINER
: 維護者資訊
格式:
MAINTAINER <name>
示例:
MAINTAINER Jasper Xu
MAINTAINER sorex@163.com
MAINTAINER Jasper Xu <sorex@163.com>
RUN
:構建映象時執行的命令
RUN 用於在映象容器中執行命令,其有以下兩種命令執行方式:
shell 執行
格式:
RUN <command>
exec 執行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注:
RUN 指令建立的中間映象會被快取,並會在下次構建中使用。如果不想使用這些快取映象,可以在構建時指定--no-cache 引數,如:docker build --no-cache
ADD
:將本地檔案新增到容器中
tar
型別檔案會自動解壓(網路壓縮資源不會被解壓)
#格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用於支援包含空格的路徑
#示例:
ADD hom* /mydir/ # 新增所有以"hom"開頭的檔案
ADD hom?.txt /mydir/ # ? 替代一個單字元,例如:"home.txt"
ADD test relativeDir/ # 新增 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 新增 "test" 到 /absoluteDir/
COPY
:功能類似 ADD
,但是是不會自動解壓檔案,也不能訪問網路資源
指令:COPY
功能描述:複製檔案到映象中
語法:COPY < src>… < dest>|[“< src>”,… “< dest>”]
提示:指令邏輯和 ADD 十分相似,同樣 Docker Daemon 會從編譯目錄尋找檔案或目錄,dest 為映象中的絕對路徑或者相對於 WORKDIR 的路徑
CMD
:構建容器後呼叫,也就是在容器啟動時才進行呼叫
#格式:
CMD ["executable","param1","param2"] (執行可執行檔案,優先)
CMD ["param1","param2"] (設定了 ENTRYPOINT,則直接呼叫 ENTRYPOINT 新增引數)
CMD command param1 param2 (執行 shell 內部命令)
#示例:
CMD echo "This is a test." | wc -
CMD ["/usr/bin/wc","--help"]注: CMD 不同於 RUN,CMD 用於指定在容器啟動時所要執行的命令,而 RUN 用於指定映象構建時所要執行的命令。
LABEL
:用於為映象新增後設資料
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
LABEL version="1.0" description="這是一個 Web 伺服器" by="IT 筆錄"
注:
使用 LABEL 指定後設資料時,一條 LABEL 指定可以指定一或多條後設資料,指定多條後設資料時不同後設資料之間通過空格分隔。推薦將所有的後設資料通過一條 LABEL 指令指定,以免生成過多的中間映象。
ENV
:設定環境變數
格式:
ENV <key> <value> #<key>之後的所有內容均會被視為其<value>的組成部分,因此,一次只能設定一個變數
ENV <key>=<value> ... #可以設定多個變數,每個變數為一個"<key>=<value>"的鍵值對,如果<key>中包含空格,可以使用\來進行轉義,也可以通過""來進行標示;另外,反斜線也可以用於續行
示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
EXPOSE
:指定於外界互動的埠
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注:
EXPOSE 並不會讓容器的埠訪問到主機。要使其可訪問,需要在 docker run 執行容器時通過-p 來發布這些埠,或通過-P 引數來發布 EXPOSE 匯出的所有埠
VOLUME
:用於指定持久化目錄
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]
注:
一個卷可以存在於一個或多個容器的指定目錄,該目錄可以繞過聯合檔案系統,並具有以下功能:
1 卷可以容器間共享和重用
2 容器並不一定要和其它容器共享卷
3 修改卷後會立即生效
4 對卷的修改不會對映象產生影響
5 卷會一直存在,直到沒有任何容器在使用它
WORKDIR
:工作目錄,類似於 cd
命令
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (這時工作目錄為/a)
WORKDIR b (這時工作目錄為/a/b)
WORKDIR c (這時工作目錄為/a/b/c)
注:
通過 WORKDIR 設定工作目錄後,Dockerfile 中其後的命令 RUN、CMD、ENTRYPOINT、ADD、COPY
等命令都會在該目錄下執行。在使用 docker run 執行容器時,可以通過-w 引數覆蓋構建時所設定的工作目錄。
ARG
:用於指定傳遞給構建執行時的變數
格式:
ARG <name>[=<default value>]
示例:
ARG site
ARG build_user=www
ONBUILD
:用於設定映象觸發器
格式:
ONBUILD [INSTRUCTION]
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
當所構建的映象被用做其它映象的基礎映象,該映象中的觸發器將會被鑰觸發
Dockerfile
構建映象案例
FROM centos7
MAINTAINER Alvin alvincy@qq.com
RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo
http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum makecache
RUN yum update -y
RUN yum install python3 -y
RUN pip3 install django
COPY docker /root/docker
WORKDIR /root/docker
EXPOSE 8080
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8080"]
相關文章
- Linux運維需要持續學習嗎?Linux學習Linux運維
- Linux基礎學習-Docker學習筆記LinuxDocker筆記
- Docker 學習筆記(第一集:認識docker)Docker筆記
- MongoDB學習之複製集MongoDB
- Docker 學習筆記(第十集:docker 叢集管理工具 swarm )Docker筆記Swarm
- 入門計算機的粗略學習-Day11計算機
- 傳智黑馬python基礎學習——day11Python
- Docker 學習筆記(第三集:容器)Docker筆記
- Docker 學習筆記(第二集:image)Docker筆記
- Linux學習之檔案操作Linux
- Linux學習之(shell展開)Linux
- Docker學習之搭建MySql容器服務DockerMySql
- Linux學習之linux的find命令如何使用?Linux
- docker學習Docker
- docker 學習Docker
- Docker學習之搭建ActiveMQ訊息服務DockerMQ
- Linux學習之iostat命令詳解LinuxiOS
- Docker 學習筆記(第七集:使用 docker 搭建 php 開發環境)Docker筆記PHP開發環境
- 一個前端工程師的Docker學習筆記【持續更新】前端工程師Docker筆記
- Linux 學習基礎入門之Linux分割槽Linux
- 【Docker 系列】docker 學習 三Docker
- [Docker 系列]docker 學習 三Docker
- Docker 學習筆記(第五集:資料卷)Docker筆記
- java基礎學習之類集框架(十)Java框架
- docker 學習之一 裝MySQL 供遠端使用 LinuxDockerMySqlLinux
- docker學習第八天 docker 基礎之網路配置Docker
- 大資料學習之Linux基礎大資料Linux
- Linux學習之Linux主要應用在哪些地方?Linux
- Linux學習之linux檔案目錄結構彙總Linux
- Linux 學習基礎入門之Linux發展史Linux
- Docker 容器學習Docker
- Docker學習2Docker
- Docker學習—SwarmDockerSwarm
- Docker學習—MachineDockerMac
- Docker學習—ComposeDocker
- Docker學習—DockerFileDocker
- docker學習(二)Docker
- Docker學習-四Docker