本文会经过一个中文情绪分析的应用(如下简称 SA)把 K8s 的一些基础概念穿插讲一讲,接着咱们会进行一次 UI 的更新以便体验一下 K8s 的滚动更新,最后咱们还会进行一次回滚,把 UI 的更新给撤销掉并回滚到上一个版本。前端
那么接下来就按照这个剧本开始吧。git
仓库地址:github.com/jwma/sentim…github
SA 分为三个部分:web
若是咱们要将 SA 部署到 K8s 集群,咱们须要先准备一些必需品:docker
参考上一篇文章,你会找到适合你本身的途径。这里我会使用 Minikube 为我启动一个本地的单节点集群。shell
容器化的细节本文就不展开了,能够参考项目源码内各部分的 Dockerfile,下面讲讲构建镜像的相关内容。json
通常来讲,咱们会把咱们的容器镜像推送到一个镜像仓库如 DockerHub,但因为咱们的集群就是在本地,因此咱们能够重用 Minikube 内置的 Docker,这样咱们就不须要浪费时间去推送镜像和拉取镜像了,便于咱们在本地体验。api
这样使用时须要注意,在为镜像打 tag 时,须要使用 :latest
之外的名字,由于当你使用了 :latest
意味着镜像拉取策略也会被修改成 Always
,在镜像不存在于默认的 Docker 镜像仓库(通常为 DockerHub)时,会引起 ErrImagePull
错误。浏览器
咱们能够这样使用 Minikube 内置的 Docker:
eval $(minikube docker-env)
复制代码
此时命令行的 Docker 就是 Minikube 的 Docker 了,接着咱们就能够构建镜像了:
# 切换到源码目录
cd /path/to/sentiment-analyzer
# 构建 sa-logic 镜像
docker build -t sa-logic:v1.0.0 sa-logic
# 成功的话会看到以下输出
# Successfully tagged sa-logic:v1.0.0
# 构建 sa-webapp 镜像
docker build -t sa-webapp:v1.0.0 sa-webapp
# 成功的话会看到以下输出
# Successfully tagged sa-webapp:v1.0.0
# 暂时没法构建 sa-frontend
# 由于其依赖了 sa-webapp 暴露的通讯地址
# 须要等咱们建立了 sa-webapp service 以后再构建
复制代码
这一部份内容比较无聊,着急的能够先跳过。
查看源码的 infrastructure 目录,其中包含了 Deployment 和 Service 配置文件。
以 sa-webapp 的 Deployment 举例:
apiVersion
指定了该资源对象所对应的 API 版本,K8s 支持多个 API 版本,K8s 团队选择在 API 级别进行版本化,而不是在资源或字段级别进行版本化,以确保 API 提供清晰,一致的系统资源和行为视图,并控制对已废止的 API 和/或实验性 API 的访问;kind
指定了该资源的类型为 Deployment;metadata
K8s 的资源对象都拥有通用的元数据,这里指定了名称和添加了一个键为 app 值为 sa-webapp 的标签,后续须要用来匹配对应的 Service;spec
描述你指望的 Deployment 的状态;spec.replicas
指按期望的 Pod 数量,默认值是 1;spec.selector
指定了 Deployment 管理 Pod 的范围,经过标签进行匹配;spec.template
指定 PodTemplate,描述了 Pod 的细节,这里为 Pod 添加了一个键为 app 值为 sa-webapp 的标签,也指明了 Pod 的名字及其实用的镜像,为了让容器能正常运行,还设置了容器所需 的环境变量,最后还暴露了容器的端口。以 sa-webapp 的 Service 举例:
kind
指定了该资源的类型为 Service;spec.selector
经过标签选择器匹配 sa-webapp Deployment;spec.type
指定 Service 类型为 LoadBalancer,也就说来自外部的流量会经过这个 Service 的负载均衡器而后打到匹配的 Pod 上;spec.ports
指定端口的映射关系,把负载均衡器的 80 端口映射到 Pod 的 8080 端口。在本文的例子中,除了认识 Deployment 和 Service 外,你还须要认识 Pod 和 RS(Replica Set),由于他们的互相结合才使得咱们可以把 SA 给运做起来。
实质上,它们都是 K8s 的 API 对象,只是他们负责的工做内容不同而已。
Pod 是 K8s 应用的基础执行单元,它是你建立或部署的最小最简单的 K8s 单元。一个 Pod 一般包含的是一个应用容器(有时候会是多个容器)。结合上文,咱们在 Deployment 声明了 PodTemplate,也就是说咱们的 Pod 会按照咱们的声明运行咱们想要运行的容器。
RS 保证 Pod 的高可用。结合上文,咱们在 Deployment 声明了 replicas
,咱们指望运行两个 Pod,而实际运行中的 Pod 的数量就是经过 RS 进行保障的。
Deployment 能够建立/更新一个服务,也能够滚动更新服务。咱们经过配置文件,能够告诉 K8s 集群咱们指望应用的运行状态,结合 Pod 咱们能把应用运行起来,结合 RS 咱们能保障 Pod 的可用性。一次对 Deployment 的操做,就是经过操做相关的 API 对象来更新应用的运行状态以达到咱们的指望。
经过上面的几个 API 对象,咱们已经保证应用可以正常运做,但没有解决如何访问这些服务的问题,Service 就是用来解决这个问题的。
在 K8s 上建立 API 对象的资源很简单,咱们可使用统一的方式进行建立:
# 切换到源码目录
cd /path/to/sentiment-analyzer
# 建立 sa-logic 的 Deployment、Service
kubectl apply -f infrastructure/deployment/sa-logic.yaml
# 查看 sa-logic 对应的 Pod 是否正常运做
kubectl get pods -l app=sa-logic
# 建立 sa-logic 的 Service
kubectl apply -f infrastructure/service/sa-logic.yaml
# 查看 sa-logic 对应的 Service
kubectl get service -l app=sa-logic
# 建立 sa-webapp 的 Deployment、Service
kubectl apply -f infrastructure/deployment/sa-webapp.yaml
kubectl apply -f infrastructure/service/sa-webapp.yaml
复制代码
到这里,咱们就把 sa-logic 和 sa-webapp 部署到 K8s 集群了,sa-webapp 是一个对外可见的服务,因此咱们在部署 sa-frontend 以前,可使用 postman 或者 curl 来访问如下 sa-webapp 看看。
因为咱们使用的是 Minikube,因此为了获取 sa-webapp 服务的通讯地址,咱们须要:
minikube service sa-webapp-service --url
复制代码
咱们会获得一个 URL,如:http://192.168.99.105:31861
,接下来咱们用 cURL 工具测试下 sa-webapp 的接口:
# 发送请求
curl --request POST \
--url http://192.168.99.105:31861/analyse \
--header 'Content-Type: application/json' \
--data '{"sentence": "很是棒"}'
# 响应结果
{"sentence":"很是棒","level":9}
复制代码
咱们成功的获得告终果。如今咱们已经获得了正确的 sa-webapp 的通讯地址了,因此咱们能够开始构建 sa-frontend 镜像而后部署了:
# 切换到源码目录
cd /path/to/sentiment-analyzer
docker build -t sa-frontend:v1.0.0 --build-arg VUE_APP_API_HOST=http://192.168.99.105:31861 sa-frontend
kubectl apply -f infrastructure/deployment/sa-frontend.yaml
kubectl apply -f infrastructure/service/sa-frontend.yaml
复制代码
而后咱们就能够获取 sa-frontend 的访问 URL 了:
# 此次不加 --url,会自动在浏览器打开
minikube service sa-frontend-service
复制代码
你也能够像我这样玩一下:
在 K8s 上要实现滚动更新是一件很是简单的事情。 咱们接下来会更新 sa-frontend,由于我以为每次提交完一个句子后,Emoji 出现的太突兀,缺少了一些动感,因此我接下来会使用 animate.css 为 Emoji 加一个动画,让画面看起来更有动感一些。
来看看整个流程吧:
这里不是重点,就跳过了。
咱们更新了代码,因此咱们也会跟着构建一个新的镜像,镜像版本号取 v1.1.0。
# 切换到源码目录
cd /path/to/sentiment-analyzer
docker build -t sa-frontend:v1.1.0 --build-arg VUE_APP_API_HOST=http://192.168.99.105:31861 sa-frontend/
复制代码
# ...省略
# 镜像修改成刚刚构建好的 v1.1.0
image: sa-frontend:v1.1.0
# ...省略
复制代码
跟第一次部署 sa-frontend 同样,咱们向 K8s 集群提交了咱们的 Deployment 配置文件。
kubectl apply -f infrastructure/deployment/sa-frontend.yaml
复制代码
我感受这样就好多了呢。
在这里,你能够不去思考 K8s 的滚动更新是怎么作的,但我认为日后你应该要去了解这件事情,这对你理解 K8s 的各个 API 对象颇有帮助。
若是你是一个比较安静的孩纸,不喜欢这么动感,你能够回滚到上一个版本:
kubectl rollout undo deployment sa-frontend-deployment
复制代码
除了回滚到上一个版本,你还能回滚到指定的版本,这里就不展开了,我相信若是要用到的时候你确定会去翻文档的。
咱们到达了此次短途旅行的终点,就像真正的旅行同样,这个终点每每会是原点,咱们不断的旅行,咱们见识到了不一样的风景,认识到了不一样的朋友,体验了不一样的风情,虽然咱们又回到了原点,但咱们不断积累阅历,让咱们面对下一个挑战更具勇气,让咱们走得更远看得更广。
但愿这两篇文章,能带你蜻蜓点水看看 K8s,若是能在你的脑中留下 K8s 好像真的不错哦,我想我就知足了。