検証環境
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
// main.go package main import ( "github.com/labstack/echo" "github.com/takaya030/helloecho/hellomodules" ) func main() { // Echoのインスタンス作る e := echo.New() // ルーティング e.GET("/hello", handler.MainPage()) e.GET("/api/hello", handler.ApiHelloGet()) // サーバー起動 e.Start(":8080") }
// hellomodules/handler.go 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)