当前位置:首页 > 科技  > 软件

摸鱼心法第一章——和配置文件说拜拜

来源: 责编: 时间:2023-08-05 11:44:34 3978观看
导读为了能摸鱼我们团队做了容器化,但是带来的问题是服务配置文件很麻烦,然后大家在群里进行了“亲切友好”的沟通图片图片图片图片对比就对比,简单对比下独立配置中心和k8s作为配置中心的区别
独立配置中心k8s作为配置中心

为了能摸鱼我们团队做了容器化,但是带来的问题是服务配置文件很麻烦,然后大家在群里进行了“亲切友好”的沟通2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

对比就对比,简单对比下独立配置中心和k8s作为配置中心的区别2cn28资讯网——每日最新资讯28at.com


2cn28资讯网——每日最新资讯28at.com

独立配置中心2cn28资讯网——每日最新资讯28at.com

k8s作为配置中心2cn28资讯网——每日最新资讯28at.com

学习成本2cn28资讯网——每日最新资讯28at.com

1.运维要学习搭建、维护2cn28资讯网——每日最新资讯28at.com

2.研发和研发都需要学习配置中心的工具、系统如何使用2cn28资讯网——每日最新资讯28at.com

1.熟悉yaml/json语法即2cn28资讯网——每日最新资讯28at.com

2.研发只需要解析环境变量,无需关注注入细节2cn28资讯网——每日最新资讯28at.com

适配工作量2cn28资讯网——每日最新资讯28at.com

  1. 代码需要引入对应配置中心的库进行开发
  2. 需要在对应的配置中心管理

  1. 服务直接解析环境变量即可
  2. k8s原生支持环境变量,并且支持通过configmap,secret资源注入到服务的环境变量中

集群维护成本2cn28资讯网——每日最新资讯28at.com

额外维护成本2cn28资讯网——每日最新资讯28at.com

保证集群etcd稳定即可,无额外成本2cn28资讯网——每日最新资讯28at.com

服务发现2cn28资讯网——每日最新资讯28at.com

支持服务发现2cn28资讯网——每日最新资讯28at.com

支持服务发现2cn28资讯网——每日最新资讯28at.com

云资源费用2cn28资讯网——每日最新资讯28at.com

增加成本2cn28资讯网——每日最新资讯28at.com

无额外成本2cn28资讯网——每日最新资讯28at.com

对比结果出来后,群里的研发也觉得k8s作为配置中心不错了2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

我这里想问问在看文章的同学:是不是都觉得运维的东西很简单?还有是不是个锅都甩给运维?像这样的研发你身边多么还是说你也是这样的研发? 2cn28资讯网——每日最新资讯28at.com

继续今天的话题,既然服务要在k8s里运行,同时也要把k8s作为配置中心使用,那服务适配需要做些啥? 咱们先列一个清单2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

服务要优雅的适配容器化环境,需要解决以下问题2cn28资讯网——每日最新资讯28at.com

  • 避免繁琐的定义和解析服务环境变量
  • 服务在本地调试下和容器环境运行两种场景下,对于环境变量的解析需要无缝切换
  • 服务的dockerfile可根据服务信息自动生成,尽量避免人工操作

1.首先说环境变量的问题

从本地开发和容器运行两个角度来看,本地开发的时候读取配文件比读取环境变量方便,容器运行中读取环境变量比读取配置文件方便,我想说你俩搁这卡bug呢?2cn28资讯网——每日最新资讯28at.com

但是这个问题其实不难,解决逻辑也很简单。那就是采用覆写的思路,如果环境变量里读取到了值就用环境变量的,否则就用代码里的值。2cn28资讯网——每日最新资讯28at.com

那按照这个思路是得有一个配置文件,然后服务读取这个配置文件?可惜这个和我们团队的一个追求相违背——代码及文档2cn28资讯网——每日最新资讯28at.com

说到文档,插个题外话,对于写文档这事儿。。。2cn28资讯网——每日最新资讯28at.com

看别人的东西,你TM文档呢? 2cn28资讯网——每日最新资讯28at.com

做自己的东西,这TM还用写文档?2cn28资讯网——每日最新资讯28at.com

回到环境变量这个问题来,其实在代码里面定义变量并提供覆写的能力就足够了。考虑到在本地开发调试的时候,需要频繁修改变量的值,无论是修改代码里的变量值或者修改环境变量还是稍显麻烦,所以覆写的信息可以来源于环境变量或一个覆写的变量文件2cn28资讯网——每日最新资讯28at.com

流程如下2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

针对提供反射机制的编程语言结合一定的规则,环境变量的key可以直接从定义的结构体里获取无需额外维护。无反射类型的编程语言也可以按照这个思路实现,只是稍显麻烦。这样环境变量的问题解决了,然后就是dockerfile的问题2cn28资讯网——每日最新资讯28at.com

2.dockerfile如何自动生成

我们再看看刚才列的清单2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

首先说说核心问题如何编译,有两种方式2cn28资讯网——每日最新资讯28at.com

1.直接在dockerfile里面写编译过程

直接手写dockerfile没有问题,因为服务的开发人员最清楚自己的服务需要怎么编译,但是不同的服务总会出现差异化的编译过程,这样从代码自动生成dockerfile的角度来讲不可控2cn28资讯网——每日最新资讯28at.com

2.makefile文件

通过makefile来执行编译步骤就解决了差异化的问题,在dockerfile里只需要执行类似make build的固定命令便完成了服务编译全过程。自动化工具按照固定的dockerfile模板生成文件,makefile完成具体的编译过程,这样服务编译与工具完美解耦2cn28资讯网——每日最新资讯28at.com

核心问题解决了,至于dockerfile如何生成,每种编程语言都可以采用自身语言提供的模板库进行生成dockerfile了。即便不用模板,拼接字符串也是可以的,条条大路通罗马。2cn28资讯网——每日最新资讯28at.com

然后我们再谈谈为什么会有编译镜像和运行镜像的区别,我们看看下面这个流程2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

从流程可以看出,服务在k8s里面启动时会从镜像仓库拉去服务镜像,这里存在一个网络传输的问题,内网都不说了,如果从公网拉镜像,并发量高一点,拉的再频繁点,不管是固定带宽还是按流量计费,老话说得好,这不就是小刀剌了貔貅腚——拉的都是钱2cn28资讯网——每日最新资讯28at.com

所以我们期望的是镜像足够小,这样在部署服务的时候更快更省钱,尤其是首次部署的时候(这里涉及到docker 分层的问题不做展开)。编译镜像一般都非常庞大并不适合作为运行镜像使用,只需要提供编译环境,编译完成后将编译后的文件放入一个很小的运行镜像中即可2cn28资讯网——每日最新资讯28at.com

以我们团队采用的是Golang语言为例,编译镜像目前采用的1.20.5-buster,AMD64的镜像大小为275M,ARM的镜像大小为264M,运行镜像采用的是gcr.io/distroless/static-debian11,最终运行镜像大小在20M左右,这不得起飞了啊,拉镜像就跟玩儿一样。2cn28资讯网——每日最新资讯28at.com

好了,今天的文章主要分享了在容器化环境下,通过抛弃服务配置文件而采用环境变量的形式来解决配置注入的问题,自动生成dockerfile需要避免的坑,希望对在走容器化道路的同学有所帮助。如果大家想听听其他的可以留言或者私信我们。2cn28资讯网——每日最新资讯28at.com

接下来就是Golang的福利时间,我们将这个变量注入的库进行了开源。现在用gin框架写个demo来演示环境变量注入和生成dockerfile。(我们在gin框架上加了一点点东西,这样更好用)2cn28资讯网——每日最新资讯28at.com

首先创建一个工程目录2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

global/config.go这个文件长这样2cn28资讯网——每日最新资讯28at.com

package globalimport (  "github.com/kunlun-qilian/conflogger"  "github.com/kunlun-qilian/confserver"  "github.com/kunlun-qilian/confx")func init() {  confx.SetConfX("demo-docker", "..")  confx.ConfP(&Config)}var Config = struct {  Logger  *conflogger.Log  Server  *confserver.Server  TestEnv string `env:""`# 环境变量标记,只要有这个标记则支持注入}{  Server: &confserver.Server{    Port: 80,    Mode: "debug",  },  TestEnv: "123",}
github.com/kunlun-qilian/confx这个库的作用就是注入环境变量和生成dockerfile,单独出来了一个库,只要是这个工程目录结构都可以使用

运行之后会生成config/default.yml,这个环境变量文件就是每次启动服务后根据上述global/config.go文件自动生成的默认配置文件,这个文件是作为后续本地覆写配置文件的蓝本,免得不知道环境变量是啥,环境变量规则是“服务名__环境变量名”2cn28资讯网——每日最新资讯28at.com

DEMO_DOCKER__Logger_Level: ""DEMO_DOCKER__Logger_Output: AlwaysDEMO_DOCKER__Server_Mode: debugDEMO_DOCKER__Server_UseH2C: "false"DEMO_DOCKER__TestEnv: "123"

demo里加入了一个接口来返回TestEnv的值2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

在本地开发的时候需要覆写默认值的时候,只需要在config目录下加入一个叫做 local.yml(这个放gitignore里)的文件并添加想替换的值2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

重新运行一下服务,再看接口,变量被local.yml里面的值替换了2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com

然后我们再通过当前命令行会话中注入一个环境变量,然后启动2cn28资讯网——每日最新资讯28at.com

export DEMO_DOCKER__TestEnv=terminal_789 && go run main.go

值又被替换成了环境变量的值,有了这个还要啥自行车?2cn28资讯网——每日最新资讯28at.com

图片图片2cn28资讯网——每日最新资讯28at.com


再看看生成的dockerfile,下面这个就是自动生成的默认dockerfile2cn28资讯网——每日最新资讯28at.com

FROM dockerproxy.com/library/golang:1.20-buster AS build-envFROM build-env AS builderWORKDIR /go/srcCOPY ./ ./# buildRUN make build WORKSPACE=demo-docker# runtimeFROM gcr.dockerproxy.com/distroless/static-debian11COPY --from=builder /go/src/cmd/demo-docker/demo-docker /go/bin/demo-dockerEXPOSE 80ARG PROJECT_NAMEARG PROJECT_VERSIONENV PROJECT_NAME=${PROJECT_NAME} PROJECT_VERSION=${PROJECT_VERSION}WORKDIR /go/binENTRYPOINT ["/go/bin/demo-docker"]

上文中提到的几个配置信息,咱们定义了一个结构,包含了编译镜像,运行镜像,GOPROXY代理,openapi文件,奥,差点忘了这篇不涉及到openapi,篇幅有限这个在后续篇章里讲,你们懂的2cn28资讯网——每日最新资讯28at.com

type DockerConfig struct {  BuildImage   string  RuntimeImage string  GoProxy      GoProxyConfig  Openapi      bool}type GoProxyConfig struct {  ProxyOn bool  Host    string}

在global/config.go中的init方法中,留了入口2cn28资讯网——每日最新资讯28at.com

func init() {  confx.SetConfX("demo-docker", "..", confx.DockerConfig{    BuildImage:   "private-harbor.xxx.com/xxx/builder:v1.0.0",    RuntimeImage: "private-harbor.xxx.com/xxx/runtime:v1.0.0",    GoProxy: confx.GoProxyConfig{      ProxyOn: true,      Host:    "https://goproxy.cn,direct",    },  })  confx.ConfP(&Config)}

然后我们再重新运行一下看看结果,编译镜像、运行镜像、代理都更新了2cn28资讯网——每日最新资讯28at.com

FROM private-harbor.xxx.com/xxx/builder:v1.0.0 AS build-envFROM build-env AS builderARG GOPROXY=https://goproxy.cn,directWORKDIR /go/srcCOPY ./ ./# buildRUN make build WORKSPACE=demo-docker# runtimeFROM private-harbor.xxx.com/xxx/runtime:v1.0.0COPY --from=builder /go/src/cmd/demo-docker/demo-docker /go/bin/demo-dockerEXPOSE 80ARG PROJECT_NAMEARG PROJECT_VERSIONENV PROJECT_NAME=${PROJECT_NAME} PROJECT_VERSION=${PROJECT_VERSION}WORKDIR /go/binENTRYPOINT ["/go/bin/demo-docker"]

如果服务有多个端口怎么处理?还是从global/config.go中下手,增加一个 TestPort 的变量,tag中加上 `env:"opt,expose"`2cn28资讯网——每日最新资讯28at.com

var Config = struct {  Logger  *conflogger.Log  Server  *confserver.Server  TestEnv string `env:""`  TestPort int `env:"opt,expose"` # 看这里,看这里}{  Server: &confserver.Server{    Port: 80,    Mode: "debug",  },  TestEnv:  "123",  TestPort: 9090,}

然后咱们再运行一次,9090端口暴露出来了,这带手表了,带啥手表了?2cn28资讯网——每日最新资讯28at.com

FROM private-harbor.xxx.com/xxx/builder:v1.0.0 AS build-envFROM build-env AS builderARG GOPROXY=https://goproxy.cn,directWORKDIR /go/srcCOPY ./ ./# buildRUN make build WORKSPACE=demo-docker# runtimeFROM private-harbor.xxx.com/xxx/runtime:v1.0.0COPY --from=builder /go/src/cmd/demo-docker/demo-docker /go/bin/demo-dockerEXPOSE 9090EXPOSE 80ARG PROJECT_NAMEARG PROJECT_VERSIONENV PROJECT_NAME=${PROJECT_NAME} PROJECT_VERSION=${PROJECT_VERSION}WORKDIR /go/binENTRYPOINT ["/go/bin/demo-docker"]

最后贴上全球最大同。。不对,是github链接,后续我们还会逐步开源一些工具2cn28资讯网——每日最新资讯28at.com

工具包confx: https://github.com/kunlun-qilian/confx本文的demo:  https://github.com/kunlun-qilian/gin-demo


2cn28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-79-0.html摸鱼心法第一章——和配置文件说拜拜

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Rust中的高吞吐量流处理

下一篇: 掘力计划第 20 期:Flutter 混合开发的混乱之治

标签:
  • 热门焦点
Top