我们有一个应用程序,其中使用了Nginx和Go容器。Nginx容器将请求代理给Go容器。Nginx暴露了端口8080 ,我们把它映射到端口80 ,所以它可以通过端口80 。然后,Nginx通过端口9090 ,这是一个静态端口,与Go容器对话。我们将使用Kubernetes卷来配置Nginx,而不是创建一个自定义镜像。
结构
├── Makefile
├── deploy
│ └── k8s
│ ├── configmap.yaml
│ ├── deployment.yaml
│ └── service.yaml
├── docker
│ └── dev
│ ├── docker-compose.yaml
│ ├── go
│ │ └── Dockerfile
│ └── nginx
│ ├── Dockerfile
│ └── default.conf
└── main.go
文件
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,你需要知道的是,这里的改变不会重启pod,所以你必须自己处理重启,这不是本篇文章的范围。
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))
}
制作文件
docker-run 和docker-test 命令是针对你的本地环境的。你可以用它们在本地环境中测试你的应用程序。
## 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'
测试
Docker
让我们在本地环境中测试我们的应用程序,看看它是否工作:
$ 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
现在让我们构建并推送我们的Docker镜像到Docker Hub。这个镜像将在我们运行部署时被调用,所以它很重要。
$ 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和Pod的细节:
$ 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中测试,看看日志:
$ 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" "-"