Dockerfile
Dockerfile
定義容器內環境中發生的事情。對網絡接口和磁盤驅動器等資源的訪問在此環境中進行虛擬化,該環境與系統的其餘部分隔離,所以您須要將端口映射到外部世界,並具體說明要「複製」到哪些文件那個環境。可是,在執行此操做以後,您能夠預期Dockerfile
在此處定義的應用程序的構建 在其運行的任何位置都會徹底相同。html
Dockerfile
建立一個空目錄。將目錄(cd
)更改成新目錄,建立一個名爲的文件Dockerfile
前端
# Use an official Python runtime as a parent image FROM python:2.7-slim # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app ADD . /app # Install any needed packages specified in requirements.txt RUN pip install --trusted-host pypi.python.org -r requirements.txt # Make port 80 available to the world outside this container EXPOSE 80 # Define environment variable ENV NAME World # Run app.py when the container launches CMD ["python", "app.py"]
這Dockerfile
是指咱們還沒有建立的幾個文件,即 app.py
和requirements.txt
。讓咱們建立下一個。python
再建立兩個文件,requirements.txt
而後app.py
將它們放在同一個文件夾中Dockerfile
。這完成了咱們的應用程序,您能夠看到它很是簡單。當上述Dockerfile
被內置到的圖像,app.py
而且 requirements.txt
是由於存在Dockerfile
的ADD
命令,並從輸出app.py
是經過HTTP得益於訪問EXPOSE
命令。web
requirements.txt
Flask Redis
app.py
from flask import Flask from redis import Redis, RedisError import os import socket # Connect to Redis redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2) app = Flask(__name__) @app.route("/") def hello(): try: visits = redis.incr("counter") except RedisError: visits = "<i>cannot connect to Redis, counter disabled</i>" html = "<h3>Hello {name}!</h3>" \ "<b>Hostname:</b> {hostname}<br/>" \ "<b>Visits:</b> {visits}" return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits) if __name__ == "__main__": app.run(host='0.0.0.0', port=80)
如今咱們看到pip install -r requirements.txt
爲Python安裝Flask和Redis庫,應用程序打印環境變量NAME
,以及調用的輸出socket.gethostname()
。最後,由於Redis沒有運行(由於咱們只安裝了Python庫,而不是Redis自己),咱們應該指望在這裏使用它的嘗試失敗併產生錯誤消息。redis
注意:在容器內部訪問容器ID時,訪問主機名稱,這相似於正在運行的可執行文件的進程ID。docker
$ ls Dockerfile app.py requirements.txt
如今運行build命令。這會建立一個Docker鏡像,使用-t
它來標記,所以它具備友好的名稱。shell
docker build -t friendlyhello .
$ docker images REPOSITORY TAG IMAGE ID friendlyhello latest 326387cea398
登陸本地計算機上的Docker公共註冊表。數據庫
$ docker login
將本地映像與註冊表上的存儲庫相關聯的表示法是 username/repository:tag
flask
docker tag image wangshu19930818/friendlyhello:v1
將標記的圖像上傳到存儲庫:瀏覽器
docker pushwangshu19930818/friendlyhello:v1
從如今開始,您可使用docker run
如下命令在任何計算機上使用和運行您的應用程序:
docker run -p 4000:80 wangshu19930818/friendlyhello:v1
在分佈式應用程序中,應用程序的不一樣部分稱爲「服務」。
若是想象一個視頻共享站點,它可能包括一個用於將應用程序數據存儲在數據庫中的服務,一個用於在後臺進行視頻轉碼的服務。用戶上傳內容,前端服務等。
服務實際上只是「生產中的容器」。服務只運行一個映像,但它編碼了映像的運行方式 - 它應該使用哪些端口,應該運行多少個容器副本,以便服務具備所需的容量,以及等等。
擴展服務會更改運行該軟件的容器實例的數量,從而爲流程中的服務分配更多計算資源。
使用Docker平臺定義,運行和擴展服務很是容易 - 只需編寫一個docker-compose.yml
文件便可。
docker-compose.yml
檔案一個docker-compose.yml
文件是一個YAML文件,它定義瞭如何Docker容器在生產中應表現。
docker-compose.yml
將此文件保存爲docker-compose.yml
您想要的任何位置。
version: "3" services: web: # replace username/repo:tag with your name and image details image: wangshu19930818/friendlyhello:v1 deploy: replicas: 5 resources: limits: cpus: "0.1" memory: 50M restart_policy: condition: on-failure ports: - "4000:80" networks: - webnet networks: webnet:
該docker-compose.yml
文件告訴Docker執行如下操做:
拉上傳的圖像從註冊表。
將該映像的5個實例做爲一個被調用的服務運行web
,限制每一個實例使用,最多10%的CPU(跨全部內核)和50MB的RAM。
若是一個失敗,當即重啓容器。
將主機上的端口4000映射到web
端口80。
指示web
容器經過稱爲負載平衡的網絡共享端口80 webnet
。(在內部,容器自己web
在短暫的端口發佈到 80端口。)
webnet
使用默認設置(負載平衡的覆蓋網絡)定義網絡。
在咱們docker stack deploy
首先運行命令以前:
docker swarm init
注意:若是您沒有運行,docker swarm init
則會收到「此節點不是羣集管理器」的錯誤。
docker stack deploy -c docker-compose.yml getstartedlab
咱們的單個服務堆棧在一臺主機上運行已部署映像的5個容器實例。
在咱們的應用程序中獲取一項服務的服務ID:
docker ps
列出服務任務:
docker service ps getstartedlab_web
若是您只列出系統上的全部容器,則任務也會顯示,但不會被服務過濾:
docker ps -q
curl -4 http://localhost:4000
連續屢次運行,或者在瀏覽器中轉到該URL並點擊刷新幾回。
能夠經過更改replicas
值docker-compose.yml
,保存更改並從新運行docker stack deploy
命令來擴展應用程序:
docker stack deploy -c docker-compose.yml getstartedlab
Docker執行就地更新,無需首先拆除堆棧或殺死任何容器。
如今,從新運行docker ps -q
以查看已從新配置的已部署實例。
若是放大副本,則會啓動更多任務,從而啓動更多容器。
將應用程序刪除docker stack rm
:
docker stack rm getstartedlab
取下羣。
docker swarm leave --force