Herkese merhaba!

Uzun yıllardır bol miktarda kişisel zaman ve enerji harcayarak bilgimizi hepinizle paylaşıyoruz. Ancak şu andan itibaren bu blogu çalışır durumda tutabilmek için yardımınıza ihtiyacımız var. Yapmanız gereken tek şey, sitedeki reklamlardan birine tıklamak olacaktır, aksi takdirde hosting vb. masraflar nedeniyle maalesef yayından kaldırılacaktır. Teşekkürler.

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.


Yapı


├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ └── service.yaml
├── docker
│ └── dev
│ ├── docker-compose.yaml
│ ├── go
│ │ └── Dockerfile
│ └── nginx
│ ├── Dockerfile
│ └── default.conf
└── main.go

Dosyalar


deployment.yaml


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.yaml


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/;
}
}

service.yaml


apiVersion: v1
kind: Service

metadata:
name: address-finder-service

spec:
type: NodePort
selector:
app: address-finder
ports:
- protocol: TCP
port: 80
targetPort: 8080

Dockerfile (go)


#
# 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"]

Dockerfile (nginx)


FROM nginx:1.19.4-alpine

COPY docker/dev/nginx/default.conf /etc/nginx/conf.d/default.conf

EXPOSE 8080

default.conf


server {
listen 8080 default_server;

location / {
proxy_pass http://address-finder-go:9090/;
}
}

docker-compose.yaml


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"

main.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))
}

Makefile


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'

Test


Docker


Ç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
.......

Dağıtım


$ 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" "-"