企业级OpenVPN搭建
引言
这篇文章其实是2019年年末记录的,当时是因为疫情原因公司需要协助员工在家办公。开发部门和总部安全部门认为直接吧公司内网系统开放访问不安全,一个一个给员工家里公网IP加白名单也不现实。就临危受命接下了搭建VPN的任务。这次将文档整理发出其实在纠结会不会被请去喝茶,毕竟话题敏感。希望人没事
PS:文档在记录时并没有太多中文参考资料,是自己摸索的,所以可能生成的有些证书并没有用上(多余的操作)。大家海涵
OpenVPN介绍
OpenVPN是一个用于创建虚拟专用网络加密通道的软件包,最早由James Yonan编写。OpenVPN允许创建的VPN使用公开密钥、电子证书、或者用户名/密码来进行身份验证。
它大量使用了OpenSSL加密库中的SSLv3/TLSv1协议函数库。
目前OpenVPN能在Solaris、Linux、OpenBSD、FreeBSD、NetBSD、Mac OS X与Microsoft Windows以及Android、iOS、MacOS(2020年官方推出Mac客户端)上运行,并包含了许多安全性的功能。它并不是一个基于Web的VPN软件,也不与IPsec及其他 ...
GitLab-CI/CD
传统的应用开发发布模式
开发团队 在开发环境中完成软件开发,单元测试,测试通过,提交到代码版本管理库。
运维团队 把应用部署到测试环境,供QA团队测试,测试通过后部署生产环境。
QA 团队 purple 进行测试,测试通过后通知部署人员发布到生产环境。
传统发布面临的挑战
错误发现不及时 很多错误在项目的早期可能就存在,到最后集成的时候才发现问题。
人工低级错误发生 产品和服务交付中的关键活动全都需要手动操作。
团队工作效率低 需要等待他人的工作完成后才能进行自己的工作。
开发运维对立 开发人员想要快速更新,运维人员追求稳定,各自的针对的方向不同。
经过上述问题我们需要作出改变,如何改变?
持续集成与持续交付软件开发的连续方法基于自动执行脚本,以最大程度地减少在开发应用程序时引入错误的机会。从开发新代码到部署新代码,他们几乎不需要人工干预,甚至根本不需要干预。
它涉及到在每次小的迭代中就不断地构建,测试和部署代码更改,从而减少了基于错误或失败的先前版本开发新代码的机会。
此方法有三种主要方法,每种方法都将根据最适合您的策略的方式进行应用。
持续集成(Continuous Inte ...
GitLab-CI语法
用 .gitlab-ci.yml配置任务此文档用于描述.gitlab-ci.yml语法,.gitlab-ci.yml文件被用来管理项目的runner 任务。如果想要快速的了解GitLab CI ,可查看快速引导。
.gitlab-ci.yml从7.12版本开始,GitLab CI使用YAML文件(.gitlab-ci.yml)来管理项目配置。该文件存放于项目仓库的根目录,它定义该项目如何构建。开始构建之前YAML文件定义了一系列带有约束说明的任务。这些任务都是以任务名开始并且至少要包含script部分:
12345job1: script: "execute-script-for-job1" job2: script: "execute-script-for-job2"
上面这个例子就是一个最简单且带有两个独立任务的CI配置,每个任务分别执行不同的命令。
script可以直接执行系统命令(例如:./configure;make;make install)或者是直接执行脚本(test.sh)。
任务是由Runners接管并且由服务器中runn ...
Golang-函数
在编程中经常会调用相同或者类似的操作,这些相同或者类似的操作由同一段代码完成,函数的出现,可以避免重复编写这些代码。函数的作用就是把相对独立的某个功能抽象出来,使之成为一个独立的实体。
例如,开发一个支持人与人之间进行对话的社交网站,对话这个功能比较复杂,可以将它封装为一个函数,每次调用该函数就可以发起对话;大型网站都有日志功能,对所有重要操作都会记录日志,而日志处理需要由多行Go文件操作相关代码组成,将这些代码组装为函数,则每次写日志时调用此函数即可。
Go语言函数支持的特性包括:
参数数量不固定(可变参数)。
匿名函数及其闭包。
函数本身作为值传递。
函数的延迟执行。
把函数作为接口调用。
声明函数使用函数函数变量可变参数匿名函数和闭包延迟执行语句函数的声明以关键字func为标识,具体格式如下:
123func 函数名(参数列表) (返回参数列表){ 函数体}
函数名:函数名由字母、数字和下划线构成,但是函数名不能以数字开头;在同一个包内,函数名不可重复。注意:可暂时简单地将一个包理解为一个文件夹。
参数列表:参数列表中的每个参数都由参数名称和参数类 ...
k8s企业级DevOps实践-Kong的两种打开方式
概述KONG的核心对象为:upstream、target、service、route
upstream: 是对上游服务器的抽象;
target: 代表了一个物理服务,是 ip + port 的抽象;
service: 是抽象层面的服务,他可以直接映射到一个物理服务(host 指向 ip + port),也可以指向一个upstream 来做到负载均衡;
route: 是路由的抽象,他负责将实际的 request 映射到 service。
KONG监听的端口为:8000、8001、8443、8444、8100
8444: 带ssl的管理端口
8000/8443: 分别是用来监听来自客户端的Http 和 Https请求,等价于 Nginx 默认的 80 端口
8001: 端口便是默认的管理端口,可以通过 HTTP Restful API 来动态管理 Kong 的配置
8100: 为prometheus获取metrics指标端口
案例Nginx Conf01:
12345678910upstream helloUpstream { server localhost:30 ...
k8s企业级DevOps实践-Kong in Kubernetes
Kong介绍本文介绍将 Kong 微服务网关作为 Kubernetes 集群内部业务项目之间通讯的最佳实践,之前写过一篇文章使用 Nginx Ingress Controller 作为集群统一的流量入口:使用 Kubernetes Ingress 对外暴露服务,但是相比于 Kong Ingress Controller来说,Kong 支持的功能更加强大,更适合微服务架构:
拥有庞大的插件生态,能轻易扩展 Kong 支持的功能,比如 API 认证,流控,访问限制等;
Kong 服务本身和 Admin 管理 API 都集成在一个进程,通过端口区分两者,简化了部署的复杂度;
Kong 节点的配置统一持久化到数据库,所有节点通过数据库共享数据,在 Ingress 更新后能实时同步到各个节点,而 Nginx Ingress Controller 是通过重新加载机制响应 Ingress 更新,这种方式代价比较大,可能会导致服务的短暂中断;
Kong 有成熟的第三方管理 UI 和 Admin 管理 API 对接,从而能可视化管理 Kong 配置。
kong是一个云原生的、高性能的、可扩展的API ...
Golang-内置容器
变量和常量虽能存储数据,但是在编写一些逻辑稍复杂的程序中,往往需要存储更多、更复杂且不同类型的数据,这些数据一般存储在Go语言的内置容器中。
Go语言的内置容器主要有数组、切片和映射。下面详细介绍以上三种内置容器的特点和使用方法,学习目标:在编程中能使用恰当的容器存储数据并对其进行增加、删除和修改等操作。
数组 Array切片 Slice映射 Map
数组是具有相同类型且长度固定的一组数据项序列,这组数据项序列对应存放在内存中的一块连续区域中。
数组中存放的元素类型可以是整型、字符串或其他自定义类型。数组在使用前需先声明,声明时必须指定数组的大小且数组大小之后不可再变。
数组元素可以通过数组下标来读取或修改,数组下标从0开始,第一个元素的数组下标为0,第二个元素的数组下标为1,以此类推。
声明数组初始化数组数组增删range关键字遍历数组数组声明格式如下:
1var 数组变量名 [数组长度]元素类型
例如,声明数组student,长度为3,元素类型为string:
1var student [3]string
12345678910package mainimport &q ...
Golang-流程控制、斐波那契数列
流程控制Go语言基本上继承了C/C++语言所有流程控制语句流程控制语句主要包括:条件判断语句(if和switch)、循环控制语句(for、break和continue)和跳转语句(goto)。
if 判断for 循环switch 分支goto 跳转Go语言中,通过if关键字构成的条件判断语句进行条件判断,格式如下:
1234567if 表达式1 { 分支1} else if 表达式2 { 分支2} else { 分支3}
当表达式1的执行结果为true时,执行分支1,否则对表达式2的执行结果进行判断;
若表达式2的结果为true,执行分支2;
如果都不满足,则执行分支3。
当表达式1的执行结果为true时,执行分支1,否则对表达式2的执行结果进行判断;
若表达式2的结果为true,执行分支2;
如果都不满足,则执行分支3。
注意⚠:表达式后跟的左括号必须与表达式放在同一行中,否则程序在编译时将会触发错误,导致程序编译无法通过。另外,if、else if和else分支中对应的右括号可以另外换行,也可以与对应的左 ...
Golang-常量与运算符
常量概述: 常量与运算符是基本概念,对于Go语言,可以使用它们进行赋值、计算和比较。Go语言支持的运算包括算术运算、比较运算和逻辑运算等。
所谓常量,就是值不能变的量,比如常用的数学常数“π”就是一个常量。大多数的编程语言会使用全大写的变量名表示常量,所以约定俗成,如果常量的名字是全大写的变量,一般不做修改。
常量的定义显式定义隐式定义常量组定义常量枚举iota常量的声明以关键字const开头,后接变量类型并进行赋值,行尾没有其他标点符号。常量的显式声明格式如下:
1const 常量名 常量类型 = value
注意⚠️:一个常量被声明后可以不使用,但是变量一旦声明则必须使用。
1234567891011package mainimport "fmt"func main() { const a float64 = 3.1415 const b string = "Hello World" fmt.Println(a)}// 3.1415由于Go是编译型语言,定义常量时可以省略常量类型,因为编译器可以根据变量的值来推断其类型。常 ...
Golang-变量与基础数据类型、指针
Golang中的变量
声明变量标准格式批量声明1var 变量名 变量类型
例:声明变量num的类型为int
1var num int 使用关键字var和小括号,可以同时声明多个变量。
12345var( a int b string c bool)
初始化变量每种类型的变量初始化后都会有对应的默认值:
整型和浮点型变量的默认值为0。
字符串变量的默认值为空字符串。
布尔型变量默认为false。
切片、映射、函数和指针变量默认为nil。
注意:nil相当于其他编程语言中的null、None和NULL等,指代零值,在Go语言中只能赋值给切片、映射、函数、接口、指针或通道类型。
标准格式类型推导短变量声明并初始化1var 变量名 变量类型 = 表达式
例:声明变量num类型为int并赋值为1
1var num int = 1 在标准格式基础上,把变量类型省略后,编译器会根据等号右边的表达式推导变量的类型。例:初始化变量age值为20
1var age = 20同样会根据等号右边的表达式推导变量的类型。
1age := 30
多重赋值
1name, age := "Tom&qu ...