GKE上webアプリケーション構築方法紹介

記事の目的

・GKEについての紹介
・簡単なwebアプリケーションを構築して、GKEにデプロイする方法の紹介

A. GKEの概要

Googleを中心に開発されているDockerコンテナの管理ソフトウェアKubernetes(k8s)のクラスタを簡単にデプロイできるサービスです。Dockerコンテナの実行にはGCE(Google Compute Engine)を利用します。

各基本概念

クラスタ(Cluster)

クラスタは1つの小さいクラウドと考えることができます。なぜかと言うとクラスタの中でVMからネットワーク、アクセス権限など色々なリソースを設定とコントロールできるからです。

クラスタは複数Nodeで構成されて、各Node間に内部ネットワークがあります。

Node

Nodeは1つのVMです。マスターNodeとワーカーNodeがあります。ワーカーNode上にkubeletサービスが稼働されていて、マスターNodeからコントロール信号を受け取ります。

Pod

Podはk8sの中でコントロールできる一番小さい単位です。通常Podは1つのアプリケーションまたは1つの稼働できる単位モジュールです。利用の目的及び稼働アプリケーションのタイプによって違うPodの種類を利用しないといけません。各種のPodの具体的は下記のリンクを参考にしてください。
https://kubernetes.io/docs/concepts/workloads/controllers/

まとめると、クラスタはk8s上に仮想ネットワークで複数VMが繋がれていて、小さいバージョンのクラウドが作られます。クラスタに色々なアプリケーションをデプロイでき、スケールイン・アウト設定が出来ます。アプリケーションはどのNodeで稼働されるかと考える必要はなく、全てk8sがコントロールします。

B. webアプリケーションをGKEにデプロイする方法

・webアプリケーション作成
・Dockerイメージをビルドする
・DockerイメージをGCP Container Registryにプッシュする
・Container RegistryからGKEにデプロイする

1. webアプリケーション作成

この記事中では、golangを利用して、labstack echoフレームワークでwebアプリケーションを作成します。

アプリケーションのフォルダ構成
simplewebapp
├── README.md
├── go.mod
├── go.sum
├── simplewebapp.Dockerfile
├── simplewebapp.deployment.yaml
└── webapp
    ├── handler
    │   └── simplewebapp_handler.go
    └── simplewebapp.go
simplewebapp.go
package main

import (
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"

	"github.com/devsamurai/gke/simplewebapp/webapp/handler"
)

// Default Server Port
const DEFAULT_SERVER_PORT = ":80"

func main() {
	// Echo instance
	e := echo.New()

	// Middleware
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())
	e.Use(middleware.CORS())

	// Route => handler
	e.GET("/", handler.SimpleWebHandler{}.Index)

	e.GET("/ping", handler.SimpleWebHandler{}.Ping)

	// Start server
	e.Logger.Fatal(e.Start(DEFAULT_SERVER_PORT))
}
simplewebapp_handler.go
package handler

import (
	"net/http"

	"github.com/labstack/echo/v4"
)

type SimpleWebHandler struct {
}

func (sh SimpleWebHandler) Index(c echo.Context) error {
	return c.String(http.StatusOK, "Hello, World!\n")
}

func (sh SimpleWebHandler) Ping(c echo.Context) error {
	return c.String(http.StatusOK, "Pong!\n")
}
ローカルで実行してみる
cd path_to_simplewebapp
go run webapp/simplewebapp.go

2. Dockerイメージをビルドする

Dockerfileを準備する

simplewebapp.Dockerfile
FROM golang:1.12 as build_env

WORKDIR /go/src/github.com/devsamurai/gke/simplewebapp

COPY ./webapp ./webapp
COPY go.mod ./
COPY go.sum ./

ENV PATH="${PATH}:$GOPATH/bin"
ENV GO111MODULE=on

RUN export GOPROXY="https://proxy.golang.org" && export GO111MODULE=on && go test ./...
RUN export GOPROXY="https://proxy.golang.org" && export GO111MODULE=on && CGO_ENABLED=0 go build -o simplewebapp webapp/simplewebapp.go

FROM alpine:latest
WORKDIR /app
COPY --from=build_env /go/src/github.com/devsamurai/gke/simplewebapp /app

EXPOSE 80
ENTRYPOINT ["./simplewebapp"]
Dockerイメージをビルドする
# Dockerを事前に起動する必要は注意
cd path_to_simplewebapp

# tag nameがあるdocker imageをビルド
docker build -t ds-gke-simplewebapp:lasters -f simplewebapp.Dockerfile .

# ビルド後の確認
docker images
> REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
> ds-gke-simplewebapp                lasters             1e2055780000        12 minutes ago      17.1MB

3. DockerイメージをGCP Container Registryにプッシュする

前提: GCPとgcloudコマンドの利用経験があることが望ましい。

# ログイン、とワーキングProjectを設定
gcloud auth login
gcloud config set project [PROJECT_ID]

# ロカルDockerはGCPにアクセスするため、GCPのcredentialを設定
gcloud auth configure-docker

# ロカルイメージをレポジトリのタグ名を付ける 
# docker tag [SOURCE_IMAGE] [HOSTNAME]/[PROJECT-ID]/[IMAGE]:[TAG]
docker images
> REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
> ds-gke-simplewebapp                lasters             1e2055780000        25 minutes ago      17.1MB

docker tag 1e2055780000 asia.gcr.io/ds-project/ds-gke-simplewebapp:lasters

# タグ名の確認
docker images
> REPOSITORY                                    TAG                 IMAGE ID            CREATED             SIZE
> asia.gcr.io/ds-project/ds-gke-simplewebapp   lasters             1e2055780000        26 minutes ago      17.1MB

# DockerイメージをContainer Registryにプッシュする
# docker push [HOSTNAME]/[PROJECT-ID]/[IMAGE]
docker push asia.gcr.io/ds-project/ds-gke-simplewebapp

Container Registry上にイメージを確認

4. Container RegistryからGKEにデプロイする

# GKEのクラスタを作成する
gcloud container clusters create ds-gke-small-cluster \
	--project ds-project \
	--zone asia-northeast1-b \
	--machine-type n1-standard-1 \
	--num-nodes 1 \
	--enable-stackdriver-kubernetes

デプロイメント定義ファイルを準備する。

simplewebapp.deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: simple-webapp-service
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: simple-webapp
  type: LoadBalancer
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: simple-webapp
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: simple-webapp
    spec:
      containers:
      - name: simple-webapp
        image: asia.gcr.io/ds-project/ds-gke-simplewebapp:lasters
        ports:
          - containerPort: 80

このデプロイメント定義ファイルは、1つのLoad Balancing作成、ポート80で公開する。webアプリケーションは後ろの2つのContainersで稼働する。

GKEにデプロイ
# k8sコントロールツールをインストール
gcloud components install kubectl
kubectl version

# GKEのクラスタにアクセスするため、credentialsを設定
gcloud container clusters get-credentials --zone asia-northeast1-b ds-gke-small-cluster

# GKEにアプリケーションを設定する
kubectl apply -f simplewebapp.deployment.yaml

デプロイ後、結果確認

Load Balancing

webアプリケーションを稼働するPod

外からwebアプリケーションにアクセス確認
curl http://34.85.10.96/
> Hello, World!

ソースコード参照

https://github.com/itdevsamurai/gke/tree/master/simplewebapp

最後まで読んで頂き、どうも有難う御座います!

DevSamurai 橋本

弊社はGoogle Cloud Platform (GCP)のパートナーとして、製品導入やクラウドに移行、アーキテクチャ設計、システム開発などのサービスを提供しております。