• 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

    cd /usr/local/src/
    mkdir data && cd data && vim docker-compose.yml
    docker-compose up -d
    docker-compose ps #查看确认
    
    • 1
    • 2
    • 3
    • 4

    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内容如下

    #!/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
    • 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
    • 28
    • 29

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

    1、goctl版本需要>=1.3.3。
    2、在Windows下上传需要注意goctl和port.sh文件权限问题。

    编写云效的pipline

    k8s配置

    配置服务发现

    创建looklook项目的命名空间

    kubectl create namespace go-zero-looklook
    
    • 1

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

    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文件如下:

    #创建账号
    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
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32

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

    ./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
    
    • 1
    配置k8s拉取私有仓库镜像

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

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

    $ docker login --username=*** registry.cn-guangzhou.aliyuncs.com
    $ Username: admin
    $ Password:
    Login Succeeded
    
    • 1
    • 2
    • 3
    • 4

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

    #查看上一步登陆harbor生成的凭证
    $ cat /root/.docker/config.json
    {
    	"auths": {
    		"registry.cn-guangzhou.aliyuncs.com": {
    			"auth": "6KaD5pe25qOuOnFp123zMTIzLg=="
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    $ cat /root/.docker/config.json  | base64 -w 0
    
    ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
    
    • 1
    • 2
    • 3

    4、创建docker-secret.yaml

    apiVersion: v1
    kind: Secret
    metadata:
      name: docker-login
    type: kubernetes.io/dockerconfigjson
    data:
      .dockerconfigjson: xxxxxxxxxxxxxxxx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    $ kubectl create -f docker-secret.yaml -n go-zero-looklook
    
    secret "docker-login" created
    
    • 1
    • 2
    • 3

    云效k8s连接

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

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

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

    $ 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    注意在阿里云上把其中的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、编辑单元测试
    编辑单元测试->流水线源选择配置仓库

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

    添加执行命令

    chmod +x goctl
    ./goctl -v
    
    • 1
    • 2

    4、编辑镜像构建
    删除原来的步骤->添加新步骤->构建->执行命令类型
    4.1 拷贝服务配置文件

    yes | cp -rf /root/workspace/looklook-pro-conf/${SERVICE_NAME}/${type}/${SERVICE_NAME}.yaml app/${SERVICE_NAME}/cmd/${type}/etc
    
    • 1

    4.2 goctl创建Dockerfile

    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
    
    • 1
    • 2
    • 3

    4.3 复制Dockerfile到项目根目录

    cp app/${SERVICE_NAME}/cmd/${type}/Dockerfile ./  && ls -l
    
    • 1

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

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


    5、添加新任务,k8s发布

    5.1 删除原有yaml文件
    添加新步骤->构建->执行命令类型

    rm -f ${DEPLOY_YAML}
    # 变量 DEPLOY_YAML = ${SERVICE_NAME}-${type}-deploy.yaml
    
    • 1
    • 2

    5.2 创建K8S YAML

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.3、发布k8s
    把默认的步骤拉到最后面

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

    6、配置完成

    运行测试

    1、先运行RPC,再运行API

    2、构建完成

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

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

    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
    • 2
    • 3
    • 4
    • 5

    问题

    1、Pod状态一直 ErrImagePull / ImagePullBackOff
    排查:kubectl describe、kubectl log查看日志,排查到原因是无法下载镜像
    解决:阿里云镜像仓库提供公网、私网的地址,yaml文件中填写私网仓库地址无法拉取到镜像,需要改为公网

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

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

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

    解决:修正代码

    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

  • 相关阅读:
    数据挖掘技术-绘制折线图
    vue启动项目,npm run dev出现error:0308010C:digital envelope routines::unsupported
    [原创]一种自动化九点标定工具原理(包涵部分源码)
    娣卞害绁炵粡缃戠粶棰勬祴妯″瀷
    修改静态IP和配置主机名
    爬虫入门篇
    python学习--字符串的常用操作
    零基础做出高端堆叠极环图
    自己一天在家没事就爱折腾
    《Linux篇》01.Linux简介安装与常用命令
  • 原文地址:https://blog.csdn.net/qq_35429326/article/details/136363455