k8s-项目测试环境部署

部署规划

概述

项目开发好后,我们需要部署,我们接下来就基于 阿里云云效 + 阿里云容器镜像服务 + k8s 搭建部署环境

阿里云云效 : 放代码,可以做cicd(https://www.aliyun.com/product/yunxiao)

阿里云容器镜像服务 : 镜像仓库(https://cr.console.aliyun.com/cn-guangzhou/instances)

k8s : 运行服务

我们只在k8s内部运行服务,至于中间件(mysql、redis、es等)就会部署在k8s之外,如果你是线上使用云服务可以直接使用云服务,如果自建也最好运行在k8s之外。这里主要演示如何部署go-zero服务到k8s中

k8s部署,参考上一篇【centos7.9 搭建k8s】,再不行就去买个按时付费的云服务k8s

所以我们需要配置如下:

服务器名称 作用 Ip
k8s集群 k8s集群,运行服务 服务器A
中间件 部署nginx、mysql、redis、es等等,k8s内部连接到此服务器 服务器B

项目

项目参考go-zero-looklookhttps://github.com/Mikaelemmmm/go-zero-looklook,或者自己参考go-zero-looklook自己写个简单的版项目。

云效使用

查看官网文档,快速入门https://help.aliyun.com/document_detail/153762.html?

  • 创建项目
  • 配置ssh公钥
  • 上传项目
  • 配置流水线

阿里云容器镜像服务

查看官网文档使用https://help.aliyun.com/zh/acr/user-guide/container-registry-personal-instance-edition-documentations/?spm=a2c4g.11186623.0.0.5ac1285d1C30XT

使用个人版

  • 创建命名空间
  • 创建镜像仓库
  • 仓库里面有操作指南,登录、拉取镜像、推送镜像等

k8s部署

参考上一篇【centos7.9 搭建k8s】

发布服务到k8s

以上把我们需要用到云效、容器镜像服务、k8s准备好了,现在来编写云效流水线将我们的服务通过云效完整的发布到k8s中。

部署中间件

将nginx、mysql、redis、es等部署到k8s之外,用作线上独立环境(至于你想把某些中间件部署到k8s内部这个自行处理,本次重点是如何将go-zero开发的微服务部署到k8s集群内部),这里我就直接使用项目下的docker-compose-env.yaml了,把所有依赖的第三方中间件环境直接安装在服务器B这台服务器,前提是这台服务器已经安装好docker、docker-compose。

登陆到 服务器B

go 复制代码
cd /usr/local/src/
mkdir data && cd data && vim docker-compose.yml
docker-compose up -d
docker-compose ps #查看确认

es占用资源比较大,一开始不需要可以先停了。filebeat日志收集也一样,这个比较占用磁盘空间。

独立配置

将每个服务的配置都独立出来,统一放在一个仓库,这样只给一个人线上仓库的权限,如果线上配置有变直接修改这个仓库的文件,在云效做cd的时候,会先拉取代码在拉取对应服务的配置自动构建,具体可以看后面的pipline。

【问】为什么不用配置中心?

1)修改db、redis等需要重启服务,但是有一些配置又不需要重启服务,运维有要去记,记混了比较容易造成线上事故

2)方便回滚。我们发新版本到线上,并且又改了新版本配置。这时候线上用户反馈有问题,线上需要快速回滚的话,如果我们使用将文件构建到镜像中,直接使用k8s一行命令就可以将上一个版本代码加配置直接回滚回来。如果使用了配置中心,回滚了代码,还要将上个版本的配置去配置中心改回来很麻烦,

独立线上仓库目录结构如下(这个结构是跟pipline中写法相关的)

仓库地址 : https://github.com/Mikaelemmmm/go-zero-looklook-pro-conf , 直接下载就好

【注】1、修改配置中的中间件,数据库、redis等都要改成服务器B这台机器的IP,我们这台机器是线上环境的中间件。

2、另外一个就是我们的服务发现,线上我们部署在k8s中,go-zero直接支持k8s服务发现,所以不需要etcd等,我们在配置zrpc client的时候,要改成target,k8s的配置方式。

3)因为在云效流水线上面我们需要使用到goctl,所以需要把goctl一起上传到配置仓库里面

官网下载地址:https://go-zero.dev/docs/tasks/installation/goctl

下载解压,只需要上传goctl文件

4)因为在云效流水线上我们需要知道对应服务的端口号,所以需要把port.sh一起上传到配置仓库里面

port.sh内容如下

go 复制代码
#!/bin/sh

case $1 in
"identity-api") echo 1001
;;
"identity-rpc") echo 1101
;;
"usercenter-api") echo 1002
;;
"usercenter-rpc") echo 1102
;;
"message-mq") echo 1207
;;
"mqueue-rpc") echo 1106
;;
"order-api") echo 1004
;;
"order-mq") echo 1204
;;
"order-rpc") echo 1104
;;
"payment-api") echo 1005
;;
"payment-rpc") echo 1105
;;
"travel-api") echo 1003
;;
"travel-rpc") echo 1103
esac

最终独立线上仓库目录结构如下

1、goctl版本需要>=1.3.3。

2、在Windows下上传需要注意goctl和port.sh文件权限问题。

编写云效的pipline

k8s配置

配置服务发现

创建looklook项目的命名空间

go 复制代码
kubectl create namespace go-zero-looklook

【注】:!!!非常重要!!!

1、构建优化:pipline中使用"goctl kube xxx"生k8s yaml的时候,我们是使用k8s方式部署不需要etcd,但是这种方式部署需要为生成的k8s yaml中指定serviceAccount。 原理可以看这篇文章下方go-zero的k8s服务发现讲解 :https://mp.weixin.qq.com/s/-WaWJaM_ePEQOf7ExNJe7w

我这边已经指定好了serviceAccount : find-endpoints

所以你需要在你的k8s创建find-endpoints这个serviceAccount并绑定相应权限,yaml文件我已经准备好了,你只需要执行

kubectl apply -f auth.yaml 即可 ,auth.yaml文件如下:

go 复制代码
#创建账号
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: go-zero-looklook
  name: find-endpoints

---
#创建角色对应操作
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: discov-endpoints
rules:
- apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["get","list","watch"]

---
#给账号绑定角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: find-endpoints-discov-endpoints
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: discov-endpoints
subjects:
- kind: ServiceAccount
  name: find-endpoints
  namespace: go-zero-looklook

配置好后,pipline生成k8s yaml的文件可以在生成时候指定serviceAccount,也就是说pipline中可以直接指定-serviceAcount 直接就在生成k8s的yaml中添加serviceAccount : find-endpoints,如下命令

go 复制代码
./goctl kube deploy -secret docker-login -replicas 2 -nodePort 3${port} -requestCpu 200 -requestMem 50 -limitCpu 300 -limitMem 100 -name ${JOB_NAME}-${type} -namespace go-zero-looklook -image ${docker_repo}/${image} -o ${deployYaml} -port ${port} --serviceAccount find-endpoints
配置k8s拉取私有仓库镜像

k8s在默认情况下,不能拉取我们镜像服务的私有仓库镜像,如果拉取私有仓库镜像,则是会报 ErrImagePull 和 ImagePullBackOff 的错误

1、先在服务器A(k8s部署机)登陆阿里云镜像

go 复制代码
$ docker login --username=*** registry.cn-guangzhou.aliyuncs.com
$ Username: admin
$ Password:
Login Succeeded

2、在k8s中生成登陆harbor配置文件

go 复制代码
#查看上一步登陆harbor生成的凭证
$ cat /root/.docker/config.json
{
	"auths": {
		"registry.cn-guangzhou.aliyuncs.com": {
			"auth": "6KaD5pe25qOuOnFp123zMTIzLg=="
		}
	}
}

3、对秘钥文件进行base64加密

go 复制代码
$ cat /root/.docker/config.json  | base64 -w 0

ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=

4、创建docker-secret.yaml

go 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: docker-login
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: xxxxxxxxxxxxxxxx
go 复制代码
$ kubectl create -f docker-secret.yaml -n go-zero-looklook

secret "docker-login" created

云效k8s连接

参考文档https://help.aliyun.com/document_detail/202419.html

登录到云效,进入项目里面,进入云效Kubernetes 集群管理页面(https://flow.aliyun.com/setting/kubernetes-manage),新建Kubernetes 集群

连接服务器A,获取k8s配置信息,并复制到阿里云中导入K8S集群

go 复制代码
$ cat /etc/rancher/k3s/k3s.yaml
----------------
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: xxxxxxxxx
    server: https://127.0.0.1:6443
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    client-certificate-data: xxxxx
    client-key-data: xxxxxxx

注意在阿里云上把其中的IP改成公网IP:server: https://127.0.0.1:6443 -> server: https://公网IP:6443

云效添加服务连接

登录到云效,进入项目里面,进入云效服务连接管理页面(https://flow.aliyun.com/setting/service-connection),新建服务连接

容器镜像服务连接

按照下图操作,阿里云容器镜像服务授权即可

云效代码服务连接

按照下图操作,云效服务授权即可

创建流水线

登录到云效,进入项目里面

我们先创建usercenter用户服务的流水线,如下图

1、修改流水线名称

配置变量和缓存

  • SERVICE_NAME: 发布的服务名称
  • DOCKER_REGISTRY:容器服务注册地址+命名空间
  • type: 运行时,选择发布服务的类型:rpc、api、mq

2、添加流水线源

添加流水线源->代码源选择云效->添加云效服务连接->选择代码仓库和分支

项目仓库和配置仓库都添加进来


工作目录和仓库名保持一致。上面截图错误了,请注意。或者自行修改命令行涉及到的工作目录

3、编辑单元测试

编辑单元测试->流水线源选择配置仓库

删除原来的步骤->添加新步骤

添加执行命令

go 复制代码
chmod +x goctl
./goctl -v

4、编辑镜像构建

删除原来的步骤->添加新步骤->构建->执行命令类型

4.1 拷贝服务配置文件

go 复制代码
yes | cp -rf /root/workspace/looklook-pro-conf/${SERVICE_NAME}/${type}/${SERVICE_NAME}.yaml app/${SERVICE_NAME}/cmd/${type}/etc

4.2 goctl创建Dockerfile

go 复制代码
chmod +x /root/workspace/looklook-pro-conf/goctl
cd app/${SERVICE_NAME}/cmd/${type} && /root/workspace/looklook-pro-conf/goctl docker -go ${SERVICE_NAME}.go && ls -l
cat Dockerfile

4.3 复制Dockerfile到项目根目录

go 复制代码
cp app/${SERVICE_NAME}/cmd/${type}/Dockerfile ./  && ls -l

4.4 镜像构建并推送至阿里云镜像仓库个人版

添加步骤->构建->镜像构建并推送至阿里云镜像仓库个人版类型

  • 连接服务:容器镜像服务连接
  • 地域:看自己地方选
  • 仓库:现在直接输入,因为涉及到变量
go 复制代码
registry.cn-guangzhou.aliyuncs.com/镜像命名空间/${SERVICE_NAME}-${type}
  • 标签: 镜像的标签
go 复制代码
${CI_COMMIT_ID_1}-${CI_COMMIT_ID_2}

5、添加新任务,k8s发布

5.1 删除原有yaml文件

添加新步骤->构建->执行命令类型

go 复制代码
rm -f ${DEPLOY_YAML}
# 变量 DEPLOY_YAML = ${SERVICE_NAME}-${type}-deploy.yaml

5.2 创建K8S YAML

go 复制代码
chmod +x ./goctl
chmod +x ./ports.sh
export port=$(./ports.sh ${SERVICE_NAME}-${type})
./goctl kube deploy -secret docker-login -replicas 2 -minReplicas 1 -maxReplicas 3 -nodePort 3${port} -requestCpu 200 -requestMem 50 -limitCpu 300 -limitMem 100 -name ${SERVICE_NAME}-${type} -namespace go-zero-looklook -image ${IMAGE_NAME} -o ${DEPLOY_YAML} -port ${port} -serviceAccount find-endpoints
cat ${DEPLOY_YAML}

# 变量 IMAGE_NAME = ${DOCKER_REGISTRY}/${SERVICE_NAME}-${type}:${CI_COMMIT_ID_1}-${CI_COMMIT_ID_2}
# 变量 DEPLOY_YAML = ${SERVICE_NAME}-${type}-deploy.yaml

5.3、发布k8s

把默认的步骤拉到最后面

  • 集群连接:选择我添加的k8s连接
  • Kubectl版本:选择和部署一直或者相近的版本(不同可能有兼容问题)
  • 命名空间:上面k8s配置的时候我们有为项目创建命名空间
  • YAML路径:

6、配置完成

运行测试

1、先运行RPC,再运行API

2、构建完成

3、查看构建推送到容器服务的镜像

4、查看服务器Ak8s部署的节点

go 复制代码
kubectl get pods -n go-zero-looklook //查看节点

kubectl describe pod usercenter-api-cc7959b84-fk4p6  -n go-zero-looklook //查看节点详细信息

kubectl logs usercenter-api-cc7959b84-fk4p6 -n go-zero-looklook//查看节点日志

问题

1、Pod状态一直 ErrImagePull / ImagePullBackOff

排查:kubectl describe、kubectl log查看日志,排查到原因是无法下载镜像

解决:阿里云镜像仓库提供公网、私网的地址,yaml文件中填写私网仓库地址无法拉取到镜像,需要改为公网

2、pod一直重启(RESTARTS一直往上增加)

排查:

  • kubectl describe、kubectl log查看日志。
  • 直接在服务器运行镜像,访问接口查看报错信息(需要把链接RPC模式改成直连)

go 复制代码
docker images
docker run -p 1004:1004 5cb981c83a2b
  • 排查到的原因,代码错误

解决:修正代码

3、端口访问错误

./goctl kube deploy -secret docker-login -... 3 -nodePort 32004 ... -port 2004 -serviceAccount find-endpoints

在pod里面监听的是2004端口(-port 2004),对外暴露是32004端口(-nodePort 32004)

4、目前Prometheus是监控不到的,真正线上环境自行研究,或者直接买个按时付费的云服务k8s

相关推荐
王码码20358 小时前
Go语言的测试:从单元测试到集成测试
后端·golang·go·接口
王码码20358 小时前
Go语言中的测试:从单元测试到集成测试
后端·golang·go·接口
嵌入式×边缘AI:打怪升级日志9 小时前
使用JsonRPC实现前后台
前端·后端
小码哥_常9 小时前
从0到1:Spring Boot 中WebSocket实战揭秘,开启实时通信新时代
后端
lolo大魔王10 小时前
Go语言的异常处理
开发语言·后端·golang
IT_陈寒12 小时前
Python多进程共享变量那个坑,我差点没爬出来
前端·人工智能·后端
码事漫谈12 小时前
2026软考高级·系统架构设计师备考指南
后端
AI茶水间管理员13 小时前
如何让LLM稳定输出 JSON 格式结果?
前端·人工智能·后端
其实是白羊14 小时前
我用 Vibe Coding 搓了一个 IDEA 插件,复制URI 再也不用手动拼了
后端·intellij idea
用户83562907805114 小时前
Python 操作 Word 文档节与页面设置
后端·python