Go 博客

使用 Docker 部署 Go 服务器

Andrew Gerrand
2014 年 9 月 26 日

引言

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

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

演示应用程序

在我们的演示中,我们将使用Go 示例代码库中的outyet程序,这是一个简单的 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://: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 SSH 进入它。从那里,尝试 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 at Google I/O and Gopher SummerFest
上一篇文章:Constants
博客索引