1. 程式人生 > 其它 >演算法-經典趣題-竊賊問題

演算法-經典趣題-竊賊問題

Docker簡介

簡介

# 官方定義
- We have a complete container solution for you - no matter who you are and where you are on your containerization journey.
- 翻譯:我們為你提供完整的解決方案,無論你是誰無論你在哪裡都可以開啟你的容器之旅
- 總結:在官方之中給的定義Docker屬於一個容器技術

Docker解決問題

  • 在開發階段專案能夠正確執行,但是在生產階段程式碼不能正確執行

    在我們執行一個Django專案的時候,我們可能需要使用到MySQL Redis RabbitMQ Elasticsearch等,假如我們在Windows作業系統進行開發使用的版本為A,當我們將程式碼在Centos作業系統進行釋出的時候可能使用的版本是B,由於版本使用的不一致導致程式碼執行環境有問題可能會出現各種異常,由於版本問題導致程式碼執行有問題會額外的給人員帶來負擔,如果我們使用Docker我們可以直接將執行的專案進行打包,直接使用Docker將程式碼專案釋出即可,我們此時無需考慮使用本版,作業系統等問題,做到一次打包終身使用的效果。
    

    優點:一次打包終身使用,無需考慮版本作業系統等問題,只需要能夠正常的執行Docker服務即可

  • 專案A記憶體資源被專案B所耗盡,導致專案A不能正常執行

    在生產環境中可能一個伺服器同時執行多個專案,在專案A中所需要大量的資源最終將整個伺服器資源耗盡,此時專案B由於無法得到正確的執行資源最終該專案無法正確對外執行,如果我們使用Docker執行專案,此時Docker在作業系統層面起到程序隔離效果,對每個容器分配單獨的執行資源,這樣每個專案就會擁有獨立的執行資源互相隔離互不影響
    

    優點二:程序之間的隔離導致各個應用獨立執行,互不影響

  • 簡化部署,提高效率

    如果在比較大的專案之中可能需要使用到多臺伺服器充當生產環境,大量的伺服器無論是運維還是環境搭建都是比較麻煩的,如果我們此時使用docker極大的降低了運維難度,減少了環境搭建的時間提高部署效率
    

    優點三:映象複製保證多個節點環境一致

Docker與虛擬機器的區別

  • Docker體積輕巧

    在上圖中我們可以看出如果在虛擬機器中安裝作業系統再次執行一些服務,導致原本輕量的虛擬機器因為安裝作業系統導致虛擬機器特保笨重同時對於應用的遷移也時分不方便,而使用Docker可以看到其直接執行在物理機中的作業系統因此Docker十分輕便	
    
  • Docker部署簡便

    在Docker中只需要安裝Docker當Docker安裝成功之後在執行Docker應用即可,而使用虛擬機器我們需要安裝虛擬機器軟體其次在虛擬機器軟體中安裝作業系統,在最終的作業系統在部署服務,這一系列的流程耗時費力
    
  • 啟動迅速節省資源

    如果使用虛擬機器的作業系統執行服務,例如MySQL需要向虛擬作業系統申請資源,虛擬作業系統需要向虛擬機器申請資源,虛擬機器再向物理機器申請資源即大致為 虛擬記憶體--->虛擬機器記憶體--->實體記憶體導致虛擬機器不但耗費資源而且啟動緩慢,然而Docker直接向物理即申請資源 即為虛擬記憶體--->實體記憶體的節省資源啟動迅速
    
對比點 傳統虛擬機器 Docker容器
磁碟佔用 幾個GB到幾十個GB左右 幾十MB到幾百MB左右
CPU記憶體佔用 虛擬作業系統非常佔用CPU和記憶體 Docker引擎佔用極低
啟動速度 (從開機到執行專案)幾分鐘 (從開啟容器到執行專案)幾秒
安裝管理 需要專門的運維技術 安裝、管理方便
應用部署 每次部署都費時費力 從第二次部署開始輕鬆簡捷
耦合性 多個應用服務安裝到一起,容易互相影響 每個應用服務一個容器,達成隔離
系統依賴 需求相同或相似的核心,目前推薦是Linux

Docker安裝配置

安裝

# 安裝依賴
[root@SR ~]# yum install -y yum-utils device-mapper-persistent-data lvm2	

# 配置國內 docker 的 yum 源(阿里雲)
[root@SR ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安裝 docker-ce
[root@SR ~]# yum install docker-ce docker-ce-cli containerd.io -y
	'''
	注:docker-ce-cli 作用是 docker 命令列工具包
    containerd.io 作用是容器介面相關包
    yum info 軟體包的名字,可以檢視一個包的具體作用。
	'''
# 啟動Docker
[root@SR ~]# systemctl start docker && systemctl enable docker

# 檢視docker版本
[root@SR ~]# docker version

# 檢視docker資訊
[root@SR ~]# docker info 

阿里源

# 由於Docker預設倉庫在國外,國外速度網速感人 因此將映象源修改國內映象源
[root@SR ~]#  mkdir -p /etc/docker
[root@SR ~]#  vim /etc/docker/daemon.json 
        {
          "registry-mirrors": ["https://lz2nib3q.mirror.aliyuncs.com"]
        }
[root@SR ~]#  systemctl daemon-reload
[root@SR ~]#  systemctl restart docker
[root@SR ~]#  docker info

Docker核心概念與架構

核心概念

映象(image)

 - 在我們傳統的安裝軟體的時候需要下載軟體的安裝包,在Docker中映象就類似我們的軟體安裝包,例如我們需要安裝MySQL時候需要找到MySQL的安裝包,同理我們需要使用Docker執行MySQL服務就需要找到MySQL映象。
 - 特點: 只讀

容器(container)

 - 當我們下載啦MySQL安裝包的時候我們進行安裝,進而MySQL的軟體包就變成了執行MySQL的程式,在我們找到某軟體映象的時候執行該映象,該映象就會成為一個執行某服務的容器 例如我們需要使用Docker跑MySQL服務,當我們將MySQL服務執行就可以變成執行MySQL的容器。
 - 特點: 可讀可寫

倉庫(repository)

- 當我們需要使用MySQL映象的時候,那麼這個從哪裡找這個映象呢,在Docker官方給我們提供了倉庫地址,在該倉庫中存放了所有的Docker映象,當我們需要獲取映象的時候只需要從倉庫地址下載即可- 遠端倉庫:Docker官方提供的存放映象的倉庫- 本地倉庫:自己本地磁碟存放的Docker映象

執行架構圖

Docker常用命令

輔助命令

# 1.安裝完成輔助命令
docker version	--------------------------	檢視docker的資訊
docker info		--------------------------	檢視更詳細的資訊
docker --help	--------------------------	幫助命令

Image命令

# 1.檢視本機中所有映象
	docker images	--------------------------	列出本地所有映象
	docker image ls	--------------------------	列出本地所有映象
		-a			列出所有映象(包含中間映像層)
  		-q			只顯示映象id
# 2.搜尋映象
	docker search [options] 映象名	-------------------	去dockerhub上查詢當前映象
		-s 指定值		列出收藏數不少於指定值的映象
  		--no-trunc	  顯示完整的映象資訊
  	docker search nginx
# 3.從倉庫下載映象	docker pull 映象名[:TAG|@DIGEST]	----------------- 下載映象		TAG:指定版本		@DIGEST:指定摘要	docker pull mysql:5.7
# 4.刪除映象	docker rmi 映象名/映象ID	--------------------------  刪除映象		-f		強制刪除	docker rmi -f 822		# 刪除所有映象	docker rm -f $(docker images -aq)

Container命令

# 1.執行容器
	docker run 映象名	--------------------------	映象名新建並啟動容器
        --name 					    別名為容器起一個名字
        -d							啟動守護式容器(在後臺啟動容器)
        -p 							對映埠號:原始埠號		 指定埠號啟動

# 2.檢視執行的容器
	docker ps					--------------------------	列出所有正在執行的容器
        -a			正在執行的和歷史執行過的容器
        -q			靜默模式,只顯示容器編號
# 3.停止|關閉|重啟容器
	docker start   容器名字或者容器id  --------------- 開啟容器
	docker restart 容器名或者容器id    --------------- 重啟容器
	docker stop  容器名或者容器id 	    ------------------ 正常停止容器執行
	docker kill  容器名或者容器id      ------------------ 立即停止容器執行
		stop:優雅退出如果使用該命令會向容器傳送訊號,容器內部會進行事務等操作
		kill:直接退出容器內部無任何操作
# 4.刪除容器
	docker rm -f 容器id和容器名    		--------------------------	強制刪除  		
	docker rm -f $(docker ps -aq)		--------------------------	刪除所有容器
# 7.檢視容器的執行日誌	docker logs [OPTIONS] 容器id或容器名	------------------ 檢視容器日誌        -t			 日誌顯示時間戳        -f			 實時展示日誌        --tail 	     數字	顯示最後多少條    docker logs -tf --tail 5 c6
# 5.檢視容器內程序	docker top 容器id或者容器名 ------------------ 檢視容器內的程序
# 6.檢視檢視容器內部細節	docker inspect 容器id 		------------------ 檢視容器內部細節
# 8.進入容器內部	docker exec [options] 容器id 容器內命令 ------------------ 進入容器執行命令		-i		以互動模式執行容器,通常與-t一起使用   		-t		分配一個偽終端    shell視窗   bash    		-d		後臺執行    docker exec -it c63 bash
# 9.容器和宿主機之間複製檔案	docker cp 檔案|目錄 容器id:容器路徑           -----------------   將宿主機複製到容器內部	docker cp 容器id:容器內資源路徑 宿主機目錄路徑  -----------------   將容器內資源拷貝到主機上
# 10.容器打包成新的映象	  docker commit -m "描述資訊" -a "作者資訊"   (容器id或者名稱)打包的映象名稱:標籤	  	  docker commit -m "nginx:1.0" -a "SR" 1e nginx:1.0
# 11.打包映象		docker save 映象名 | ID -o  名稱.tar				docker save 15 -o nginx.tar
# 12.載入映象		docker load -i   名稱.tar		docker load -i nginx.tar
# 13.容器開機自啟
		docker run --restart=always 映象名稱 | ID
		docker run -d -p 80:80 --restart=always c2
# 14.資料卷(volum)實現與宿主機共享目錄
docker run -v 宿主機的路徑|任意別名:/容器內的路徑 映象名
	注意: 
			1.如果是宿主機路徑是絕對路徑,宿主機目錄會覆蓋容器內目錄內容 如果宿主機器目錄不存在會自動建立
			2.如果是宿主機器是相對路徑則會在docker執行容器時自動在宿主機中建立一個目錄,並將容器目錄檔案複製到宿主機中
			3.容器目錄不可以為相對路徑必須為絕對路徑
			4.容器內部修改掛載點的許可權宿主機器會根據容器內部屬主的UID在對應的宿主機更改許可權
			5.容器刪除不會影響宿主機掛載的目錄
# 如果是宿主機器是相對路徑則會在docker執行容器時自動在宿主機中建立一個目錄,並將容器目錄檔案複製到宿主機中
docker run -d -v test2:/etc/ nginx:latest --name centos2
# 容器目錄不可以為相對路徑必須為絕對路徑
docker run -d -v /root/test3:etc nginx:latest --name centos2
# 	容器內部修改掛載點的許可權宿主機器會根據容器內部屬主的UID在對應的宿主機更改許可權ll -d test4/
# 容器刪除不會影響宿主機掛載的目錄docker rm -f centos4ll 
# 指定容器名稱docker run -h (容器名稱) 容器映象 | IDdocker run -d -p 82:80 --name nginx2 -h nginx2 nginx:latest docker exec -it nginx2 bash

Docker映象組成原理

映象組成

在上述中我們可以將映象看做一個軟體包,既然映象屬於軟體包那麼一個映象就應該有軟體包執行所需要的檔案 例如:本省的軟體檔案,依賴檔案,庫檔案,配置檔案,環境變數等。

映象體積過大

在Docker中容器屬於操作系用級別隔離,因此執行一個Docker映象還需要擁有作業系統,最終可以看出一個映象組成包含作業系統依賴,軟體自身依賴,以及軟體自身包等,由於這些各種檔案依賴等導致雖然Docker輕量然而映象體積過大。

聯合檔案系統

Union檔案系統是一種分層,輕量級並且高效能的檔案系統,它支援對檔案系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬檔案系統。而Docker就是使用聯合檔案系統,在上圖中可以看到一個完整的Docker映象其實是由多個檔案系統共同組成對外提供一個檔案系統,在Docker映象之中每個檔案系統都被載入,而對外提供的系統是由一個個子檔案系統組成而該子檔案系統都被載入因此整個外部檔案系統所需要的所有檔案都被載入。

Docker分層架構

在上圖中可以看出其實映象底層都需要作業系統等基礎映象依賴以及一些公共的庫,因此我們可以將這些公共的檔案進行抽象處理,這樣就無需拉取映象的時候都會拉取一些重複的檔案。

如果我們進行映象分層,可以實現資源的共享,無需載入一些重複的檔案系統,這樣下載映象的時候降低了映象的大小,執行映象的時候無需重複執行一些重複的檔案系統節省資源。

Docker網路模式

常用命令

檢視網路資訊

[root@localhost ~]# docker network ls

建立網橋

# -d指定網橋網路型別
[root@localhost ~]# docker network create lnmp -d bridge 

刪除網橋

[root@localhost ~]# docker network rm lnmp 

bridge模式

當我們執行某些專案的時候,可能需要執行多個容器,在某些情況下我們需要保證容器之間能夠進行網路之間的通訊。

當Docker服務被啟動的時候,作業系統會自動生成一個網絡卡 docker0,該網絡卡物理上屬於一塊網絡卡,邏輯上可以看做一個虛擬交換機,當Docker執行容器的時候容器會繫結到該虛擬交換機上,這樣通過該虛擬交換機就行成一個二層網路用來容器互聯。

在Docker容器被啟動的時候建立主機會建立一對虛擬網絡卡 veth pair 裝置(這一對網絡卡中其中一個網絡卡接收的資料,另外一塊網絡卡會接收相同的資料),Docker將 veth pair 網絡卡其中一塊放在Docker容器內部命名為 eth0,另外一塊網絡卡繫結在虛擬交換機上名稱以 veth 開頭,並且該虛擬交換機會自動給容器分配 IP 地址,容器內部會將網橋的 IP 地址充當閘道器。

圖解

容器互通

# 執行兩個容器
[root@localhost ~]# docker run -d -p 80:80 --network lnmp --restart=always --name nginx0 nginx:latest 

[root@localhost ~]# docker run -d -p 81:80 --network lnmp --restart=always --name nginx1 nginx:latest 

# 檢視網橋的詳細資訊
[root@localhost ~]# docker inspect lnmp 
# 檢視容器ip
root@1524edfbce9e:~# ifconfig  

# 檢測網路連通性
root@1524edfbce9e:~# ping 172.19.0.2 -c 1

IP與容器名對映

雖然網橋為我們容器分配啦 IP地址,但是該地址屬於自動分配不是靜態的地址,大多數的時候我們需要一個固定的 IP 地址,在Docker中會將容器 IP 地址與容器名稱進行對映,當我們訪問容器名稱的時候就是訪問容器的 IP地址,簡單粗暴的認為此時容器名稱就是容器的 IP地址。

root@1524edfbce9e:~# ping nginx0 -c 1
    
root@1524edfbce9e:~# curl nginx0    

Docker資料卷

作用

在Docker中一般使用容器用來進行計算,通俗點來說資料卷是將容器檔案與宿主機檔案進行對映實現將容器內的資料儲存到宿主機器內,這樣不但實現了資料的持久化儲存同時實現了資料的共享,當我們操作宿主機器時候會將操作的結果同步到容器內。

特點

  • 資料卷可以在容器與容器之間進行共享
  • 對資料卷的操作會立馬生效
  • 對資料卷的更新不會影響映象
  • 容器是否存在不會影響資料卷

常用命令

建立資料卷

[root@localhost ~]# docker volume create test 

檢視資料卷

[root@localhost ~]# docker volume ls

檢視詳細資訊

[root@localhost ~]# docker volume inspect test 

刪除資料卷

# 刪除指定資料卷
[root@localhost ~]# docker volume rm test 		

# 刪除未使用的資料卷
[root@localhost ~]# docker volume prune test 

掛載對映

# 自動建立掛載目錄會在docker預設的掛載目錄下生成目錄
[root@localhost ~]# docker run -d -p 80:80 --name nginx0 -h nginx0 -v nginx:/usr/share/nginx/html nginx:latest 

[root@localhost ~]# cd /var/lib/docker/volumes/nginx/_data

# 向掛載點寫入資料
[root@localhost _data]# echo "hello world" > index.html
# 容器向宿主機器寫入資料
root@nginx0:/usr/share/nginx/html/projectA# echo "hello world" > test.txt
# 容器只讀
[root@localhost ~]# docker run -d -p 81:80 --name nginx1 -h nginx1 --restart=always -v nginx:/usr/share/nginx/html:ro nginx:latest 
# 外部訪問容器資料
[root@localhost ~]# curl 172.17.0.2/projectA/index.html

Docker安裝常用服務

安裝mysql

# 1.拉取mysql映象到本地
	docker pull mysql:tag (tag不加預設最新版本)
	
# 2.執行mysql服務
	docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:tag  						  --沒有暴露外部埠外部不能連線
	docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d  mysql:tag  --沒有暴露外部埠

# 3.進入mysql容器
	docker exec -it 容器名稱|容器id bash

# 4.外部檢視mysql日誌
	docker logs 容器名稱|容器id

# 5.使用自定義配置引數
	docker run --name mysql -v /root/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -d mysql:tag

# 6.將容器資料位置與宿主機位置掛載保證資料安全
	docker run --name mysql -v /root/mysql/data:/var/lib/mysql -v /root/mysql/conf.d:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:tag

# 7.通過其他客戶端訪問 如在window系統|macos系統使用客戶端工具訪問
	
# 8.將mysql資料庫備份為sql檔案
	docker exec mysql|容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql  --匯出全部資料
	docker exec mysql sh -c 'exec mysqldump --databases 庫表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql  --匯出指定庫資料
	docker exec mysql sh -c 'exec mysqldump --no-data --databases 庫表 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql  --匯出指定庫資料不要資料

# 9.執行sql檔案到mysql中
	docker exec -i mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /root/xxx.sql

安裝Redis服務

# 1.在docker hub搜尋redis映象	docker search redis# 2.拉取redis映象到本地	docker pull redis# 3.啟動redis服務執行容器	docker run --name redis -d redis:tag (沒有暴露外部埠)	docker run --name redis -p 6379:6379 -d redis:tag (暴露外部宿主機埠為6379進行連線) # 4.檢視啟動日誌	docker logs -t -f 容器id|容器名稱# 5.進入容器內部檢視	docker exec -it 容器id|名稱 bash  # 6.載入外部自定義配置啟動redis容器	預設情況下redis官方映象中沒有redis.conf配置檔案 需要去官網下載指定版本的配置檔案	1. wget http://download.redis.io/releases/redis-5.0.8.tar.gz  下載官方安裝包	2. 將官方安裝包中配置檔案進行復制到宿主機指定目錄中如 /root/redis/redis.conf檔案	3. 修改需要自定義的配置		 bind 0.0.0.0 開啟遠端許可權		 appenonly yes 開啟aof持久化	4. 載入配置啟動	docker run --name redis -v /root/redis:/usr/local/etc/redis -p 6379:6379 -d redis redis-server /usr/local/etc/redis/redis.conf  # 7.將資料目錄掛在到本地保證資料安全	docker run --name redis -v /root/redis/data:/data -v /root/redis/redis.conf:/usr/local/etc/redis/redis.conf -p 6379:6379 -d redis redis-server 					/usr/local/etc/redis/redis.conf  

安裝Nginx

# 1.在docker hub搜尋nginx	docker search nginx# 2.拉取nginx映象到本地	[root@localhost ~]# docker pull nginx    Using default tag: latest    latest: Pulling from library/nginx    afb6ec6fdc1c: Pull complete     b90c53a0b692: Pull complete     11fa52a0fdc0: Pull complete     Digest: sha256:30dfa439718a17baafefadf16c5e7c9d0a1cde97b4fd84f63b69e13513be7097    Status: Downloaded newer image for nginx:latest    docker.io/library/nginx:latest# 3.啟動nginx容器		docker run -p 80:80 --name nginx01 -d nginx# 4.進入容器		docker exec -it nginx01 /bin/bash		查詢目錄:  whereis nginx		配置檔案:  /etc/nginx/nginx.conf# 5.複製配置檔案到宿主機		docker cp nginx01(容器id|容器名稱):/etc/nginx/nginx.conf 宿主機名錄# 6.掛在nginx配置以及html到宿主機外部		docker run --name nginx02 -v /root/nginx/nginx.conf:/etc/nginx/nginx.conf -v /root/nginx/html:/usr/share/nginx/html -p 80:80 -d nginx		

安裝Tomcat

# 1.在docker hub搜尋tomcat	docker search tomcat# 2.下載tomcat映象	docker pull tomcat# 3.執行tomcat映象	docker run -p 8080:8080 -d --name mytomcat tomcat# 4.進入tomcat容器	docker exec -it mytomcat /bin/bash# 5.將webapps目錄掛載在外部	docker run -p 8080:8080 -v /root/webapps:/usr/local/tomcat/webapps -d --name mytomcat tomcat

安裝MongoDB資料庫

# 1.執行mongDB
	docker run -d -p 27017:27017 --name mymongo mongo  ---無須許可權
	docker logs -f mymongo --檢視mongo執行日誌

# 2.進入mongodb容器
	docker exec -it mymongo /bin/bash
		直接執行mongo命令進行操作

# 3.常見具有許可權的容器
	docker run --name  mymongo  -p 27017:27017  -d mongo --auth

# 4.進入容器配置使用者名稱密碼
	mongo
	use admin 選擇admin庫
	db.createUser({user:"root",pwd:"root",roles:[{role:'root',db:'admin'}]})   //建立使用者,此使用者建立成功,則後續操作都需要使用者認證
	exit

# 5.將mongoDB中資料目錄對映到宿主機中
	docker run -d -p 27017:27017 -v /root/mongo/data:/data/db --name mymongo mongo 

安裝ElasticSearch

  • 注意:調高JVM執行緒數限制數量

拉取映象執行elasticsearch

# 1.dockerhub 拉取映象
	docker pull elasticsearch:6.4.2
# 2.檢視docker映象
	docker images
# 3.執行docker映象
	docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.4.2
  • 啟動出現如下錯誤

預先配置

# 1.在centos虛擬機器中,修改配置sysctl.conf
	vim /etc/sysctl.conf
# 2.加入如下配置
	vm.max_map_count=262144 
# 3.啟用配置
	sysctl -p
	注:這一步是為了防止啟動容器時,報出如下錯誤:
	bootstrap checks failed max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]

啟動EleasticSearch容器

# 0.複製容器中data目錄到宿主機中	docker cp 容器id:/usr/share/share/elasticsearch/data /root/es# 1.執行ES容器 指定jvm記憶體大小並指定ik分詞器位置	docker run -d --name es -p 9200:9200 -p 9300:9300 -e ES_JAVA_OPTS="-Xms128m -Xmx128m" -v /root/es/plugins:/usr/share/elasticsearch/plugins -v /root/es/data:/usr/share/elasticsearch/data elasticsearch:6.4.2

安裝IK分詞器

# 1.下載對應版本的IK分詞器	wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.4.2/elasticsearch-analysis-ik-6.4.2.zip# 2.解壓到plugins資料夾中	yum install -y unzip	unzip -d ik elasticsearch-analysis-ik-6.4.2.zip# 3.新增自定義擴充套件詞和停用詞	cd plugins/elasticsearch/config	vim IKAnalyzer.cfg.xml	<properties>		<comment>IK Analyzer 擴充套件配置</comment>		<!--使用者可以在這裡配置自己的擴充套件字典 -->		<entry key="ext_dict">ext_dict.dic</entry>		<!--使用者可以在這裡配置自己的擴充套件停止詞字典-->		<entry key="ext_stopwords">ext_stopwords.dic</entry>	</properties># 4.在ik分詞器目錄下config目錄中建立ext_dict.dic檔案   編碼一定要為UTF-8才能生效	vim ext_dict.dic 加入擴充套件詞即可# 5. 在ik分詞器目錄下config目錄中建立ext_stopword.dic檔案 	vim ext_stopwords.dic 加入停用詞即可# 6.重啟容器生效	docker restart 容器id# 7.將此容器提交成為一個新的映象	docker commit -a="xiaochen" -m="es with IKAnalyzer" 容器id xiaochen/elasticsearch:6.4.2

安裝Kibana

# 1.下載kibana映象到本地	docker pull kibana:6.4.2# 2.啟動kibana容器	docker run -d --name kibana -e ELASTICSEARCH_URL=http://10.15.0.3:9200 -p 5601:5601 kibana:6.4.2

Dockerfile

簡介

Dockerfile內部是由一系列的指令組成,可以類似看成一個指令碼,當執行Dockerfile檔案可以幫我們生成一個自定義的映象

自定義映象

我們可以根據自己的業務專門製作專屬的映象,同時可以將自己的應用打包製作成映象,後期我們進行專案遷移,或者多臺伺服器執行該應用我們只需要執行該映象即可,真正的做到了一次製作,終身使用。

Dockerfile執行解析

宿主機在某目錄下建立 Dockerfile 檔案,包含該 Dockerfile 的目錄被稱之為上下文目錄,在 Dockerfile 目錄下寫入構建映象的指令,當 Dockerfile檔案書寫完畢之後執行 Docker build 命令, Docker會將 Dockerfile 所在的上下文目錄傳送給 Docker 服務端,服務端解析 Dockerfile 檔案中的指令,執行一條指令會生成一個映象檔案,並且將生成的映象檔案存放在 Docker Cache 中,最終所有的映象組合成一個最終的映象暴露給外部使用者。

Dockerfile命令簡介

保留字 作用
FROM 當前映象是基於哪個映象的
MAINTAINER 映象維護者的姓名和郵箱地址(已經啟用無需再寫)
RUN 構建映象時需要執行的指令:例如執行mysql 需要使用mysql -u root - p
EXPOS 當前容器對外暴露出的埠號:方便宿主機器與容器對映**
WORKDIR 指定在建立容器後,終端預設登入進來的工作目錄,一個落腳點
ENV 用來在構建映象過程中設定環境變數:例如mysql的MYSQL_ROOT_PASSWORD
ADD 將宿主機目錄下的檔案拷貝進映象且ADD命令會自動處理URL和解壓tar包
COPY 類似於ADD,拷貝檔案和目錄到映象中
將從構建上下文目錄中<原路徑>的檔案/目錄複製到新的一層的映象內的<目標路徑>位置
VOLUME 容器資料卷,用於資料儲存和持久化工作
CMD 指定一個容器啟動時要執行的命令
Dockerfile中可以有多個CMD指令,但只有最後一個生效,CMD會被docker run之後的引數替換
ENTRYPOINT 指定一個容器啟動時要執行的命令
ENTRYPOINT的目的和CMD一樣,都是在指定容器啟動程式及其引數

官方說明

Dockerfile命令詳解

FROM

  • 基於那個映象進行構建新的映象,在構建時會自動從docker hub拉取base映象 必須作為Dockerfile的第一個指令出現
  • 語法:
FROM  <image>
FROM  <image>[:<tag>]     使用版本不寫為latest
FROM  <image>[@<digest>]  使用摘要

[root@localhost dockerfile]# vim Dockerfile
        # 基於centos映象
        FROM centos:7

# 構建上下文生成映象
[root@localhost dockerfile]# docker build -t mycentos7:01 ./

MAINTAINER

  • 映象維護者的姓名和郵箱地址[廢棄]
  • 語法:
MAINTAINER <name>

RUN

  • RUN指令將在當前映像之上的新層中執行任何命令並提交結果。生成的提交映像將用於Dockerfile中的下一步

  • 語法:

RUN ["executable", "param1", "param2"] (exec form)RUN ["/bin/bash", "-c", "echo hello"][root@localhost dockerfile]# vim Dockerfile        # 基於centos映象        FROM centos:7        # 給新映象新增vim命令        RUN yum -y install vim# 構建上下文生成映象[root@localhost dockerfile]# docker build -t mycentos7:02 ./

EXPOSE

  • 用來指定構建的映象在執行為容器時對外暴露的埠
  • 語法:
EXPOSE 80/tcp  如果沒有顯示指定則預設暴露都是tcpEXPOSE 80/udp[root@localhost dockerfile]# vim Dockerfile 	FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp  [root@localhost dockerfile]# docker build -t mycentos7:03 ./[root@localhost dockerfile]# docker run -p 80:80 mycentos7:03 

WORKDIR

  • 用來為Dockerfile中的任何RUN、CMD、ENTRYPOINT、COPY和ADD指令設定工作目錄。如果WORKDIR不存在,即使它沒有在任何後續Dockerfile指令中使用,它也將被建立。
  • 語法:
WORKDIR /path/to/workdir# 注意:WORKDIR指令可以在Dockerfile中多次使用。如果提供了相對路徑,則該路徑將與先前WORKDIR指令的路徑相對WORKDIR /aWORKDIR bWORKDIR c[root@localhost dockerfile]# vim Dockerfile     FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    # 配置工作路徑	    WORKDIR /path/test[root@localhost dockerfile]# docker build -t mycentos7:04 ./

COPY

  • 用來將context目錄中指定檔案複製到映象的指定目錄中

  • 語法:

COPY src destCOPY ["<src>",... "<dest>"][root@localhost dockerfile]# cat Dockerfile     FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    WORKDIR /path/test    # 將a.txt檔案複製到/path/test中    COPY a.txt /path/test[root@localhost dockerfile]# docker build -t mycentos7:05 ./

ADD

  • 用來從context上下文複製新檔案、目錄或遠端檔案url,並將它們新增到位於指定路徑的映像檔案系統中,如果是壓縮包在映象中會自動解壓。

  • 語法:

ADD hom* /mydir/       萬用字元新增多個檔案ADD hom?.txt /mydir/   萬用字元新增ADD test.txt relativeDir/  可以指定相對路徑ADD test.txt /absoluteDir/ 也可以指定絕對路徑ADD url [root@localhost dockerfile]# cat Dockerfile     FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    WORKDIR /path/test    # 將a.txt檔案複製到/path/test中    COPY a.txt /path/test    # 複製b.txt到/path/test中    ADD b.txt /path/test    # 複製url到指定目錄下	ADD https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.70/bin/apache-tomcat-8.5.70-fulldocs.tar.gz /path/test/download[root@localhost dockerfile]# docker build -t mycentos7:06 ./
[root@localhost dockerfile]# vim Dockerfile 	FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    WORKDIR /path/test    COPY a.txt /path/test    ADD b.txt /path/test    # 複製壓縮包到指定目錄在容器內部會被自動解壓    ADD apache-tomcat-8.5.70-fulldocs.tar.gz /path/test[root@localhost dockerfile]# docker build -t mycentos7:08 ./

VOLUME

  • 用來定義容器執行時可以掛在到宿主機的目錄
  • 語法:
VOLUME ["/path1","path2"]
VOLUME /path

[root@localhost dockerfile]# vim Dockerfile 
	FROM centos:7
    RUN yum -y install vim
    EXPOSE 80/tcp
    EXPOSE 80/udp
    WORKDIR /path/test
    COPY a.txt /path/test
    ADD b.txt /path/test
    # 複製壓縮包到指定目錄在容器內部會被自動解壓
    ADD apache-tomcat-8.5.70-fulldocs.tar.gz /path/test
    VOLUME /path/test

[root@localhost dockerfile]# docker build -t mycentos7:10 ./

[root@localhost dockerfile]# docker run -itd --restart=always -v /path/test:/path/test mycentos7:10

[root@localhost dockerfile]# echo mysql hostos path is /path/tes > /path/test/test.txt

ENV

  • 用來為構建映象設定環境變數。這個值將出現在構建階段中所有後續指令的環境中。

  • 語法:

ENV <key> <value>
ENV <key>=<value> ...

[root@localhost dockerfile]# vim Dockerfile 
	FROM centos:7
    RUN yum -y install vim
    EXPOSE 80/tcp
    EXPOSE 80/udp
    RUN mkdir -p /path/test
    
    # 將/path/test設定成環境變數
    ENV BASE_DIR /path/test
    # 呼叫環境變數BASE_DIR
    WORKDIR $BASE_DIR
    COPY a.txt $BASE_DIR
    ADD b.txt $BASE_DIR
    ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
    VOLUME $BASE_DIR
[root@localhost dockerfile]# docker build -t mycentos7:13 .

CMD 命令

  • 用來為啟動的容器指定執行的命令,在Dockerfile中只能有一條CMD指令。如果列出多個命令,則只有最後一個命令才會生效。
  • 如果我們在執行容器的時候給CMD傳入命令,則預設的命令會被傳入的命令覆蓋
  • 語法:
CMD ["executable","param1","param2"] (exec form, this is the preferred form)CMD ["param1","param2"] (as default parameters to ENTRYPOINT)CMD command param1 param2 (shell form)[root@localhost dockerfile]# vim Dockerfile     FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    RUN mkdir -p /path/test    ENV BASE_DIR /path/test    WORKDIR $BASE_DIR    COPY a.txt $BASE_DIR    ADD b.txt $BASE_DIR    ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR    VOLUME $BASE_DIR[root@localhost dockerfile]# docker build -t mycentos7:14
[root@localhost dockerfile]# vim Dockerfile     FROM centos:7    RUN yum -y install vim    EXPOSE 80/tcp    EXPOSE 80/udp    RUN mkdir -p /path/test    ENV BASE_DIR /path/test    WORKDIR $BASE_DIR    COPY a.txt $BASE_DIR    ADD b.txt $BASE_DIR    ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR    VOLUME $BASE_DIR    # 啟動檢視目錄    CMD ls $BASE_DIR[root@localhost dockerfile]# docker build -t mycentos7:17
[root@localhost dockerfile]# docker run -it mycentos7:17 ls /path/test

ENTRYPOINT

  • 用來為啟動的容器指定執行的命令,當有多個命令的時候其只執行最後一條命令
  • 預設情況下如果我們我們在執行容器的時候給ENTRYPOINT傳入命令其不會覆蓋原有指令
  • 語法:
["executable", "param1", "param2"]
ENTRYPOINT command param1 param2

[root@localhost dockerfile]# vim Dockerfile 
    FROM centos:7
    RUN yum -y install vim
    EXPOSE 80/tcp
    EXPOSE 80/udp
    RUN mkdir -p /path/test
    ENV BASE_DIR /path/test
    WORKDIR $BASE_DIR
    COPY a.txt $BASE_DIR
    ADD b.txt $BASE_DIR
    ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
    VOLUME $BASE_DIR
    ENTRYPOINT ls $BASE_DIR
    # 只會執行最後一條
    ENTRYPOINT echo "hello world"
[root@localhost dockerfile]# docker build -t mycentos7:19
# entrypoint預設情況下該命令不會被覆蓋
[root@localhost dockerfile]# docker run -it mycentos7:19 ls /path/test
# 新增entrypoint引數覆蓋指定命令
[root@localhost dockerfile]# docker run -it --entrypoint=ls mycentos7:19 /path/test

CMD與ENTRYPOINT共用

ENTRYPOINT指令,往往用於設定容器啟動後的第一個命令,這對一個容器來說往往是固定的。CMD指令,往往用於設定容器啟動的第一個命令的預設引數,這對一個容器來說可以是變化的。

[root@localhost dockerfile]# vim Dockerfile 
    FROM centos:7
    RUN yum -y install vim
    EXPOSE 80/tcp
    EXPOSE 80/udp
    RUN mkdir -p /path/test
    ENV BASE_DIR /path/test
    WORKDIR $BASE_DIR
    COPY a.txt $BASE_DIR
    ADD b.txt $BASE_DIR
    ADD apache-tomcat-8.5.70-fulldocs.tar.gz $BASE_DIR
    VOLUME $BASE_DIR
    CMD ["echo test cmd argument"]
    ENTRYPOINT ["echo"]
    
[root@localhost dockerfile]# docker build -t mycentos7:27 .

# 此時CMD會以引數的形式傳遞給ENTRYPOINT 在執行的時候沒有傳入引數會以預設引數
[rootvim@localhost dockerfile]# docker run -it mycentos7:27
# 手動傳入會覆蓋預設引數[root@localhost dockerfile]# docker run -it mycentos7:27 hello world

Dockerfile構建Django

[root@localhost dockerfile]# vim Dockerfile   #指定基礎映象  FROM python:3.6.12  RUN pip3 install django==1.11.11 -i https://pypi.douban.com/simple/  # 建立Django專案  RUN django-admin startproject app  # 配置工作目錄  WORKDIR /app  # 暴露外部埠  EXPOSE 8000  # 啟動服務  ENTRYPOINT ["python3","manage.py","runserver"]  # 當作引數  CMD [""]# 構建映象[root@localhost dockerfile]# docker build -t demo:01 .# 啟動映象 0.0.0.0:8000會被CMD以引數的形式傳遞給ENTRYPOINTroot@localhost test]# docker run -d -p 8000:8000 --name demo1 --restart=always demo:01 0.0.0.0:8000

Docker-compose

簡介

Docker-compose 專案是 Docker 官方的開源專案,負責實現對 Docker 容器叢集的快速編排。所謂容器編排即是按照一種指定順序對相應的容器啟動。

在上述中使用一個 Dockerfile 模板檔案,可以讓使用者很方便的定義一個單獨的應用容器。然而,在日常工作中,經常會碰到需要多個容器相互配合來完成某項任務的情況。例如要實現一個 Web 專案,除了 Web 服務容器本身,往往還需要再加上後端的資料庫服務容器,甚至還包括負載均衡容器等。

Docker-compose 恰好滿足了這樣的需求。它允許使用者通過一個單獨的 docker-compose.yml 模板檔案來定義一組相關聯的應用容器為一個專案(project)。

Docker-compose 中有兩個重要的概念:

  • 服務 (service):一個應用的容器,實際上可以包括若干執行相同映象的容器例項。
  • 專案 (project):由一組關聯的應用容器組成的一個完整業務單元,在 docker-compose.yml 檔案中定義。

專案地址

安裝

# 下載二進位制檔案[root@localhost dockerfile]# curl -L https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose# 新增執行許可權[root@localhost dockerfile]# chmod +x /usr/local/bin/docker-compose# 查詢是否安裝成功[root@localhost ~]# docker-compose -v

簡單使用

[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"  # 專案版本
    services:
      nginx:       # 服務名稱
        image: nginx       # 當前服務所使用的映象
        container_name: nginx       # 容器名稱      
        ports:
          - 80:80           # 對映埠
 # 執行       
[root@localhost ~]# docker-compose up

模板檔案命令

image

指定為映象名稱或映象 ID。如果映象在本地不存在,Compose 將會嘗試拉取這個映象。

# 語法
image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"  # 專案版本
    services:
      nginx:       # 服務名稱
        image: nginx       # 當前服務所使用的映象不指定tag預設為最新的   
        
  # 執行       
[root@localhost ~]# docker-compose up

[root@localhost ~]# docker images 

ports

暴露埠資訊。使用宿主埠:容器埠 (HOST:CONTAINER) 格式,或者僅僅指定容器的埠(宿主將會隨機選擇埠)都可以。

'''
當使用 `HOST:CONTAINER` 格式來對映埠時,如果你使用的容器埠小於 60 並且沒放到引號裡,可能會得到錯誤結果,因為 `YAML` 會自動解析 `xx:yy` 這種數字格式為 60 進位制。為避免出現這種問題,建議數字串都採用引號包括起來的字串格式。
'''
# 語法
ports:
 - "3000"
 - "8000:8000"
 - "49100:22"
 - "127.0.0.1:8001:8001"
    
[root@localhost dockercompose]# vim docker-compose.yml 
   version: "3.0"
    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
  # 執行       
[root@localhost ~]# docker-compose up       
[root@localhost ~]# docker ps

networks

配置容器連線的網路。

# 語法
networks:
	# 網路名稱 如果只是這樣定義需要手動建立網路
     - some-network
     - other-network
# 自動建立上述網橋
networks:
  some-network:
  other-network:
  
[root@localhost dockercompose]# cat docker-compose.yml 
	version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
          
    networks: 
      test:
  # 執行       
[root@localhost ~]# docker-compose up

[root@localhost dockercompose]# docker network ls
[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
    networks: 
      test:
        external:  # 使用指定網路名稱
          true  # 如果為true網橋必須先建立
[root@localhost dockercompose]# docker-compose up
# 建立網橋[root@localhost dockercompose]# docker network create test[root@localhost dockercompose]# docker-compose up# 檢視詳情[root@localhost dockercompose]# docker inspect dockercompose_tomcat_1 
# 自定義網路
[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3"
    services:
      nginx:
       image: tomcat:8.0-jre8
       container_name: tomcat
       networks:
         test:
          # 指定容器ip地址
          ipv4_address: 172.66.0.2

    networks:
      test:
       ipam:
         config:
         # 配置網段
         - subnet: 172.66.0.0/16
           # 配置閘道器
           gateway: 172.66.0.1

[root@localhost dockercompose]# docker inspect tomcat

container_name

配置容器執行名稱

# 語法
container_name: 容器名稱       # 容器名稱      

[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
        container_name: tomcat	# 配置容器名稱

    networks: 
      test:
        external:  # 使用指定網路名稱
          true  # 如果為true網橋必須先建立
        
[root@localhost dockercompose]# docker-compose up

[root@localhost dockercompose]# docker ps

hostname

配置容器執行內部名稱

# 語法hostname: 容器名稱[root@localhost dockercompose]# vim docker-compose.yml     version: "3.0"    services:       tomcat:        image: tomcat:8.0-jre8        ports:           - "8080:8080"        networks:           - test        container_name: tomcat	# 配置容器名稱        hostname: tomcat    networks:       test:        external:  # 使用指定網路名稱          true  # 如果為true網橋必須先建立        [root@localhost dockercompose]# docker exec -it tomcat bashroot@tomcat:/usr/local/tomcat# cat /etc/hostname 

restart

配置容器開機自啟動

# 語法restart: always[root@localhost dockercompose]# vim docker-compose.yml     version: "3.0"    services:       tomcat:        image: tomcat:8.0-jre8        ports:           - "8080:8080"        networks:           - test        container_name: tomcat	# 配置容器名稱        hostname: tomcat        restart: always    networks:       test:        external:  # 使用指定網路名稱          true  # 如果為true網橋必須先建立

working_dir

配置進入容器所處目錄

# 語法
restart: path

[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
        container_name: tomcat	# 配置容器名稱
        hostname: tomcat
        restart: always
        working_dir: /root/test



    networks: 
      test:
        external:  # 使用指定網路名稱
          true  # 如果為true網橋必須先建立

volumes

資料卷所掛載路徑設定。可以設定為宿主機路徑(HOST:CONTAINER)或者資料卷名稱(VOLUME:CONTAINER),並且可以設定訪問模式 (HOST:CONTAINER:ro)。

# 語法
volumes:
 - /var/lib/mysql
 - cache/:/tmp/cache
 - ~/configs:/etc/configs/:ro
 
[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
        container_name: tomcat

        hostname: tomcat

        restart: always

        working_dir: /root/test

        volumes: 
          - /root/test:/root/test   
      
networks: 
  test:
    external:  # 使用指定網路名稱
      true  # 如果為true網橋必須先建立

    # 寫入資料
[root@localhost dockercompose]# echo "hello world" > /root/test/test.txt
[root@localhost dockercompose]# docker exec -it tomcat bash
root@tomcat:~/test# cat test.txt 

[root@localhost dockercompose]# vim docker-compose.yml 

    version: "3.0"

    services: 
      tomcat:
        image: tomcat:8.0-jre8
        ports: 
          - "8080:8080"
        networks: 
          - test
        container_name: tomcat

        hostname: tomcat

        restart: always

        working_dir: /root/test

        volumes: 
          - /root/test:/root/test
          # 使用相對路徑進行對映 必須需要宣告
          - tomcat01:/usr/local/tomcat/webapps

    networks: 
      test:
        external:  # 使用指定網路名稱
          true  # 如果為true網橋必須先建立
[root@localhost dockercompose]# vim docker-compose.yml     # 宣告資料卷    version: "3.0"    services:       tomcat:        image: tomcat:8.0-jre8        ports:           - "8080:8080"        networks:           - test        container_name: tomcat        hostname: tomcat        restart: always        working_dir: /root/test        volumes:           - /root/test:/root/test          # 使用相對路徑進行對映          - tomcat01:/usr/local/tomcat/webapp    networks:       test:        external:  # 使用指定網路名稱          true  # 如果為true網橋必須先建立            volumes: 	  # 宣告資料卷      tomcat01:            [root@localhost dockercompose]# docker volume ls 
[root@localhost dockercompose]# vim docker-compose.yml     version: "3.0"    services:       tomcat:        image: tomcat:8.0-jre8        ports:           - "8080:8080"        networks:           - test        container_name: tomcat        hostname: tomcat        restart: always        working_dir: /root/test        volumes:           - /root/test:/root/test          # 使用相對路徑進行對映          - tomcat01:/usr/local/tomcat/webapps    networks:       test:        external:  # 使用指定網路名稱          true  # 如果為true網橋必須先建立    volumes: 	 # 使用此種方式必須先宣告資料卷      tomcat01:        # 使用指定資料卷名稱        external:           true[root@localhost dockercompose]# docker volume inspect tomcat01 

environment

設定環境變數。你可以使用陣列或字典兩種格式。

只給定名稱的變數會自動獲取執行 Compose 主機上對應變數的值,可以用來防止洩露不必要的資料。

# 語法environment:  RACK_ENV: development  SESSION_SECRET:environment:  - RACK_ENV=development  - SESSION_SECRET[root@localhost dockercompose]# vim docker-compose.yml     version: "3.0"    services:       tomcat:        image: tomcat:8.0-jre8        ports:           - "8080:8080"        networks:           - test        container_name: tomcat        hostname: tomcat        restart: always        working_dir: /root/test        volumes:           - /root/test:/root/test          # 使用相對路徑進行對映          - tomcat01:/usr/local/tomcat/webapps      mysql:        image: mysql:5.7.31        # 配置環境變數        environment:           - MYSQL_ROOT_PASSWORD=root        ports:           - "3306:3306"    networks:       test:        external:  # 使用指定網路名稱          true  # 如果為true網橋必須先建立    volumes:       tomcat01:        external:           true$ mysql -uroot -proot -h10.1.1.2 

env_file

從檔案中獲取環境變數,可以為單獨的檔案路徑或列表。

如果通過 docker-compose -f FILE 方式來指定 Compose 模板檔案,則 env_file 中變數的路徑會基於模板檔案路徑。

如果有變數名稱與 environment 指令衝突,則按照慣例,以後者為準。

# 語法env_file: .envenv_file:  - ./common.env  - ./apps/web.env  - /opt/secrets.env[root@localhost dockercompose]# vim docker-compose.yml     version: "3"    services:      tomcat:       image: tomcat:8.0-jre8       container_name: tomcat       hostname: tomcat       restart: always       working_dir: /root/test       ports:         - "8080:8080"       volumes:          - /root/test:/root/test        # 使用相對路徑進行對映         - tomcat01:/usr/local/tomcat/webapps       networks:         test:          ipv4_address: 172.66.0.2      mysql:       image: mysql:5.7.31       container_name: mysql       hostname: mysql       restart: always       working_dir: /var/lib/mysql       env_file:        # 寫配置檔案路徑         - ./mysqlconfig.env       ports:         - "3306:3306"       volumes:         - mysqldata:/var/lib/mysql        - mysqlconf:/etc/mysql       networks:         test:          ipv4_address: 172.66.0.3       redis:       image: redis:5.0.10       container_name: redis       hostname: redis       restart: always       working_dir: /data       ports:         - "6379:6379"       volumes:         - redisdata:/data       networks:          test:          ipv4_address: 172.66.0.4       command: "redis-server --appendonly yes"    networks:      test:       ipam:         config:         - subnet: 172.66.0.0/16           gateway: 172.66.0.1    volumes:      tomcat01:        external: true      mysqlconf:      mysqldata:      redisdata:$ mysql -uroot -proot -h10.1.1.2

command

覆蓋容器啟動後預設執行的命令。

# 語法
command: "執行命令"
    
[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3"
    services:
      tomcat:
       image: tomcat:8.0-jre8
       container_name: tomcat
       hostname: tomcat
       restart: always
       working_dir: /root/test
       ports: 
        - "8080:8080"
       volumes: 
         - /root/test:/root/test
        # 使用相對路徑進行對映
         - tomcat01:/usr/local/tomcat/webapps

       networks:
         test:
          ipv4_address: 172.66.0.2
      mysql:
       image: mysql:5.7.31
       container_name: mysql
       hostname: mysql
       restart: always
       environment:
         - MYSQL_ROOT_PASSWORD=root
       working_dir: /var/lib/mysql
       ports: 
        - "3306:3306"
       volumes: 
        - mysqldata:/var/lib/mysql
        - mysqlconf:/etc/mysql
       networks:
         test:
          ipv4_address: 172.66.0.3 

      redis:
       image: redis:5.0.10
       container_name: redis
       hostname: redis
       restart: always
       working_dir: /data
       ports: 
        - "6379:6379"
       volumes: 
        - redisdata:/data
       networks: 
         test:
          ipv4_address: 172.66.0.4
       command: "redis-server --appendonly yes"

    networks:
      test:
       ipam:
         config:
         - subnet: 172.66.0.0/16
           gateway: 172.66.0.1

    volumes: 

      tomcat01:
        external: true

      mysqlconf:
      mysqldata:
      redisdata:

# 遠端連線redis
$ redis-cli -h 10.1.1.2
	# 寫入資料
	10.1.1.2:6379> set namq SR

# 檢視資料
[root@localhost _data]# cat appendonly.aof 

depends_on

解決容器的依賴、啟動先後的問題。以下例子中會先啟動 redis 再啟動 mysql

# 語法depends_on:  # 服務名稱  - mysql  - redis[root@localhost dockercompose]# vim docker-compose.yml     version: "3"    services:      tomcat:       image: tomcat:8.0-jre8       container_name: tomcat       hostname: tomcat       restart: always       working_dir: /root/test       ports:         - "8080:8080"       volumes:          - /root/test:/root/test        # 使用相對路徑進行對映         - tomcat01:/usr/local/tomcat/webapps       depends_on:        # 填寫服務名稱         - mysql         - redis       networks:         test:          ipv4_address: 172.66.0.2      mysql:       image: mysql:5.7.31       container_name: mysql       hostname: mysql       restart: always       working_dir: /var/lib/mysql       env_file:         - ./mysqlconfig.env       ports:         - "3306:3306"       volumes:         - mysqldata:/var/lib/mysql        - mysqlconf:/etc/mysql       networks:         test:          ipv4_address: 172.66.0.3       redis:       image: redis:5.0.10       container_name: redis       hostname: redis       restart: always       working_dir: /data       ports:         - "6379:6379"       volumes:         - redisdata:/data       networks:          test:          ipv4_address: 172.66.0.4       command: "redis-server --appendonly yes"    networks:      test:       ipam:         config:         - subnet: 172.66.0.0/16           gateway: 172.66.0.1    volumes:      tomcat01:        external: true      mysqlconf:      mysqldata:      redisdata:

healthcheck

通過命令檢查容器是否健康執行。

# 語法
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost"]
  interval: 1m30s
  timeout: 10s
  retries: 3

[root@localhost dockercompose]# cat docker-compose.yml 
    version: "3"
    services:
      tomcat:
       image: tomcat:8.0-jre8
       container_name: tomcat
       hostname: tomcat
       restart: always
       working_dir: /root/test
       ports: 
        - "8080:8080"
       volumes: 
         - /root/test:/root/test
        # 使用相對路徑進行對映
         - tomcat01:/usr/local/tomcat/webapps
       depends_on:
         - mysql
         - redis
       networks:
         test:
          ipv4_address: 172.66.0.2
       healthcheck:
         test: [ "CMD", "curl", "-f", "http://localhost" ]
         interval: 1m30s
         timeout: 10s
         retries: 3
      mysql:
       image: mysql:5.7.31
       container_name: mysql
       hostname: mysql
       restart: always
       working_dir: /var/lib/mysql
       env_file:
         - ./mysqlconfig.env
       ports: 
        - "3306:3306"
       volumes: 
        - mysqldata:/var/lib/mysql
        - mysqlconf:/etc/mysql
       networks:
         test:
          ipv4_address: 172.66.0.3 

      redis:
       image: redis:5.0.10
       container_name: redis
       hostname: redis
       restart: always
       working_dir: /data
       ports: 
        - "6379:6379"
       volumes: 
        - redisdata:/data
       networks: 
         test:
          ipv4_address: 172.66.0.4
       command: "redis-server --appendonly yes"

    networks:
      test:
       ipam:
         config:
         - subnet: 172.66.0.0/16
           gateway: 172.66.0.1

    volumes:
      tomcat01:
        external: true
      mysqlconf:
      mysqldata:
      redisdata:

sysctls

配置容器核心引數。

# 語法
sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0
    
[root@localhost dockercompose]# cat docker-compose.yml 
    version: "3"
    services:
      tomcat:
       image: tomcat:8.0-jre8
       container_name: tomcat
       hostname: tomcat
       restart: always
       working_dir: /root/test
       ports: 
        - "8080:8080"
       volumes: 
         - /root/test:/root/test
        # 使用相對路徑進行對映
         - tomcat01:/usr/local/tomcat/webapps
       depends_on:
         - mysql
         - redis
       networks:
         test:
          ipv4_address: 172.66.0.2
       healthcheck:
         test: [ "CMD", "curl", "-f", "http://localhost" ]
         interval: 1m30s
         timeout: 10s
         retries: 3
       sysctls:
         net.core.somaxconn: 1024
         net.ipv4.tcp_syncookies: 0
      mysql:
       image: mysql:5.7.31
       container_name: mysql
       hostname: mysql
       restart: always
       working_dir: /var/lib/mysql
       env_file:
         - ./mysqlconfig.env
       ports: 
        - "3306:3306"
       volumes: 
        - mysqldata:/var/lib/mysql
        - mysqlconf:/etc/mysql
       networks:
         test:
          ipv4_address: 172.66.0.3 

      redis:
       image: redis:5.0.10
       container_name: redis
       hostname: redis
       restart: always
       working_dir: /data
       ports: 
        - "6379:6379"
       volumes: 
        - redisdata:/data
       networks: 
         test:
          ipv4_address: 172.66.0.4
       command: "redis-server --appendonly yes"

    networks:
      test:
       ipam:
         config:
         - subnet: 172.66.0.0/16
           gateway: 172.66.0.1

    volumes:
      tomcat01:
        external: true
      mysqlconf:
      mysqldata:
      redisdata:

ulimits

指定容器的 ulimits 限制值。

例如,指定最大程序數為 65535,指定檔案控制代碼數為 20000(軟限制,應用可以隨時修改,不能超過硬限制) 和 40000(系統硬限制,只能 root 使用者提高)。

# 語法
  ulimits:
    nproc: 65535
    nofile:
      soft: 20000
      hard: 40000
        
[root@localhost dockercompose]# cat docker-compose.yml 
    version: "3"
    services:
      tomcat:
       image: tomcat:8.0-jre8
       container_name: tomcat
       hostname: tomcat
       restart: always
       working_dir: /root/test
       ports: 
        - "8080:8080"
       volumes: 
         - /root/test:/root/test
        # 使用相對路徑進行對映
         - tomcat01:/usr/local/tomcat/webapps
       depends_on:
         - mysql
         - redis
       networks:
         test:
          ipv4_address: 172.66.0.2
       healthcheck:
         test: [ "CMD", "curl", "-f", "http://localhost" ]
         interval: 1m30s
         timeout: 10s
         retries: 3
       sysctls:
         net.core.somaxconn: 1024
         net.ipv4.tcp_syncookies: 0
       ulimits:
        nproc: 65535
        nofile:
          soft: 20000
          hard: 40000
      mysql:
       image: mysql:5.7.31
       container_name: mysql
       hostname: mysql
       restart: always
       working_dir: /var/lib/mysql
       env_file:
         - ./mysqlconfig.env
       ports: 
        - "3306:3306"
       volumes: 
        - mysqldata:/var/lib/mysql
        - mysqlconf:/etc/mysql
       networks:
         test:
          ipv4_address: 172.66.0.3 

      redis:
       image: redis:5.0.10
       container_name: redis
       hostname: redis
       restart: always
       working_dir: /data
       ports: 
        - "6379:6379"
       volumes: 
        - redisdata:/data
       networks: 
         test:
          ipv4_address: 172.66.0.4
       command: "redis-server --appendonly yes"

    networks:
      test:
       ipam:
         config:
         - subnet: 172.66.0.0/16
           gateway: 172.66.0.1

    volumes:
      tomcat01:
        external: true
      mysqlconf:
      mysqldata:
      redisdata:

build

指定 Dockerfile 所在資料夾的路徑(可以是絕對路徑,或者相對 docker-compose.yml 檔案的路徑)。 Compose 將會利用它自動構建這個映象,然後使用這個映象。

# 語法
version: '3'
services:

  webapp:
    build:
      # 指定dockerfile上下文目錄
      context: ./dir
      # dockerfile檔案
      dockerfile: Dockerfile
      # 構建映象時候變數
      args:
        buildno: 1
            
[root@localhost dockercompose]# vim docker-compose.yml 
    version: "3"
    services:
      django:
        build:
          # dockerfile上下文目錄路徑
          context: ./dockerfile
          # dockerfile檔案
          dockerfile: Dockerfile
        container_name: django
        hostname: django
        ports:
        - "8000:8000"
        restart: always
        depends_on:
          - mysql
          - redis
        networks:
          test:
           ipv4_address: 172.66.0.5
      tomcat:
       image: tomcat:8.0-jre8
       container_name: tomcat
       hostname: tomcat
       restart: always
       working_dir: /root/test
       ports: 
        - "8080:8080"
       volumes: 
         - /root/test:/root/test
        # 使用相對路徑進行對映
         - tomcat01:/usr/local/tomcat/webapps
       depends_on:
         - mysql
         - redis
       networks:
         test:
          ipv4_address: 172.66.0.2
       healthcheck:
         test: [ "CMD", "curl", "-f", "http://localhost" ]
         interval: 1m30s
         timeout: 10s
         retries: 3
      mysql:
       image: mysql:5.7.31
       container_name: mysql
       hostname: mysql
       restart: always
       working_dir: /var/lib/mysql
       env_file:
         - ./mysqlconfig.env
       ports: 
        - "3306:3306"
       volumes: 
        - mysqldata:/var/lib/mysql
        - mysqlconf:/etc/mysql
       networks:
         test:
          ipv4_address: 172.66.0.3 

      redis:
       image: redis:5.0.10
       container_name: redis
       hostname: redis
       restart: always
       working_dir: /data
       ports: 
        - "6379:6379"
       volumes: 
        - redisdata:/data
       networks: 
         test:
          ipv4_address: 172.66.0.4
       command: "redis-server --appendonly yes"

    networks:
      test:
       ipam:
         config:
         - subnet: 172.66.0.0/16
           gateway: 172.66.0.1

    volumes:
      tomcat01:
        external: true
      mysqlconf:
      mysqldata:
      redisdata:

docker-compose常用命令

命令物件與格式

對於 Compose 來說,大部分命令的物件既可以是專案本身,也可以指定為專案中的服務或者容器。如果沒有特別的說明,命令物件將是專案,這意味著專案中所有的服務都會受到命令影響。

執行 docker-compose [COMMAND] --help 或者 docker-compose help [COMMAND] 可以檢視具體某個命令的使用格式。

docker-compose 命令的基本的使用格式是

docker-compose [-f=<arg>...] [options] [COMMAND] [ARGS...]

命令選項

  • -f, --file FILE 指定使用的 Compose 模板檔案,預設為 docker-compose.yml,可以多次指定。
  • -p, --project-name NAME 指定專案名稱,預設將使用所在目錄名稱作為專案名。
  • --x-networking 使用 Docker 的可拔插網路後端特性
  • --x-network-driver DRIVER 指定網路後端的驅動,預設為 bridge
  • --verbose 輸出更多除錯資訊。
  • -v, --version 列印版本並退出。

命令使用案例

up

格式為 docker-compose up [options] [SERVICE...]

  • 該命令十分強大,它將嘗試自動完成包括構建映象,(重新)建立服務,啟動服務,並關聯服務相關容器的一系列操作。

  • 連結的服務都將會被自動啟動,除非已經處於執行狀態。

  • 可以說,大部分時候都可以直接通過該命令來啟動一個專案。

  • 預設情況,docker-compose up 啟動的容器都在前臺,控制檯將會同時列印所有容器的輸出資訊,可以很方便進行除錯。

  • 當通過 Ctrl-C 停止命令時,所有容器將會停止。

  • 如果使用 docker-compose up -d,將會在後臺啟動並執行所有的容器。一般推薦生產環境下使用該選項。

  • 預設情況,如果服務容器已經存在,docker-compose up 將會嘗試停止容器,然後重新建立(保持使用 volumes-from 掛載的卷),以保證新啟動的服務匹配 docker-compose.yml 檔案的最新內容

# 後臺啟動
[root@localhost dockercompose]# docker-compose up -d
down`
  • 此命令將會停止 up 命令所啟動的容器,並移除網路
[root@localhost dockercompose]# docker-compose down 
exec
  • 進入指定的容器。
# exec後跟服務名稱
[root@localhost dockercompose]# docker-compose exec redis bash
ps
  • 列出專案中目前的所有容器。
[root@localhost dockercompose]# docker-compose ps
rm

刪除所有(停止狀態的)服務容器。推薦先執行 docker-compose stop 命令來停止容器。

選項:

  • -f, --force 強制直接刪除,包括非停止狀態的容器。一般儘量不要使用該選項。
  • -v 刪除容器所掛載的資料卷。
[root@localhost dockercompose]# docker-compose stop tomcat

[root@localhost dockercompose]# docker-compose rm -f tomcat

[root@localhost dockercompose]# docker-compose ps
top
  • 檢視各個服務容器內執行的程序。
[root@localhost dockercompose]# docker-compose top
pause
  • 將執行的容器暫停
[root@localhost dockercompose]# docker-compose pause redis

[root@localhost dockercompose]# docker-compose ps redis
unpause
  • 恢復處於暫停狀態中的服務
[root@localhost dockercompose]# docker-compose unpause redis

[root@localhost dockercompose]# docker-compose ps redis
stop

停止已經處於執行狀態的容器,但不刪除它。通過 docker-compose start 可以再次啟動這些容器。

選項:

  • -t, --timeout TIMEOUT 停止容器時候的超時(預設為 10 秒)。
[root@localhost dockercompose]# docker-compose stop redis

[root@localhost dockercompose]# docker-compose ps redis
start
  • 啟動已經存在的服務容器。
[root@localhost dockercompose]# docker-compose start redis

[root@localhost dockercompose]# docker-compose ps redis
restart

格式為 docker-compose restart [options] [SERVICE...]

重啟專案中的服務。

選項:

  • -t, --timeout TIMEOUT 指定重啟前停止容器的超時(預設為 10 秒)。

Docker視覺化工具

安裝Portainer

[root@localhost ~]# docker pull  portainer/portainer

[root@localhost ~]# docker volume create portainer_data

'''
1:Portainer內部埠8000 web介面埠9000 
2:需要與docker引擎通訊 因此需要對映scok檔案
'''
[root@localhost ~]#docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer