咱们用一个系列来解说从需要到上线、从代码到k8s部署、从日志到监控等各个方面的微服务残缺实际。

整个我的项目应用了go-zero开发的微服务,根本蕴含了go-zero以及相干go-zero作者开发的一些中间件,所用到的技术栈根本是go-zero项目组的自研组件,根本是go-zero全家桶了。

实战我的项目地址:https://github.com/Mikaelemmm...

1、概述

上一节,咱们曾经把gitlab、jenkins、harbor、k8s都曾经搭建好了,这一节咱们来编写jenkins的pipline将咱们的服务通过jenkins残缺的公布到k8s中。

2、部署中间件

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

登陆到 192.168.1.181

$ mkdir data && cd data && vim docker-compose.yml$ docker-compose up -d$ docker-compose ps #查看确认

3、独立配置

将每个服务的配置都独立进去,对立放在一个git仓库,这样只给一个人线上仓库的权限,如果线上配置有变间接批改这个仓库的文件,在jenkins做cd的时候,会先拉取代码再拉取对应服务的配置主动构建,具体能够看前面的pipline。

【问】为什么不必配置核心?

1)批改db、redis等须要重启服务,然而有一些配置又不须要重启服务,运维又要去记,记混了比拟容易造成线上事变

2)不便回滚。咱们发新版本到线上,并且又改了新版本配置。这时候线上用户反馈有问题,线上须要疾速回滚的话,如果咱们应用将文件构建到镜像中,间接应用k8s一行命令就能够将上一个版本代码加配置间接回滚回来。如果应用了配置核心,回滚了代码,还要将上个版本的配置去配置核心改回来,很麻烦。

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

仓库地址 : https://github.com/Mikaelemmm... , 间接下载就好

1、批改配置中的中间件,数据库、redis等都要改成192.168.1.181这台机器,咱们把这台机器当成线上环境的中间件。

2、另外一个就是咱们的服务发现,线上咱们部署在k8s中,go-zero间接反对k8s服务发现,所以不须要etcd等,咱们在配置zrpc client的时候,要改成target,k8s的配置形式。

4、编写 jenkins 的 pipline

4.1 配置参数

拜访 http://192.168.1.180:8989/ 关上jenkins,进入jenkins首页,点击左侧菜单新建Item

咱们先创立 identity 受权服务的流水线

而后点击“General” , 抉择“This project is parameterized” , "增加参数",“Choice Parameter”,如下图

而后编写内容如下

间接保留。

4.2 编写pipline

向下滑动找到Pipeline script,填写脚本内容

pipeline {  agent any  parameters {      gitParameter name: 'branch',       type: 'PT_BRANCH',      branchFilter: 'origin/(.*)',      defaultValue: 'master',      selectedValue: 'DEFAULT',      sortMode: 'ASCENDING_SMART',      description: '抉择须要构建的分支'  }  stages {      stage('服务信息')    {          steps {              sh 'echo 分支:$branch'              sh 'echo 构建服务类型:${JOB_NAME}-$type'          }      }      stage('拉取代码') {          steps {              checkout([$class: 'GitSCM',               branches: [[name: '$branch']],              doGenerateSubmoduleConfigurations: false,               extensions: [],               submoduleCfg: [],              userRemoteConfigs: [[credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook.git']]])          }         }      stage('获取commit_id') {          steps {              echo '获取commit_id'              git credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook.git'              script {                  env.commit_id = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()              }          }      }      stage('拉取配置文件') {              steps {                  checkout([$class: 'GitSCM',                   branches: [[name: '$branch']],                  doGenerateSubmoduleConfigurations: false,                   extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'conf']],                   submoduleCfg: [],                  userRemoteConfigs: [[credentialsId: 'gitlab-cert', url: 'ssh://git@192.168.1.180:2222/root/go-zero-looklook-pro-conf.git']]])              }         }      stage('goctl版本检测') {          steps{              sh '/usr/local/bin/goctl -v'          }      }            stage('Dockerfile Build') {          steps{                 sh 'yes | cp  -rf conf/${JOB_NAME}/${type}/${JOB_NAME}.yaml  app/${JOB_NAME}/cmd/${type}/etc'   //线上配置文件                 sh 'cd app/${JOB_NAME}/cmd/${type} && /usr/local/bin/goctl docker -go ${JOB_NAME}.go && ls -l'                 script{                     env.image = sh(returnStdout: true, script: 'echo ${JOB_NAME}-${type}:${commit_id}').trim()                 }                 sh 'echo 镜像名称:${image} && cp app/${JOB_NAME}/cmd/${type}/Dockerfile ./  && ls -l && docker build  -t ${image} .'          }      }      stage('上传到镜像仓库') {          steps{                //docker login 这里要留神,会把账号密码输入到jenkins页面,能够通过port.sh相似形式解决,官网文档有这里我就不具体写了              sh 'docker login --username=${docker_username} --password=${docker_pwd} http://${docker_repo}'               sh 'docker tag  ${image} ${docker_repo}/go-zero-looklook/${image}'              sh 'docker push ${docker_repo}/go-zero-looklook/${image}'          }      }      stage('部署到k8s') {          steps{              script{                  env.deployYaml = sh(returnStdout: true, script: 'echo ${JOB_NAME}-${type}-deploy.yaml').trim()                  env.port=sh(returnStdout: true, script: '/root/port.sh ${JOB_NAME}-${type}').trim()              }              sh 'echo ${port}'              sh 'rm -f ${deployYaml}'              sh '/usr/local/bin/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} --home /root/template'              sh '/usr/local/bin/kubectl apply -f ${deployYaml}'          }      }       stage('Clean') {           steps{               sh 'docker rmi -f ${image}'               sh 'docker rmi -f ${docker_repo}/${image}'               cleanWs notFailBuild: true           }       }  }}
十分重要!!!
  1. 构建优化:pipline中生成dockerfile的时候,咱们是应用k8s形式部署不须要etcd,然而这种形式部署须要指定账号(有去k8s的endpoints中get的权限,应用默认default就好了,每次创立一个新的命名空间k8s会主动帮咱们创立好一个default),然而应用goctl 生成的 k8s yml没有增加指定账号选项,这个曾经反馈了,可能后续版本会加上,这里咱们也用模版做了,同样模版是在我的项目目录下https://github.com/Mikaelemmm...,pipline中构建指定这个模版即可
  2. ${credentialsId}要替换为你的具体凭据值,即【增加凭据】模块中的一串字符串,咱们之前配置的是gitlab-cert所以这里就填写gitlab-cert,如果你不是这个本人要更换,${gitUrl}须要替换为你代码的git仓库地址,其余的${xxx}模式的变量无需批改,放弃原样即可。
  3. 这里跟官网文档有一点点不一样,因为我我的项目文件夹目录不同,goctl生成的dockerfile文件我手动做了点调整,在一个我不是在构建时候生成的dockerfile,是在创立我的项目时候就把dockerfile一起放在目录下,这样构建镜像时候不须要goctl了

5、配置k8s拉取公有仓库镜像

k8s在默认状况下,只能拉取harbor镜像仓库的私有镜像,如果拉取公有仓库镜像,则是会报 ErrImagePullImagePullBackOff 的谬误

1、先在jenkins公布机器登陆harbor

$ docker login 192.168.1.180:8077$ Username: admin$ Password:Login Succeeded

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

#查看上一步登陆harbor生成的凭证$ cat /root/.docker/config.json  {    "auths": {        "192.168.1.180:8077": {            "auth": "YWRtaW46SGFyYm9yMTIzNDU="        }}

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

$ cat /root/.docker/config.json  | base64 -w 0ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=

4、创立docker-secret.yaml

apiVersion: v1kind: Secretmetadata:  name: docker-logintype: kubernetes.io/dockerconfigjsondata:  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
$ kubectl create -f docker-secret.yaml -n go-zero-looklooksecret "docker-login" created

6、构建

咱们进入首页,点击idenity进入详情页

而后能够看到,下面咱们配置好的identity服务,如下图 ,点击“Build with Parameters”, 而后抉择rpc,点击“开始构建”

第一次构建在拉代码时候都会失败,应该是初始化啥货色,再点一次就好了。

部署胜利

同样情理,去构建identity-api,再去配置usercenter服务 构建usercenter-rpc、构建usercenter-api,接着配置其余服务、构建即可,本次咱们先只构建identity-api、identity-rpc、usercenter-rpc、usercenter-api给大家演示。

6、增加网关

因为咱们的api服务通过goctl公布在k8s中都会裸露nodeport端口,索引咱们看下k8s中go-zero-looklook命名空间下的service的nodeport端口服务,而后将nodeport配置在nignx即可。

本次咱们独立一台虚拟机在k8s之外,装置nginx,将k8s后端api服务通过nodeport形式把端口裸露给nginx,而后nginx在配置中配置此api服务,这样nginx就充当网关应用。

nginx的装置就不再这里多说了,记得肯定要有auth_request模块,没有的话本人去装置。

nginx的配置

server{    listen 8081;    access_log /var/log/nginx/looklook.com_access.log;    error_log /var/log/nginx//looklook.com_error.log;    location /auth {        internal;      proxy_set_header X-Original-URI $request_uri;        proxy_pass_request_body off;        proxy_set_header Content-Length "";        proxy_pass http://192.168.1.182:31001/identity/v1/verify/token;    }    location ~ /usercenter/ {       auth_request /auth;       auth_request_set $user $upstream_http_x_user;       proxy_set_header x-user $user;       proxy_set_header Host $http_host;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header REMOTE-HOST $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_pass http://192.168.1.182:31002;   }   location ~ /travel/ {       auth_request /auth;       auth_request_set $user $upstream_http_x_user;       proxy_set_header x-user $user;       proxy_set_header Host $http_host;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header REMOTE-HOST $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_pass http://192.168.1.182:31003;   }   location ~ /order/ {       auth_request /auth;       auth_request_set $user $upstream_http_x_user;       proxy_set_header x-user $user;       proxy_set_header Host $http_host;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header REMOTE-HOST $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_pass http://192.168.1.182:31004;   }   location ~ /payment/ {       auth_request /auth;       auth_request_set $user $upstream_http_x_user;       proxy_set_header x-user $user;       proxy_set_header Host $http_host;       proxy_set_header X-Real-IP $remote_addr;       proxy_set_header REMOTE-HOST $remote_addr;       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;       proxy_pass http://192.168.1.182:31005;   }}

如果是线上的话,应该配置多台nignx放弃高可用,在nignx后面还会有一个slb,你的域名包含https配置都应该解析到slb,在slb后面在有防火墙等这些。

8、结束语

至此,整个系列就完结了,整体架构图应该如第一篇所展现,本系列心愿能给你带来帮忙。

我的项目地址

https://github.com/zeromicro/go-zero

欢送应用 go-zerostar 反对咱们!

微信交换群

关注『微服务实际』公众号并点击 交换群 获取社区群二维码。