1. 前言

前前后后学习kubernetes也有一个来月了,关于kubernetes的博客也写了有十多篇。但是技术如果无法落地到实际的应用场景终归是纸上谈兵,所以就有了这一出:通过结合kubernetesazure devops实现项目的CI/CD以及均衡负载

写完这篇后kubernetes的相关学习也暂时告一段落了,有种终于闯关成功了啊的感觉,当然这是题外话了。

以下只是以Net Core项目为例,实际运用场景中,只要是无状态服务,除了dockfile的编写有差别,剩下整个自动化部署链条中的技术也好,工具也好,都可以复用,与语言和语言框架本身无关。

以下场景需要用到的工具或者技术:

  • .Net Core

部署的应用本身

作为代码仓库

  • kubernetes

    • docker
    • helm【kubernetes的包管理工具】
    • ingress【使用ingress绑定域名和https证书,实现域名访问】
  • Azure DevOps

作为CI/CD的工具

:以下所有的相关部署代码,都在下面这个仓库

  • 仓库内容只是我自己用的一个小工具,当然具体是什么内容不重要,这篇只是演示部署相关的

https://github.com/lzw5399/TocGenerator


2. Net Core项目本身的准备

2.1 dockerfile

你需要一个dockerfile来构建一个docker image, 如果是.Net Core项目,vs提供了傻瓜式生成dockerfile的功能,可以免去初学时编写dockerfile的烦恼

  • 本示例dockerfile路径和内容

2.2 创建kubernetes用于helm的chart包

2.2.1 说明

这一部分需要有helm相关的知识,说白了就是将你的如果熟悉k8s但不熟悉helm,可以参照:

kubernetes系列(十六) - Helm安装和入门

2.2.2 chart文件目录和文件组成

自定义的chart包,位于以下路径

https://github.com/lzw5399/TocGenerator/tree/master/kubernetes

如上图可以看出是一个很经典的自定义chart包的文件目录,即:

.
├── Chart.yaml 【chart的name和version等信息】
├── templates 【k8s的资源清单模板,可以引用values.yaml的变量】
| ├── deployment.yaml
| └── service.yaml
├── values.yaml 【定义变量,供template/下的yaml使用,实现动态替换yaml内容】

3. Azure Devops创建仓库的pipeline

3.1 前言

Azure DevOps是微软出品的DevOps平台,里面包含了Pipelines工具链,对个人免费,可以用于项目的CI/CD

https://dev.azure.com

3.2 使用azure devops准备操作

  • 如果之前使用过azure devops,这几步可以视情况跳过。
  1. 进入azure devops注册账号
  2. 之后按照引导新建一个organization
  3. 再新建一个project
  4. 进入project

3.3 创建service connections

这里要创建一个service connections,用于之后pipeline访问k8s的master服务器

  1. 点击peject setting
  2. 这里点击service connections来创建一个连接,用于访问k8s的master服务器
  3. 然后填写具体的凭证,之后的pipeline上需要

3.4 新建pipeline流水线

新建pipeline流水线用于自定义部署流程

  1. 点击pipelines,然后点击create pipelines,新建一条流水线来部署我们的应用
  2. 选择代码仓库位置,选github
  3. 然后会跳到github进行授权,授权完成后会显示github的repo列表,选择具体的仓库
  4. 选择完仓库后,会自动按照你当前项目的语言,在github仓库的根目录生成一个默认的azure-pipelines.yml文件,
  5. 替换文件的内容,我们最终使用的yaml文件步骤大概如下
    • 第一步:构建docker镜像
    • 第二步:将自定义的chart包拷贝到master服务器上
    • 第三步:执行deploy.sh脚本,完成部署
# 哪条分支会触发构建
trigger:
- master resources:
- repo: self # 定义变量
variables:
- name: appName
value: tocgenerator - name: tag
value: $(Build.BuildNumber) - name: imageNameWithoutTag
value: $(dockerid)/$(appName) - name: imageNameWithTag
value: $(imageNameWithoutTag):$(tag) - name: serverChartLocation
value: /root/helm-chart-folder/toc stages:
- stage: Build
jobs:
- job: Build
pool:
vmImage: 'ubuntu-latest' # 这下面是每个我们要具体执行的任务
steps:
# build docker images并且push到仓库
- task: Docker@2
displayName: docker build and push
inputs:
containerRegistry: 'my_docker_hub'
repository: '$(imageNameWithoutTag)'
command: 'buildAndPush'
Dockerfile: '**/Dockerfile'
buildContext: '.'
tags: $(tag)
addPipelineData: false # 将kubernetes文件夹,即chart包拷贝到k8s的master服务器
- task: CopyFilesOverSSH@0
displayName: copy helm chart to server
inputs:
# 这个endpoint就是我们刚刚创建的service connection的名字
sshEndpoint: 'my_server'
sourceFolder: 'kubernetes'
contents: '**'
targetFolder: $(serverChartLocation)
readyTimeout: '20000' # 在k8s的master服务器上运行我们github仓库的根目录的deploy.sh,进行部署操作
- task: SSH@0
displayName: run deploy shell on server
inputs:
# 这个endpoint就是我们刚刚创建的service connection的名字
sshEndpoint: 'my_server'
runOptions: 'script'
scriptPath: 'deploy.sh'
args: '$(tag) $(serverChartLocation)'
readyTimeout: '20000'

3.5 创建部署shell脚本

部署脚本的位置

https://github.com/lzw5399/TocGenerator/blob/master/deploy.sh

几点说明

  1. echo纯粹是为了记录log使用的,下面的示例把echo部分删除了
  2. $1 and $2 代表外部传入的参数
  3. $1是image的tag,$2是k8s的master服务器上我们自定义的chart的目录
  4. 移除没有tag的悬挂docker image,纯粹为了节省服务器空间,为可选项
#!/bin/bash

# 出现错误退出脚本执行
set -o errexit # $1 and $2 代表外部传入的参数
# $1是image的tag,$2是k8s的master服务器上我们自定义的chart的目录
buildNumber=$1
serverChartLocation=$2
cd $serverChartLocation # 安装或者升级我们的helm release
# 即如果查询到了有release存在就upgrade,没有则install
if test -z "$(helm ls | grep toc-release)"; then
helm install -f values.yaml --set env.buildnumber=$buildNumber --set image.tag=$buildNumber toc-release .
else
helm upgrade -f values.yaml --set env.buildnumber=$buildNumber --set image.tag=$buildNumber toc-release .
fi # 移除没有tag的悬挂docker image(可选)
danglings=$(sudo docker images -f "dangling=true" -q)
if test -n "$danglings"; then
sudo docker rmi $(sudo docker images -f "dangling=true" -q) >>/dev/null 2>&1
if [[ $? != 0 ]]; then
exit $?
fi
fi exit 0

4. 触发pipeline部署流水线

这里有两种办法,

  1. 点击我们刚刚创建的pipeline手动run一个
  2. 通过push代码到仓库的指定分支(我们设置的master)触发构建

显示构建成功之后就可以查看了!

5. 关于均衡负载

均衡负载是kubernetes自带的基础功能之一,这里只是做了一个试验可以更加直观地感受到而已

如下

  1. 定义一个静态的guid
  2. 在/version 路由下输出guid

则如果有2个实例,且均衡负载成功的话,每次刷新这个界面,会随机显示这两个guid

  • deployment的replicas实例数需要设置2以上

最后均衡负载试验的地址,也是本次实例项目的线上地址

https://toc.codepie.fun/version

  • 如下,会出现两个不同的guid

kubernetes+Azure DevOps实现.Net Core项目的自动化部署&均衡负载的更多相关文章

  1. Docker+GitLab+Jenkins+kubernetes实现DevOps 持续化集成和持续化部署概念图

    Docker+GitLab+Jenkins+kubernetes实现DevOps 持续化集成和持续化部署概念图 转载自:原创 IT综合 作者:百联达 时间:2017-05-09 15:48:08 41 ...

  2. 利用PowerShell+Jenkins,实现项目的自动化部署

    当项目越来越庞大,部署环境越来越多以后,就会越来越依赖于自动化.比如本人公司的项目,目前有6个web和4个windows service,同时本地有两套环境:开发自测试环境和QA测试环境.每次版本发布 ...

  3. 利用Jenkins实现JavaWeb项目的自动化部署

    修改代码,打包,上传,重启... 大把的时间花费在这些重复无味的工作上.笔者与当前主流的价值观保持一致:我们应该把时间花费在更有意义的事情上.我们可以尝试借助一些工具,让这些重复机械的工作交给计算机去 ...

  4. 使用Git实现Laravel项目的自动化部署

    简介 不知道大家一开始是怎么使用 git 进行开发的,反正我个人是先将代码提交到 github 仓库,然后用 SSH 登录到服务器,然后进行克隆或者版本更新.听起来就很麻烦,当然实际操作中也很麻烦,那 ...

  5. 【Azure DevOps系列】Azure DevOps使用Docker将.NET应用程序部署在云服务器

    Docker持续集成 本章我们要实现的是通过我们往代码仓库push代码后,我们将每次的push进行一次docker自动化打包发布到docker hub中,发布到之后我将进行部署环节,我们将通过ssh方 ...

  6. 在Azure DevOps Server(TFS系统)中部署回退/回滚方案(Rollback)

    概述 Azure DevOps Server(之前名TFS)是微软公司实现软件研发.测试和部署一体化的全流程解决方案.在近几年的研发过程中,Azure DevOps Server 大幅增强了软件部署过 ...

  7. 利用jenkins做项目的自动化部署

    最近领导要求上海本地的项目需要使用进jenkins实现自动化部署,以便可以直接将项目移交给运维的同学,减轻开发的工作量.记录下这次爬坑的过程. 一.前言 Jenkins是基于Java开发的一种持续集成 ...

  8. jenkins+maven+svn实现springboot项目的自动化部署过程

    说明:部署springboot项目的jar 前提(参考:https://www.cnblogs.com/myitnews/p/11493779.html): 全局安全配置(前面配置过) 全局工具配置( ...

  9. Kubernetes笔记(三):Gitlab+Jenkins Pipeline+Docker+k8s+Helm自动化部署实践(干货分享!)

    通过前面两篇文章,我们已经有了一个"嗷嗷待哺"的K8s集群环境,也对相关的概念与组件有了一个基本了解(前期对概念有个印象即可,因为只有实践了才能对其有深入理解,所谓"纸上 ...

随机推荐

  1. JavaWeb网上图书商城完整项目--day02-10.提交注册表单功能之页面实现

    1.当从服务器返回的注册错误信息的时候,我们在注册界面需要将错误信息显示出来 我们需要修改regist.jsp页面的代码:其中error是一个haspmap,c标签对map的属性可以直接使用 ${er ...

  2. SDL软件安全读书笔记(一)

    # 如何应对当前的全球网络安全威胁? 开发安全漏洞尽可能少的软件,应该着眼于源头安全. 边界安全盒深度防御是重要的安全手段,但软件自身的安全是安全防护的第一关. 即使软件源头存在较少的漏洞,这些漏洞也 ...

  3. 入门大数据---Kafka的搭建与应用

    前言 上一章介绍了Kafka是什么,这章就讲讲怎么搭建以及如何使用. 快速开始 Step 1:Download the code Download the 2.4.1 release and un-t ...

  4. 【部分】ASP.NET MVC的Controller接收输入详解

    原文:https://blog.csdn.net/lxrj2008/article/details/79455360 ASP.NET mvc的Controller要正确的响应用户发出的请求就要获取到用 ...

  5. ASP.NET 开源导入导出库Magicodes.IE 多Sheet导入教程

    多Sheet导入教程 说明 本教程主要说明如何使用Magicodes.IE.Excel完成多个Sheet数据的Excel导入. 要点 多个相同格式的Sheet数据导入 多个不同格式的Sheet数据导入 ...

  6. Oracle IO性能测试

    Oracle IO性能测试 前言 最近发生了迁移测试库后(单节点迁移RAC)因为IO性能问题导致迁移后性能非常差的问题. 原本想在创建ASM磁盘组之前用Orion做测试,但是忘了做就没做结果出了这档子 ...

  7. SQL注入原理及代码分析(一)

    前言 我们都知道,学安全,懂SQL注入是重中之重,因为即使是现在SQL注入漏洞依然存在,只是相对于之前现在挖SQL注入变的困难了.而且知识点比较多,所以在这里总结一下.通过构造有缺陷的代码,来理解常见 ...

  8. List AND Set

    第二章 List集合 Collection中的常用几个子类(java.util.List集合.java.util.Set集合). 1.1 List接口介绍 java.util.List接口继承自Col ...

  9. 自描述C++部分面试题集

    1.谈谈啥叫对象成员以及对象成员的构造函数调用调用方式. 在类中定义的数据成员一般都是基本的数据类型.但是类中的成员也可以是对象,叫做对象成员. C++中对对象的初始化时非常重要的操作,当创建一个对象 ...

  10. 总结几个移动端H5软键盘的大坑

    1.部分机型软键盘弹起挡住原来的视图 解决方法:可以通过监听移动端软键盘弹起 Element.scrollIntoView() 方法让当前的元素滚动到浏览器窗口的可视区域内.参数如下. true,表示 ...