如何连接Docker容器

使用Docker来容纳应用程序时,通常的做法是在单独的容器中运行应用程序的每个组件。例如,一个网站可能有一个Web服务器,应用程序和数据库,每个都在自己的容器中运行。

配置容器以相互通信和主机可能是一个挑战。本指南将使用一个简单的示例应用程序来演示Docker容器通信的基础知识。该应用程序将包含一个Node.js应用程序,该应用程序从PostgreSQL数据库中读取数据。

准备工作

安装Docker CE

您需要安装带有Docker CE的Linode才能按照本指南中的步骤操作。

这些步骤使用官方Ubuntu存储库安装Docker Community Edition(CE)。要在其他发行版上安装,请参阅官方安装页面

  1. 删除系统上可能存在的旧版Docker: sudo apt remove docker docker-engine docker.io
  2. 确保你拥有必要的软件包以允许使用Docker的存储库: sudo apt install apt-transport-https ca-certificates curl software-properties-common
  3. 添加Docker的GPG密钥: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  4. 验证GPG密钥的指纹: sudo apt-key fingerprint 0EBFCD88 应该看到类似于以下内容的输出: pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) <docker@docker.com> sub 4096R/F273FCD8 2017-02-22
  5. 添加stableDocker库: sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  6. 更新软件包索引并安装Docker CE: sudo apt update sudo apt install docker-ce
  7. 添加部分Linux帐户到docker组: sudo usermod -aG docker exampleuser 需要重新启动shell会话才能使此更改生效。
  8. 通过运行内置的“Hello World”程序检查安装是否成功: docker run hello-world

示例Node.js应用程序

本指南中使用的示例应用程序将是一个简单的Node.js应用程序,它将从PostgreSQL数据库中读取“Hello world”并将其打印到控制台。在本节中,您将在不使用容器的情况下在Linode上构建和测试应用程序。

安装和配置PostgreSQL

  1. 更新你的系统: sudo apt update && sudo apt upgrade
  2. 安装PostGreSQL: sudo apt install postgresql postgresql-contrib
  3. 更改postgres用户密码: sudo passwd postgres
  4. postgres数据库用户设置密码: su - postgres psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';"
  5. 为示例应用程序创建数据库并连接它: createdb nodejs psql nodejs
  6. 将“Hello world”添加到数据库: nodejs=# CREATE TABLE hello (message varchar); nodejs=# INSERT INTO hello VALUES ('Hello world'); nodejs=# \q
  7. 创建数据库转储以供以后使用: pg_dumpall > backup.sql
  8. 退出postgresLinux用户: exit
  9. 将数据转储复制到你的主目录: sudo cp /var/lib/postgresql/backup.sql ~/.
  10. 由于你将从容器(拥有IP地址d,而不是localhost)连接到此数据库,因此您需要编辑PostgreSQL配置文件以允许来自远程地址的连接。在文本编辑器中打开/etc/postgresql/9.5/main/postgresql.conf。取消注释行--listen_addresses,并将其设置为“*”: # /etc/postgresql/9.5/main/postgresql.conf #------------------------------------------------------------------------------#CONNECTIONS AND AUTHENTICATION #-------------------------------------- listen_addresses = '*' 设置被监听地址
  11. 启用并启动postgresql服务: sudo systemctl enable postgresql sudo systemctl start postgresql

创建一个Hello World App

  1. 安装Node和NPM: curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs
  2. 切换到主目录并创建并进入一个目录: cd mkdir app && cd app
  3. 使用文本编辑器,创建app.js并添加以下内容: const { Client } = require('pg') const client = new Client({ user: 'postgres', host: 'localhost', database: 'nodejs', password: 'newpassword', port: 5432 }) client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })

此应用程序使用pgNPM模块(node-postgres)连接到上一节中创建的数据库。然后查询'hello'表(返回“Hello world”消息)并将响应记录到控制台。把'newpassword'替换postgres您在上一节中设置的数据库用户密码。 注意pg模块还可以使用环境变量来配置客户端连接。这是生产应用程序的推荐选项。在node-postgres文档中阅读有关环境变量的更多信息。

  1. 安装pg模块: npm install pg
  2. 测试应用程序: node app.js 如果数据库配置正确,控制台上将显示“Hello world”。

连接容器到Docker主机

本节说明了Node.js应用程序从Docker容器运行并连接到Docker主机上运行的数据库的用例。

设置Docker容器

  1. 返回主目录: cd
  2. 创建一个Dockerfile来运行Node.js应用程序: # Dockerfile FROM debian RUN apt update -y && apt install -y gnupg curl RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt install -y nodejs COPY app/ /home/ ENTRYPOINT tail -F /dev/null
  3. 将Dockerfile创建的镜像拷贝到app/目录下。编辑app.js以允许应用程序连接到database主机而不是localhost: # app/ app.js const client = new Client({ user: 'postgres', host: 'database', database: 'nodejs', password: 'newpassword', port: 5432 })
  4. 从Dockerfile构建镜像: docker build -t node_image .

将Container连接到数据库

  1. Docker自动设置通过网络接口访问的默认网桥docker0。使用ifconfigip查看此界面: ifconfig docker0 输出将类似于以下内容: docker0 Link encap:Ethernet HWaddr 02:42:1e:e8:39:54 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:1eff:fee8:3954/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3848 errors:0 dropped:0 overruns:0 frame:0 TX packets:5084 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:246416 (246.4 KB) TX bytes:94809688 (94.8 MB) Docker主机(你的Linode)的内部IP地址是172.17.0.1。
  2. 允许PostgreSQL接受来自Docker接口的连接。/etc/postgresql/9.5/main/pg_hba.conf在文本编辑器中打开并添加以下行: # /etc/postgresql/9.5/main/pg_hba.conf1 host all postgres 172.17.0.0/16 password 由于172.17.0.1是Docker主机的IP,因此主机上的所有容器都将具有172.17.0.0/16网段内的IP地址。
  3. 重启数据库: sudo systemctl restart postgresql
  4. 启动容器: docker run -d --add-host=database:172.17.0.1 --name node_container node_image 该--add-host选项定义了一个database主机,它指向Docker主机的IP地址。database在运行时声明主机,而不是硬编码应用程序中的IP地址,有助于保持容器可重用。
  5. 在容器内,用ping测试与database主机的连接: docker exec -it node_container ping database
  6. 每个Docker容器都从172.17.0.0/16块中分配了自己的IP地址。找到此容器的IP地址ip: docker exec -it node_container ip addr show eth0 你可以通过从Docker主机ping该地址来测试此连接。
  7. 运行应用程序: docker exec -it node_container node home/app.js

如果配置成功,你将在控制台看见“Hello world”。

连接两个容器

在本节中,应用程序和数据库将在不同的容器中运行。您可以使用Docker Hub中的官方postgres镜像并加载之前创建的SQL。

特别说明:您不应将生产数据库数据存储在Docker容器中。应将容器视为临时实体:如果容器意外崩溃或重新启动,则数据库中的所有数据都将丢失。

  1. 停止并删除Node.js容器: docker stop node_container docker rm node_container
  2. postgres镜像: docker pull postgres
  3. 确保你的backup.sql文件位于当前工作目录中,然后运行postgres镜像: docker run -d -v `pwd`:/backup/ --name pg_container postgres -v选项将当前工作目录安装到/backup/新容器上的目录中。
  4. 新容器将自动启动postgres数据库并创建postgres用户。输入容器并加载SQL转储: docker exec -it pg_container bash cd backup psql -U postgres -f backup.sql postgres exit
  5. 再次运行节点镜像。这一次,不用--add-host选项,而使用--link选项将容器连接到pg_container: docker run -d --name node_container --link=pg_container:database node_image 该命令将链接pg_container主机名下database
  6. 在node_container中打开/etc/hosts,并确认已建立链接: docker exec -it node_container cat /etc/hosts 应该有一行类似于以下内容: 172.17.0.2 database pg_container 这表明pg_container已分配给IP地址172.17.0.2,并按database预期通过主机名连接到此容器。
  7. 由于Node.js应用程序仍然希望连接到database主机上的PostgreSQL数据库,因此无需进一步更改。你应该能够像以前一样运行应用程序: docker exec -it node_container node home/app.js

使用Docker Compose

每次启动容器时使用--link--host选项都很麻烦。如果您的服务器或任何容器崩溃,则必须手动重新连接。对于需要持续可用性的任何应用程序而言,这不是理想情况。幸运的是,Docker提供了Docker Compose来管理多个容器,并在启动时自动将它们链接在一起。本节将使用Docker Compose重现上一节的结果。

注意:有关Docker Compose以及如何编写docker-compose.yml配置文件的更全面说明,请参阅完整的Docker Compose指南。

  1. 安装Docker Compose: sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
  2. 在与Dockerfile相同的目录中,创建一个docker-compose.yml包含以下内容的文件: #docker-compose.yml version: '3' services: database: image: postgres container_name: pg_container volumes: - pgdata:/var/lib/postgresql/data app: build: . container_name: node_container links: - database environment: - PGPASSWORD=newpassword - PGUSER=postgres - PGDATABASE=nodejs - PGHOST=database - PGPORT=5432 depends_on: - database volumes: pgdata: {}

当你使用此文件运行Docker Compose时,它将从上一会话中创建pg_containernode_container。和之前一样,数据库容器将使用官方PostgreSQL镜像,而app容器将从Dockerfile构建。该links条目与前面使用--linkrun命令中的选项具有相同的功能。

  1. Docker Compose还允许您设置环境值,因此您可以简化应用程序以使用这些值,而不是将值硬编码。编辑app.js以删除这些值: # app.js const express = require('express') const { Client } = require('pg') const client = new Client() client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })

  1. 删除以前的容器: docker rm -f node_container pg_container
  2. 使用Docker Compose调出容器: docker-compose up -d
  3. 将示例数据加载到新容器中: docker cp backup.sql pg_container:/ docker exec -it pg_container psql -U postgres -f backup.sql postgres
  4. app.js从app容器运行: docker exec -it node_container node home/app.js

该应用程序应该像以前一样运行

结论

默认情况下,Docker会自动为每个容器和Docker主机分配IP地址。您可以使用这些地址手动连接容器之间的服务(假设您的防火墙允许连接)。

但是,Docker还为这些连接提供了许多方便的包装器,以帮助您加速和简化连接过程。您可以将Docker主机连接到具有唯一主机名的容器,或直接链接两个容器。使用Docker Compose可以进一步简化此过程,允许您在docker-compose.yml文件中声明连接,以便在启动容器时自动建立连接。

本指南中未介绍其他连接选项。例如,您可以运行容器--net="host",它将与Docker主机共享该容器的网络堆栈:localhost容器上将指向localhostDocker主机。您还可以在每个Docker容器上公开端口,或配置默认桥接网络以获得更大的灵活性。有关这些选项的更深入讨论,请参阅下面“更多信息”部分中的链接。

更多信息

有关此主题的其他信息,您可能需要参考以下资源。虽然提供这些是希望它们有用,但请注意,我们无法保证外部托管材料的准确性或及时性。

本文的版权归 大大刺猬 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏信安之路

手把手教你制作漏洞复现环境

在学习的过程中, 是否看到别人搭建的 Exploit 练习平台心痒痒呢? 通过本篇教程的学习, 将手把手教你搭建属于自己的漏洞测试利用环境, 不管是自己学习还有...

22900
来自专栏散尽浮华

Docker集中化web界面管理平台-Shipyard部署记录

之前介绍了DOcker的web管理工具DockerUI,下面介绍下Docker的另一个web界面管理工具Shipyard的使用。Shipyard(github)...

613100
来自专栏云计算

Docker for Devs:创建一个开发版镜像

Docker for Devs 系列包括以下6篇文章,这是第二篇。

35390
来自专栏古时的风筝

Docker:镜像操作和容器操作

镜像操作 列出镜像: $ sudo docker images REPOSITORY TAG IMAGE ID...

231100
来自专栏云计算

使用ACS和Kubernetes部署Red Hat JBoss Fuse

Red Hat JBoss Fuse十多年来一直是构建Java Web / RESTful服务的事实标准。但是,你该如何在当今以云为中心的世界中有效运行?如您所...

278100
来自专栏雨过天晴

原 荐 docker清理

20620
来自专栏IT派

用Docker玩转PHP环境配置

是否有这样的场景,你搞了一个项目,在本地开发时需要搭建环境,放到线上时也需要搭建环境,到公司想暗戳戳玩一下要搭建环境,不搭还不行,因为你的环境依赖还挺多。这个时...

23620
来自专栏纯洁的微笑

Docker(四):Docker 三剑客之 Docker Compose

前两篇文章我们介绍了 Dockerfile 的使用Docker(二):Dockerfile 使用介绍,我们知道使用一个 Dockerfile 模板文件可以定义一...

43730
来自专栏python爬虫实战之路

docker配置redis集群和scrapyd服务

Redis集群的配置方式我们上一篇已经介绍过了,而且使用Dockerfile配置文件我们也介绍了,不过介绍的并不详细,可能有些人看不明白,这篇我们再介绍一些Do...

15930
来自专栏运维技术迷

Veeam Backup & Replication(二):添加虚拟化主机和配置备份存储

一、添加虚拟化主机 veeam可以添加单个ESXi主机,也可以添加vCenter服务器,因为做实验,就添加一台ESXI主机为例吧。 1.1 选择 Virtual...

520120

扫码关注云+社区

领取腾讯云代金券