Docker介紹 Docker 是應用最廣泛的開源容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中 然後發佈到任何流行的 Linux或Windows 機器上,也可以實現虛擬化。 每個容器擁有一套和宿主機完全隔離的文件系統(共用linux內核),程式在這個虛擬容器里運行,就好像在真實 ...
Docker介紹
- Docker 是應用最廣泛的開源容器引擎,讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中
- 然後發佈到任何流行的 Linux或Windows 機器上,也可以實現虛擬化。
- 每個容器擁有一套和宿主機完全隔離的文件系統(共用linux內核),程式在這個虛擬容器里運行,就好像在真實的物理機上運行一樣。
容器:
- 容器是一個操作系統級別下的虛擬化技術,運行一個容器就行運行一個進程一樣
- 容器依賴linux內核特性:Namespace(資源隔離)和Cgroups(資源限制)
Docker思想:
- Docker的思想源於集裝箱,集裝箱解決了什麼問題呢?
- 在早期運輸貨物需要不同分類的船,例如運輸水果的船,運輸生活用品的船
- 有了集裝箱後,在大船上,可以把貨物分類到不同的集裝箱中,水果一個集裝箱,生活用品一個集裝箱
- 它們之間互不影響,只要把貨物封裝好集裝箱里,就可以把不同類的貨物一起運走。
- 通過Docker logo也可以看出所以然來,Docker就像大船,集裝箱就是容器。
- 一條鯨魚拖著若幹個集裝箱的經典形象已經深入人心。
docker 與 虛擬機比較:
- docker設計小巧,部署遷移快速,運行高效,按照應用隔離,管理人員可以看到所有容器的內容。
- 虛擬化技術比較臃腫,需要先創建新的系統,按照系統隔離,管理員無法看到系統內部信息。
舉例:
Docker就是手機中的各種APP,只需要一個系統就可以下載自己所需的應用
虛擬化技術相當於蘋果手機安裝一個龐大軟體,這個軟體上安裝安卓系統、魅族系統等,每個系統上還要安裝各類應用。
docker版本
- 社區版(Community Edition, CE)
- 企業版(Enterprise Edition, EE)
Docker 安裝
Docker 安裝參考官方文檔:
- docker官方文檔:https://docs.docker.com/
- centos安裝docker:https://docs.docker.com/install/linux/docker-ce/centos/
- docker CE只支持 centos7 不支持centos6
安裝:
# 1.安裝依賴包 yum install -y yum-utils device-mapper-persistent-data lvm2 # 2.添加Docker軟體包源(否則doker安裝的不是新版本) yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo # 3.安裝Docker CE yum install -y docker-ce # 4.啟動Docker服務並設置開機啟動 systemctl start docker systemctl enable docker # 5.測試docker是否安裝成功(hello-world是官方提供的一個測試鏡像) docker run hello-world # 6.查看docker基本信息 docker info docker version
Docker 創建一個ngixn容器:
# 1.創建一個nginx容器 docker run -it nginx # 2.查看docker運行的容器(可以獲取到這個容器的id) docker ps # 3.訪問這個容器 # 進入這個nginx容器(進入的文件系統和宿主機是完全隔離的,有自己獨立的文件系統) docker exec -it 73877e65c07d bash # 4.查看當前容器的 IP docker inspect 73877e65c07d # 73877e65c07d是通過docekr ps查看到的容器ID curl 172.17.0.2 # 測試這個nginx容器是否可以訪問
Docker 鏡像
什麼是Docker鏡像:
1. docker鏡像不包含Linux內核而又精簡的Linux操作系統
2. docker鏡像是一個分層存儲的文件,一個鏡像可以創建N個容器
3. 可以這麼理解,docker 鏡像是 docker 容器的靜態視角,docker 容器是 docker 鏡像的運行狀態。
4. 容器只是對docker鏡像的引用,如果docker鏡像刪除,此鏡像創建的容器也都失效
Docker 鏡像與容器的區別:
1. 當由 ubuntu:14.04 鏡像啟動容器時,ubuntu:14.04 鏡像的鏡像層內容將作為容器的 rootfs;
2. 而 ubuntu:14.04 鏡像的 json 文件,會由 docker daemon 解析,並提取出其中的容器執行入口 CMD 信息,
以及容器進程的環境變數 ENV 信息,最終初始化容器進程。
3. 當然,容器進程的執行入口來源於鏡像提供的 rootfs。
rootfs
- rootfs 是 docker 容器在啟動時內部進程可見的文件系統,即 docker 容器的根目錄。
- rootfs 通常包含一個操作系統運行所需的文件系統,例如可能包含典型的類 Unix 操作系統中的目錄系統, 如 /dev、/proc、/bin、/etc、/lib、/usr、 /tmp及運行 docker 容器所需的配置文件、工具等。
- 在傳統的 Linux 操作系統內核啟動時,首先掛載一個只讀的 rootfs,當系統檢測其完整性之後,再將其切換為讀寫模式。
- 而在 docker 架構中,當 docker daemon 為 docker 容器掛載 rootfs 時,沿用了 Linux 內核啟動時的做法,即將 rootfs 設為只讀模式。
- 在掛載完畢之後,利用聯合掛載(union mount)技術在已有的只讀 rootfs 上再掛載一個讀寫層。
- 這樣,可讀寫的層處於 docker 容器文件系統的最頂層,其下可能聯合掛載了多個只讀的層,
- 只有在 docker 容器運行過程中文件系統發生變化時,才會把變化的文件內容寫到可讀寫層,並隱藏只讀層中的舊版本文件。
Docker 鏡像的主要特點
為了更好的理解 docker 鏡像的結構,下麵介紹一下 docker 鏡像設計上的關鍵技術。
分層
docker 鏡像是採用分層的方式構建的,每個鏡像都由一系列的 "鏡像層" 組成。分層結構是 docker 鏡像如此輕量的重要原因。當需要修改容器鏡像內的某個文件時,只對處於最上方的讀寫層進行變動,不覆寫下層已有文件系統的內容,已有文件在只讀層中的原始版本仍然存在,但會被讀寫層中的新版本所隱藏。當使用 docker commit 提交這個修改過的容器文件系統為一個新的鏡像時,保存的內容僅為最上層讀寫文件系統中被更新過的文件。分層達到了在不的容器同鏡像之間共用鏡像層的效果。
寫時複製
docker 鏡像使用了寫時複製(copy-on-write)的策略,在多個容器之間共用鏡像,每個容器在啟動的時候並不需要單獨複製一份鏡像文件,而是將所有鏡像層以只讀的方式掛載到一個掛載點,再在上面覆蓋一個可讀寫的容器層。在未更改文件內容時,所有容器共用同一份數據,只有在 docker 容器運行過程中文件系統發生變化時,才會把變化的文件內容寫到可讀寫層,並隱藏只讀層中的老版本文件。寫時複製配合分層機制減少了鏡像對磁碟空間的占用和容器啟動時間。
內容定址
在 docker 1.10 版本後,docker 鏡像改動較大,其中最重要的特性便是引入了內容定址存儲(content-addressable storage) 的機制,根據文件的內容來索引鏡像和鏡像層。與之前版本對每個鏡像層隨機生成一個 UUID 不同,新模型對鏡像層的內容計算校驗和,生成一個內容哈希值,並以此哈希值代替之前的 UUID 作為鏡像層的唯一標識。該機制主要提高了鏡像的安全性,併在 pull、push、load 和 save 操作後檢測數據的完整性。另外,基於內容哈希來索引鏡像層,在一定程度上減少了 ID 的衝突並且增強了鏡像層的共用。對於來自不同構建的鏡像層,主要擁有相同的內容哈希,也能被不同的鏡像共用。
聯合掛載
通俗地講,聯合掛載技術可以在一個掛載點同時掛載多個文件系統,將掛載點的原目錄與被掛載內容進行整合,使得最終可見的文件系統將會包含整合之後的各層的文件和目錄。實現這種聯合掛載技術的文件系統通常被稱為聯合文件系統(union filesystem)。以下圖所示的運行 Ubuntu:14.04 鏡像後的容器中的 aufs 文件系統為例:
由於初始掛載時讀寫層為空,所以從用戶的角度看,該容器的文件系統與底層的 rootfs 沒有差別;然而從內核的角度看,則是顯式區分開來的兩個層次。當需要修改鏡像內的某個文件時,只對處於最上方的讀寫層進行了變動,不覆寫下層已有文件系統的內容,已有文件在只讀層中的原始版本仍然存在,但會被讀寫層中的新版本文件所隱藏,當 docker commit 這個修改過的容器文件系統為一個新的鏡像時,保存的內容僅為最上層讀寫文件系統中被更新過的文件。
聯合掛載是用於將多個鏡像層的文件系統掛載到一個掛載點來實現一個統一文件系統視圖的途徑,是下層存儲驅動(aufs、overlay等) 實現分層合併的方式。所以嚴格來說,聯合掛載並不是 docker 鏡像的必需技術,比如在使用 device mapper 存儲驅動時,其實是使用了快照技術來達到分層的效果。
容器讀寫層
- 容器其實是在鏡像的最上面加了一層讀寫層,在運行容器里文件改動時,會先從鏡像里要寫的文件複製到容器自己的文件系統中(讀寫層)。
- 如果容器刪除了,最上面的讀寫層也就刪除了,改動也就丟失了。
- 所以無論多少個容器共用一個鏡像,所做的寫操作都是從鏡像的文件系統中複製過來操作的,並不會修改鏡像的源文件
- 若想持久化這些改動,可以通過docker commit 將容器保存成一個新鏡像
docker鏡像從哪裡來
- Docker Hub是由Docker公司負責維護的公共註冊中心,包含大量的容器鏡像,Docker工具預設從這個公共鏡像庫下載鏡像。
- 地址:https://hub.docker.com/explore # docker官方鏡像和使用方法參考地址
- 配置鏡像加速器:https://www.daocloud.io/mirror
[root@linux-node2 ~]# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io [root@linux-node2 ~]# cat /etc/docker/daemon.json # 執行上面命令後就會將鏡像源修改成國內的地址 {"registry-mirrors": ["http://f1361db2.m.daocloud.io"]} [root@linux-node2 ~]# systemctl restart docker # 重啟docker生效
看下圖詳細介紹:
docker 的應用場景
節省項目環境部署時間(一)
單項目打包:
- 每次部署項目到測試、生產等環境,都要部署一大堆依賴的軟體、工具,時間久,出錯概率大。
- Docker主要理念就是環境打包部署,可在任意Docker Engine運行。
- 我們只需要將每個項目環境打包到鏡像,push到鏡像倉庫,當有需要部署這個項目時,
- 直接pull鏡像啟動容器,這個項目就可以訪問了!一次構建多次部署,一勞永逸。
整套項目打包
- 比如有一個產品可以整套部署到客戶那裡,以往都是派一名實施工程師到客戶那部署。
- 如果用了Docker,我們可以前期將這套項目封裝打包起來,實現一鍵部署,分分鐘鐘搞定,就不需要再派人過去了。比如官方的Docker Compose編排工具。
新開源技術試用
- 有時,我們想調研一些開源項目,我們可以直接從公共鏡像倉庫pull項目官方做好鏡像啟動容器即可。
環境一致性(二)
- 項目在開發電腦本地運行沒問題,到了測試或生產環境就運行不起來。
- Docker將項目環境打包成鏡像,可以在任何Docker Engine部署。
持續集成(三)
- 一個項目版本快速迭代的測試場景,需要一個合理的CI(持續集成)/CD(持續部署)環境支撐。
- CI/CD是一個周期性自動化項目測試流程,包括構建、部署、測試、發佈等工作,很少需要人工干預。
- Docker通過項目鏡像構建和快速部署,打通測試環境與生產環境,高度保持多個環境之間一致性。
微服務(四)
- 微服務指儘可能細粒度拆分業務程式架構,由多個獨立服務組成業務系統。
- Docker容器作為這些獨立服務的部署單元,每個服務單獨部署到一個docker容器中。
Docker 常用命令
Docker鏡像管理常用命令
docker help # 查看docker幫助 docker image --help # 查看 docker中 鏡像相關幫助 docker image ls # 查看當前所有鏡像
docker image inspect nginx # 查看指定鏡像(nginx鏡像)詳細信息 docker pull nginx:1.14 # 下載指定版本鏡像 nginx docker image rm nginx:1.14 # 刪除nginx 1.14版本 docker image save nginx > nginx.tar # 導出niginx鏡像
Docker創建容器常用命令
-d: 後臺運行容器,並返回容器ID; -i: 以交互模式運行容器,通常與 -t 同時使用; -t: 為容器重新分配一個偽輸入終端,通常與 -i 同時使用; -P: 隨機埠映射,容器內部埠隨機映射到主機的高埠 -p: 指定埠映射,格式為:主機(宿主)埠:容器埠 --name="nginx-lb": 為容器指定一個名稱; --dns 8.8.8.8: 指定容器使用的DNS伺服器,預設和宿主一致;
--dns-search example.com: 指定容器DNS搜索功能變數名稱,預設和宿主一致; -h "mars": 指定容器的hostname; -e username="ritchie": 設置環境變數; --env-file=[]: 從指定文件讀入環境變數; --cpuset="0-2" or --cpuset="0,1,2": 綁定容器到指定CPU運行; -m :設置容器使用記憶體最大值; --net="bridge": 指定容器的網路連接類型,支持 bridge/host/none/container: 四種類型; --link=[]: 添加鏈接到另一個容器; --expose=[]: 開放一個埠或一組埠; --volume , -v: 綁定一個捲 -a stdin: 指定標準輸入輸出內容類型,可選 STDIN/STDOUT/STDERR 三項;
docker run --help # 查看創建容器幫助 docker run -it centos # 創建centos鏡像併進入終端 docker run -d nginx # 後臺啟動nginx容器 docker stop 6bb09dce461f # 關閉一個容器 docker ps -l # 查看最近運行的容器 docker run -itd centos # 啟用一個偽終端守護centos容器
docker container run -d --name web3 -e test=123456 -p 8800:80 -h webhostname --restart always nginx -d # 後臺啟動nginx容器 --name web3 # 自定義容器名字(預設會是一段隨機字元串) -e test=123456 # 啟動容器添加變數 test=123456 (echo $test) -p 8800:80 # 宿主機的8800埠映射到docker容器的80埠中 -h webhostname # docker容器主機名 (a300f394af88) --restart always # 宿主機重啟自動拉起這個docker容器 nginx # 使用這個nginx鏡像啟動容器 註:http://192.168.56.12:8800/ 訪問這個docker nginx docker logs web # 查看上面啟動的web容器的日誌 docker exec -it web bash # 進入容器web
容器資源限制
記憶體限額: 允許容器最多使用500M記憶體和100M的Swap,並禁用 OOM Killer
docker run -d --name nginx03 --memory="500m" --memory-swap="600m" --oom-kill-disable nginx
CPU限額:
docker run -d --name nginx04 --cpus="1.5" nginx # 允許容器最多使用一個半的CPU
docker run -d --name nginx05 --cpus=".5" nginx # 允許容器最多使用50%的CPU
Docker管理容器常用命令
docker ps # 僅列出當前運行的容器 docker ps -l # 列出最新創建得容器 docker ps -a # 列出素有容器(包括 未運行的) docker inspect web4 # 列出指定容器的詳細信息
持久化容器
docker exec -it web4 bash # 進入容器web4中 touch 1.txt 2.txt # 對容器進行修改 docker commit web4 nginx:web4 # 將修改後的web4容器提交為一個新鏡像 nginx:web4 docker images # 可以看到 多了一個 TAG標記為 web4 的鏡像 docker run -d --name web4-1 nginx:web4 # 使用剛剛提交的鏡像web4創建一個容器web4-1 docker exec -it web4-1 bash # 進入web4-1的bash環境
從宿主機複製文件到docker容器
docker cp nginx.tar web4-1:/home # 將宿主機nginx.tar文件拷貝到容器web4-1的/home目錄中 docker exec -it web4-1 ls /home # 在容器web4-1中執行 "ls /home" 命令
容器常用查詢命令
docker logs web4-1 # 查看web4-1中控制台日誌 docker port 55f870061ed9 # 查看指定容器埠映射 docker top 00f7ddc96622 # 查看容器中有哪些進程 docker stats 00f7ddc96622 # 查看容器資源使用情況
啟動、停止、刪除 容器
docker ps -a # 列出素有容器(包括 未運行的) docker start web # 啟動容器web docker stop web # 停止容器web docker rm web
Docker 將數據掛載到容器的三種方式
Docker提供三種方式將數據從宿主機掛載到容器中
volumes:Docker管理宿主機文件系統的一部分(/var/lib/docker/volumes) 保存數據的最佳方式。
bind mounts:將宿主機上的任意位置的文件或者目錄掛載到容器中, 就像軟連接一樣。
tmpfs:掛載存儲在主機系統的記憶體中,而不會寫入主機的文件系統(不常用)。
區別: volume : 是docker的宿主機文件系統一部分,只有docker可以進行更改,其他進程不能修改 bind mounts : 是掛載在宿主機文件系統的任意位置,除了docker所有進程都可以進行修改、
管理捲:
docker volume create nginx-vol # 創建一個數據捲 nginx-vol
docker volume ls # 查看宿主機數據捲信息 docker volume inspect nginx-vol # 查看 nginx-vol 這個數據捲詳細信息 ls /var/lib/docker/volumes/nginx-vol/_data # 詳細信息中會顯示 nginx-vol 這個捲實際在宿主機位置 docker rm -f $(docker ps -a |awk '{print $1}') # 刪除所有容器
volumes:將容器中的數據持久化到宿主機中
用捲創建一個容器:
docker run -d --name=nginx-test -p 88:80 --mount src=nginx-vol,dst=/usr/share/nginx/html nginx run -d # 後臺啟動一個nginx容器 --name=nginx-test # 自定義容器名字(預設會是一段隨機字元串) -p 88:80 # 將宿主機的88埠映射到容器的80埠 --mount src=nginx-vol, # 掛載數據捲名稱nginx-vol dst=/usr/share/nginx/html # 將/usr/share/nginx/html文件掛載到nginx-vol數據捲中 nginx # 使用這個nginx鏡像啟動容器 vim /var/lib/docker/volumes/nginx-vol/_data/index.html # 修改nginx的 index.html文件可以發現頁面發生改變 http://192.168.56.12:88/
清理捲:
docker stop nginx-test # 關閉正在使用捲nginx-vol的容器nginx-test docker rm nginx-test # 刪除容器 nginx-test docker volume rm nginx-vol # 刪除捲 nginx-vol
bind mounts:將宿主機中的數據掛載到容器中
用捲創建一個容器:
docker run -d --name=nginx-test -p 88:80 --mount type=bind,src=/mnt/,dst=/usr/share/nginx/html nginx run -d # 後臺啟動一個nginx容器 --name=nginx-test # 自定義容器名字(預設會是一段隨機字元串) -p 88:80 # 將宿主機的88埠映射到容器的80埠 --mount type=bind # 將/usr/share/nginx/html文件夾掛載到宿主機/mnt/文件夾中 src=/mnt/, # 宿主機中掛載目錄 /mnt/ dst=/usr/share/nginx/html # 容器中/usr/share/nginx/html文件夾 nginx # 使用這個nginx鏡像啟動容器 docker exec -it nginx-test bash # 進入容器 cd /usr/share/nginx/html # 進入容器的掛載目錄 echo "hello I come here" > index.html # 在目錄中創建一個 index.html文件 http://192.168.56.12:88/ # 可以在頁面訪問到 index.html首頁 vim /mnt/index.html # 修改 /mnt/index.html 就等同修改容器中的index.html頁面
清理:
docker stop nginx-test # 關閉正在使用捲nginx-vol的容器nginx-test docker rm nginx-test # 刪除容器 nginx-test
註意:
- 如果源文件/目錄沒有存在,不會自動創建,會拋出一個錯誤。
- 如果掛載目標在容器中非空目錄,則該目錄現有內容將被隱藏。
Volume特點:
- 多個運行容器之間共用數據。
- 當容器停止或被移除時,該捲依然存在。
- 多個容器可以同時掛載相同的捲。
- 當明確刪除捲時,捲才會被刪除。
- 將容器的數據存儲在遠程主機或其他存儲上
- 將數據從一臺Docker主機遷移到另一臺時,先停止容器,然後備份捲的目錄(/var/lib/docker/volumes/)
Bind Mounts特點:
- 從主機共用配置文件到容器。預設情況下,掛載主機/etc/resolv.conf到每個容器,提供DNS解析。
- 在Docker主機上的開發環境和容器之間共用源代碼。例如,可以將Maven target目錄掛載到容器中,每次在Docker主機上構建Maven項目時,容器都可以 訪問構建的項目包。
- 當Docker主機的文件或目錄結構保證與容器所需的綁定掛載一致時
網路模式:
- bridge(常用)
–net=bridge
預設網路,Docker啟動後創建一個docker0網橋,預設創建的容器也是添加到這個網橋中。
- host(常用)
–net=host
容器不會獲得一個獨立的network namespace,而是與宿主機共用一個。這就意味著容器不會有自己的網卡信息,而是使用宿主
機的。容器除了網路,其他都是隔離的。
- none(不常用)
–net=none
獲取獨立的network namespace,但不為容器進行任何網路配置,需要我們手動配置。
- container(不常用)
–net=container:Name/ID
與指定的容器使用同一個network namespace,具有同樣的網路配置信息,兩個容器除了網路,其他都還是隔離的。
- 自定義網路(最佳方式)
與預設的bridge原理一樣,但自定義網路具備內部DNS發現,可以通過容器名或者主機名容器之間網路通信。
'''開啟Linux系統的IP轉發功能 ''' # 1. 出於安全考慮,Linux系統預設是禁止數據包轉發的。 # 2. 所謂轉發即當主機擁有多於一塊的網卡時,將收到的數據包轉發給其他網卡 [root@linux-node4 ~]# vim /etc/sysctl.conf net.ipv4.ip_forward=1 [root@linux-node4 ~]# systemctl restart network [root@linux-node4 ~]# sysctl net.ipv4.ip_forward # 輸出為1時則證明是成功的
測試 自定義網路 和 container
下載busybox鏡像用於測試
docker pull busybox # 下載一個測試鏡像,一些工具都有了 docker run -it busybox # 進入busybox 預設 bash docker run -it --net=host busybox # 以 host 網路模式進入bash
自定義網路模式
docker network create bs-test # 創建一個網路 bs-test docker run -it --name bs3 --net bs-test busybox # 創建容器bst加入網路bs-test docker run -it --name bs4 --net bs-test busybox # 創建容器bst加入網路bs-test ping bs3 # 在bs3和bs4容器中可以通過主機名ping通 ping bs4 docker start bs3 # 啟動容器bs3 docker exec -it bs3 sh # 進入bs3 bash環境
container網路模式
docker run -itd --name bs -p 99:80 busybox # 創建一個名字為bs的容器,並將宿主機99埠映射到80埠 docker run -d --name nginx01 --net container:bs nginx # 使用nginx鏡像創建一個容器名nginx01,加入到bs容器中 http://192.168.56.12:99/ docker exec -it bs sh # 註:bs容器中雖然沒有nginx服務,但是可以訪問nginx服務,因為nginx01容器加入了
Dockerfile 構建 nginx 項目鏡像
'''1.DOckerfile常用命令 ''' FROM python:3.6 # 指定拉取鏡像版本 ENV PYTHONUNBUFFERED 1 # 不緩衝stdin、stdout和stderr,直接把輸出重定向到文件 MAINITAINER zhangsan # 指定作者 RUN mkdri /code # 運行的linux命令 WORKDIR /code # 指定項目工作根路徑 ADD . /code/ # 將宿主機文件複製到鏡像中 COPY dj.conf /etc/nginx/conf.d # docker內部文件拷貝 VOLUME ["/data1","/data2"] # 將宿主機文件夾掛載到容器中 EXPOSE 8080 # 暴露埠 CMD ["sh","/code/start.sh"] # 容器啟動時要運行的命令 CMD ["python", "manage.py", "runserver", "0:8000"] '''2.生成鏡像並運行容器''' docker build -t nginx:v1 -f Dockerfile-nginx . # 使用Dockerfile-nginx文件生成鏡像 nginx:v1 docker push linux-node4.example.com/test/nginx:v1 # 推送鏡像到harbor中 docker run -d -p 192.168.56.14:8000:8080 nginx:v1 # 運行docker容器
使用 Dockerfile-nginx 文件構建一個基礎鏡像 nginx:v1
FROM centos:7 MAINTAINER www.ctnrs.com RUN yum install -y gcc gcc-c++ make \ openssl-devel pcre-devel gd-devel \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://nginx.org/download/nginx-1.15.5.tar.gz && \ tar zxf nginx-1.15.5.tar.gz && \ cd nginx-1.15.5 && \ ./configure --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_stub_status_module && \ make -j 4 && make install && \ rm -rf /usr/local/nginx/html/* && \ echo "ok" >> /usr/local/nginx/html/status.html && \ cd / && rm -rf nginx-1.12.2* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/nginx/sbin #COPY nginx.conf /usr/local/nginx/conf/nginx.conf WORKDIR /usr/local/nginx EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
docker build -t nginx:v1 -f Dockerfile-nginx . # 使用 Dockerfile-nginx 文件構建一個基礎鏡像 nginx:v1 -t nginx:v1 # 指定版本tag=v1 -f Dockerfile-nginx # 指定dockerfile的名稱 . # 指定上下文(比如配置文件在那個位置等) docker images # 查看 nginx:v1 鏡像是否創建成功 docker run -d --name nginx01 -p 88:80 nginx:v1 # 使用 nginx:v1 鏡像創建一個容器 nginx01 http://192.168.56.12:88/status.html # 測試是否可以訪問容器nginx01的web服務
使用nginx:v1 基礎鏡像構建一個項目鏡像
vim Dockerfile
FROM nginx:v1 COPY index.html /usr/local/nginx/html # 需要在當前目錄中創建index.html文件
docker build -t nginx:v2 -f Dockerfile . # 使用Dockerfile創建一個項目鏡像 nginx:v2
docker run -d --name nginx02 -p 89:80 nginx:v2 # 使用 nginx:v2 創建一個容器 nginx02
http://192.168.56.12:89/ # 測試訪問 容器 nginx:v2中的nginx服務
使用 Dockerfile-nginx 文件構建一個基礎鏡像 nginx:v1
FROM centos:7 MAINTAINER www.ctnrs.com RUN yum install epel-release -y && \ yum install -y gcc gcc-c++ make gd-devel libxml2-devel \ libcurl-devel libjpeg-devel libpng-devel openssl-devel \ libmcrypt-devel libxslt-devel libtidy-devel autoconf \ iproute net-tools telnet wget curl && \ yum clean all && \ rm -rf /var/cache/yum/* RUN wget http://docs.php.net/distributions/php-5.6.36.tar.gz && \ tar zxf php-5.6.36.tar.gz && \ cd php-5.6.36 && \ ./configure --prefix=/usr/local/php \ --with-config-file-path=/usr/local/php/etc \ --enable-fpm --enable-opcache \ --with-mysql --with-mysqli --with-pdo-mysql \ --with-openssl --with-zlib --with-curl --with-gd \ --with-jpeg-dir --with-png-dir --with-freetype-dir \ --enable-mbstring --with-mcrypt --enable-hash && \ make -j 4 && make install && \ cp php.ini-production /usr/local/php/etc/php.ini && \ cp sapi/fpm/php-fpm.conf /usr/local/php/etc/php-fpm.conf && \ sed -i "90a \daemonize = no" /usr/local/php/etc/php-fpm.conf && \ mkdir /usr/local/php/log && \ cd / && rm -rf php* && \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime ENV PATH $PATH:/usr/local/php/sbin COPY php.ini /usr/local/php/etc/ COPY php-fpm.conf /usr/local/php/etc/ WORKDIR /usr/local/php EXPOSE 9000 CMD ["php-fpm"]Dockerfile-php php.ini
;;;;;;;;;;;;;;;;;;;;; ; FPM Configuration ; ;;;;;;;;;;;;;;;;;;;;; ; All relative paths in this configuration file are relative to PHP's install ; prefix (/usr/local/php). This prefix can be dynamically changed by using the ; '-p' argument from the command line. ; Include one or more files. If glob(3) exists, it is used to include a bunch of ; files from a glob(3) pattern. This directive can be used everywhere in the ; file. ; Relative path can also be used. They will be prefixed by: ; - the global prefix if it's been set (-p argument) ; - /usr/local/php otherwise ;include=etc/fpm.d/*.conf ;;;;;;;;;;;;;;;;;; ; Global Options ; ;;;;;;;;;;;;;;;;;; [global] ; Pid file ; Note: the default prefix is /usr/local/php/var ; Default Value: none pid = /var/run/php-fpm.pid ; Error log file ; If it's set to "syslog", log is sent to syslogd instead of being written ; in a local file. ; Note: the default prefix is /usr/local/php/var ; Default Value: log/php-fpm.log error_log = /usr/local/php/log/php-fpm.log ; syslog_facility is used to specify what type of program is logging the ; message. This lets syslogd specify that messages from different facilities ; will be handled differently. ; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) ; Default Value: daemon ;syslog.facility = daemon ; syslog_ident is prepended to every message. If you have multiple FPM ; instances running on the same server, you can change the default value ; which must suit common needs. ; Default Value: php-fpm ;syslog.ident = php-fpm ; Log level ; Possible Values: alert, error, warning, notice, debug ; Default Value: notice log_level = warning ; If this number of child processes exit with SIGSEGV or SIGBUS within the time ; interval set by emergency_restart_interval then FPM will restart. A value ; of '0' means 'Off'. ; Default Value: 0 ;emergency_restart_threshold = 0 ; Interval of time used by emergency_restart_interval to determine when ; a graceful restart will be initiated. This can be useful to work around ; accidental corruptions in an accelerator's shared memory. ; Available Units: s(econds), m(inutes), h(ours), or d(ays) ; Default Unit: seconds ; Default Value: 0 emergency_restart_interval = 24h ; Time limit for child processes to wait for a reaction on signals from master. ; Available units: s(econds), m(inutes), h(ours), or d(ays) ; Default Unit: seconds ; Default Value: 0 process_control_timeout = 5s ; The maximum number of processes FPM will fork. This has been design to control ; the global number of processes when using dynamic PM within a lot of pools. ; Use it with caution. ; Note: A value of 0 indicates no limit ; Default Value: 0 ; process.max = 128 ; Specify the nice(2) priority to apply to the master process (only if set) ; The value can vary from -19 (highest priority) to 20 (lower priority) ; Note: - It will only work if the FPM master process is launched as root ; - The pool process will inherit the master process priority ; unless it specified otherwise ; Default Value: no set ; process.priority = -19 ; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. ; Default Value: yes daemonize = no ; Set open file descriptor rlimit for the master process. ; D