在这个例子中,我们将创建两个独立的应用程序,它们都将在各自的命名空间中运行。命名空间就像主集群中的虚拟集群。它们主要用于隔离相关组件组。你可以为集群中的每个环境使用命名空间,如开发、QA、暂存、沙盒、生产。另一种方法是使用应用程序名称。在这个例子中,我打算把这两种方法结合起来,以使事情在视觉上明显。如果你删除一个命名空间,里面的所有组件也会被删除。你可以使用kubectl config set-context --current --namespace={namespace} 命令来切换命名空间。
TCP服务器
结构
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── namespace.yaml
│ └── service.yaml
├── docker
│ └── dev
│ └── Dockerfile
├── .env
└── main.go
文件
.env
TCP_HOST=0.0.0.0
TCP_PORT=8882
main.go
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"))
}
Docker文件
# 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
namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: football-develop-namespace
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: football-configmap
namespace: football-develop-namespace
data:
TCP_HOST: 0.0.0.0
TCP_PORT: "8888"
部署.yaml
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
service.yaml
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
HTTP服务器
结构
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── namespace.yaml
│ └── service.yaml
├── docker
│ └── dev
│ └── Dockerfile
├── .env
└── main.go
文件
.env
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
main.go
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)))
}
Docker文件
# 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
namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: api-develop-namespace
configmap.yaml
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
部署.yaml
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
service.yaml
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
测试
首先你需要推送你的服务镜像,然后用make publish 和make deploy 命令进行部署。
TCP服务器
$ make k8s-test
curl --request GET http://192.168.99.100:32630/teams
Arsenal | Liverpool | Manchester United
HTTP服务器
$ make k8s-test
curl --request GET http://192.168.99.100:31233/api/v1/teams
Arsenal | Liverpool | Manchester United