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

     

 

 

 

posted @ 2019-01-08 16:10  py哥  阅读(9921)  评论(0编辑  收藏  举报