Go 部落格

在 Docker 中部署 Go 伺服器

Andrew Gerrand
2014 年 9 月 26 日

簡介

本週 Docker 宣布 Go 和其他主要語言的官方基礎映像,讓程式設計人員能以受信任且輕鬆的方式為其 Go 程式建置容器。

在本文中,我們將逐步示範如何為簡易 Go 網路應用程式建立 Docker 容器,並將該容器部署至 Google Compute Engine。如果您不熟悉 Docker,您應該在繼續閱讀前閱讀 了解 Docker

展示應用程式

在我們的示範中,我們將使用 outyet 程式,該程式來自 Go 實例存放庫,它是一個簡易的網路伺服器,會報告已發布下一版 Go 的資訊(用來支援 isgo1point4.outyet.org 等網站)。它沒有標準函式庫之外的依賴項,且執行時不需要其他資料檔案;對於網路伺服器而言,它已變得非常簡潔。

使用「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 套件來源,建置它,然後最後執行它。

ADD、RUN 和 ENTRYPOINT 步驟是所有 Go 專案的共同任務。要簡化這項任務,有一個onbuild 衍生自 golang 影像,它會自動複製套件來源、取得應用程式的相依性、建置程式和設定它在啟動時執行。

透過 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 在外部埠 6060 上公開容器埠 8080。

--name 旗標讓我們容器得到一個可預測名稱,以便更容易操作。

--rm 旗標告訴 Docker 在 outyet 伺服器離開時移除容器影像。

在容器執行時,在網頁瀏覽器中開啟 https://127.0.0.1:6060/ ,您會看到類似這樣的畫面

(如果您的 docker daemon 執行於另一台電腦(或虛擬電腦),您應該將 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 取代為您的自動建置名稱。)p>

使用 gcloud 工具 建立執行容器的虛擬機器執行個體

$ 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 檔案。

--tags 旗標將您的虛擬機器執行個體標記為 HTTP 伺服器,調整防火牆讓公眾網路介面公開埠 80。

--zone--machine-type 旗標指定虛擬機器要執行的區域和機器類型。 (要看機器類型和區域的清單,執行 gcloud compute machine-types list。)p>

在完成之後,gcloud 指令應該會列印一些關於執行個體的資訊。在輸出中,找到 networkInterfaces 部分,找出執行個體的外部 IP 地址。在幾分鐘內,您應該可以使用您的網路瀏覽器存取那個 IP,並且看到「Go 1.4 已發布了嗎?」這個網頁。

(要查看新虛擬機器執行個體的執行狀況,您可以使用 gcloud compute ssh outyet 來透過 SSH 連線其中。在那之後,嘗試 sudo docker ps 以查看哪些 Docker 容器正在執行。)p>

深入了解

這只是冰山一角—有更多您可以使用 Go、Docker 和 Google Compute Engine 執行的動作。

若要深入了解 Docker,請參閱其 完整文件

若要深入了解 Docker 和 Go,請參閱 官方 golang Docker Hub 儲存庫 和 Kelsey Hightower 的 針對靜態二進位檔最佳化 Docker 影像

若要深入了解 Docker 和 Google Compute Engine,請參閱 容器最佳化 VM 網頁google/docker-registry Docker Hub 儲存庫

下一篇:Google I/O 的 Go 和 Gopher SummerFest
上一篇:常數
部落格索引