資源:
1、github 上的 docker 手冊:https://github.com/docker-library/
2、docker-hub : https://hub.docker.com/
————————— 使用Dockerfile定制鏡像(images) ————————
【明確概念】:Dockerfile 是拿來構建自定義鏡像的,並沒有直接生成容器。只是可以再運行鏡像運行容器而已。
做容器編排以部署環境,是使用 docker-compose.yml 文件進行的,里面可能會需要用到 Dockerfile 。
原因:可以使用 commit 將容器保存為鏡像,但是不要使用這種方法。因為會把所有的改動全部記錄下來,不小心就可能導致鏡像非常的臃腫。並且這屬於黑箱操作,除了操作者本人,其他人都不知道修改了什么。
把每一層修改、安裝、構建、操作的命令都寫入一個腳本,用這個腳本來構建、定制鏡像,那么之前提及的無法重復的問題、鏡像構建透明性的問題、體積的問題就都會解決。這個腳本就是 Dockerfile。
// 一個例子:
1、創建一個最簡單的 Dockerfile 文件
// 1、創建 Dockerfile mkdir mynginx cd mynginx vim Dockerfile // 2、輸入以下內容並保存: FROM nginx RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html // 在 Dockerfile 目錄下執行,生成新的自定義 images docker build -t nginx:v3 .
———— . 表示的是【 當前目錄下的(所有內容)送給 docker-engineer 構建 images 】 ,並命名為 nginx:v3。所以一般情況下建一個空目錄,然后將Dockerfile 和所需的資源放入。再執行 build
———— 理解構建上下文對於鏡像構建是很重要的,避免犯一些不應該的錯誤。比如有些初學者在發現 COPY /opt/xxxx /app
不工作后,於是干脆將 Dockerfile
放到了硬盤根目錄去構建,結果發現 docker build
執行后,在發送一個幾十 GB 的東西,極為緩慢而且很容易構建失敗。那是因為這種做法是在讓 docker build
打包整個硬盤,這顯然是使用錯誤。
Dockerfile 部分指令:
// FROM 指定基礎鏡像 FROM nginx // RUN 執行命令。每一條 RUN 都會生成一層,一個需求盡量使用&&,這樣就減少了 RUN ,即減少了分層 RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html RUN yum update && yum install -y vim \ python-dev // COPY: 源路徑下的 package.json 復制到新一層的鏡像路徑/usr/src/app COPY package.json /usr/src/app/ // WORKDIR 指定工作目錄。指定下層工作的目錄為容器內的/data,盡量使用絕對目錄 WORKDIR /data // ADD 添加,ADD能自動解壓文件。以下例子最終 hello 在/data/test 下 WORKDIR /data ADD hello test/ // COPY 拷貝 與ADD類似,只是不能解壓縮文件。 WORKDIR /DATA COPY hello test/ // CMD 執行命令 CMD ["python", "app.py"] // ENV 設置環境變量 定義 NAME=Happy Feet,那么之后就可以使用 $NAME 來執行了 ENV VERSION=1.0 DEBUG=on \ NAME="Happy Feet"
// VOLUMES
掛載 // EXPOSE 端口暴露 EXPOSE <端口1> [<端口2>...]
—— 所以你應該創建 Dockerfile ,分享給別人,就可以創建一個跟你一樣的鏡像了。而不是直接分享鏡像給別人。
———————— 多容器應用 - Docker-compose ————————
docker-compose 是官方開源項目,負責實現對 Docker 容器集群的快速編排,部署分布式應用。
通過一個單獨的 docker-compose.yml
模板文件(YAML 格式)來定義一組相關聯的應用容器為一個項目(project)
// 安裝docker-compose:
mac 和 win 下已經默認裝好了。而 linux 下得手動安裝。有三種方式,這里我們采用二進制包的方式
$ sudo curl -L https://github.com/docker/compose/releases/download/1.23.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose // 測試 docker-compose docker-compose --version
// 一般使用步驟:
1、創建一個空目錄。
1、定義 Dockerfile,方便遷移到任何地方
2、編寫 docker-compose.yml 文件
3、運行 docker-compose up 啟動服務
// docker-compose 使用舉例:
下面我們用 Python
來建立一個能夠記錄頁面訪問次數的 web 網站。
1、建一個空目錄:
mkdir -p /data/test
2、在該空文件下建立 app.py,輸入以下內容:
from flask import Flask from redis import Redis app = Flask(__name__) redis = Redis(host='redis', port=6379) @app.route('/') def hello(): count = redis.incr('hits') return 'Hello World! 該頁面已被訪問 {} 次。\n'.format(count) if __name__ == "__main__": app.run(host="0.0.0.0", debug=True)
3、編寫 Dockerfile 文件:
FROM python:3.6-alpine ADD . /code WORKDIR /code RUN pip install redis flask CMD ["python", "app.py"]
4、編寫 docker-compose.yml 文件
version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
—— 此時該空目錄下共有:app.py、Dockerfile、docker-compose.yml 文件
5、執行 docker-compose 項目
docker-compose up
———— 這樣,你訪問本地5000端口就會增加一次訪問次數。
// yml 模板文件的說明:
示例文件:
version: '3' services: phpfpm: image: yoogr/phpfpm:0.0.1 container_name: ct-phpfpm build: context: . dockerfile: Dockerfile expose: - "9000" volumes: - ${DIR_WWW}:${DIR_WWW}:rw - ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro - ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw - ./conf/supervisor/conf.d:/etc/supervisor/conf.d/:ro - ./log/php-fpm/:/var/log/php-fpm/:rw - ./log/supervisor/:/var/log/supervisor/:rw command: supervisord -n links: - mysql:mysql - redis:redis
—— 每個 service 代表一個 container,container 可以通過 dockerhub的 image 來創建,也可以從本地的 Dockerfile build 出來的鏡像來創建。
—— yml 文件可以指定 volume 和 network。
某個服務需要用到 Dockerfile build 出來的鏡像,則在 docker-compose 里面指明 build 的文本位置和文件名。請查看以上例子。
—— 這里有點問題,就是使用了 links,這個官方已經不建議使用了。link 其實相當於在容器 host 文件添加了名字,類似於172.17.0.3 mysql
—— 請使用 network,就是自己創建一個bridge,然后把所有 container 都連在上面。
// 如下,是一個使用了 network 和 volumes 參數的例子(放在與 service 同層的關系):
version: '3' services: wordpress: image: wordpress ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_PASSWORD: examplepass network: - my-bridge db: image: mysql:5.7 environment: MYSQL_DATABASE: wordpress MYSQL_ROOT_PASSWORD: 123456 volumes: - mysql-data:/var/lib/mysql networks: - my-bridge volumes: my-data networks: my-bridge: driver:bridge
—— 以上例子。網絡和卷的定義類似於 docker network create
和 docker volume create。
如果你沒有指定連接network,那么才會使用 link。
// docker-compose 常用命令:
// up 該命令十分強大,它將嘗試自動完成包括構建鏡像,(重新)創建服務,啟動服務,並關聯服務相關容器的一系列操作 docker-compose up [options] [SERVICE...] // -d 比較常用,不會打印過程。 //down 停止 up 命令所啟動的容器,並移除網絡。——這里需要特別注意,up 啟動的,不應該使用rm 去刪除,因為這樣無法刪除網絡 docker-compose down // run 命令 docker-compose run [options] [-p PORT...] [-e KEY=VAL...] SERVICE [COMMAND] [ARGS...] // ps 查看項目中的所有容器 docker-compose ps // restart 重啟服務 docker-compose restart [options] [SERVICE...]。 // stop start 停止和開啟容器 docker-compose stop xxx docker-compose start xxx // kill 強制停止某容器 docker-compose kill -s SIGINT // rm 刪除指定或所有的服務容器 docker-compose rm -f [service] // build 重建某個容器,在 Dockerfile 發生了改變的時候,可以重建image。然后再 up 運行起來所有的容器 docker-composer build //重建所有容器 docker-compose build xxx //重建指定容器 //exec 進入某個容器 docker-compose exec -it ct-phpfpm /bin/bash // images 查看compose文件中包含的鏡像 docker-compose images // pull 拉取依賴 docker-compose pull [options] [SERVICE...] // push 推送服務依賴的鏡像到 Docker 鏡像倉庫。 docker-compose push // port 打印某容器的映射端口 docker-compose port xxx // config 驗證 docker-compose 文件格式是否正確 docker-compose config// top 查看所有容器的進程 docker-compose top
————————占位符