K8s 线上采坑 03 基于 k8s 的服务搭建

服务搭建与改造流程框架

搭建基础运维环境

  1. 服务器(4+1 台)
  • 安装 CentOS 7.6 版本系统
  • 4 台做 k8s, 1 台做仓库
  1. 升级 yum 包, 安装 Docker, KubeAdm
  • 使用 yum 安装 docker, kubeadm 时需要添加 repo, 不使用自带源
  • 使用 kubeadm 搭建 k8s 环境, 不使用 yum 方式
  1. 外部搭建 Git 仓库, Registry 仓库, Registry UI, WebHook(替代 Jenkins)
  • Registry 需要绑定域名, HTTPS 授权
  • Registry UI 需要在 Registry 端配置 Access-Control-Allow-Origin, 写 UI 的访问地址(只写一个, 不支持多个和 *)
  • 每个项目都需要手动创建一个 WebHook (自动下载代码, 编译, 打包, 推送到 Registry 仓库)
  1. TODO 服务监控
  • 监控在集群内部: Dashboard, 外部访问端口
  • 监控在集群外部: Prometheus Client + Server
  1. TODO 服务网格
  • istio

原服务改造

  1. 打包服务到 image(Dockerfile, WebHook, Registry 授权)
  • 每个项目建立 Dockerfile 文件, 方便一键打包成 image

  • 自动打包(推送到 git 指定分支, 自动获取上一次版本计算本次版本, 服务器打包, tag 到 Registry, push)

  • 手动打包(指定版本, 本地打包, tag 到 Registry, push)

  • 小版本自动打包, 大版本手动打包

  • TODO 一个 git 仓库多个项目入口

  • TODO 多人协作,个人测试分支打包 image 的命名问题

  1. 外部服务映射到集群内 (Redis, MySQL..)
  • 外部域名服务: ExternalName Service
  • 外部 IP 服务: 端口映射 Service + Endpoints
  1. 配置文件管理
  • ConfigMap 基于环境(正式服, 测试服)做配置文件管理
  • 基于命令行管理: create cm CM_NAME --from-file=FILE_NAME=FILE_PATH
  • 基于 configMapGenerator 管理: apply -k .
  1. 服务上线, 更新, 回滚
  • 上线 apply
  • 更新 set image DEPLOYMENT_NAME CONTAINER_NAME=image:version
  • 查看版本历史 rollout history DEPLOYMENT_NAME
  • 查看版本详情 rollout history DEPLOYMENT_NAME --revision=version
  • 回滚(默认上一个版本) rollout undo DEPLOYMENT_NAME [--to-revision=version]
  1. TODO 服务集群向外部暴露服务
  • Igress

常规项目部署流程举例

服务的原始状态

首先本项目初始化状态为可以统计当月盈亏列表, 并且发送钉钉通知.

服务代码部分的改造

改造第一步, 编写一个 Dockerfile 文件, 用于将需要服务打包成 docker image 镜像. 由于每个服务语言的不同(NodeJS, Python, PHP, Golang…)导致需要的依赖不同, 是否需要编译(一段构建, 多段构建…)等.

按照愿望, 编写好 Dockerfile 之后, 需要对其进行测试, 我觉得比较好的方式就是构建 docker-compose.yml.

于是, 服务改写完文件如下

需要注意的是, 打包 Dockerfile 的时候并没有将配置文件加进去, 在 docker-compose.yml 通过目录映射到指定位置. 在后面, 我们将服务部署到 k8s 中时, 配置文件也是使用类似的方法映射进去的.

至此, 服务代码部分改写完毕.

配置自动打包

1. 配置服务的 git 地址

https://git.XXX.cc:10080/ 中, quant 组中创建项目 quant-profit-collector

名字与本地文件夹名字一致. 将本地代码提交到 git 上.

2. 配置 git web hook 地址

首先配置项目的部署权限(WebHook 机器的 ssh 公钥)

1
ssh-rsa AAAA... ono-test-server

然后打开配置页面, 找到 WebHook 配置

配置自动打包 Hook

PS: 自动打包 Hook 创建的时候, 需要输入密码, 密码不正确不会触发自动打包.

配置钉钉自动通知 Hook

PS: 钉钉 Hook 的地址, 在钉钉机器人申请的时候, 需要绑定 Gitea 的 IP 地址进行授权.

至此, 提交 push 到指定分支, 就会触发自动打包 Registry, 并且推送到 docker registry 中.

3. Webhook 的报错问题排查

  1. /data/logs/supervisor/git-webhook.log 中出现
1
2
3
4
5
6
7
8
9
10
Gitea: Unauthorized
Public (Deploy) Key: 2:ono-test-server is not authorized to read quant/quant-profit-collector.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
./standard.sh: 第 32 行:cd: /data/projects/quant-profit-collector: 没有那个文件或目录
chmod: 无法访问"/data/projects/quant-profit-collector": 没有那个文件或目录
invalid argument "quant-profit-collector:" for "-t, --tag" flag: invalid reference format
See 'docker build --help'.

说明没有拉取代码权限, 请重新进行 配置 git web hook 地址

  1. git 拉取失败

如果是新部署的 WebHook, 改过 git 域名等问题, 那么需要手动 ssh 一下, 弹出 \[yes|no\] 选择 yes, 将 git 域名对应的信息写入到本地 ~/.ssh/known_hosts

将服务部署到 k8s 中

1. 配置 ConfigMap (创建, 更新)

在 k8s master 机器上, 放置好 config.yaml, create-cm.sh, update-cm.sh 文件

执行 create 会以 config.yaml 中的内容创建 config map quant-profit-collector

执行 update 会以 config.yaml 中的内容更新 config map quant-profit-collector

2. 配置外部服务映射 Service

本服务没有用到外部服务.

TODO 外部服务向内映射

3. 配置服务 Deployment, 执行上线

本服务不是 Deployment 一直存在的服务类型, 应该属于一种定时执行的服务 Cronjob.

创建文件 quant-profit-collector-cronjob.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: quant-profit-collector
spec:
schedule: "0 */1 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: quant-profit-collector
image: docker-hub.XXX.cc:5000/quant-profit-collector:0.0.1
volumeMounts:
- name: data
mountPath: /project/data
- name: config
mountPath: /project/etc
imagePullSecrets:
- name: XXX
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: quant-profit-collector
restartPolicy: OnFailure

在 k8s master 主机执行 kubectl apply -f quant-profit-collector-cronjob.yml 使服务生效.

其中有 configMap 映射到 /project/etc 文件夹相关的配置. 与本地测试用的 docker-compose.yml 异曲同工.

TODO 部署 Deployment 服务

4. 服务更新, 回滚

对服务更新新的镜像:

kubectl set image cronjob/quant-profit-collector quant-profit-collector=docker-hub.XXX.cc:5000/quant-profit-collector:0.0.2

Note: 只有 Deployment 支持回滚; Pod, Cronjob 都不支持回滚, 只能在出错的时候, 将镜像更新回原来的版本(并不是回滚, 是设置新的镜像为低版本)

TODO 版本回滚

我们总结一下名字一致的地方

  • 本地项目文件夹
  • git 项目名
  • web hook 中调用的名字
  • web hook 脚本名字
  • docker image 名字
  • k8s 中 deployment, pod, service 名字

以上的地方, 名称一致(有些可以不一致), 需要理解虽然名称相同但是代表的意思不同.

Donate - Support to make this site better.
捐助 - 支持我让我做得更好.