Docker概念
Docker是開發人員和系統管理員 使用容器開發,部署和運行應用程序的平台。使用Linux容器部署應用程序稱為容器化。容器不是新的,但它們用於輕松部署應用程序。
容器化越來越受歡迎,因為容器是:
- 靈活:即使是最復雜的應用也可以集裝箱化。
- 輕量級:容器利用並共享主機內核。
- 可互換:您可以即時部署更新和升級。
- 便攜式:您可以在本地構建,部署到雲,並在任何地方運行。
- 可擴展:您可以增加並自動分發容器副本。
- 可堆疊:您可以垂直和即時堆疊服務。
圖像和容器
通過運行映像啟動容器。一個圖像是一個可執行的包,其中包括運行應用程序所需的所有內容-的代碼,運行時,庫,環境變量,和配置文件。
甲容器是圖像的運行時實例-當被執行時(即,與狀態的圖像,或者用戶進程)在存儲器中什么圖像變得。您可以使用該命令查看正在運行的容器列表docker ps
,就像在Linux中一樣。
容器和虛擬機
一個容器中運行原生 Linux和共享主機與其它容器的內核。它運行一個獨立的進程,不占用任何其他可執行文件的內存,使其輕量級。
相比之下,虛擬機(VM)運行一個完整的“客戶”操作系統,通過虛擬機管理程序對主機資源進行虛擬訪問。通常,VM提供的環境比大多數應用程序需要的資源更多。
![]() |
![]() |
准備Docker環境
在支持的平台上安裝維護版本的Docker Community Edition(CE)或Enterprise Edition(EE) 。
完整的Kubernetes集成
- Docker for Mac上的Kubernetes 可在17.12 Edge(mac45)或 17.12 Stable(mac46)及更高版本中使用。
- Docker for Windows 上的Kubernetes僅在 18.02 Edge(win50)和更高邊緣通道中提供。
測試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