Minikube를 이용한 Gin개발환경 만들기
회사에서 개발중인 프로젝트는 약 20개의 컨테이너를 docker compose로 관리하고 있었습니다.
관리에 한계를 느껴 쿠버네티스로 전환을 준비중입니다.
우선 쿠버네티스 개발환경 세팅을 조사하여 기록을 남깁니다.
최종 목표는 서비스 메시, 모니터링, 로그 트레이싱까지 구현하여 AWS EKS에 배포 및 운영하는 것입니다.
목표
- Minikube에 Host 디렉터리 연결하기
- 로컬 도커 이미지를 Minikube에서 사용하기
- 코드 Hot-reloading
요약
1. Minikube에 host 디렉토리 연결하기
$ minikube start --mount --mount-string=$PWD:/host
2. 로컬 도커 이미지를 Minikube에서 사용하기
$ eval $(minikube -p minikube docker-env)
$ docker build . -t gin
3. 코드 Hot-reloading
- nodemon설정
{
"watch": ["*"],
"ext": "go",
"exec": "go run main.go && lsof -t -i:8080 | xargs kill -9 && go run main.go || exit 1"
}
- Pod에 hostPath설정
apiVersion: v1
kind: Pod
metadata:
name: gin-app
labels:
app: gin
spec:
containers:
- name: gin-app
image: gin
imagePullPolicy: Never
ports:
- containerPort: 8080
volumeMounts:
- name: src
mountPath: /app
volumes:
- name: src
hostPath:
path: /host
상세
사용 버전
OS: MacOS 11.6
go: 1.17.2
Minikube: 1.24.0
kubectl: 1.21.5
최종 생성 파일
Dockerfile
go.mod
go.sum
main.go
nodemon.json
gin-svc.yaml
1. Dockerfile준비
1-1. go mod 생성 및 Gin 설치
$ go mod init gin.practice # go.mod파일이 생성된다
$ go get github.com/gin-gonic/gin # go.sum파일이 생성된다
1-2. main.go 작성
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "hello world"})
})
r.Run()
}
1-3. nodemon설치
$ npm install -g nodemon
1-4. nodemon.json 작성
nodemon으로 Hot-reloading을 구현합니다.
{
"watch": ["*"],
"ext": "go",
"exec": "go run main.go && lsof -t -i:8080 | xargs kill -9 && go run main.go || exit 1"
}
1-5. Dockerfile 생성
FROM golang:1.17.3-alpine
RUN apk add --update nodejs npm lsof && npm install -g nodemon
RUN mkdir app
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
EXPOSE 8080
CMD nodemon --legacy-watch
2. Minikube에 Host 디렉토리 연결하기
2-1. 현재 폴더(PWD)를 Minikube 노드의 /host폴더에 마운트합니다.
이때 절대경로 또는 상대경로를 지정해도 됩니다.
yaml작성 시 소스폴더를 어디로 지정할지 생각해서 작성해주세요.
$ brew install hyperkit # hyperkit이 설치되어있지 않은 경우
$ minikube delete # Minikube를 이미 start한 경우
$ minikube start --mount --mount-string=$PWD:/host --driver=hyperkit
3. 로컬 도커 이미지를 Minikube에서 사용하기
3-1. docker 커맨드를 Minikube 내부 도커와 연결시키기
아래 커맨드를 입력하면 해당 터미널에서 실행하는 도커 명령은 Minikube내부의 도커로 연결됩니다.
$ eval $(minikube -p minikube docker-env)
3-2. docker build
이미지를 빌드하면 Minikube내부의 도커에 등록됩니다.
$ docker build . -t gin
4. Minikube에 Pod생성 및 테스트
4-1. gin-svc.yaml 생성
apiVersion: v1
kind: Pod
metadata:
name: gin-app
labels:
app: gin
spec:
containers:
- name: gin-app
image: gin
imagePullPolicy: Never # 이미지를 Pull하지 않습니다.
resources:
limits:
memory: "256Mi"
cpu: "500m"
ports:
- containerPort: 8080
volumeMounts:
- name: src
mountPath: /app
volumes:
- name: src
hostPath:
path: /host # 호스트 디렉터리를 마운트할 때 설정에 따라 달라집니다.
---
apiVersion: v1
kind: Service
metadata:
name: gin-np
spec:
type: NodePort
ports:
- port: 8080
protocol: TCP
nodePort: 31000
selector:
app: gin
4-2. 리소스 생성
$ kubectl apply -f gin-svc.yaml
4-3. 다른 터미널에서 로그 확인
kubectl logs -f pod/gin-app
4-4. 접속 확인
Hello World가 보인다면 성공입니다.
$ curl $(minikube ip):31000
4-5. 코드 수정 후 반영 확인
main.go를 수정하고 저장해봅니다.
서버로그를 보시면 Gin이 재시작 될 것입니다.
curl을 날려 반영되었는지 확인해봅시다.
고생하셨습니다.
부디 성공하셨길 바랍니다.