diff --git a/2025/helm/dst03106/Dockerfile b/2025/helm/dst03106/Dockerfile new file mode 100644 index 0000000..b0fa463 --- /dev/null +++ b/2025/helm/dst03106/Dockerfile @@ -0,0 +1,10 @@ +FROM golang:alpine AS builder +WORKDIR /app +COPY main.go . +RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o main main.go +# -s : (디버거를 위한) 심볼 테이블 제거, -w: 디버깅 정보 제거 + +FROM scratch +COPY --from=builder /app/main /main + +ENTRYPOINT ["/main"] diff --git a/2025/helm/dst03106/Makefile b/2025/helm/dst03106/Makefile new file mode 100644 index 0000000..5a8ff35 --- /dev/null +++ b/2025/helm/dst03106/Makefile @@ -0,0 +1,40 @@ +CLUSTER_NAME=my-cluster +APP_NAME=my-app +NAMESPACE=my-namespace +CHART_PATH=./charts + +.PHONY: all docker-build docker-test create-cluster delete-cluster install helm-debug pod-debug test + +all: docker-build create-cluster install test delete-cluster + +docker-build: + docker build -t $(APP_NAME):latest . + +docker-test: + make docker-build + docker images $(APP_NAME):latest + docker run -d -p "8000:8080" --rm --name $(APP_NAME) $(APP_NAME):latest + sleep 2 + curl http://localhost:8000/healthcheck + docker stop $(APP_NAME) + +create-cluster: + k3d cluster create ${CLUSTER_NAME} --port "30080:30080@loadbalancer" + k3d image import ${APP_NAME}:latest -c ${CLUSTER_NAME} + docker exec k3d-${CLUSTER_NAME}-server-0 sh -c 'echo "nameserver 8.8.8.8" > /etc/resolv.conf' + +delete-cluster: + k3d cluster delete ${CLUSTER_NAME} + +install: + helm install ${APP_NAME} ${CHART_PATH}/ --wait + +helm-debug: + helm template ${CHART_PATH}/ --debug + +pod-debug: + kubectl describe pod + +test: + curl http://localhost:30080/api/v1/dst03106 + curl http://localhost:30080/healthcheck diff --git a/2025/helm/dst03106/charts/Chart.yaml b/2025/helm/dst03106/charts/Chart.yaml new file mode 100644 index 0000000..bc8e848 --- /dev/null +++ b/2025/helm/dst03106/charts/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: my-service +description: A minimal Helm chart for my app +version: 0.1.0 +appVersion: "1.0" diff --git a/2025/helm/dst03106/charts/templates/_helpers.tpl b/2025/helm/dst03106/charts/templates/_helpers.tpl new file mode 100644 index 0000000..0029f91 --- /dev/null +++ b/2025/helm/dst03106/charts/templates/_helpers.tpl @@ -0,0 +1,7 @@ +{{- define "my-chart.name" -}} +{{- .Chart.Name -}} +{{- end -}} + +{{- define "my-chart.fullname" -}} +{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/2025/helm/dst03106/charts/templates/deployment.yaml b/2025/helm/dst03106/charts/templates/deployment.yaml new file mode 100644 index 0000000..15c8295 --- /dev/null +++ b/2025/helm/dst03106/charts/templates/deployment.yaml @@ -0,0 +1,34 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "my-chart.fullname" . }} +spec: + replicas: {{ .Values.replicaCount }} + # Existing ReplicaSets whose pods are selected by this + # ... will be the ones affected by this deployment. + selector: + matchLabels: + app: {{ include "my-chart.name" . }} + tier: backend + matchExpressions: # ref. https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/ + - {key : environment, operator: NotIn, values: [dev]} + # Template describes the pods that will be created. + template: + metadata: + labels: # labels과 selector는 object 타입 + app: {{ include "my-chart.name" . }} + tier: backend + environment: prod + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.name }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: PORT + value: "{{ .Values.service.targetPort }}" + ports: + - containerPort: {{ .Values.service.targetPort }} # 문서화용 데이터 + # List of ports to expose from the container. + # Not specifying a port here DOES NOT prevent that port from being exposed. + # Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. diff --git a/2025/helm/dst03106/charts/templates/service.yaml b/2025/helm/dst03106/charts/templates/service.yaml new file mode 100644 index 0000000..2f7560f --- /dev/null +++ b/2025/helm/dst03106/charts/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "my-chart.fullname" . }} +spec: + type: {{ .Values.service.type }} + ports: + - name: http + port: {{ .Values.service.port }} + targetPort: {{ .Values.service.targetPort }} + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + protocol: TCP + selector: # 어떤 파드에 트래픽을 보낼지 라벨로 선택 + app: {{ include "my-chart.name" . }} + tier: backend diff --git a/2025/helm/dst03106/charts/values.yaml b/2025/helm/dst03106/charts/values.yaml new file mode 100644 index 0000000..2ec266e --- /dev/null +++ b/2025/helm/dst03106/charts/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 + +image: + name: my-app:latest + pullPolicy: IfNotPresent + +service: + type: NodePort + port: 80 # Service가 제공하는 포트 번호 (클러스터 내부에서 사용) + nodePort: 30080 # 클러스터 외부에서 노드 IP를 통해 접근하는 포트 번호 + targetPort: 8080 # 실제 Pod 내부 컨테이너의 포트 번호 + # 30080 포트 요청 -> Kubernetes Service (80) -> 선택된 Pod의 컨테이너 내부 포트(8080)으로 전달 diff --git a/2025/helm/dst03106/main.go b/2025/helm/dst03106/main.go new file mode 100644 index 0000000..85efa87 --- /dev/null +++ b/2025/helm/dst03106/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" +) + +func healthcheckHandler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + fmt.Fprint(w, `{"status": "ok"}`) +} + +func myHandler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + fmt.Fprintln(w, `{"message": "Hello world"}`) +} + +func getPort() string { + if port := os.Getenv("PORT"); port != "" { + return port + } + return "8080" +} + +func main() { + http.HandleFunc("/healthcheck", healthcheckHandler) + http.HandleFunc("/api/v1/dst03106", myHandler) + + port := getPort() + host := "0.0.0.0" + log.Printf("Server running on http://%s:%s\n", host, port) + err := http.ListenAndServe(host+":"+port, nil) + if err != nil { + log.Fatalf("Failed to start server: %v", err) + } +}