全部內容來自重要記錄的複製,轉自於https://juejin.im/book/5b7ba116e51d4556f30b476chtml
以CentOS爲例,所需命令以下,包括了啓動mysql
$ sudo yum install yum-utils device-mapper-persistent-data lvm2 $ $ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo $ sudo yum install docker-ce $ $ sudo systemctl enable docker $ sudo systemctl start docker
查看 Docker 版本的命令:docker version
linux
$ sudo docker version Client: Version: 18.06.1-ce API version: 1.38 Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:23:03 2018 OS/Arch: linux/amd64 Experimental: false Server: Engine: Version: 18.06.1-ce API version: 1.38 (minimum version 1.12) Go version: go1.10.3 Git commit: e68fc7a Built: Tue Aug 21 17:25:29 2018 OS/Arch: linux/amd64 Experimental: false
查看更多信息能夠用
docker info
這個命令nginx
由 Docker 官方提供的國內鏡像源web
registry.docker-cn.com
此地址的協議是
https
在Linux
環境下,咱們能夠經過修改/etc/docker/daemon.json
( 若是文件不存在,你能夠直接建立它 ) 這個 Docker 服務的配置文件達到效果。redis
{ "registry-mirrors": [ "https://registry.docker-cn.com" ] }
配置後須要重啓來生效sql
$ sudo systemctl restart docker
再經過docker info
來查看,發現配置已生效docker
$ sudo docker info # ...... Registry Mirrors: https://registry.docker-cn.com/ # ......
之因此鏡像一般直接採用軟件名,這還要回歸到 Docker 對容器的輕量化設計中。Docker 對容器的設計和定義是微型容器而不是龐大臃腫的完整環境 ( 這固然歸功於容器技術在實現虛擬化過程當中性能幾乎無損 ),這就使得咱們一般會只在一個容器中運行一個應用程序,這樣的好處天然是可以大幅下降程序之間相互的影響,也有利於利用容器技術控制每一個程序所使用的資源。數據庫
https://hub.docker.com/
中能夠直接從中央倉庫中搜索鏡像docker search tomcat
命令也能夠查找相應的鏡像若是不想下載最新的,而是指定鏡像的tag(冊子裏也說了,其實就是想指定某個軟件的版本進行下載),能夠參考:https://www.linuxidc.com/Linux/2019-03/157690.htmjson
# 這樣獲取到的是最新的 sudo docker pull ubuntu # 也能夠像這樣指定版本獲取 sudo docker pull openresty/openresty:1.13.6.2-alpine
docker images
上面的docker images
只能查看鏡像列表,若是想查看本地某個鏡像的詳情,能夠以下:
sudo docker inspect redis:3.2
sudo docker rmi ubuntu:latest # 也能夠一次刪除多個鏡像,中間空格 sudo docker rmi redis:3.2 redis:4.0
刪除鏡像的過程實際上是刪除鏡像內的鏡像層,在刪除鏡像命令打印的結果裏,咱們能夠看到被刪除的鏡像層以及它們的 ID。固然,若是存在兩個鏡像共用一個鏡像層的狀況,你也不須要擔憂 Docker 會刪除被共享的那部分鏡像層,只有當鏡像層只被當前被刪除的鏡像所引用時,Docker 纔會將它們從硬盤空間中移除。
# 這種是直接建立,沒有給它起名,在使用時若是指定 容器id 來使用,會很麻煩 sudo docker create nginx:1.12 # 在建立容器的時候指定下名字(給起了一個 nginx111 的名字) # 補充一句,名字是惟一的,重複起相同的名字會報錯 sudo docker create --name nginx111 nginx:1.12
注:若是本地環境中沒有nginx,tag爲1.12的鏡像,會直接從中央倉庫pull,而後再進行建立容器
# 由於建立時指定了名字,因此啓動時能夠經過名稱來啓動 sudo docker start nginx111
下面粘貼了幾張啓動時的截圖,能夠方便啓動後的狀態變化
也能夠用docker run
命令,將docker create
和docker start
合併成一步,提高效率
sudo docker run --name nginx -d nginx:1.12
這裏須要注意的一點是,一般來講咱們啓動容器會指望它運行在「後臺」,而
docker run
在啓動容器時,會採用「前臺」運行這種方式,這時候咱們的控制檯就會銜接到容器上,不能再進行其餘操做了。咱們能夠經過-d
或--detach
這個選項告訴 Docker 在啓動後將程序與控制檯分離,使其進入「後臺」運行。
# 查看當前正在運行的容器 sudo docker ps # 查看當前全部容器(-a <==> --all) sudo docker ps -a
若是經過-a
來啓動,能夠看到全部容器,status中是當前容器的運行狀態
這裏面有幾個選項:
# 中止後,能夠再經過docker start來啓動 sudo docker stop nginx
sudo docker rm nginx
可是容器在運行時不容許被刪除,能夠經過-f
的選項強行刪除
sudo docker rm -f nginx
# 進入到以前建立的nginx這個容器 sudo docker exec -it nginx bash
在藉助 docker exec 進入容器的時候,咱們須要特別注意命令中的兩個選項不可或缺,即 -i 和 -t ( 它們倆能夠利用簡寫機制合併成 -it )。
其中 -i ( --interactive ) 表示保持咱們的輸入流,只有使用它才能保證控制檯程序可以正確識別咱們的命令。而 -t ( --tty ) 表示啓用一個僞終端,造成咱們與 bash 的交互,若是沒有它,咱們沒法看到 bash 內部的執行結果。
進入後直接按ctrl+d
便可退出
目前 Docker 官方爲咱們提供了五種 Docker 網絡驅動,分別是:Bridge Driver、Host Driver、Overlay Driver、MacLan Driver、None Driver
比較經常使用的就是
Bridge
和Overlay
在建立容器時,經過在docker create
和docker run
命令中,添加--link
參數,指定容器名,就能夠鏈接到相應容器上
$ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql $ sudo docker run -d --name webapp --link mysql webapp:latest
這時,若是webapp應用,若是想要鏈接mysql數據庫,以下:
String url = "jdbc:mysql://mysql:3306/webapp";
有點相似開防火牆功能,給防火牆開個端口號
先看下mysql默認的,默認只開放了3306和33060端口:
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 95507bc88082 mysql:5.7 "docker-entrypoint.s…" 17 seconds ago Up 16 seconds 3306/tcp, 33060/tcp mysql
要開放更多的端口,能夠用--expose
選項:
sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
再查看下開放的端口:
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3c4e645f21d7 mysql:5.7 "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 3306/tcp, 13306/tcp, 23306/tcp, 33060/tcp mysql
# --link <name>:<alias>(前面是鏈接的容器名,後面是給起的別名) $ sudo docker run -d --name webapp --link mysql:database webapp:latest
這樣能夠經過別名來鏈接
String url = "jdbc:mysql://database:3306/webapp";
若是不指定網絡,默認會把建立的容器添加到一個默認的bridge的網絡。而默認同一個網絡內是能互相通訊的,但不一樣網絡間是不能通訊的
# 能夠經過docker inspect來查看網絡 $ sudo docker inspect mysql [ { # ...... "NetworkSettings": { # ...... "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "bc14eb1da66b67c7d155d6c78cb5389d4ffa6c719c8be3280628b7b54617441b", "EndpointID": "1e201db6858341d326be4510971b2f81f0f85ebd09b9b168e1df61bab18a6f22", "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 } } # ...... } # ...... } ]
docker CLI 裏與網絡相關的命令都以docker network
開頭,其中建立網絡的命令是docker network create
# 建立了一個individual的網絡 $ sudo docker network create -d bridge individual
命令中經過-d
來指定網絡類型,而網絡類型就是上面提到的那向種:bridge、host、overlay、maclan、none
$ sudo docker network ls NETWORK ID NAME DRIVER SCOPE bc14eb1da66b bridge bridge local 35c3ef1cc27d individual bridge local
# 能夠經過--network individual來指定加入到individual網絡 $ sudo docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --network individual mysql:5.7
能夠再來查看下mysql所加入的網絡
$ sudo docker inspect mysql [ { # ...... "NetworkSettings": { # ...... "Networks": { "individual": { "IPAMConfig": null, "Links": null, "Aliases": [ "2ad678e6d110" ], "NetworkID": "35c3ef1cc27d24e15a2b22bdd606dc28e58f0593ead6a57da34a8ed989b1b15d", "EndpointID": "41a2345b913a45c3c5aae258776fcd1be03b812403e249f96b161e50d66595ab", "Gateway": "172.18.0.1", "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:12:00:02", "DriverOpts": null } } # ...... } # ...... } ]
就是將容器的端口映身到宿主機上,經過外網訪問宿主機的端口,其實就是訪問到容器的那個端口
$ sudo docker run -d --name nginx -p 80:80 -p 443:443 nginx:1.12
使用端口映射選項的格式是-p <ip>:<host-port>:<container-port>
,其中 ip 是宿主操做系統的監聽 ip,能夠用來控制監聽的網卡,默認爲0.0.0.0
,也就是監聽全部網卡
咱們能夠將容器的 80 端口映射到宿主操做系統的 8080 端口,傳入
-p 8080:80
便可
而後咱們再查看下容器
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc79fc5d42a6 nginx:1.12 "nginx -g 'daemon of…" 4 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp nginx
以前說容器使用的原則是即停即刪,但容器中的數據怎麼辦?--冊子上說通常就是掛載到宿主機的磁盤中,使得即使刪除,數據也還在
掛載方式有三種:Bind Mount
、 Volume
和Tmpfs Mount
使用-v
或--volume
命令
-v <host-path>:<container-path>
,其中 host-path 和 container-path 分別表明宿主操做系統中的目錄和容器中的目錄。這裏的路徑要用絕對路徑,特別是<host-path>
,若是僅僅是個名稱的話,就不是Bind Mount
,而是Volume
方式
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html nginx:1.12
能夠查看下容器
$ sudo docker inspect nginx [ { # ...... "Mounts": [ { "Type": "bind", "Source": "/webapp/html", "Destination": "/usr/share/nginx/html", "Mode": "", "RW": true, "Propagation": "rprivate" } ], # ...... } ]
能夠看到這裏的RW = true,也就是容器內的數據能夠寫文件到宿主機,若是隻讓容器只讀,能夠加:ro
參數
$ sudo docker run -d --name nginx -v /webapp/html:/usr/share/nginx/html:ro nginx:1.12
因爲Tmpfs Mount
這種方式是掛載到宿主機的內存中,因此不須要指定宿主機目錄,直接指定要掛載的容器目錄就能夠了
$ sudo docker run -d --name webapp --tmpfs /webapp/cache webapp:latest
這時再查看下詳情
$ sudo docker inspect webapp [ { # ...... "Tmpfs": { "/webapp/cache": "" }, # ...... } ]
其實也就是用 Volume
方式掛載。由於是由Docker管理,不用去管他給掛載到宿主機的位置,但能夠經過操做數據卷的方式來操做它。
# 也是使用-v來掛載,只是直接指定容器的目錄便可 $ sudo docker run -d --name webapp -v /webapp/storage webapp:latest
使用
docker inspect
查看,其實就是掛載到了/var/lib/docker/volumes/
目錄下。
$ sudo docker inspect webapp [ { # ...... "Mounts": [ { "Type": "volume", "Name": "2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336", "Source": "/var/lib/docker/volumes/2bbd2719b81fbe030e6f446243386d763ef25879ec82bb60c9be7ef7f3a25336/_data", "Destination": "/webapp/storage", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], # ...... } ]
可是上面沒有爲數據卷命名,因此咱們掛載時,能夠手動起一個數據卷名,規則:-v
# 手動叫appdata的數據卷名 $ sudo docker run -d --name webapp -v appdata:/webapp/storage webapp:latest
能夠給多個容器掛載到同一數據捲上(起同樣的名),這樣數據也就共享了
$ sudo docker run -d --name webapp -v html:/webapp/html webapp:latest $ sudo docker run -d --name nginx -v html:/usr/share/nginx/html:ro nginx:1.12
能夠直接經過docker volume xxx
來操做數據卷
$ sudo docker volume create appdata
使用docker volume ls
來查看
$ sudo docker volume ls DRIVER VOLUME NAME local html local appdata
可使用docker volume rm
來刪除指定數據卷
$ sudo docker volume rm appdata
在刪除數據卷以前,咱們必須保證數據卷沒有被任何容器所使用 ( 也就是以前引用過這個數據卷的容器都已經刪除 ),不然 Docker 不會容許咱們刪除這個數據卷。
有些數據卷在建立時沒有指定名稱
這時刪除能夠用下面兩種方式:
1.在刪除容器時連帶着刪除它,使用-v
命令便可
$ sudo docker rm -v webapp
2.使用docker volume prune
,它能夠刪除那些沒有被容器引用的數據卷
$ sudo docker volume prune -f Deleted Volumes: af6459286b5ce42bb5f205d0d323ac11ce8b8d9df4c65909ddc2feea7c3d1d53 0783665df434533f6b53afe3d9decfa791929570913c7aff10f302c17ed1a389 65b822e27d0be93d149304afb1515f8111344da9ea18adc3b3a34bddd2b243c7 # ......