docker入門使用教程


Docker概念

Docker是開發人員和系統管理員 使用容器開發,部署和運行應用程序的平台。使用Linux容器部署應用程序稱為容器化容器不是新的,但它們用於輕松部署應用程序。

容器化越來越受歡迎,因為容器是:

  • 靈活:即使是最復雜的應用也可以集裝箱化。
  • 輕量級:容器利用並共享主機內核。
  • 可互換:您可以即時部署更新和升級。
  • 便攜式:您可以在本地構建,部署到雲,並在任何地方運行。
  • 可擴展:您可以增加並自動分發容器副本。
  • 可堆疊:您可以垂直和即時堆疊服務。

容器是便攜式的

圖像和容器

通過運行映像啟動容器。一個圖像是一個可執行的包,其中包括運行應用程序所需的所有內容-的代碼,運行時,庫,環境變量,和配置文件。

容器是圖像的運行時實例-當被執行時(即,與狀態的圖像,或者用戶進程)在存儲器中什么圖像變得。您可以使用該命令查看正在運行的容器列表docker ps,就像在Linux中一樣。

容器和虛擬機

一個容器中運行原生 Linux和共享主機與其它容器的內核。它運行一個獨立的進程,不占用任何其他可執行文件的內存,使其輕量級。

相比之下,虛擬機(VM)運行一個完整的“客戶”操作系統,通過虛擬機管理程序對主機資源進行虛擬訪問。通常,VM提供的環境比大多數應用程序需要的資源更多。

容器堆棧示例 虛擬機堆棧示例

准備Docker環境

支持的平台安裝維護版本的Docker Community Edition(CE)或Enterprise Edition(EE) 

完整的Kubernetes集成

安裝Docker

 

測試Docker版本

  1. 運行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

     

  2. 運行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安裝

  1. 通過運行簡單的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:~# 
  2. 列出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:~# 
  3. 列出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.pyrequirements.txt讓我們創建下一個。

應用程序本身

再創建兩個文件,requirements.txt然后app.py將它們放在同一個文件夾中Dockerfile這完成了我們的應用程序,您可以看到它非常簡單。當上述Dockerfile被內置到的圖像,app.py並且 requirements.txt是因為存在DockerfileCOPY命令,並從輸出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 friendlyhello
root@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,從而生成正確的URL http://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存儲庫,除了代碼已經構建。注冊表上的帳戶可以創建許多存儲庫。dockerCLI使用泊塢窗的公共注冊表默認情況下。

注意:我們在這里使用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容器通過稱為負載平衡的網絡共享端口80 webnet(在內部,容器本身web在短暫的端口發布到 80端口。)

  • webnet使用默認設置(負載平衡的覆蓋網絡)定義網絡。

運行新的負載均衡應用

在我們docker stack deploy首先運行命令之前

docker swarm init

現在讓我們來運行吧。您需要為您的應用程序命名。在這里,它被設置為 getstartedlab

docker stack deploy -c docker-compose.yml getstartedlab
root@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)的輸出匹配

擴展應用程序

您可以通過更改replicasdocker-compose.yml,保存更改並重新運行docker stack deploy命令來擴展應用程序

docker stack deploy -c docker-compose.yml getstartedlab

Docker執行就地更新,無需首先拆除堆棧或殺死任何容器。

現在,重新運行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

     

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM