乐趣区

关于golang:微服务从代码到k8s部署应有尽有大结局k8s部署

咱们用一个系列来解说从需要到上线、从代码到 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 0

ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=

4、创立 docker-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: docker-login
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjEuMTgwOjgwNzciOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9Cgl9Cn0=
$ kubectl create -f docker-secret.yaml -n go-zero-looklook

secret "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 反对咱们!

微信交换群

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

退出移动版