15/11/2020 - GO, KUBERNETES, NGINX
Nginx ve Go konteynerlerinin kullanıldığı bir uygulamamız var. Nginx istekleri Go konteynerine iletir. Nginx, 8080
bağlantı noktasını açığa çıkarır ve onu 80
bağlantı noktasına eşleriz, böylece 80
bağlantı noktası üzerinden dışarıdan erişilebilir. Nginx daha sonra statik bir bağlantı noktası olan 9090
bağlantı noktası aracılığıyla Go konteyner ile iletişim kurar. Yeni bir Nginx imajı oluşturmak yerine, Nginx konfigürasyon dosyası için Kubernetes volume kullanacağız.
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ └── service.yaml
├── docker
│ └── dev
│ ├── docker-compose.yaml
│ ├── go
│ │ └── Dockerfile
│ └── nginx
│ ├── Dockerfile
│ └── default.conf
└── main.go
apiVersion: apps/v1
kind: Deployment
metadata:
name: address-finder-deployment
labels:
app: address-finder
spec:
replicas: 1
selector:
matchLabels:
app: address-finder
template:
metadata:
labels:
app: address-finder
spec:
containers:
- name: go
image: you/address-finder-go:latest
- name: nginx
image: nginx:1.19.4-alpine
ports:
- containerPort: 8080
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d/default.conf
subPath: nginx.conf
readOnly: true
volumes:
- name: nginx-config
configMap:
name: address-finder-config
Configmap hakkında bilmeniz gereken şey, buradaki değişikliklerin Podları yeniden başlatmayacağıdır, bu nedenle yeniden başlatmaları kendiniz halletmeniz gerekecek.
apiVersion: v1
kind: ConfigMap
metadata:
name: address-finder-config
data:
nginx.conf: |
server {
listen 8080 default_server;
location / {
proxy_pass http://127.0.0.1:9090/;
}
}
apiVersion: v1
kind: Service
metadata:
name: address-finder-service
spec:
type: NodePort
selector:
app: address-finder
ports:
- protocol: TCP
port: 80
targetPort: 8080
#
# STAGE 1: build
#
FROM golang:1.15-alpine3.12 as build
WORKDIR /source
COPY . .
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o bin/main main.go
#
# STAGE 2: run
#
FROM alpine:3.12 as run
COPY --from=build /source/bin/main /main
ENTRYPOINT ["/main"]
FROM nginx:1.19.4-alpine
COPY docker/dev/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
server {
listen 8080 default_server;
location / {
proxy_pass http://address-finder-go:9090/;
}
}
version: "3.4"
services:
address-finder-go:
container_name: "address-finder-go"
build:
context: "../.."
dockerfile: "docker/dev/go/Dockerfile"
address-finder-nginx:
container_name: "address-finder-nginx"
build:
context: "../.."
dockerfile: "docker/dev/nginx/Dockerfile"
ports:
- "80:8080"
depends_on:
- "address-finder-go"
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(r.Header.Get("X-Request-Id") + "\n"))
})
log.Println("go server is running on :9090")
log.Fatal(http.ListenAndServe(":9090", nil))
}
docker-run
ve docker-test
komutları local ortam içindir. Uygulamanızı yerel ortamda test etmek için bunları kullanabilirsiniz.
## Build and run.
.PHONY: docker-run
docker-run:
docker-compose -f docker/dev/docker-compose.yaml build --no-cache
docker-compose -f docker/dev/docker-compose.yaml up
## Remove.
.PHONY: docker-down
docker-down:
docker-compose -f docker/dev/docker-compose.yaml down
docker system prune --volumes --force
## Build, tag and push application image to registry then clean up.
.PHONY: docker-push
docker-push:
docker build -t you/address-finder-go:latest -f ./docker/dev/go/Dockerfile .
docker push you/address-finder-go:latest
docker rmi you/address-finder-go:latest
docker system prune --volumes --force
## Build and run.
.PHONY: docker-test
docker-test:
curl --request GET 'http://localhost:80' --header 'X-Request-Id: my-request-id'
## -----------------------------------------------------------------------------------
## Apply secret and deploy application to kubernetes cluster.
.PHONY: k8s-deploy
k8s-deploy:
kubectl apply -f deploy/k8s/configmap.yaml
kubectl apply -f deploy/k8s/deployment.yaml
kubectl apply -f deploy/k8s/service.yaml
## Send a dummy request to the exposed pod on kubernetes.
.PHONY: k8s-test
k8s-test:
curl --request GET $(shell minikube service address-finder-service --url) --header 'X-Request-Id: my-request-id'
Çalışıp çalışmadığını görmek için uygulamanızı yerel ortamımızda test edelim.
$ make docker-run
Recreating address-finder-go ... done
Recreating address-finder-nginx ... done
address-finder-go | 2020/11/15 21:50:14 go server is running on :9090
address-finder-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
$ make docker-test
curl --request GET 'http://localhost:80' --header 'X-Request-Id: my-request-id'
my-request-id
Şimdi Docker imajımızı derleyip Docker Hub'a aktaralım. Bu imaj, dağıtımımızı çalıştırdığımızda çekilecek, bu yüzden önemlidir.
$ make push
docker build -t you/address-finder-go:latest -f ./docker/dev/go/Dockerfile .
Sending build context to Docker daemon 7.762MB
.......
$ make k8s-deploy
kubectl apply -f deploy/k8s/configmap.yaml
configmap/address-finder-config created
kubectl apply -f deploy/k8s/deployment.yaml
deployment.apps/address-finder-deployment created
kubectl apply -f deploy/k8s/service.yaml
service/address-finder-service created
ConfigMap ve Pod ayrıntılarını kontrol edelim.
$ kubectl describe configmap address-finder-config
Name: address-finder-config
Namespace: default
Labels:
Annotations: ...
Data
====
nginx.conf:
----
server {
listen 8080 default_server;
location / {
proxy_pass http://127.0.0.1:9090/;
}
}
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
address-finder-deployment-68dd5b79b8-m6sgd 2/2 Running 0 110s
$ kubectl logs address-finder-deployment-68dd5b79b8-m6sgd go
2020/11/15 22:15:17 go server is running on :9090
$ kubectl logs address-finder-deployment-68dd5b79b8-m6sgd nginx
/docker-entrypoint.sh: Configuration complete; ready for start up
Kubernetes'te test edip günlükleri görmeyelim.
$ make k8s-test
curl --request GET http://192.168.99.100:31615 --header 'X-Request-Id: my-request-id'
my-request-id
172.17.0.1 - - [15/Nov/2020:22:20:57 +0000] "GET / HTTP/1.1" 200 14 "-" "curl/7.54.0" "-"