検証環境
Windows11 Home Edition (version 22H2)
VirtualBox 7.0.6
vagrant 2.3.4
# Docker Host OS
ubuntu 22.04.2 LTS
go version go1.20.3 linux/amd64
Docker version 23.0.3, build 3e7cbfd
minikube version: v1.30.1
skaffold v2.3.0
ファイル構成
helloecho
フォルダを作成しその中に main.go
と hellomodules/hander.go
を作成する
helloecho
├── hellomodules
│ └── handler.go
└── main.go
package main
import (
"github.com/labstack/echo"
"github.com/takaya030/helloecho/hellomodules"
)
func main() {
e := echo.New()
e.GET("/hello", handler.MainPage())
e.GET("/api/hello", handler.ApiHelloGet())
e.Start(":8080")
}
package handler
import (
"net/http"
"github.com/labstack/echo"
)
func MainPage() echo.HandlerFunc {
return func(c echo.Context) error {
return c.String(http.StatusOK, "Hello World")
}
}
func ApiHelloGet() echo.HandlerFunc {
return func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{"hello": "world"})
}
}
Go Modules の初期化
$ cd helloecho
$ go mod init github.com/takaya030/helloecho
$ go mod tidy
成功すると go.mod
と go.sum
が作られる
helloecho
├── go.mod
├── go.sum
├── hellomodules
│ └── handler.go
└── main.go
Dockerfile の作成
下記の内容で Dockerfile
を作成する
FROM golang:1.20 as build
WORKDIR /go/src/app
COPY go.mod go.sum /go/src/app/
RUN go mod download
COPY . /go/src/app
RUN go build -o /go/bin/app
FROM gcr.io/distroless/base-debian10
COPY --from=build /go/bin/app /
CMD ["/app"]
マニュフェストの作成
下記の内容で k8s-app.yaml
を作成する
apiVersion: v1
kind: Service
metadata:
name: sample-app
spec:
selector:
app: sample-app
ports:
- port: 80
targetPort: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app
spec:
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: sample-app
image: sample-app:latest
imagePullPolicy: Never
ports:
- name: http
containerPort: 8080
Skaffold 定義ファイルの作成
以下のコマンドで定義ファイルのテンプレートを作成
$ skaffold init --force
作成された skaffold.yaml
を下記内容に変更
( portForward
の設定を追加)
apiVersion: skaffold/v4beta4
kind: Config
metadata:
name: helloecho
build:
artifacts:
- image: sample-app
docker:
dockerfile: Dockerfile
manifests:
rawYaml:
- k8s-app.yaml
portForward:
- resourceType: service
resourceName: sample-app
namespace: default
port: 80
address: 0.0.0.0
localPort: 8080
最終的なファイル構成
helloecho
├── Dockerfile
├── go.mod
├── go.sum
├── hellomodules
│ └── handler.go
├── k8s-app.yaml
├── main.go
└── skaffold.yaml
動作確認
minikube
を起動
$ minikube start --listen-address=0.0.0.0
docker
が minikube
のリポジトリを使用するように変更
$ eval $(minikube -p minikube docker-env)
helloecho
フォルダに移動後、 skaffold dev
を実行
$ cd helloecho
$ skaffold dev --port-forward
エラーが無ければ以下のように web サーバーが起動する
Starting deploy...
- service/sample-app created
- deployment.apps/sample-app created
Waiting for deployments to stabilize...
- deployment/sample-app is ready.
Deployments stabilized in 3.224 seconds
Port forwarding service/sample-app in namespace default, remote port 80 -> http://0.0.0.0:8080
Listing files to watch...
- sample-app
Press Ctrl+C to exit
Watching for changes...
[sample-app]
[sample-app] ____ __
[sample-app] / __/___/ / ___
[sample-app] / _// __/ _ \/ _ \
[sample-app] /___/\__/_//_/\___/ v3.3.10-dev
[sample-app] High performance, minimalist Go web framework
[sample-app] https://echo.labstack.com
[sample-app] ____________________________________O/_______
[sample-app] O\
[sample-app] ⇨ http server started on [::]:8080
http://[minikubeのホスト]:8080/hello
を GET
して Hello World が返れば成功
$ curl http://192.168.33.10:8080/hello
Hello World
このままの状態で hellomodules/handler.go
を下記内容に変更
--- a/handler.go 2023-04-15 13:51:14.986453215 +0000
+++ b/handler.go 2023-04-15 13:52:29.530453215 +0000
@@ -8,7 +8,7 @@
func MainPage() echo.HandlerFunc {
return func(c echo.Context) error {
- return c.String(http.StatusOK, "Hello World")
+ return c.String(http.StatusOK, "Hello Echo")
}
}
変更を保存すると自動でビルドが実行される
Generating tags...
- sample-app -> sample-app:latest
Some taggers failed. Rerun with -vdebug for errors.
Checking cache...
- sample-app: Not found. Building
Starting build...
Found [minikube] context, using local docker daemon.
Building [sample-app]...
Target platforms: [linux/amd64]
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile:
#1 transferring dockerfile: 32B 0.0s done
#1 DONE 0.1s
#2 [internal] load .dockerignore
#2 transferring context: 2B 0.0s done
#2 DONE 0.1s
#3 [internal] load metadata for gcr.io/distroless/base-debian10:latest
#3 DONE 0.0s
#4 [internal] load metadata for docker.io/library/golang:1.20
#4 DONE 0.0s
#5 [build 1/6] FROM docker.io/library/golang:1.20
#5 DONE 0.0s
#6 [stage-1 1/2] FROM gcr.io/distroless/base-debian10
#6 DONE 0.0s
#7 [internal] load build context
#7 transferring context: 610B 0.0s done
#7 DONE 0.1s
#8 [build 3/6] COPY go.mod go.sum /go/src/app/
#8 CACHED
#9 [build 2/6] WORKDIR /go/src/app
#9 CACHED
#10 [build 4/6] RUN go mod download
#10 CACHED
#11 [build 5/6] COPY . /go/src/app
#11 DONE 0.3s
#12 [build 6/6] RUN go build -o /go/bin/app
#12 DONE 30.3s
#6 [stage-1 1/2] FROM gcr.io/distroless/base-debian10
#6 CACHED
#13 [stage-1 2/2] COPY --from=build /go/bin/app /
#13 DONE 0.2s
#14 exporting to image
#14 exporting layers
#14 exporting layers 0.2s done
#14 writing image sha256:d01915d4980a60dfd909d4b7403ea1c41146f29e0a2841547fa2f4a4177886f2 done
#14 naming to docker.io/library/sample-app:latest done
#14 DONE 0.2s
Build [sample-app] succeeded
Tags used in deployment:
- sample-app -> sample-app:d01915d4980a60dfd909d4b7403ea1c41146f29e0a2841547fa2f4a4177886f2
Starting deploy...
- deployment.apps/sample-app configured
Waiting for deployments to stabilize...
- deployment/sample-app is ready.
Deployments stabilized in 3.289 seconds
Port forwarding service/sample-app in namespace default, remote port 80 -> http://0.0.0.0:8080
Watching for changes...
ビルド終了後再度 http://[minikubeのホスト]:8080/hello
を GET
すると変更が反映されている
$ curl http://192.168.33.10:8080/hello
Hello Echo
終了処理
Ctrl + C
で skaffold
を停止
minikube
を停止
$ minikube stop
docker
のリポジトリの向き先を戻す
$ eval $(minikube docker-env -u)
参考サイト
qiita.com
zenn.dev
developer.mamezou-tech.com
developer.mamezou-tech.com
skaffold.dev