前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何连接Docker容器

如何连接Docker容器

作者头像
大大刺猬
发布2018-08-28 16:29:52
5.6K0
发布2018-08-28 16:29:52

使用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 条评论
热度
最新
推荐阅读
目录
  • 准备工作
    • 安装Docker CE
    • 示例Node.js应用程序
      • 安装和配置PostgreSQL
        • 创建一个Hello World App
        • 连接容器到Docker主机
          • 设置Docker容器
            • 将Container连接到数据库
            • 连接两个容器
            • 使用Docker Compose
            • 结论
            • 更多信息
            相关产品与服务
            容器镜像服务
            容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档