docker 超詳細解說

2020-08-12 00:52:43

轉自 狂神說

Docker安裝

# 系統內核是3.10以上的
root@theSun:/# uname -r
4.4.0-185-generic
  •  
# 系統版本
root@theSun:/# cat /etc/os-release 

文件:

https://docs.docker.com/engine/install/ubuntu/
阿裡雲映象參考:
https://blog.csdn.net/xie1xiao1jun/article/details/79413436

# step 1: 安裝必要的一些系統工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安裝GPG證書
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 寫入軟體源資訊
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新並安裝 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce

瞭解:

# 檢視映象
docker image

解除安裝:
1、解除安裝依賴
sudo apt-get purge docker-ce docker-ce-cli containerd.io
2、刪除資源
sudo rm -rf /var/lib/docker

阿裡雲容器映象加速

在这里插入图片描述

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://9htdhp67.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

Docker的常用命令

幫助命令

docker version
docker info
docker 命令 --help

幫助文件地址:https://docs.docker.com/reference/

映象命令

docker images

-a, --all    #列出所有映象
-q, --quiet		#只顯示映象id
  •  

docker search 搜尋映象

# 通過收藏來過濾
root@theSun:/var/lib/docker# docker search mysql --filter=STARS=3000
NAME                DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
mysql               MySQL is a widely used, open-source relation…   9780                [OK]                
mariadb             MariaDB is a community-developed fork of MyS…   3569                [OK]     

docker pull 下載映象

# 下載映象 docker pull 映象名[:tag]
root@theSun:/var/lib/docker# docker pull mysql
Using default tag: latest # 如果不寫tag,預設就是latest
latest: Pulling from library/mysql
6ec8c9369e08: Pull complete 	# 分層下載,docker image的核心 聯合檔案系統
177e5de89054: Pull complete 
ab6ccb86eb40: Pull complete 
e1ee78841235: Pull complete 
09cd86ccee56: Pull complete 
78bea0594a44: Pull complete 
caf5f529ae89: Pull complete 
cf0fc09f046d: Pull complete 
4ccd5b05a8f6: Pull complete 
76d29d8de5d4: Pull complete 
8077a91f5d16: Pull complete 
922753e827ec: Pull complete 
Digest: sha256:fb6a6a26111ba75f9e8487db639bc5721d4431beba4cd668a4e922b8f8b14acc	#簽名,防僞標誌
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest	#真實地址

# 等價的
docker pull mysql
docker pull docker.io/library/mysql:latest

#指定版本下載
root@theSun:/var/lib/docker# docker pull mysql:5.7
5.7: Pulling from library/mysql
6ec8c9369e08: Already exists 
177e5de89054: Already exists 
ab6ccb86eb40: Already exists 
e1ee78841235: Already exists 
09cd86ccee56: Already exists 
78bea0594a44: Already exists 
caf5f529ae89: Already exists 
4e54a8bcf566: Pull complete 
50c21ba6527b: Pull complete 
68e74bb27b39: Pull complete 
5f13eadfe747: Pull complete 
Digest: sha256:97869b42772dac5b767f4e4692434fbd5e6b86bcb8695d4feafb52b59fe9ae24
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

docker rmi 刪除映象

docker rmi -f 容器id #刪除指定容器
docker rmi -f 容器id 容器id 容器id #刪除多個容器
docker rmi -f $(docker images -aq) #刪除全部容器
  •  

容器命令

說明:有了映象纔可以建立容器,linux,下載一個centos映象來測試學習

docker pull centos

新建容器並啓動

docker run [可選參數] image

# 參數說明
--name="Name"	容器名字	tomact01 tomcat02,用來區分容器
-d				後臺方式執行
-it				使用互動方式執行,進入容器檢視內容
-p				指定容器的埠 -p 8080:8080
	-p ip:主機埠:容器埠
	-p 主機埠:容器埠 (常用)
	-p 容器埠
	容器埠
-p				隨機指定埠

# 測試,啓動並進入容器
root@theSun:/var/lib/docker# docker run -it centos /bin/bash
[root@c0cd544258f3 /]# ls	# 檢視容器內的centos,基礎版本,很多命令都是不完善的
bin  etc   lib	  lost+found  mnt  proc  run   srv  tmp  var
dev  home  lib64  media       opt  root  sbin  sys  usr
# 從容器中退回主機
[root@c0cd544258f3 /]# exit
exit
root@theSun:/var/lib/docker# ls
builder   containers  network   plugins   swarm  trust
buildkit  image       overlay2  runtimes  tmp    volumes

列出所有的執行的容器

# docker ps 命令
		# 列出當前正在執行的容器
-a		# 列出當前正在執行的容器+歷史執行過的
-n=?	# 顯示最近建立的容器
-q		# 只顯示容器的編號

root@theSun:/var/lib/docker# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
root@theSun:/var/lib/docker# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
c0cd544258f3        centos              "/bin/bash"         4 minutes ago       Exited (0) About a minute ago                       naughty_mcclintock
7dc103532dd1        hello-world         "/hello"            25 hours ago        Exited (0) 25 hours ago                             elegant_blackburn

退出容器

exit	# 直接容器停止並退出
Ctrl+P+Q	# 容器不停止退出
  • 刪除容器
docker rm 容器id	# 刪除指定的容器
docker rm -f $(docker ps -aq)	# 刪除所有容器
docker ps -a -q|xargs docker rm  # 刪除所有容器
  •  

啓動和停止容器的操作

docker start 容器id		
docker restart 容器id
docker stop 容器id
docker kill 容器id		# 強制停止當前容器
  •  

常用其他命令

後臺啓動容器

# 命令 docker run -d 映象名
docker run -d centos

# 問題docker ps,發現 centos 停止了
# 常見的坑,docker容器使用後臺執行,就必須要有一個前臺進程,docker發現沒有應用,就會自動停止
# nginx,容器啓動後,發現自己沒有提供服務,就會立刻停止,就是沒有程式了。
  •  

檢視日誌

docker logs -f -t --tail [CONTAINER ID]
# 自己寫一段shell指令碼
docker run -d centos /bin/sh -c "while true;do echo kuangshen;sleep 1; done"
# 顯示日誌
-tf		# 顯示日誌
--tail number	# 要顯示日誌條數
docker logs -tf --tail 10 [CONTAINER ID]

檢視容器中進程資訊

docker top [容器id]
PID:當前進程id
PPID:父進程id

檢視映象的元數據

docker inspect [容器id]
  •  

進入當前正在執行的容器

# 通常容器都是使用後臺方式執行的,需要進入容器,修改一些設定

# 命令
docker exec -it 容器id bashShell

# 測試
docker exect -it [容器id] /bin/bash

# 方法二
docker attach 容器id

# docker exec		# 進入容器後開啓一個新的終端,可以在裏面操作(常用)
# docker attach		# 進入容器正在執行的終端,不會啓動新的進程!

從容器內拷貝檔案到主機上

docker cp 容器id:容器內路徑 目的主機路徑

root@theSun:/home# docker attach 4ec656c03592
[root@4ec656c03592 /]# cd /home
[root@4ec656c03592 home]# ls
[root@4ec656c03592 home]# touch test.java
[root@4ec656c03592 home]# ls
test.java
[root@4ec656c03592 home]# exit
exit
root@theSun:/home# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
4ec656c03592        centos              "/bin/bash"         2 minutes ago       Exited (0) 6 seconds ago                       intelligent_goodall
c0cd544258f3        centos              "/bin/bash"         12 hours ago        Exited (0) 12 hours ago                        naughty_mcclintock
7dc103532dd1        hello-world         "/hello"            37 hours ago        Exited (0) 37 hours ago                        elegant_blackburn
# 拷貝
root@theSun:/home# docker cp 4ec656c03592:/home/test.java /home
root@theSun:/home# ls
test.java

# 拷貝是一個手動過程,未來可以使用 -v 卷的技術,可以實現自動同步

作業練習

Docker安裝Nginx

# 1、搜尋映象 search 建議去dockerhub搜尋
# 2、下載映象 pull
# 3、執行測試
root@theSun:/home# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx

root@theSun:/home# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mysql               5.7                 8679ced16d20        8 days ago          448MB
mysql               latest              e3fcc9e1cc04        8 days ago          544MB
nginx               latest              8cf1bfb43ff5        9 days ago          132MB
centos              latest              831691599b88        6 weeks ago         215MB
hello-world         latest              bf756fb1ae65        7 months ago        13.3kB

# -d 後臺執行
# --name 給容器命名
# -p 宿主機埠:容器內部埠
root@theSun:/home# docker run -d --name nginx01 -p 3389:80 nginx
4ece82f587c1aad352303f6e938a384dd5a130cab88965e3f08c475b291f7c14

root@theSun:/home# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4ece82f587c1        nginx               "/docker-entrypoint.…"   6 seconds ago       Up 4 seconds        0.0.0.0:3389->80/tcp   nginx01

root@theSun:/home# curl localhost:3389
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
...

# 進入容器
root@theSun:/home# docker exec -it nginx01 /bin/bash
root@4ece82f587c1:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
root@4ece82f587c1:/# cd /etc/nginx/
root@4ece82f587c1:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf
root@4ece82f587c1:/etc/nginx# 

思考:每次改動nginx組態檔,都需要進入容器內部?十分麻煩,如果可以在容器外部提供一個對映路徑,達到在容器外部修改組態檔,容器內部就可以自動修改? -v 數據卷!

作業:docker裝一個tomcat

# 官方的使用
docker run -it --rm tomcat:9.0

#之前的啓動都是後臺,停止了容器之後,容器還可以查到	docker run -it --rm,一般用來測試,用完就刪除【容器】

# 下載再啓動
docker pull tomcat

# 啓動執行
docker run -d -p 3389:8080 --name tomcat01 tomcat

# 測試存取沒有問題

# 進入容器
root@theSun:/home# docker exec -it tomcat01 /bin/bash

# 發現問題:1、linux命令少了,2、沒有webapps。阿裡雲映象的原因。預設是最小的映象,所有不必要的都剔除掉。保證最少可執行的環境。
  •  

思考:以後要部署專案,如果每次都要進入容器會很麻煩。要是可以在容器外部提供一個對映路徑,webapps,在外部放置專案,自動同步到內部就好了!

作業:部署es + kibana

# es 暴露的埠很多
# es 十分消耗記憶體
# es 的數據一般需要放置到安全目錄。掛載
# --net somenetwork ? 網路設定

# 啓動
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.8.1
# 啓動了 Linux就卡住了

#增加記憶體限制,修改組態檔 -e 環境設定修改
docker run -d --name elasticsearch01 -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.8.1

# 檢視 docker stats

思考:用kibana連線es,網路如何才能 纔能連線過去

視覺化

  • porttainer(先用這個)
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
  • 1
  • Rancher(CI/CD 持續整合、部署再用)
    什麼是portainer: Docker 圖形化介面管理工具,提供一個後臺面板供操作。
    平時不會用

Docker映象講解

映象是什麼

映象是一種輕量級、可執行的獨立軟體包,用來打包軟體執行環境和基於執行環境開發的軟體,它包含執行某個軟體所需的所有內容,包括程式碼、執行時、庫、環境變數和組態檔。
如何得到映象:

  • 從遠端倉庫下載
  • 朋友拷貝
  • 自己製作一個映象DockerFile

Docker映象載入原理

UnionFS(聯合檔案系統)

下載的時候看到的一層層就是這個。
UnionFS(聯合檔案系統)∶Union檔案系統(UnionFS)是一種分層、輕量級並且高效能的檔案系統,它支援對檔案系統的修改作爲一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統下(unite several directories into asinglevirtual filesystem)。Union檔案系統是Docker映象的基礎。映象可以通過分層來進行繼承,基於基礎映象(沒有父映象),可以製作各種具體的應用映象。
特性∶一次同時載入多個檔案系統,但從外面看起來,只能看到一個檔案系統,聯合載入會把各層檔案系統疊加起來,這樣最終的檔案系統會包含所有底層的檔案和目錄。

Docker映象載入原理

docker的映象實際上由一層一層的檔案系統組成,這種層級的檔案系統UnionFS。
bootfs(boot ilesystem)主要包含bootloader和kerne,bootloader主要是引導載入kernel,Linux剛啓動時會載入bootfs檔案系統,在Docker映象的最底層是bootfs。這一層與我們典型的Linux/Unix系統是一樣的,包含boot載入器和內核。當boot載入完成之後整個內核就都在記憶體中了,此時記憶體的使用權已由botfs轉交給內核,此時系統也會解除安裝bootfs。[個人理解:bootfs用於開機,rootfs用於命令。]
rootfs(root file system),在bootfs之上。包含的就是典型Linux系統中的/de,/proc,/bin,/etc等標準目錄和檔案。roots就是各種不同的操作系統發行版,比如Ubuntu,Centos等等。
在这里插入图片描述
爲什麼虛擬機器很大,Docker很小?
對於一個精簡的OS,rootfs可以很小,只需要包含最基本的命令,工具和程式庫就可以了,因爲底層直接用Host的kernel,自己只需要提供rootfs就可以了。由此可見對於不同的linux發行版, bootfs基本是一致的,rootfs會有差別,因此不同的發行版可以公用bootfs。
虛擬機器是分鐘級別,容器是秒級!

分層原理

理解:
所有的Docker┌映象都起始於一個基礎映象層,當進行修改或增加新的內容時,就會在當前映象層之上,建立新的映象層。
舉一個簡單的例子,假如基於UbuntuLinux16.04建立一個新的映象,這就是新映象的第一層;如果在該映象中新增Python包,就會在基礎映象層之上建立第二個映象層;如果繼續新增一個安全修補程式,就會建立第三個映象層。
該映象當前已經包含3個映象層,如下圖所示(這只是一個用於演示的很簡單的例子)。
在这里插入图片描述
在新增額外的映象層的同時,映象始終保持是當前所有映象的組合,理解這一點非常重要。下圖中舉了一個簡單的例子,每個映象層包含3個檔案,而映象包含了來自兩個映象層的6個檔案。
在这里插入图片描述
上圖中的映象層跟之前圖中的略有區別,主要目的是便於展示檔案。
下圖中展示了一個稍微複雜的三層映象,在外部看來整個映象只有6個檔案,這是因爲最上層中的檔案7是檔案5的一個更新版本。
在这里插入图片描述
這種情況下,上層映象層中的檔案覆蓋了底層映象層中的檔案。這樣就使得檔案的更新版本作爲一個新映象層新增到映象當中。
Docker通過儲存引擎(新版本採用快照機制 機製)的方式來實現映象層堆疊,並保證多映象層對外展示爲統一的檔案系統。
Linux上可用的儲存引擎有AUFS、Overlay2、Device Mapper、Btrfs以及ZFS。顧名思義,每種儲存引擎都基於Linux中對應的檔案系統或者塊裝置技術,並且每種儲存引擎都有其獨有的效能特點。
Docker在Windows上僅支援windowsfiter一種儲存引擎,該引擎基於NTFS檔案系統之上實現了分層和CoW【1】.
下圖展示了與系統顯示相同的三層映象。所有映象層堆疊併合並,對外提供統一的檢視。
在这里插入图片描述

特點

Docker映象都是隻讀的,當容器啓動時,一個新的可寫層被載入到映象的頂部。這一層就是我們通常說的容器層,容器之下的都叫映象層。

如何提交一個自己的映象

commit映象

docker commit 提交容器成爲一個新的副本

# 命令和git原理類似
docker commit -m="提交的描述資訊" -a="作者" 容器id 目標映象名:[TAG]

實戰測試

# 1、啓動一個預設的tomcat

# 2、發現這個預設的tomcat沒有webapps應用,映象的原因,官方的預設映象webapps下是沒有檔案的。

# 3、自己拷貝進去基本的檔案

# 4、將操作過的容器通過commit提交爲一個映象,以後就用修改過的映象即可。【類似於快照】

root@theSun:~# docker commit -a="thesun" -m="add webapps app" 09e54f1544b3 tomcat02:1.0
sha256:4f8525461d89ced0becbd7faa6cbc4d77534e2f502c346b5ddc07681dc3addcd
root@theSun:~# docker images
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
tomcat02              1.0                 4f8525461d89        13 seconds ago      652MB
tomcat                9.0                 9a9ad4f631f8        5 days ago          647MB
tomcat                latest              9a9ad4f631f8        5 days ago          647MB
portainer/portainer   latest              62771b0b9b09        11 days ago         79.1MB
mysql                 5.7                 8679ced16d20        11 days ago         448MB
mysql                 latest              e3fcc9e1cc04        11 days ago         544MB
nginx                 latest              8cf1bfb43ff5        12 days ago         132MB
elasticsearch         7.8.1               a529963ec236        12 days ago         811MB
centos                latest              831691599b88        6 weeks ago         215MB
hello-world           latest              bf756fb1ae65        7 months ago        13.3kB

容器數據卷

什麼是容器數據卷

數據如果都在容器中,那麼刪除容器後,數據就會丟失。需求:數據可以持久化
即容器之間可以有一個數據共用的技術,Docker容器中產生的數據,同步到本地!卷技術,目錄的掛載,將容器內的目錄,掛載到linux上。
總結:容器的持久化和同步操作,容器間也是可以數據共用的。

使用數據卷

方式一:直接使用命令來掛載 -v v:volume

docker run -it -v 主機目錄:容器內目錄

# 測試
root@theSun:/home# docker run -it -v /home/ceshi:/home centos /bin/bash

# 啓動後可以通過docker inspect 容器id

在这里插入图片描述
好處:以後修改只需要在本地修改即可,容器內會自動同步!

實戰:安裝MySQL

思考:MySQL的數據持久化問題!

# 獲取映象
docker pull mysql:5.7

# 執行容器,需要做數據掛載,安裝啓動mysql,需要設定密碼
# 官方測試:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

-d	後臺執行
-p	埠對映
-v	卷掛載
-e	環境設定
--name	容器名稱
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

具名和匿名掛載

# 匿名掛載,在-v只寫了容器內的路徑,沒有寫容器外的路徑。
-v 容器內路徑
docker run -d -p --name nginx01 -v /etc/nginx nginx

# 檢視多有的volume 情況
docker volume ls

# 具名掛載
# 通過 
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx nginx
# 通過-v 卷名:容器內路徑

所有的docker容器內的卷,沒有指定目錄的情況下都是在/var/lib/docker/volumes/xxxx/_data
通過具名掛載可以方便地找到一個卷,大多數情況在使用具名掛載

# 如何確定是具名掛載還是匿名掛載,還是指定路徑掛載
-v 容器內路徑		# 匿名掛載
-v 具名:容器內路徑	# 具名掛載
-v /宿主機路徑:容器內路徑	# 指定路徑掛載

拓展:
# 通過-v 容器內路徑:ro rw  改變讀寫許可權
ro	readonly	# 只讀
rw	readwrite	# 可讀可寫

# 一旦設定了容器許可權,容器對掛載出來的內容就有限定了
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
docker run -d -p --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

# ro 只要看到ro就說明這個路徑只能通過宿主機來操作,容器內部是無法操作的。

初識Dockerfile

Dockerfile就是用來構建docker映象的構建檔案!命令指令碼!
通過這個指令碼可以生成映象,映象是一層一層的,指令碼每個命令都是一層。

# 建立一個dockerfile檔案,名字可以隨機 建議 Dockerfile
# 檔案中的內容 指令(大寫) 參數
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"

CMD /bin/bash

# 這裏每個命令就是映象的一層
# 生成一個映象,在建立映象時就 掛載檔案
# 此處相當於匿名掛載

docker build -f /home/docker-test-volume/dockerfile1 -t /thesun/centos:1.0 .

此種方式用的多,因爲通常會構建自己的映象,假設構建映象時沒有掛載卷,要手動映象掛載 -v 卷名:容器內路徑!

數據卷容器

多個mysql同步數據!

docker run -d -p 3310:3306 -v /home/mysql/conf -v /home/mysql/data -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
  •  

結論:容器之間設定資訊的傳遞,數據卷容器的生命週期一直持續到沒有容器使用爲止。
但一旦持久化到了本地,原生的數據是不會刪除的!

DockerFile

DockerFIle介紹

dockerfile是用來構建docker映象的檔案!=命令參數指令碼
構建步驟:
1、編寫一個dockerfile檔案
2、dockerbuild構建成爲一個映象
3、docker run 執行映象
4、docker push 發佈映象(DockerHub,阿裡雲映象倉庫!)

DockerFile構建過程

基礎知識:
1、每個關鍵字(指令)都必須是大寫字母
2、每個指令都會建立一個新的映象層,並提交。
在这里插入图片描述
DockerFIle:構建檔案,定義了一切的步驟,原始碼
DockerImages:通過DOckerFIle構建生成的映象,最終發佈和執行的產品。
Docker容器:映象執行起來提供服務。

DockerFile的指令

FROM			#基礎映象,一些從這裏開始構建
MAINTAINER		#映象是誰寫的,姓名+郵箱
RUN				#映象構建的時候需要執行的命令
ADD				#步驟:tomcat映象,這個tomcat壓縮包!新增內容
WORKDIR			#映象的工作目錄
VOLUME			#掛載的目錄
EXPOSE			#暴露埠設定
CMD				#指定這個容器啓動時要執行的命令,只有最後一個會生效,可被替代
ENTRYPOINT		#指定這個容器啓動時候要執行的命令,可以追加命令
ONBUILD			#當構建一個被繼承的DockerFile就會執行ONBUILD指令。觸發指令
COPY			#類似ADD,將檔案拷貝到映象中
ENV				#構建的時候設定環境變數

實戰測試

# 1 編寫DockerFIle檔案
FROM centos
MAINTAINER thesun<[email protected]>

#相當於定義一個變數
ENV MYPATH /usr/local
WORKDIR $MYPATH

# 新增vim 和 net-tools功能
RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "-----end-----"
#啓動後進入哪個命令列
CMD /bin/bash

# 2 通過檔案構建映象
# 命令 docker build -f dockerfile檔案路徑 -t 映象名:[tag] .
root@theSun:/home/dockerfile# docker build -f mydockerfile-centos -t mycentos:0.1 .

# 通過history可以列出本地進行的變更歷史
docker history 映象id

CMD 和 ENTRYPOINT區別

CMD				#指定這個容器啓動時要執行的命令,只有最後一個會生效,可被替代
ENTRYPOINT		#指定這個容器啓動時候要執行的命令,可以追加命令

測試cmd

vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]

# 構建映象
root@theSun:/home/dockerfile# docker build -f dockerfile-cmd-test -t cmdtest .
# run執行,發現ls -a生效
root@theSun:/home/dockerfile# docker run 74e69730ee78

# 想追加一個命令 -l即 ls -al
root@theSun:/home/dockerfile# docker run 74e69730ee78 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"-l\": executable file not found in $PATH": unknown.

# -l 替換了CMD ["ls","-a"]命令,-l不是命令所以報錯!

測試 ENTRYPOINT

vim dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls","-a"]

# 追加的命令,是直接拼接在ENTRYPOINT命令的後面!
# ls -al
docker run [容器id] -l	不會報錯

實戰:Tomcat映象

1、準備映象檔案 tomcat壓縮包,jdk壓縮包。
2、編寫dockerfile檔案

FROM centos
MAINTAINER thesun<[email protected]>

COPY readme.txt /usr/local/readme.txt

# ADD命令會自動解壓
ADD jdk-8u261-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.37.tar.gz /usr/local/

RUN yum -y install vim

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_261
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.37
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.37/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.37/bin/logs/catalina.o
ut

3、構建映象

# 將檔案命名爲Dockerfile,就不用加-f。會自動在當前目錄下查詢
root@theSun:/home/build# docker build -t diytomcat .
  • 1
  • 2

4、啓動映象

docker run -d -p 9090:8080 --name thesuntomcat -v /home/build/tomcat/test:/usr/local/apache-tomcat-9.0.37/webapps/test -v /home/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.37/logs diytomcat
  •  

5、存取測試
6、發佈專案(由於做了卷掛載,直接在本地編寫專案就可以發佈了!)

  <?xml version="1.0" encoding="UTF-8"?>
  <web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                               http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
           version="2.5">

  </web-app>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Hello, theSun!!</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("----my test web logs----")
%>
</body>
</html>

發現:專案部署成功!
以後開發的步驟:需要掌握DOckerfile的編寫!以後一切都是使用docker映象來發布執行!

發佈自己的映象

DockerHub

# 登錄
docker login -u [username]

# 提交映象
docker push diytomcat

# 增加一個tag
#自己發佈的映象儘量帶上版本號
docker tag [映象Id] thesun/tomcat:1.0

阿裡雲映象服務上

1、登錄阿裡雲
2、找到容器映象服務
3、建立名稱空間
4、建立容器映象
參考官方文件

Docker網路

理解Docker0

在这里插入图片描述

# 問題,docker是如何處理容器網路存取的?
docker run -d -P --name tomcat01 tomcat

# 檢視容器的內部網路地址 ip addr ,發現容器啓動的時候會得到一個eth0@if121 ip地址,docker分配的!
root@theSun:/# docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
120: eth0@if121: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

# 宿主機可以通過此ip地址ping通該容器。

原理

1、每啓動一個docker容器,docker就會給docker容器分配一個Ip,只要安裝了docker,就會有一個網絡卡docker0,橋接模式,使用的技術是evth-pair

# 發現容器的網絡卡,都是一對一對的
# evth-pair 就是一對的虛擬裝置介面,它們都是成對出現的,一端連着協定,一端彼此相連。正因爲有這個特性,evth-pair可以充當一個橋樑,用於連線各種虛擬網路裝置。 
# OpenStack,DOcker容器之間的連線,ovs的連線,都是使用evth-pair技術

在这里插入图片描述
結論:tomcat01和tomcat02是共用一個路由器,docker0.
所有的容器不指定網路的情況下,都是docker0路由的,docker會給容器分配一個預設的可用IP
Docker中的所有網路介面都是虛擬的。虛擬的轉發效率高!(內網傳遞檔案)

–link

思考一個場景:編寫了一個微服務,database url=ip: , 專案不重新啓動,數據庫ip換掉了,希望可以用名字來存取容器。

docker run -d -P --name tomcat03 --link tomcat02 tomcat

docker exec -it tomcat03 ping tomcat02

在这里插入图片描述
–link 就是在hosts設定中增加了一個對映
已不建議使用

自定義網路

檢視所有的docker網路

docker network ls

網路模式
bridge:橋接 docker預設,自己建立也使用bridge模式
none:不設定網路
host:和宿主機共用網路
container:容器網路連通(用得少,侷限大)

# 直接啓動的命令 預設帶--net bridge,就是docker0
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0特點:預設,域名不能存取, --Link可以打通連線,但不建議使用

# 可以自定義一個網路
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

docker network inspect mynet # 檢視網路具體詳情

# 使用自己定義的網路建立容器
docker run -d -P --name tomcat-net-01 --net mynet tomcat 
docker run -d -P --name tomcat-net-02 --net mynet tomcat

# 現在不使用--link ,就可以通過容器名相互ping通
docker exec -it tomcat-net-01 ping tomcat-net-02

# 自定義的網路可以自動維護對應的關係,推薦平時這樣使用網路。
# 好處:使用redis叢集搭建一個網路,mysql再搭建一個,不同的叢集使用不同的網路,保證叢集是安全和健康的。

網路連通

不同網段下的容器互相連通。(docker0網段下的tomcat連通mynet網路)

docker network connect mynet tomcat01

# 連通之後就是將tomcat01放到了mynet網路下。
# 一個容器兩個ip地址!類似於公網ip,私網ip

結論:如果要跨網路操作別人,就需要使用docker network connect連通!

實戰:部署Redis叢集

在这里插入图片描述

# 通過指令碼建立六個redis設定
for port in $(seq 1 6);
do
mkdir -p /mydata/redis/node-${port}/conf 
touch /mydata/redis/node-${port}/conf/redis.conf 
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf 
port 6379 
bind 0.0.0.0 
cluster-enabled yes
cluster-config-file nodes.conf 
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379 
cluster-announce-bus-port 16379 
appendonly yes 
EOF 
done

docker run -p 637${port}:6379 -p 1637${port]:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \

docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 建立叢集
redis-c1-cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
  •  

SpringBoot微服務打包Docker映象

預告:如果有很多映象,如何維護?

企業實戰

Docker Compose

簡介

原先dockerfile build run,需要手動操作,單個容器
Docker Compose 可以高效管理容器,定義執行多個容器。
作用:批次容器編排

Compose是Docker官方的開源專案。需要安裝!
web服務,redis,mysql,nginx……多個容器,通過compose可以快速啓動。

Compose重要概念:

  • 服務services,容器應用。(web,redis,mysql…)
  • 專案project。一組關聯的容器。 部落格,web,mysql wp

安裝Compose

1、下載

sudo curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 備用地址,比較快
curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-'uname -s'-'uname-m' > /usr/local/bin/docker-compose
  • 1
  • 2
  • 3
  • 4

2、授權

chmod +x /usr/local/bin/docker-compose
  • 1

getting start體驗

官方地址:https://docs.docker.com/compose/gettingstarted/
python應用,計數器,redis

1、應用 app.py
2、Dockerfile 應用打包爲映象
3、Docker-compose yml 檔案(定義整個服務需要的環境:web, redis)
4、啓動compose專案(docker-compose up)

預設的服務名 檔名_服務名_num
多個伺服器 叢集 A B _num副本數量
服務redis服務 =》4個副本
叢集狀態,服務都不可能只有一個執行範例。彈性

網路規則:
專案中的內容都在同個網路下。可通過名稱存取(需要在同一網路下),保證了高可用

停止:docker-compose down ctrl+c

以前都是單個docker run啓動容器,docker-compose通過yml組態檔,可以通過compose一鍵啓動所有服務、停止

yaml規則

Docker Swarm

叢集的方式部署

CI/CD Jenkins流水線