前面已經講解過docker的一些基礎使用,鏡像創建的操作過程,如果大量容器需要同時部署,一個一個容器進行服務器上的部署,估計要瘋掉,在使用上我們需要找到更好更便捷的使用方式,今天要講解的容器編排工具docker-compose就是其中之一
簡介
Compose是一個用於定義和運行多容器Docker應用程序的工具。使用Compose,您可以使用YAML文件來配置應用程序的服務。然后,使用單個命令,您可以從配置中創建並啟動所有服務。
docker-compose作為容器編排工具,專門用於處理多容器部署問題,當然,目前對於系統運維有更好的處理方式,比如k8s,由於筆者並不是系統運維人員,所以不會涉及這么深入,本文也只是淺顯的介紹下docker-compose,記錄下自己的使用過程
特征
單個主機上的多個隔離環境
compose使用項目名稱將環境彼此隔離。每次我們使用docker-compose創建多個容器時,其會自動幫我們將彼此環境進行隔離,非常有用
- 在開發主機上,創建單個環境的多個副本,例如當您要為項目的每個功能分支運行穩定副本時
- 在CI服務器上,為了防止構建相互干擾,可以將項目名稱設置為唯一的構建號
- 在共享主機或開發主機上,以防止可能使用相同服務名稱的不同項目相互干擾
這里可以使用-p
參數來設置此次compose啟動的項目名,可以自行安裝測試下
僅重新創建已更改的容器
compose會緩存用於創建容器的配置。當重新啟動未更改的服務時,compose將重新使用現有容器。重用容器意味着您可以非常快速地更改環境。比如當我們使用compose啟動一組容器時,如果我們更新了其中一個容器所使用的鏡像,當我們執行更新容器命令時,docker-compose不會更新所有容器,只會更新那個改變了鏡像的容器
共享文件和項目配置
compose支持在compose文件中定義變量。您可以使用這些變量為不同環境或不同用戶自定義組合,參考官方文檔:
https://docs.docker.com/compose/extends/
使用步驟
- 定義您的應用程序環境,Dockerfile以便可以在任何地方進行復制
- 定義構成應用程序的服務,docker-compose.yml 以便它們可以在隔離的環境中一起運行
- Run docker-compose up和Compose啟動並運行整個應用程序
安裝
首先需要安裝docker環境,然后再安裝docker-compose,筆者是在centos7環境下安裝的
1.安裝依賴環境
sudo yum install epel-release
sudo yum install -y python-pip
2.安裝docker-compose
sudo pip install docker-compose
使用示例
以我自己的網站為例,目前個人網站部署在阿里雲服務器上,以使用docker-compose進行部署,目前環境如下:
- nginx前置機
- solo博客服務
- 數據庫mysql
關於博客系統的部分,本人已部署過ghost,wordpress,太復雜感覺不適合我,目前選擇了輕量級博客solo,后期有更適合的可能會進行替換
雖然只有一台雲服務器,本人還是部署了集群服務,雖然沒什么用,只是想多實踐下,nginx單節點,solo雙節點,mysql單節點,目前個人博客環境就是這樣
配置文件
創建docker-compose.yml文件,vim操作修改如下,其中有些地方解釋下:
在配置文件中,將需要保存的文件映射到宿主機上,即你自己的服務器真實目錄或文件上,方便下次進行遷移或者容器出現無法恢復的問題時重新部署,其中需要注意的是,如果沒有進行網絡相關配置,且沒有將端口與主機進行映射,則其會自行創建網絡,使得這組容器可以相互訪問,但是外界不能訪問,宿主機也不行。這里將nginx容器進行了端口映射,這組容器只能通過這兩個端口進行訪問
nginx的配置文件中,如果配置了upstream,這里對應的server寫solo_1:8080即可,對應配置文件,你可以把這里理解成這組容器中這個域名對應solo_1容器服務,至於nginx的配置文件部分,就不貼出來了,沒有太多復雜的部分,自行找資料進行配置
version: '2'
services:
solo_db:
image: mysql:latest
container_name: solo_db
volumes:
- /var/solomysql/data:/var/lib/mysql # 將數據庫文件映射到本地服務器便於遷移
restart: always
expose:
- 3306
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_USER: root
MYSQL_PASSWORD: so
MYSQL_DATABASE: so
solo_1:
depends_on:
- solo_db
image: b3log/solo:v3.6.3
container_name: solo_1
volumes: # 日志配置文件和皮膚映射便於我配置修改,添加皮膚
- /root/solodata/log4j.properties:/opt/solo/WEB-INF/classes/log4j.properties
- /root/solodata/skins/:/opt/solo/skins/
links:
- solo_db
expose:
- 8080
restart: always
environment:
RUNTIME_DB: MYSQL
JDBC_USERNAME: so
JDBC_PASSWORD: so
JDBC_DRIVER: com.mysql.jdbc.Driver
JDBC_URL: jdbc:mysql://solo_db:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
command: --listen_port=8080 --server_port=80 --server_scheme=https --server_host=www.gclearning.cn
solo_2:
depends_on:
- solo_db
image: b3log/solo:v3.6.3
container_name: solo_2
volumes:
- /root/solodata/log4j.properties:/opt/solo/WEB-INF/classes/log4j.properties
- /root/solodata/skins/:/opt/solo/skins/
links:
- solo_db
expose:
- 8080
restart: always
environment:
RUNTIME_DB: MYSQL
JDBC_USERNAME: so
JDBC_PASSWORD: so
JDBC_DRIVER: com.mysql.jdbc.Driver
JDBC_URL: jdbc:mysql://solo_db:3306/solo?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
command: --listen_port=8080 --server_port=80 --server_scheme=https --server_host=www.gclearning.cn
solonginx:
image: docker.io/nginx:1.0 # 我自己將官方nginx鏡像時區修改了下重新打包的鏡像,用官方鏡像也可,日志部分時間相差8個時區
container_name: solonginx
links:
- solo_1
- solo_2
ports:
- 80:80
- 443:443
volumes: # nginx配置文件,靜態資源,證書等目錄映射到宿主機上,可根據需要自行配置
- /root/solonginx/nginxconfig/nginx.conf:/etc/nginx/nginx.conf
- /root/solonginx/nginxconfig/conf.d:/etc/nginx/conf.d
- /root/solonginx/log/:/var/log/nginx/
- /root/solonginx/nginxconfig/cert/:/etc/nginx/cert/
- /root/solonginx/nginxconfig/www/:/var/www/
運行容器組
在你所創建的docker-compose目錄下,執行如下命令,即可啟動一組容器
docker-compose up -d
docker-compose ps
查看容器狀態,處於up狀態,則表示容器創建成功,如下:
如果我們修改了nginx配置,只需要對其中的nginx容器進行重啟即可,執行如下命令:
docker-compose restart solonginx
總結
docker-compose為我們同時操作一組容器提供了便捷的方式,多個服務之間需要進行編排,端口,網絡,硬件配置等在我們定義好了之后可以方便我們進行部署,遷移,如果之后出現了無法恢復的問題,我們可以將落地的數據進行遷移,瞬間啟動一組環境來對外提供服務,極大的解放了運維人員的生產力,也不用再為安裝一堆依賴環境而頭疼,也不用再記錄各個服務之間的關系,配置等而憂慮
在學習與使用docker的過程中,越來越感覺到這種技術對運維的重要性(雖然我不是運維),開發人員當然也需要去了解其使用,會讓你看到一個更開闊的技術領域
以上內容如有問題歡迎指出,筆者驗證后將及時修正,謝謝