Docker概念
Docker是開發人員和系統管理員 使用容器開發,部署和運行應用程序的平臺。使用Linux容器部署應用程序稱爲容器化。容器不是新的,但它們用於輕鬆部署應用程序。html
容器化愈來愈受歡迎,由於容器是:前端
- 靈活:即便是最複雜的應用也能夠集裝箱化。
- 輕量級:容器利用並共享主機內核。
- 可互換:您能夠即時部署更新和升級。
- 便攜式:您能夠在本地構建,部署到雲,並在任何地方運行。
- 可擴展:您能夠增長並自動分發容器副本。
- 可堆疊:您能夠垂直和即時堆疊服務。
圖像和容器
經過運行映像啓動容器。一個圖像是一個可執行的包,其中包括運行應用程序所需的全部內容-的代碼,運行時,庫,環境變量,和配置文件。node
甲容器是圖像的運行時實例-當被執行時(即,與狀態的圖像,或者用戶進程)在存儲器中什麼圖像變得。您可使用該命令查看正在運行的容器列表docker ps
,就像在Linux中同樣。python
容器和虛擬機
一個容器中運行原生 Linux和共享主機與其它容器的內核。它運行一個獨立的進程,不佔用任何其餘可執行文件的內存,使其輕量級。linux
相比之下,虛擬機(VM)運行一個完整的「客戶」操做系統,經過虛擬機管理程序對主機資源進行虛擬訪問。一般,VM提供的環境比大多數應用程序須要的資源更多。web
準備Docker環境
在支持的平臺上安裝維護版本的Docker Community Edition(CE)或Enterprise Edition(EE) 。redis
完整的Kubernetes集成docker
- Docker for Mac上的Kubernetes 可在17.12 Edge(mac45)或 17.12 Stable(mac46)及更高版本中使用。
- Docker for Windows 上的Kubernetes僅在 18.02 Edge(win50)和更高邊緣通道中提供。
安裝Dockershell
測試Docker版本
-
運行
docker --version
並確保您擁有受支持的Docker版本:數據庫root@jwh-virtual-machine:~# docker version Client: Version: 18.09.0 API version: 1.39 Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:48:57 2018 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 18.09.0 API version: 1.39 (minimum version 1.12) Go version: go1.10.4 Git commit: 4d60db4 Built: Wed Nov 7 00:16:44 2018 OS/Arch: linux/amd64 Experimental: false
-
運行
docker info
或(docker version
without--
)查看有關docker安裝的更多詳細信息:root@jwh-virtual-machine:~# docker info Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 0 Server Version: 18.09.0 Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39 runc version: 4fc53a81fb7c994640722ac585fa9ca548971871 init version: fec3683 Security Options: apparmor seccomp Profile: default Kernel Version: 4.10.0-28-generic Operating System: Ubuntu 16.04.3 LTS OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 1.87GiB Name: jwh-virtual-machine ID: SS2S:4LLL:PDXM:NC7D:FIW6:LCP5:H4FP:SMHU:WNTR:LTVH:YDRQ:R567 Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false Product License: Community Engine WARNING: No swap limit support root@jwh-virtual-machine:~#
要避免權限錯誤(以及使用
sudo
),請將您的用戶添加到docker
組中。閱讀更多。
測試Docker安裝
-
經過運行簡單的Docker鏡像hello-world來測試您的安裝是否有效 :
root@jwh-virtual-machine:~# docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/ root@jwh-virtual-machine:~#
-
列出
hello-world
下載到您的計算機的圖像:root@jwh-virtual-machine:~# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest fce289e99eb9 7 days ago 1.84kB root@jwh-virtual-machine:~#
-
列出
hello-world
在顯示其消息後退出的容器(由圖像生成)。若是它仍在運行,您將不須要--all
選項:root@jwh-virtual-machine:~# docker container ls --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e240e4b70492 hello-world "/hello" About a minute ago Exited (0) About a minute ago compassionate_ride root@jwh-virtual-machine:~#
在過去,若是您要開始編寫Python應用程序,那麼您的第一個業務是在您的計算機上安裝Python運行時。可是,這會致使您的計算機上的環境很是適合您的應用程序按預期運行,而且還須要與您的生產環境相匹配。
使用Docker,您能夠將可移植的Python運行時做爲映像獲取,無需安裝。而後,您的構建能夠在應用程序代碼旁邊包含基本Python映像,確保您的應用程序,其依賴項和運行時都一塊兒運行。
這些可移植圖像由稱爲a的東西定義Dockerfile
。
使用定義容器 Dockerfile
Dockerfile
定義容器內環境中發生的事情。對網絡接口和磁盤驅動器等資源的訪問在此環境中進行虛擬化,該環境與系統的其餘部分隔離,所以您須要將端口映射到外部世界,並具體說明要「複製」到哪些文件那個環境。可是,在執行此操做以後,您能夠預期Dockerfile
在此處定義的應用程序的構建 在其運行的任何位置都會徹底相同。
Dockerfile
建立一個空目錄。將目錄(cd
)更改爲新目錄,建立一個名爲Dockerfile的文件,將如下內容複製並粘貼到該文件中,而後保存。記下解釋新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 COPY . /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
。讓咱們建立下一個。
應用程序自己
再建立兩個文件,requirements.txt
而後app.py
將它們放在同一個文件夾中Dockerfile
。這完成了咱們的應用程序,您能夠看到它很是簡單。當上述Dockerfile
被內置到的圖像,app.py
而且 requirements.txt
是由於存在Dockerfile
的COPY
命令,並從輸出app.py
是經過HTTP得益於訪問EXPOSE
命令。
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自己),咱們應該指望在這裏使用它的嘗試失敗併產生錯誤消息。
注意:在容器內部訪問容器ID時,訪問主機名稱,這相似於正在運行的可執行文件的進程ID。
而已!您不須要Python或requirements.txt
系統中的任何內容,也不須要構建或運行此映像將它們安裝在您的系統上。看起來你並無真正創建一個Python和Flask的環境,但你有。
構建應用程序
咱們準備構建應用程序。確保您仍處於新目錄的頂層。這是ls
應該顯示的內容:
root@jwh-virtual-machine:/testdocker# ls app.py Dockerfile requirements.txt
如今運行build命令。這將建立一個Docker鏡像,咱們將使用該--tag
選項命名。使用-t
,若是你想使用一個較短的選項。
docker build --tag=friendlyhello .
root@jwh-virtual-machine:/testdocker# docker build --tag=friendlyhello . Sending build context to Docker daemon 5.12kB Step 1/7 : FROM python:2.7-slim 2.7-slim: Pulling from library/python 177e7ef0df69: Pull complete f6b2167b8d5a: Pull complete 432b044db3f9: Pull complete 7356f8556c46: Pull complete Digest: sha256:9fc89764be6827ef37feefc0f921953e7762a75b68f159483a5d877f34df0f47 Status: Downloaded newer image for python:2.7-slim ---> f090c78858fa Step 2/7 : WORKDIR /app ---> Running in 9cdd56ae3b3b Removing intermediate container 9cdd56ae3b3b ---> 36654f1a1077 Step 3/7 : COPY . /app ---> 895d9a50a195 Step 4/7 : RUN pip install --trusted-host pypi.python.org -r requirements.txt ---> Running in c296c6f17cb4 Collecting Flask (from -r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl (91kB) Collecting Redis (from -r requirements.txt (line 2)) Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB) Collecting itsdangerous>=0.24 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl Collecting Jinja2>=2.10 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl (126kB) Collecting Werkzeug>=0.14 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl (322kB) Collecting click>=5.1 (from Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB) Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->Flask->-r requirements.txt (line 1)) Downloading https://files.pythonhosted.org/packages/bc/3a/6bfd7b4b202fa33bdda8e4e3d3acc719f381fd730f9a0e7c5f34e845bd4d/MarkupSafe-1.1.0-cp27-cp27mu-manylinux1_x86_64.whl Installing collected packages: itsdangerous, MarkupSafe, Jinja2, Werkzeug, click, Flask, Redis Successfully installed Flask-1.0.2 Jinja2-2.10 MarkupSafe-1.1.0 Redis-3.0.1 Werkzeug-0.14.1 click-7.0 itsdangerous-1.1.0 Removing intermediate container c296c6f17cb4 ---> c3bfa7d44503 Step 5/7 : EXPOSE 80 ---> Running in d7f0b929aaa5 Removing intermediate container d7f0b929aaa5 ---> 07a38d8ea172 Step 6/7 : ENV NAME World ---> Running in d582ade4179d Removing intermediate container d582ade4179d ---> 81103116670b Step 7/7 : CMD ["python", "app.py"] ---> Running in d485dcaee07f Removing intermediate container d485dcaee07f ---> 4fd1ea568df5 Successfully built 4fd1ea568df5 Successfully tagged friendlyhello:latest root@jwh-virtual-machine:/testdocker#
你的構建鏡像在哪裏?它位於您機器的本地Docker鏡像註冊表中:
root@jwh-virtual-machine:/testdocker# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE friendlyhello latest 4fd1ea568df5 46 seconds ago 131MB hello-world latest fce289e99eb9 7 days ago 1.84kB python 2.7-slim f090c78858fa 9 days ago 120MB root@jwh-virtual-machine:/testdocker#
注意標籤是如何默認的latest
。標籤選項的完整語法相似於--tag=friendlyhello:v0.0.1
。
Linux用戶的故障排除
代理服務器設置
代理服務器能夠在啓動並運行後阻止與Web應用程序的鏈接。若是您位於代理服務器後面,請使用如下
ENV
命令將如下行添加到Dockerfile中,以指定代理服務器的主機和端口:# Set proxy server, replace host:port with values for your servers ENV http_proxy host:port ENV https_proxy host:port
DNS設置
DNS配置錯誤可能會產生問題
pip
。您須要設置本身的DNS服務器地址才能pip
正常工做。您可能想要更改Docker守護程序的DNS設置。您能夠/etc/docker/daemon.json
使用dns
密鑰編輯(或建立)配置文件,以下所示:{ "dns": ["your_dns_address", "8.8.8.8"] }
在上面的示例中,列表的第一個元素是DNS服務器的地址。第二項是Google的DNS,可在第一項沒法使用時使用。
在繼續以前,請保存
daemon.json
並從新啓動docker服務。
sudo service docker restart
修復後,重試運行該
build
命令。運行該應用程序
運行應用程序,使用如下方法將計算機的端口4000映射到容器的已發佈端口80
-p
:docker run -p 4000:80 friendlyhelloroot@jwh-virtual-machine:/testdocker# docker run -p 4000:80 friendlyhello * Serving Flask app "app" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)您應該看到Python正在爲您的應用程序提供服務的消息
http://0.0.0.0:80
。可是該消息來自容器內部,它不知道您將該容器的端口80映射到4000,從而生成正確的URLhttp://localhost:4000
。在Web瀏覽器中轉到該URL,以查看在網頁上提供的顯示內容。
您還能夠
curl
在shell中使用該命令來查看相同的內容。$ curl http://192.168.146.128:4000/ % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 118 100 118 0 0 951 0 --:--:-- --:--:-- --:--:-- 951
<h3>Hello World!</h3><b>Hostname:</b> 9ceedd5fdd97<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>這個端口從新映射的
4000:80
演示之間的差別EXPOSE
中的Dockerfile
哪些的publish
運行時值設置docker run -p
。在後面的步驟中,將主機上的端口4000映射到容器中的端口80並使用http://localhost
。點擊
CTRL+C
你的終端退出。在Windows上,顯式中止容器
在Windows系統上,
CTRL+C
不會中止容器。所以,首先鍵入CTRL+C
以獲取提示(或打開另外一個shell),而後鍵入docker container ls
以列出正在運行的容器,而後docker container stop <Container NAME or ID>
中止容器。不然,當您嘗試在下一步中從新運行容器時,會從守護程序收到錯誤響應。如今讓咱們以分離模式在後臺運行應用程序:
root@jwh-virtual-machine:/testdocker# docker run -d -p 4000:80 friendlyhello 3d69fad2ec47daa1b0a51341e30839afde9918ccf9436975b3d7861366319280您得到應用程序的長容器ID,而後被踢回終端。您的容器正在後臺運行。您還能夠看到縮寫的容器ID
docker container ls
(而且在運行命令時均可以互換):root@jwh-virtual-machine:/testdocker# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3d69fad2ec47 friendlyhello "python app.py" 39 seconds ago Up 38 seconds 0.0.0.0:4000->80/tcp frosty_knuth如今
docker container stop
用來結束這個過程,使用CONTAINER ID
以下:root@jwh-virtual-machine:/testdocker# docker container stop 3d69fad2ec47 3d69fad2ec47
分享你的形象
爲了演示咱們剛剛建立的內容的可移植性,讓咱們上傳咱們構建的圖像並在其餘地方運行它。畢竟,當您想要將容器部署到生產環境時,您須要知道如何推送到註冊表。
註冊表是存儲庫的集合,存儲庫是圖像的集合 - 相似於GitHub存儲庫,除了代碼已經構建。註冊表上的賬戶能夠建立許多存儲庫。該
docker
CLI使用泊塢窗的公共註冊表默認狀況下。注意:咱們在這裏使用Docker的公共註冊表只是由於它是免費和預先配置的,但有許多公共註冊表可供選擇,您甚至可使用Docker Trusted Registry設置本身的私有註冊表。
使用您的Docker ID登陸
若是您沒有Docker賬戶,請在hub.docker.com上註冊一個賬戶 。記下您的用戶名。
登陸本地計算機上的Docker公共註冊表。
root@jwh-virtual-machine:/testdocker# docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: jiangwenhui Password: WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded root@jwh-virtual-machine:/testdocker#標記圖像
將本地映像與註冊表上的存儲庫相關聯的表示法是
username/repository:tag
。標籤是可選的,但建議使用,由於它是註冊管理機構用來爲Docker鏡像提供版本的機制。爲上下文提供存儲庫和標記有意義的名稱,例如get-started:part2
。這會將圖像放入get-started
存儲庫並將其標記爲part2
。如今,把它們放在一塊兒來標記圖像。
docker tag image
使用您的用戶名,存儲庫和標記名稱運行,以便將圖像上載到所需的目標位置。該命令的語法是:docker tag image username/repository:tag例如:
root@jwh-virtual-machine:/testdocker# docker tag friendlyhello jiangwenhui/jiang-test:part2 root@jwh-virtual-machine:/testdocker#
運行docker image ls以查看新標記的圖像。
root@jwh-virtual-machine:/testdocker# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE jiangwenhui/jiang-test part2 4fd1ea568df5 18 minutes ago 131MB friendlyhello latest 4fd1ea568df5 18 minutes ago 131MB hello-world latest fce289e99eb9 7 days ago 1.84kB python 2.7-slim f090c78858fa 10 days ago 120MB root@jwh-virtual-machine:/testdocker#發佈圖像
將標記的圖像上傳到存儲庫:
docker push username/repository:tag例如:
root@jwh-virtual-machine:/testdocker# docker push jiangwenhui/jiang-test:part2 The push refers to repository [docker.io/jiangwenhui/jiang-test] a4c803cedd56: Pushed 84fc571f8852: Pushed 286d546f86e5: Pushed af9628477752: Mounted from library/python f1bd403e5041: Mounted from library/python b7fcb2747224: Mounted from library/python 7b4e562e58dc: Mounted from library/python part2: digest: sha256:596c068cdbdb26bc60feebfaab0ad1a7ffb71627440832bc3d2de89a69be8674 size: 1788 root@jwh-virtual-machine:/testdocker#完成後,此上傳的結果將公開發布。若是您登陸到Docker Hub,則會在其中看到新圖像及其pull命令。
從遠程存儲庫中拉出並運行映像
從如今開始,您可使用
docker run
如下命令在任何計算機上使用和運行您的應用程序:docker run -p 4000:80 jiangwenhui/jiang-test:part2若是映像在計算機上不可用,則Docker會從存儲庫中提取映像。
$ docker run -p 4000:80 jiangwenhui/jiang-test:part2 Unable to find image 'jiangwenhui/jiang-test:part2' locally part2: Pulling from jiangwenhui/jiang-test:part2 10a267c67f42: Already exists f68a39a6a5e4: Already exists 9beaffc0cf19: Already exists 3c1fe835fb6b: Already exists 4c9f1fa8fcb8: Already exists ee7d8f576a14: Already exists fbccdcced46e: Already exists Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068 Status: Downloaded newer image for jiangwenhui/jiang-test:part2 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)不管在哪裏
docker run
執行,它都會提取您的圖像,以及Python和全部依賴項requirements.txt
,並運行您的代碼。它們都在一個整潔的小包中一塊兒旅行,你不須要在主機上安裝任何東西,以便Docker運行它。回顧和備忘單(可選)
如下是此頁面中基本Docker命令的列表,以及一些相關的命令,若是您想在繼續以前稍微探索一下。
docker build -t friendlyhello . # Create image using this directory's Dockerfile docker run -p 4000:80 friendlyhello # Run "friendlyname" mapping port 4000 to 80 docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode docker container ls # List all running containers docker container ls -a # List all containers, even those not running docker container stop <hash> # Gracefully stop the specified container docker container kill <hash> # Force shutdown of the specified container docker container rm <hash> # Remove specified container from this machine docker container rm $(docker container ls -a -q) # Remove all containers docker image ls -a # List all images on this machine docker image rm <image id> # Remove specified image from this machine docker image rm $(docker image ls -a -q) # Remove all images from this machine docker login # Log in this CLI session using your Docker credentials docker tag <image> username/repository:tag # Tag <image> for upload to registry docker push username/repository:tag # Upload tagged image to registry docker run username/repository:tag # Run image from a registry
關於服務
在分佈式應用程序中,應用程序的不一樣部分稱爲「服務」。例如,若是您想象一個視頻共享站點,它可能包括一個用於在數據庫中存儲應用程序數據的服務,一個用戶在上傳內容後在後臺進行視頻轉碼的服務,一個用於前端的服務,等等。
服務實際上只是「生產中的容器」。服務只運行一個映像,但它編碼了映像的運行方式 - 它應該使用哪些端口,應該運行多少個容器副本,以便服務具備所需的容量,以及等等。擴展服務會更改運行該軟件的容器實例的數量,從而爲流程中的服務分配更多計算資源。
幸運的是,使用Docker平臺定義,運行和擴展服務很是容易 - 只需編寫一個
docker-compose.yml
文件便可。你的第一個
docker-compose.yml
檔案一個
docker-compose.yml
文件是一個YAML文件,它定義瞭如何Docker容器在生產中應表現。
docker-compose.yml
將此文件保存爲
docker-compose.yml
您想要的任何位置。確保已將 第2部分中建立的圖像推送到註冊表,並經過替換 圖像詳細信息進行更新。.yml
username/repo:tag
version: "3" services: web: # replace username/repo:tag with your name and image details image: username/repo:tag 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執行如下操做:
pull咱們在步驟2中上傳的鏡像從註冊表。
將該映像的5個實例做爲一個被調用的服務運行
web
,限制每一個實例使用,最多10%的CPU(跨全部內核)和50MB的RAM。若是一個失敗,當即重啓容器。
將主機上的端口4000映射到
web
端口80。指示
web
容器經過稱爲負載平衡的網絡共享端口80webnet
。(在內部,容器自己web
在短暫的端口發佈到 80端口。)
webnet
使用默認設置(負載平衡的覆蓋網絡)定義網絡。運行新的負載均衡應用
在咱們
docker stack deploy
首先運行命令以前:docker swarm init如今讓咱們來運行吧。您須要爲您的應用程序命名。在這裏,它被設置爲
getstartedlab
:docker stack deploy -c docker-compose.yml getstartedlabroot@jwh-virtual-machine:/opt/new_test# docker stack deploy -c docker-compose.yml getstartedlab Creating network getstartedlab_webnet Creating service getstartedlab_web root@jwh-virtual-machine:/opt/new_test#
咱們的單個服務堆棧在一臺主機上運行已部署映像的5個容器實例。咱們來調查吧。
在咱們的應用程序中獲取一項服務的服務ID:
root@jwh-virtual-machine:/opt/new_test# docker service ls ID NAME MODE REPLICAS IMAGE PORTS zyuwks3ygy7e getstartedlab_web replicated 5/5 jiangwenhui/jiang-test:part2 *:4000->80/tcp查找服務的輸出
web
,並附上您的應用名稱。若是您將其命名爲與此示例中顯示的相同,則名稱爲getstartedlab_web
。還列出了服務ID,以及副本數,映像名稱和公開端口。在服務中運行的單個容器稱爲任務。任務被賦予以數字遞增的惟一ID,最多爲
replicas
您定義 的數量docker-compose.yml
。列出您的服務任務:root@jwh-virtual-machine:/opt/new_test# docker service ps getstartedlab_web ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS z6vocrwm597t getstartedlab_web.1 jiangwenhui/jiang-test:part2 jwh-virtual-machine Running Running about a minute ago 6lvqrzq2ufmm getstartedlab_web.2 jiangwenhui/jiang-test:part2 jwh-virtual-machine Running Running about a minute ago hz7286ekji8n getstartedlab_web.3 jiangwenhui/jiang-test:part2 jwh-virtual-machine Running Running about a minute ago h2utp2d2p6bp getstartedlab_web.4 jiangwenhui/jiang-test:part2 jwh-virtual-machine Running Running about a minute ago v9z1ud2wmsm6 getstartedlab_web.5 jiangwenhui/jiang-test:part2 jwh-virtual-machine Running Running about a minute ago root@jwh-virtual-machine:/opt/new_test#若是您只列出系統上的全部容器,則任務也會顯示,但不會被服務過濾:
root@jwh-virtual-machine:/opt/new_test# docker container ls -q 62640ce74d5e 6bb416f77d19 5109bc435ff1 6b492c384d09 c074d76eedf1 root@jwh-virtual-machine:/opt/new_test#您能夠
curl -4 http://localhost:4000
連續屢次運行,或者在瀏覽器中轉到該URL並點擊刷新幾回。不管哪一種方式,容器ID都會發生變化,從而證實負載均衡; 對於每一個請求,以循環方式選擇5個任務中的一個來響應。容器ID與上一個命令(
docker container ls -q
)的輸出匹配。擴展應用程序
您能夠經過更改
replicas
值docker-compose.yml
,保存更改並從新運行docker stack deploy
命令來擴展應用程序:docker stack deploy -c docker-compose.yml getstartedlabDocker執行就地更新,無需首先拆除堆棧或殺死任何容器。
如今,從新運行
docker container ls -q
以查看已從新配置的已部署實例。若是放大副本,則會啓動更多任務,從而啓動更多容器。取下應用程序和羣
將應用程序刪除
docker stack rm
:docker stack rm getstartedlab取下羣。
docker swarm leave --force雖然鍵入
docker run
很簡單,但生產中容器的真正實現是將其做爲服務運行。服務在Compose文件中編碼容器的行爲,此文件可用於擴展,限制和從新部署咱們的應用程序。使用啓動服務的相同命令,能夠在運行時應用對服務的更改:docker stack deploy
。在此階段要探索的一些命令:
docker stack ls # List stacks or apps docker stack deploy -c <composefile> <appname> # Run the specified Compose file docker service ls # List running services associated with an app docker service ps <service> # List tasks associated with an app docker inspect <task or container> # Inspect task or container docker container ls -q # List container IDs docker stack rm <appname> # Tear down an application docker swarm leave --force # Take down a single node swarm from the manager