Go 博客

使用 Docker 部署 Go 服务器

Andrew Gerrand
2014 年 9 月 26 日

简介

本周 Docker 宣布 Go 和其他主要语言的官方 基础镜像,为程序员提供了一种可靠且简便的方式来为他们的 Go 程序构建容器。

在本文中,我们将逐步介绍一个创建用于简单 Go Web 应用程序的 Docker 容器并将其部署到 Google Compute Engine 的方法。如果您不熟悉 Docker,请在继续阅读之前阅读 了解 Docker

演示应用程序

为了演示,我们将使用 outyet 程序,该程序来自 Go 示例存储库,这是一个简单的 Web 服务器,用于报告下一个版本的 Go 是否已发布(旨在为类似于 isgo1point4.outyet.org 的网站提供支持)。它没有标准库以外的任何依赖关系,并且在运行时不需要额外的文件;对于一个 Web 服务器来说,这已经相当简单了。

使用“go get”命令在您的 工作区 中获取并安装 outyet

$ go get golang.org/x/example/outyet

编写 Dockerfile

outyet 目录中用以下内容替换名为 Dockerfile 的文件

# Start from a Debian image with the latest version of Go installed
# and a workspace (GOPATH) configured at /go.
FROM golang

# Copy the local package files to the container's workspace.
ADD . /go/src/golang.org/x/example/outyet

# Build the outyet command inside the container.
# (You may fetch or manage dependencies here,
# either manually or with a tool like "godep".)
RUN go install golang.org/x/example/outyet

# Run the outyet command by default when the container starts.
ENTRYPOINT /go/bin/outyet

# Document that the service listens on port 8080.
EXPOSE 8080

这个 Dockerfile 指定了如何构建运行 outyet 的容器,从基本依赖项开始(安装了 Go 的 Debian 系统;官方 golang docker 镜像),添加 outyet 包源代码,构建它,最后运行它。

ADDRUNENTRYPOINT 步骤是任何 Go 项目的常见任务。为了简化此过程,golang 镜像有一个 onbuild 变体,它会自动复制包源代码,获取应用程序依赖项,构建程序,并配置它在启动时运行。

使用 onbuild 变体,Dockerfile 更加简洁

FROM golang:onbuild
EXPOSE 8080

构建并运行镜像

outyet 包目录调用 Docker 来使用 Dockerfile 构建镜像

$ docker build -t outyet .

这将从 Docker Hub 中获取 golang 基础镜像, 将包源代码复制到其中,在镜像中构建包,并将生成的镜像标记为 outyet

要从生成的镜像运行容器,请执行以下操作

$ docker run --publish 6060:8080 --name test --rm outyet

--publish 标记告诉 docker 将容器的端口 8080 发布到外部端口 6060 上。

--name 标记为我们的容器提供了一个可预测的 名称,以便更容易地进行操作。

--rm 标记告诉 docker 在 outyet 服务器退出时删除容器镜像。

容器运行后,在 Web 浏览器中打开 https://127.0.0.1:6060/,您应该看到类似于以下内容的内容

(如果您的 docker 守护进程在另一台机器上运行(或在虚拟机中运行),您应该将 localhost 替换为该机器的地址。如果您在 OS X 或 Windows 上使用 boot2docker ,可以使用 boot2docker ip 命令找到该地址。)

现在我们已经验证了镜像可以正常工作,请从另一个终端窗口关闭正在运行的容器

$ docker stop test

在 Docker Hub 上创建一个存储库

Docker Hub 是我们之前从中拉取 golang 镜像的容器注册中心,它提供了一个名为 自动构建 的功能,可以从 GitHub 或 BitBucket 存储库构建镜像。

通过将 Dockerfile 提交到存储库并为它创建 自动构建,任何安装了 Docker 的人都可以使用单个命令下载并运行我们的镜像。(我们将在下一节看到它的用途。)

要设置自动构建,请将 Dockerfile 提交到您在 GitHubBitBucket 上的存储库中,在 Docker Hub 上创建一个帐户,并按照 创建自动构建 的说明操作。

完成后,您可以使用自动构建的名称来运行您的容器

$ docker run goexample/outyet

(将 goexample/outyet 替换为您创建的自动构建的名称。)

将容器部署到 Google Compute Engine

Google 提供了 经过容器优化的 Google Compute Engine 镜像,使您可以轻松地启动运行任意 Docker 容器的虚拟机。在启动时,实例上运行的程序会读取一个配置文件,该配置文件指定要运行的容器,获取容器镜像,并运行它。

创建一个 containers.yaml 文件,该文件指定要运行的 docker 镜像以及要公开的端口

version: v1beta2
containers:
- name: outyet
  image: goexample/outyet
  ports:
  - name: http
    hostPort: 80
    containerPort: 8080

(请注意,我们将容器的端口 8080 发布为外部端口 80,这是用于提供 HTTP 流量的默认端口。并且,同样,您应该将 goexample/outyet 替换为您自动构建的名称。)

使用 gcloud 工具 创建运行容器的 VM 实例

$ gcloud compute instances create outyet \
    --image container-vm-v20140925 \
    --image-project google-containers \
    --metadata-from-file google-container-manifest=containers.yaml \
    --tags http-server \
    --zone us-central1-a \
    --machine-type f1-micro

第一个参数 (outyet) 指定了实例名称,这是一个方便的管理标签。

--image 和 --image-project 标记指定要使用的特殊容器优化系统镜像(请按原样复制这些标记)。

--metadata-from-file 标记将您的 containers.yaml 文件提供给 VM。

--tags 标记将您的 VM 实例标记为 HTTP 服务器,并调整防火墙以在公共网络接口上公开端口 80。

--zone--machine-type 标记指定运行 VM 的区域以及要运行的机器类型。(要查看机器类型和区域列表,请运行 gcloud compute machine-types list。)

完成后,gcloud 命令应该会打印一些有关该实例的信息。在输出中,找到 networkInterfaces 部分以找到该实例的外部 IP 地址。在几分钟内,您应该能够使用 Web 浏览器访问该 IP 并看到“Go 1.4 是否已发布?”页面。

(要查看新 VM 实例上的情况,可以使用 gcloud compute ssh outyet 命令登录到该实例。从那里,尝试使用 sudo docker ps 命令查看哪些 Docker 容器正在运行。)

了解更多

这仅仅是冰山一角——您可以使用 Go、Docker 和 Google Compute Engine 做更多的事情。

要详细了解 Docker,请查看他们的 完整文档

要详细了解 Docker 和 Go,请查看 官方 golang Docker Hub 存储库 以及 Kelsey Hightower 的 针对静态 Go 二进制文件的优化 Docker 镜像

要详细了解 Docker 和 Google Compute Engine,请查看 经过容器优化的 VM 页面 以及 google/docker-registry Docker Hub 存储库

下一篇文章:Go 在 Google I/O 和 Gopher SummerFest 上
上一篇文章:常量
博客索引