PR

kindでKubernetes(k8s)のローカル開発環境を作ってGo言語(Golang)のAPIをデプロイする方法

応用

こんにちは。Tomoyuki(@tomoyuki65)です。

Go言語(Golang)はマイクロサービスでよく使われたりしますが、そんなマイクロサービスを大規模なサービスで開発している場合、インフラにはKubernetes(略してk8s)を使っていることが多いのではないでしょうか。

k8sを実務で使える機会はなかなか無いと思いますが、Go言語を極めていくなら触れておいた方がいい技術ではあるので、今回はkind(Kubernetes in Docker)というツールを使ったk8sの使い方についてご紹介します。

 

kindでKubernetes(k8s)のローカル開発環境を作ってGo言語(Golang)のAPIをデプロイする方法

今回はkind(Kubernetes in Docker)というツールを使いますが、これを使うには事前にDockerを使える必要もあるので、もしまだDocker環境が無い方は事前にDocker Desktopなどをインストールして使えるようにして下さい。

そしてMacOSならお馴染みのHomebrewを前提に話を進めますが、以下のコマンドを実行し、必要なツールをインストールして下さい。

$ brew install kubectl
$ brew install kind

※kubectlはk8s用のコマンドラインツールです

 

次に以下のコマンドを実行し、コマンドが使えることを確認して下さい。

$ kubectl version --client
$ kind --version

 

スポンサーリンク

事前に簡単なGo言語(Golang)のAPIを作成する

事前に簡単なGo言語(Golang)のAPIを作るため、以下のコマンドを実行して各種ファイルを作成して下さい。

$ mkdir k8s-go && cd k8s-go
$ mkdir src && cd src
$ touch main.go
$ cd ..
$ mkdir -p docker/local && cd docker/local
$ touch Dockerfile
$ cd ../..
$ touch compose.yml

 

次に作成したファイルをそれぞれ以下のように記述します。

package main

import (
  "net/http"
  "github.com/labstack/echo/v4"
)

func main() {
  e := echo.New()

  e.GET("/", func(c echo.Context) error {
    return c.String(http.StatusOK, "Hello, World !!")
  })

  e.GET("/k8s-go", func(c echo.Context) error {
    return c.String(http.StatusOK, "Go API on k8s !!")
  })

  e.Logger.Fatal(e.Start(":8080"))
}

※Go言語のフレームワークにはEchoを使ってます。

 

FROM golang:1.24-alpine

WORKDIR /go/src

COPY ./src .

# モジュールの依存関係をインストール
RUN if [ -f ./go.mod ]; then \
      go install; \
    fi

# air をインストール
RUN go install github.com/air-verse/air@latest

EXPOSE 8080

 

services:
  api:
    container_name: k8s-go-api
    build:
      context: .
      dockerfile: ./docker/local/Dockerfile
    command: air -c .air.toml
    volumes:
      - ./src:/go/src
    tty: true
    stdin_open: true
    ports:
      - 8080:8080

 

次に以下のコマンドを実行し、コンテナのビルドから開発サーバーの起動まで行います。

$ docker compose build --no-cache
$ docker compose run --rm api go mod init k8s-go
$ docker compose run --rm api air init
$ docker compose run --rm api go mod tidy
$ docker compose up -d

 

次にブラウザで「http://localhost:8080」や「http://localhost:8080/k8s-go」を開き、画面にそれぞれテキストが表示されればOKです。

 

次に以下のコマンドを実行し、コンテナを停止して下さい。

$ docker compose down

 

k8sにデプロイするためのDockerコンテナを作成する

次に以下のコマンドを実行し、k8sにデプロイするためのDockerコンテナ用のDockerfileを作成します。

$ mkdir -p docker/prod && cd docker/prod
$ touch Dockerfile
$ cd ../..

 

次に作成したDockerfileを以下のように記述します。

####################
# ビルドステージ
####################
FROM golang:1.24-alpine AS builder

WORKDIR /go/src

COPY ./src .

# 依存関係を反映
RUN go install

# ビルド
RUN go build -o main .

####################
# 実行ステージ
####################
FROM alpine:3.21

WORKDIR /go/src

# コンテナ用ユーザー作成
RUN addgroup --system --gid 1001 appuser && \
    adduser --system --uid 1001 appuser

# ビルドステージで作成したバイナリをコピー
COPY --from=builder --chown=appuser:appuser ./go/src/main .

# ポートを設定
EXPOSE 8080

# コンテナ起動ユーザー
USER appuser

# APIサーバー起動コマンド
CMD ["./main"]

 

次に以下のコマンドを実行し、k8sにデプロイするためのコンテナをビルドします。

$ docker build --no-cache -f ./docker/prod/Dockerfile -t k8s-go-api:latest .

 

次に以下のコマンドを実行し、コンテナを起動します。

$ docker run -p 80:8080 k8s-go-api

 

次にブラウザで「http://localhost」や「http://localhost/k8s-go」を開き、画面にそれぞれテキストが表示されればOKです。

 

次にMacOSの場合はターミナルをアクティブにして以下のショートカットキーを実行し、コンテナを停止して下さい。

control + c 

 

スポンサーリンク

kind(Kubernetes in Docker)でk8sのローカル開発環境を構築する

次に以下のコマンドを実行し、kind(Kubernetes in Docker)でk8sのローカル開発環境を構築するための各種ファイルを作成します。

$ mkdir k8s && cd k8s
$ touch kind-cluster.yaml
$ touch kind-deployment.yaml
$ touch kind-service.yaml
$ cd ..

 

次に作成した各種ファイルはそれぞれ以下のように記述します。

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
# マスターノード1
- role: control-plane
  extraPortMappings:
  - containerPort: 30010
    hostPort: 80
# ワーカーノード2
- role: worker
- role: worker

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kind-go-deployment
  # Podと関連付けるラベル
  labels:
    app: go-api
spec:
  # Podの数の定義
  replicas: 3
  # Deploymentが管理するPodの定義
  selector:
    matchLabels:
      app: go-api
  # 新しいPodを作成する際のテンプレート定義
  template:
    metadata:
      labels:
        app: go-api
    spec:
      containers:
      - name: go-api
        image: k8s-go-api:latest
        # ローカルのDockerイメージを使う設定
        imagePullPolicy: Never
        ports:
        - containerPort: 8080

 

apiVersion: v1
kind: Service
metadata:
  name: kind-go-service
spec:
  selector:
    app: go-api
  # 接続方法
  type: NodePort
  ports:
  - port: 8080
    nodePort: 30010

 

次に以下のコマンドを実行し、クラスターおよびノードを作成します。

$ kind create cluster --config k8s/kind-cluster.yaml

※クラスター(Cluster)は、k8sが管理する複数のノードの集合体です。そしてノード(Node)は、クラスタを構成する個々のコンピューターで、ポッドを実行するためのものです。

 

コマンド実行後、ターミナルでは以下のようになります。

 

次に以下のコマンドを実行し、ノードが作成されていることを確認します。

$ kubectl get nodes -o wide

※オプション「-o wide」は詳細を表示させるもの

 

コマンド実行後、ターミナルでは以下のようになります。

 

次に以下のコマンドを実行し、ローカル環境で事前にビルドしたDockerコンテナのイメージをkindにロードします。

$ kind load docker-image k8s-go-api:latest

 

次に以下のコマンドを実行し、ポッドをデプロイします。

$ kubectl create -f k8s/kind-deployment.yaml

※ポッド(Pod)は、k8sにおけるアプリケーションの最小単位で、一つ以上のコンテナとそれらコンテナの動作に必要な情報をまとめています。

 

次に以下のコマンドを実行し、ポッドが作成されていることを確認します。

$ kubectl get pods -o wide

 

コマンド実行後、ターミナルでは以下のようになります。

※「STATUS」がRunnningであること。また対象のPodがどのノードに属しているかは「NODE」の部分を確認する。

 

次に以下のコマンドを実行し、サービスを作成してブラウザからアクセスできるようにします。

$ kubectl create -f k8s/kind-service.yaml

※サービス(Service)は、ポッドへアクセスするための仕組みです。ポッドはノード上で動的に作成・削除され、そのIPアドレスは常に変わる可能性がありますが、サービスはこれら動的に変化するポッドへのアクセスを安定的に提供します。

 

次に以下のコマンドを実行し、サービスが作成されていることを確認します。

$ kubectl get services -o wide

 

コマンド実行後、ターミナルでは以下のようになります。

 

次にブラウザで「http://localhost」や「http://localhost/k8s-go」を開き、画面にそれぞれテキストが表示されればOKです。

 

スポンサーリンク

GoのAPIを修正してPodを更新する

次にGoのAPIを以下のように修正します。

package main

import (
  "net/http"
  "github.com/labstack/echo/v4"
)

func main() {
  e := echo.New()

  e.GET("/", func(c echo.Context) error {
    return c.String(http.StatusOK, "Hello, World !!")
  })

  e.GET("/k8s-go", func(c echo.Context) error {
    return c.String(http.StatusOK, "Go API on k8s with kind !!")
  })

  e.Logger.Fatal(e.Start(":8080"))
}

※API「/k8s-go」の出力を修正

 

次に以下のコマンドを実行し、Dokcerコンテナを再ビルドします。

$ docker build --no-cache -f ./docker/prod/Dockerfile -t k8s-go-api:latest .

 

次に以下のコマンドを実行し、ローカル環境で事前にビルドしたDockerコンテナのイメージをkindにロードします。

$ kind load docker-image k8s-go-api:latest

 

次のコマンドを実行し、デプロイメントの全てのレプリカを再起動(ポッドを削除して新しいポッドをデプロイ)します。

$ kubectl rollout restart deployment kind-go-deployment

 

次にブラウザで「http://localhost/k8s-go」を開き、画面に変更したテキストが表示されればOKです。

 

クラスターを削除して終了する

次に以下のコマンドを実行し、クラスターを削除して終了します。

$ kind delete cluster

 

スポンサーリンク

最後

今回はkind(Kubernetes in Docker)というツールを使ったk8sの使い方についてご紹介しました。

インフラにk8sを使うことでアプリケーションを分散処理することができ、自動スケーリング(自動的にポッドの数を増減)や自己修復(ノードやポッドに障害が発生しても、自動的に再起動や再配置する)も可能になるため、可用性と障害耐性を高めることが可能です。

k8sは大手企業などの大規模サービス以外ではあまり使われず、実務で使える機会はなかなか無いと思いますが、これからk8sを試してみたいという方は、ぜひ参考にしてみて下さい!

 

この記事を書いた人
Tomoyuki

SE→ブロガーを経て、現在はWeb系エンジニアをしています!

Tomoyukiをフォローする
応用
スポンサーリンク
Tomoyukiをフォローする

コメント

タイトルとURLをコピーしました