Kubernetes入门之微服务实践
微服务是最近几年非常流行的平台架构方案。微服务将项目拆分成多个小而全的工程,工程之间通过http或tcp交互自己的数据。微服务的部署一直都是一个棘手的问题,由于docker, kubernetes的兴起,让我们管理部署微服务更加简单。
可以通过gitlab + docker + harbor + drone + kubernetes打造公司项目一键管理发布,扩容,下架。
这篇文章会讲解如何从零开始部署一个项目到kubernetes,你需要了解一些kubernetes, Docker的基础知识,比如Deployment、Pods、Service、Ingress和Dockerfile等一些知识点。你可以通过这篇文章来学习下。
一个微小的服务
通过编写一个简单程序来作为我们的第一个微服务。使golang的echo架构编写几个简单的http接口。
我将使用go的1.12版本,为工程初化一个mod。
go mod init github.com/tianliangzhou/k8s-microservice
Note: 如果你想使用go mod功能,你需要将你的go升级到1.11以上.
接口实现
示例中实现了三个接口,监听本地端口1323。
- 一个将输出
Hello, World! - 随机输出一段长度等于10的字符串
- 输出一段html表格(内容读取本地文件)
package main
import (
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
echoRandom "github.com/labstack/gommon/random"
"io/ioutil"
"net/http"
"os"
)
func main() {
// Echo instance
e := echo.New()
// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())
// Routes
e.GET("/", hello)
e.GET("/random", random)
e.GET("/table", table)
// Start server
e.Logger.Fatal(e.Start(":1323"))
}
// Handler
func hello(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
}
func random(c echo.Context) error {
return c.String(http.StatusOK, echoRandom.String(10, echoRandom.Uppercase, echoRandom.Lowercase))
}
func table(c echo.Context) error {
fs, _ := os.Open("./template/table.html")
table, _ := ioutil.ReadAll(fs)
html := string(table)
return c.HTML(http.StatusOK, html)
}
完成代码之后,执行下go mod vendor,将代码依赖下载到vendor目录中。
编译测试
代码完成后,可以编译测试下接口。
meshell@k8s-microservice$ go build
meshell@k8s-microservice$ ./k8s-microservice
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.5
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1323
测试下面三个地址:
打包镜像
打包镜像需要自己有hub.docker.com的账号,下载Docker客户端登录其账号。在代码根目录新建Dockerfile文件,它是描述镜像构建流程的文本文件,编写一些特定的组合指令来完成。
你可以通过这篇文章来了解怎么编写Dockerfile文件。
FROM golang:1.12.7
WORKDIR /go/src/project/
COPY . /go/src/project/
RUN go build -o /go/bin/k8s-microservice
EXPOSE 1323/tcp
ENTRYPOINT ["/go/bin/k8s-microservice"]
上面就是整个Dockerfile的完整内容。
构建镜像
通过docker build命令可以构建一个完整的镜像,之后通过docker run命令运行docker镜像。
meshell@k8s-microservice$ docker build -t k8s-microservice:lastet .
Sending build context to Docker daemon 22.15MB
Step 1/6 : FROM golang:1.12.7
---> be63d15101cb
Step 2/6 : WORKDIR /go/src/project/
---> Using cache
---> c2613edfead2
Step 3/6 : COPY . /go/src/project/
---> a42e4a1c96c5
Step 4/6 : RUN go build -o /go/bin/k8s-microservice
---> Running in ad280dcd951e
Removing intermediate container ad280dcd951e
---> c16dd3cf8c24
Step 5/6 : EXPOSE 1323/tcp
---> Running in d6b0ee26c004
Removing intermediate container d6b0ee26c004
---> b2f52c9c90e5
Step 6/6 : ENTRYPOINT ["/go/bin/k8s-microservice"]
---> Running in 29628dc95289
Removing intermediate container 29628dc95289
---> 6827bacf77de
Successfully built 6827bacf77de
Successfully tagged k8s-microservice:lastet
在docker环境运行镜像。将本地1323端口转发到容器中的1323端口。
meshell@k8s-microservice$ docker run -p 1323:1323 --rm k8s-microservice:lastet
____ __
/ __/___/ / ___
/ _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.5
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
O\
⇨ http server started on [::]:1323
现在又可以访问测试地址,只是这次程序布署在docker环境中而不是本地。
推送镜像
在kubernetes中创建Deployment是需要镜像名称的,我们需要把自己的镜像推送到docker镜像仓库中。
为镜像打上tag指定远程境像名称,使用docker push推送镜像。
meshell@k8s-microservice$ docker tag k8s-microservice mfkgdyve/k8s-microservice:latest
meshell@k8s-microservice$ docker push mfkgdyve/k8s-microservice:latest
推送完成之后可以查看hub.docker.com自己的repository。本境像的地址https://cloud.docker.com/repository/docker/mfkgdyve/k8s-microservice
部署
部署到kubernetes之前我们需要创建对应的Deployment、Service、Ingress对象的配置文件。
- Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: echo-demo-deployment
spec:
selector:
matchLabels:
app: echo-demo
replicas: 3
template:
metadata:
labels:
app: echo-demo
spec:
containers:
- name: k8s-microservice
image: mfkgdyve/k8s-microservice:latest
ports:
- containerPort: 1323
通过kubectl apply创建部署:
meshell@k8s-microservice$ kubectl apply -f k8s-microservice-deployment.yaml
deployment.extensions/echo-demo-deployment created
创建建之后需要等待一段时间,从配置文件(replicas: 3)可以看到我们创建了三个副本(Pods)。
可以通过kubectl get deployment echo-demo-deployment或者kubectl describe deployment echo-demo-deployment查看Deployment的情况。
- Service
apiVersion: v1
kind: Service
metadata:
name: echo-demo-service
spec:
selector:
app: echo-demo
ports:
- protocol: TCP
port: 1323
targetPort: 1323
以标签为app=echo-demo的Pod的TCP端口1323为目标对名为”echo-demo-service”的Endpoint对象进行POST更新。
通过kubectl apply创建服务:
meshell@k8s-microservice$ kubectl apply -f k8s-microservice-service.yaml
service/echo-demo-service created
通过kubectl get service查看服务:
meshell@k8s-microservice$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo-demo-service ClusterIP 10.98.119.95 <none> 1323/TCP 12s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
nginx-service ClusterIP 10.101.100.90 <none> 80/TCP 4d20h
- Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: echo-demo-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: \"false\"
spec:
rules:
- host: echo.demo
http:
paths:
- path: /
backend:
serviceName: echo-demo-service
servicePort: 1323
指host为echo.demo的请求访问到服务名echo-demo-service上面。
通过kubectl apply创建Ingress:
meshell@k8s-microservice$ kubectl apply -f k8s-microservice-ingress.yaml
ingress.extensions/echo-demo-ingress created
查看Ingress:
meshell@k8s-microservice$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
echo-demo-ingress echo.demo 80 34s
nginx-ingress loocode.de 10.0.2.15 80 4d20h
现在只需要把echo.demo绑定到集成ip就行了。我这里是本地集群环境使用minikube ip来获得ip。
meshell@k8s-microservice$ minikube ip
192.168.99.105
修改/etc/hosts文件将域名绑定到ip上。
192.168.99.105 echo.demo

整个部署过程已经完成,如果你想增加Pods你只需要加大(replicas: 3)配置就行了。可以将整个流程部署在公司内网实现一键发布,扩容,下架。
文章就到此为止了,如果你什么问题你可以在正文留言反馈。