30/11/2020 - KUBERNETES
Bu örnekte iki bağımsız uygulama oluşturacağız ve her ikisi de kendi namespace alanlarında çalışacak. Namespace alanları, ana küme içindeki sanal kümeler gibidir. Esas olarak ilgili bileşen gruplarını izole etmek için kullanılırlar. Develop, qa, staging, sandbox, production gibi bir kümedeki her ortam için namespace alanlarını kullanabilirsiniz. Diğer bir yol, uygulama adlarını kullanmaktır. Bu örnekte, her şeyi görsel olarak bariz hale getirmek için ikisini de birleştireceğim. Bir namespace alanını silerseniz, içindeki tüm bileşenler de silinir. Namespace alanını arasında geçiş yapmak isterseniz kubectl config set-context --current --namespace={namespace}
komutunu kullanabilirsiniz.
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── namespace.yaml
│ └── service.yaml
├── docker
│ └── dev
│ └── Dockerfile
├── .env
└── main.go
TCP_HOST=0.0.0.0
TCP_PORT=8882
package main
import (
"log"
"net"
"net/http"
"os"
"github.com/joho/godotenv"
)
func main() {
_ = godotenv.Load()
lis, err := net.Listen("tcp", os.Getenv("TCP_HOST") + ":" + os.Getenv("TCP_PORT"))
if err != nil {
log.Fatalln(err)
}
rtr := http.NewServeMux()
rtr.HandleFunc("/teams", team)
if err := http.Serve(lis, rtr); err != nil && err != http.ErrServerClosed {
log.Fatalln(err)
}
}
func team(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte("Arsenal | Liverpool | Manchester United"))
}
# 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"]
## Build application binary.
.PHONY: build
build:
go build -race -ldflags "-s -w" -o bin/main main.go
## Build application binary and run it.
.PHONY: run
run: build
bin/main
## Send a dummy request to the local server.
.PHONY: local-test
local-test:
curl --request GET http://localhost:8882/teams
## -------------------------------------------------------------
## Build, tag and push application image to registry then clean up.
.PHONY: push
push:
docker build -t you/football:latest -f ./docker/dev/Dockerfile .
docker push you/football:latest
docker rmi you/football:latest
docker system prune --volumes --force
## Deploy application to kubernetes cluster.
.PHONY: deploy
deploy:
kubectl apply -f deploy/k8s/namespace.yaml
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 football-service --url --namespace=football-develop-namespace)/teams
apiVersion: v1
kind: Namespace
metadata:
name: football-develop-namespace
apiVersion: v1
kind: ConfigMap
metadata:
name: football-configmap
namespace: football-develop-namespace
data:
TCP_HOST: 0.0.0.0
TCP_PORT: "8888"
apiVersion: apps/v1
kind: Deployment
metadata:
name: football-deployment
namespace: football-develop-namespace
labels:
app: football
spec:
replicas: 1
selector:
matchLabels:
app: football
template:
metadata:
labels:
app: football
spec:
containers:
- name: golang
image: you/football:latest
ports:
- containerPort: 8888
envFrom:
- configMapRef:
name: football-configmap
apiVersion: v1
kind: Service
metadata:
name: football-service
namespace: football-develop-namespace
spec:
type: NodePort
selector:
app: football
ports:
- protocol: TCP
port: 80
targetPort: 8888
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── namespace.yaml
│ └── service.yaml
├── docker
│ └── dev
│ └── Dockerfile
├── .env
└── main.go
HTTP_HOST=localhost
HTTP_PORT=8881
# You can use the K8S POD address here if you wish to test it against the actual K8S cluster.
# You can find out what it is by running `make k8s-test` command.
FOOTBALL_URL=http://localhost:8882
package main
import (
"io/ioutil"
"log"
"net/http"
"os"
"github.com/joho/godotenv"
)
func main() {
_ = godotenv.Load()
rtr := http.NewServeMux()
rtr.HandleFunc("/api/v1/teams", team)
if err := http.ListenAndServe(os.Getenv("HTTP_HOST") + ":" + os.Getenv("HTTP_PORT"), rtr); err != nil {
log.Fatalln(err)
}
}
func team(w http.ResponseWriter, _ *http.Request) {
req, err := http.NewRequest(http.MethodGet, os.Getenv("FOOTBALL_URL") + "/teams", nil)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte("build request:" + err.Error()))
return
}
res, err := http.DefaultClient.Do(req)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte("make request:" + err.Error()))
return
}
defer res.Body.Close()
bdy, err := ioutil.ReadAll(res.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte("read body:" + err.Error()))
return
}
_, _ = w.Write([]byte(string(bdy)))
}
# 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"]
## Build application binary.
.PHONY: build
build:
go build -race -ldflags "-s -w" -o bin/main main.go
## Build application binary and run it.
.PHONY: run
run: build
bin/main
## Send a dummy request to the local server.
.PHONY: local-test
local-test:
curl --request GET http://localhost:8881/api/v1/teams
## -------------------------------------------------------------
## Build, tag and push application image to registry then clean up.
.PHONY: push
push:
docker build -t you/api:latest -f ./docker/dev/Dockerfile .
docker push you/api:latest
docker rmi you/api:latest
docker system prune --volumes --force
## Deploy application to kubernetes cluster.
.PHONY: deploy
deploy:
kubectl apply -f deploy/k8s/namespace.yaml
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 api-service --url --namespace=api-develop-namespace)/api/v1/teams
apiVersion: v1
kind: Namespace
metadata:
name: api-develop-namespace
apiVersion: v1
kind: ConfigMap
metadata:
name: api-configmap
namespace: api-develop-namespace
data:
HTTP_HOST: 0.0.0.0
HTTP_PORT: "8888"
FOOTBALL_URL: http://football-service.football-develop-namespace
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
namespace: api-develop-namespace
labels:
app: api
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: golang
image: you/api:latest
ports:
- containerPort: 8888
envFrom:
- configMapRef:
name: api-configmap
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: api-develop-namespace
spec:
type: NodePort
selector:
app: api
ports:
- protocol: TCP
port: 80
targetPort: 8888
Önce make publish
ve make deploy
komutları ile imajları aktarmanız ve ardından dağıtmanız gerekir.
$ make k8s-test
curl --request GET http://192.168.99.100:32630/teams
Arsenal | Liverpool | Manchester United
$ make k8s-test
curl --request GET http://192.168.99.100:31233/api/v1/teams
Arsenal | Liverpool | Manchester United