docker入门使用教程
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