共计 7579 个字符,预计需要花费 19 分钟才能阅读完成。
咱们用一个系列来解说从需要到上线、从代码到 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
}
}
}
}
十分重要!!!
- 构建优化:pipline 中生成 dockerfile 的时候,咱们是应用 k8s 形式部署不须要 etcd,然而这种形式部署须要指定账号(有去 k8s 的 endpoints 中 get 的权限,应用默认 default 就好了,每次创立一个新的命名空间 k8s 会主动帮咱们创立好一个 default),然而应用 goctl 生成的 k8s yml 没有增加指定账号选项,这个曾经反馈了,可能后续版本会加上,这里咱们也用模版做了,同样模版是在我的项目目录下 https://github.com/Mikaelemmm…,pipline 中构建指定这个模版即可
- ${credentialsId}要替换为你的具体凭据值,即【增加凭据】模块中的一串字符串,咱们之前配置的是 gitlab-cert 所以这里就填写 gitlab-cert,如果你不是这个本人要更换,${gitUrl}须要替换为你代码的 git 仓库地址,其余的 ${xxx}模式的变量无需批改,放弃原样即可。
- 这里跟官网文档有一点点不一样,因为我我的项目文件夹目录不同,goctl 生成的 dockerfile 文件我手动做了点调整,在一个我不是在构建时候生成的 dockerfile,是在创立我的项目时候就把 dockerfile 一起放在目录下,这样构建镜像时候不须要 goctl 了
5、配置 k8s 拉取公有仓库镜像
k8s 在默认状况下,只能拉取 harbor 镜像仓库的私有镜像,如果拉取公有仓库镜像,则是会报 ErrImagePull
和 ImagePullBackOff
的谬误
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-zero
并 star 反对咱们!
微信交换群
关注『微服务实际 』公众号并点击 交换群 获取社区群二维码。