自动替换 Kubernetes 镜像

821cd6e9f56cb3c6ba6b56f13e04a7c8.gif

来源:云原生指北
作者:Addo Zhang

最近萌生了个想法,维护一个后网络友好的仓库镜像,在 Pod 创建时将镜像仓库切换到自维护的仓库,从自维护的仓库拉取镜像。

前几天体验了极狐Gitlab 的容器镜像库,便是为这个想法做的准备。当然其他的云厂商也有提供针对个人版的免费镜像仓库和企业版仓库。

正好 Pipy 作为策略引擎,非常适合实现这种策略的执行。

实现思路

d3bf874f846cf56099d61ced339fb651.png

Admission Webhook

Kubernetes 动态准备控制的 MutatingWebhookConfiguration 可以 hook Pod 的创建或者更新,然后调用目标服务对 Pod 资源对象进行 patch 操作。

策略引擎

Pipy 作为应用的核心,也就是 MutatingWebhookConfiguration 的目标服务,以策略引擎的角色完成策略的执行。

Pipy 支持从文件或者 HTTP 地址加载脚本,这里为了便于策略的更新,使用了后者。

对于从 HTTP 地址加载脚本,HTTP 地址返回内容的第一行会作为 Pipy 的主脚本,Pipy 启动时会加载主脚本,其他的文件也会被缓存到内存中。

#地址 http://localhost:6080/repo/registry-mirror/
$ curl http://localhost:6080/repo/registry-mirror/
/main.js
/config.json

Pipy 会每隔 5s 检查脚本和配置文件的 etag(就是文件的最后更新时间),假如与当前文件的 etag 不一致,则会缓存并重新加载。

利用 Pipy 的这个特性,便可以策略和配置的准实时更新。

策略

对于策略的部分,我们将其逻辑和配置进行了分离。配置部分,配置了需要进行替换的镜像的前缀,以及替换成的内容;而逻辑,这是对 MutatingWebhookConfiguration 的 AdmissionReview 的对象进行检查。

配置:

{
"registries":{
"gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd":"registry.gitlab.cn/flomesh/registry-mirror/tekton-pipeline"
}
}

比如说,对于镜像 gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/controller:v0.28.1,将 gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd 替换成 registry.gitlab.cn/addozhang/registry-mirror/tekton-pipeline

Demo

本文使用所有的源码都已上传到了 github。

脚本服务器

既然选用了 HTTP 方式加载 Pipy 的脚本,那就需要实现一个脚本服务器。实现的方式有两种:使用脚本实现脚本服务器和使用 Pipy 内置的 Codebase。

使用脚本实现脚本服务器

根据需求定义两种路由:

/repo/registry-mirror/:返回脚本和配置的文件列表•/repo/registry-mirror/[File Name]:返回对应的文件的内容,同时需要在响应头添加 etag,值是文件的更新时间

具体脚本如下:

#repo.js
pipy({_serveFile:(req, type, filename)=>(filename = req.head.path.substring(22),os.stat(filename)?(
newMessage(
{bodiless: req.head.method ==='HEAD',headers:{
'etag': os.stat(filename)?.mtime |0,
'content-type': type,
},
},req.head.method ==='HEAD'?null: os.readFile(filename),
)
):(
newMessage({ status:404},`file ${filename} not found`)
)
),_router:new algo.URLRouter({
'/repo/registry-mirror/':()=>newMessage('/main.js\n/config.json'),
'/repo/registry-mirror/*': req => _serveFile(req,'text/plain')
}),
})
.listen(6080)
.serveHTTP(req => _router.find(req.head.path)(req)
)%
$ pipy repo.js
2021-10-0521:40:25[info][config]
2021-10-0521:40:25[info][config]Module/repo.js
2021-10-0521:40:25[info][config]===============
2021-10-0521:40:25[info][config]
2021-10-0521:40:25[info][config][Listen on :::6080]
2021-10-0521:40:25[info][config]----->|
2021-10-0521:40:25[info][config]|
2021-10-0521:40:25[info][config]       serveHTTP
2021-10-0521:40:25[info][config]|
2021-10-0521:40:25[info][config]<-----|
2021-10-0521:40:25[info][config]
2021-10-0521:40:25[info][listener]Listening on port 6080 at ::

检查路由:

$ curl http://localhost:6080/repo/registry-mirror/
/main.js
/config.json
$ curl http://localhost:6080/repo/registry-mirror/main.js
#省略 main.js 的内容
$ curl http://localhost:6080/repo/registry-mirror/config.json
#省略 config.json 的内容

使用 Pipy 内置的 Codebase

在最新发布的 Pipy 内置了一个 Codebase,大家可以理解成脚本仓库,但是比单纯的仓库功能更加强大(后面会有文档介绍该特性)。

目前版本的 Codebase 还未支持持久化的存储,数据都是保存在内存中。后续会提供 KV store 或者 git 类型的持久化支持。

启动 Pipy 的 Codebase很简单:

$ pipy
2021-10-0521:49:08[info][codebase]Starting codebase service...
2021-10-0521:49:08[info][listener]Listening on port 6060 at ::
ba81ddbc4100dc948ea8bcafb2019a14.png

对于新的 Codebase 控制台的使用,这里不做过多的介绍,直接使用 REST API 完成脚本的写入:

#创建 registry-mirror codebase,会自动创建一个空的 main.js
$ curl -X POST http://localhost:6060/api/v1/repo/registry-mirror
#更新 main.js
$ curl -X POST 'http://localhost:6060/api/v1/repo/registry-mirror/main.js'--data-binary '@scripts/main.js'
#创建 config.json
$ curl -X POST 'http://localhost:6060/api/v1/repo/registry-mirror/config.json'--data-binary '@scripts/config.json'
#检查 codebase 的版本
$ curl -s http://localhost:6060/api/v1/repo/registry-mirror | jq -r .version
#更新版本
$ curl -X POST 'http://localhost:6060/api/v1/repo/registry-mirror'--data-raw '{"version":2}'

安装

进入到项目的根目录中,执行:

$ helm install registry-mirror ./registry-mirror -n default
NAME: registry-mirror
LAST DEPLOYED:TueOct522:19:262021
NAMESPACE:default
STATUS: deployed
REVISION:1
TEST SUITE:None

查看 webhook:

$ kubectl get mutatingwebhookconfigurations
NAME                      WEBHOOKS   AGE
registry-mirror-webhook   12m6s

检查 pod 的启动日志:

$ kubectl logs -n pipy -l app=pipy
2021-10-0514:19:28[info][codebase] GET http://192.168.1.101:6060/repo/registry-mirror/ -> 21 bytes
2021-10-0514:19:28[info][codebase] GET /repo/registry-mirror/main.js ->2213 bytes
2021-10-0514:19:28[info][codebase] GET /repo/registry-mirror/config.json ->149 bytes
2021-10-0514:19:28[info][config]
2021-10-0514:19:28[info][config]Module/main.js
2021-10-0514:19:28[info][config]===============
2021-10-0514:19:28[info][config]
2021-10-0514:19:28[info][config][Listen on :::6443]
2021-10-0514:19:28[info][config]----->|
2021-10-0514:19:28[info][config]|
2021-10-0514:19:28[info][config]       acceptTLS
2021-10-0514:19:28[info][config]|
2021-10-0514:19:28[info][config]|-->[tls-offloaded]
2021-10-0514:19:28[info][config]              decodeHTTPRequest
2021-10-0514:19:28[info][config]              replaceMessage
2021-10-0514:19:28[info][config]              encodeHTTPResponse -->|
2021-10-0514:19:28[info][config]|
2021-10-0514:19:28[info][config]<---------------------------------|
2021-10-0514:19:28[info][config]
2021-10-0514:19:28[info][listener]Listening on port 6443 at ::

测试

$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.28.1/release.yaml
$ kubectl get pod -n tekton-pipelines
NAME                                           READY   STATUS    RESTARTS   AGE
tekton-pipelines-controller-75974fbfb8-f62dv   1/1Running07m36s
tekton-pipelines-webhook-6cc478f7ff-mm5l9      1/1Running07m36s

检查结果:

$ kubectl get pod -o json -n tekton-pipelines -l app=tekton-pipelines-controller | jq -r '.items[].spec.containers[].image'
registry.gitlab.cn/flomesh/registry-mirror/tekton-pipeline/controller:v0.28.1
$ kubectl get pod -o json -n tekton-pipelines -l app=tekton-pipelines-webhook | jq -r '.items[].spec.containers[].image'
registry.gitlab.cn/flomesh/registry-mirror/tekton-pipeline/webhook:v0.28.1

从上面的结果可以看到结果是符合预期的。

总结

整个实现的策略部分加上配置,只有 70 多行的代码。并且实现了逻辑与配置的分离之后,后续的配置也都可以做到实时的更新而无需修改任何逻辑代码,更无需重新部署。

但是目前的实现,是需要手动把镜像推送的自维护的镜像仓库中。实际上理想的情况是检查自维护的仓库中是否存在镜像(比如通过 REST API),如果未发现镜像,先把镜像拉取到本地,tag 后再推送到自维护的仓库。不过这种操作,还是需要网络的畅通。当然也尝试过通过 REST API 触发 CICD Pipeline 的执行拉取镜像并 tag,但是极狐Gitlab 是部署在某云的环境上,同样也受困于网络问题。

引用链接

Kubernetes 动态准备控制: https://kubernetes.io/zh/docs/reference/access-authn-authz/extensible-admission-controllers/
源码: https://github.com/addozhang/registry-mirror

55daba1533f4fc7cbf28c3241fa0817b.gif

77f52d40d961a06b6d2053fa384ba72f.png

往期推荐

移动云亮相2021 IDC年度盛典

数学在左,人生在右

Redis很厉害,使用规范来啦

低代码会让程序员更加内卷吗?

a058aaea98f7522054982fc230db9f87.gif

点分享

66393d9d0c981893093df7834073548f.gif

点收藏

b012ee1ddeb2d3f15a0c6827ec26d356.gif

点点赞

f403508d9299a465370647f4c2ac2d1b.gif

点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flagger on ASM——基于Mixerless Telemetry实现渐进式灰度发布系列 3 渐进式灰度发布

简介&#xff1a; 作为CNCF[成员](https://landscape.cncf.io/card-mode?categorycontinuous-integration-delivery&groupingcategory&selectedweave-flagger)&#xff0c;[Weave Flagger](flagger.app)提供了持续集成和持续交付的各项能力。Flagger将渐进式发布总结为…

react 使用 leaflet 百度地图_【React】react项目中应用百度地图添加起始点绘制路线...

如图&#xff1a;项目中百度地图的应用添加起始点、终点并绘制路线在展示代码的时候首先展示一下后台返回给我的接口{其中position_list参数代表的是用户的行驶点&#xff0c; area参数代表的是服务区的坐标点&#xff0c;下面会用到参数下面开始展示代码了index.html引入百度地…

基线长度中误差的计算_电子战支援实施中的测向技术

派遣一个机载电子战机组执行支援压制敌防空系统任务&#xff0c;在任务计划阶段&#xff0c;全体人员将会获取任务区域内的EOB&#xff0c;机载电子战人员会优先识别他们在任务期间可能会遇到的威胁辐射源&#xff0c;以及其他中立、友好辐射源。当机载电子战人员进入目标作战区…

洞察设计模式的底层逻辑

简介&#xff1a; 设计模式是开发同学经常聊到的话题&#xff0c;也经常被用到实际的开发项目中&#xff0c;熟练的人可以做到信手拈来&#xff0c;不熟悉的人陷入苦思冥想中。笔者认为&#xff0c;不仅仅要掌握设计模式的用法&#xff0c;更要洞察设计模式的底层逻辑&#xff…

pta段错误是什么意思_用Python执行Django数据迁移时报!(1091错误及解决方法)...

前言&#xff1a;今天为大家带来的内容是用Python执行Django数据迁移时报!(1091错误及解决方法)本文内容具有不错的参考意义&#xff0c;希望在此能够帮助到大家&#xff01;前几天在Pycharm 中的Terminal下&#xff0c;执行数据迁移操作时&#xff1a;第一步&#xff1a; Pyth…

cad大理石填充图案_CAD制图初学入门者必须知道的CAD填充问题

在使用浩辰CAD软件绘制图纸的过程中&#xff0c;经常会用到CAD填充功能。但是CAD制图初学入门者在进行CAD填充时偶尔会遇到一些问题&#xff0c;比如在自己的CAD软件中填充是完整的&#xff0c;但是在别人的CAD软件中打开却出现了缺口&#xff0c;这是什么原因呢&#xff1f;接…

苹果:iOS 比 Android 更安全!

整理 | 祝涛 出品 | CSDN据报道&#xff0c;在答复欧盟委员会数字市场行动的函件中&#xff0c;苹果援引诺基亚2019年、2020年的威胁情况报告称&#xff0c;安卓平台恶意软件的数量是iPhone的15~47倍。苹果称iOS比安卓安全就在于无法绕过商店安装软件&#xff0c;因此坚决…

日志服务SLS 助力识货 APP,解决业务数据采集查询监控问题

简介&#xff1a; 日志服务SLS 助力识货 APP&#xff0c;解决业务数据采集查询监控问题 更多存储标杆案例 欢迎点击下方链接查看 阿里云存储标杆案例样板间 公司介绍 识货APP是虎扑体育旗下的导购应用&#xff0c;致力于为广大年轻用户提供专业的网购决策指导&#xff0c;为…

html5 烟雾,jQuery烟雾背景发生器(HTML5 Canvas插件waterpipe.js

插件描述&#xff1a;waterpipe.js是一个创建烟雾弥漫的背景,有多种效果可选择&#xff0c;自定义参数效果还是挺酷的哦&#xff01;使用方法1、包括jQuery和waterpipe.js2、创建画布元素内包装Your browser does not support HTML5 canvas.3、创建画布元素内包装var smokyBG …

数据仓库分层存储技术揭秘

简介&#xff1a; 本文介绍数据仓库产品作为企业中数据存储和管理的基础设施&#xff0c;在通过分层存储技术来降低企业存储成本时的关键问题和核心技术。 作者 | 沄浩、士远 来源 | 阿里技术公众号 一 背景 据IDC发布的《数据时代2025》报告显示&#xff0c;全球每年产生的数…

cups支持的打印机列表_网络存储让你的打印机瞬间变无线,打印文件不用愁

无论是公司的文件、合同还是学校的教材作业总有需要打印的而且还需要满足手机、电脑等设备的无线打印不然文件来回拷贝实在是太麻烦了只要打印机搭配群晖NAS旧打印机也能上岗再就业轻松实现无线打印&#xff01;话不多说&#xff0c;这就开始教大家如何使用&#xff01;先确认一…

python同时输出多个值_怎样在python中输出多个数组元素?

展开全部 如果2113要输出多个列表元素&#xff0c;实际上是列表的分片5261或者说是切片。 以下代码运4102行通过&#xff1a;12list [a, b, mpilgrim, z, example]print(\n, list[0:3]) 运行效1653果&#xff1a;1.python输出一维矩阵或numpy数组中的非0元素 import numpy as …

网游云上网络优化方案

简介&#xff1a; 网游云上网络优化方案1. 游戏行业背景 1.1 行业概况 2019全球数字游戏营收1094亿美元&#xff0c;其中中国市场328亿美元。国内游戏⽤户数6.5亿&#xff1b;移动端 (60%)>PC端>主机。移动游戏占⽐逐年增⻓已成为绝对的主流。国内公司近3万&#xff0c;近…

云栖大会展出两款一体机,搭载新一代无影融合架构

10月18日云栖大会开放日上&#xff0c;阿里云基于新一代无影架构的两款一体机已对观众展出。两款新品分为23.8寸标准版和27寸Pro版&#xff0c;Pro版为手绘场景配有触控屏和触控笔&#xff0c;官方介绍为首款设计师云电脑。 在云栖大会展区&#xff0c;观众已经可以对一体机进…

ansys如何删除线_绘画新手不懂如何用ps提取线稿?教你用PS提取自己喜欢的线稿!...

绘画新手不懂如何用ps提取线稿&#xff1f;初学者如何自学绘画&#xff1f;自学板画难吗&#xff1f;怎样才能学习好绘画&#xff1f;想必这些都是绘画初学者们经常在想的问题吧&#xff0c;就是不知道如何才能学习好绘画&#xff0c;然后绘画出自己想要画的东西那么今天灵猫课…

Service Mesh 从“趋势”走向“无聊”

简介&#xff1a; 过去一年&#xff0c;阿里巴巴在 Service Mesh 的探索道路上依旧扎实前行&#xff0c;这种坚定并非只因坚信 Service Mesh 未来一定是云计算基础技术的关键组成部分&#xff0c;还因需要借这一技术趋势去偿还过去所积累下来的技术债&#xff08;“技术债”并非…

python增加一列数据_python数据怎么添加列?

python在DataFrame数据中添加列的方法&#xff1a; 1、使用concat方法在数据中添加列 concat方法相当于数据库中的全连接&#xff08;union all&#xff09;&#xff0c;它不仅可以指定连接的方式&#xff08;outer join或inner join&#xff09;还可以指定按照某个轴进行连接。…

开源 1 年半 star 破 1.2 万的 Dapr 是如何在阿里落地的?

简介&#xff1a; Dapr 是 2019 年 10 月微软开源的可移植、事件驱动分布式运行时&#xff0c;它使开发人员能够轻松地构建运行在云平台和边缘的弹性而微服务化的无状态和有状态的应用程序&#xff0c;从而降低基于微服务架构构建现代云原生应用的准入门槛。 作者 | 敖小剑 来源…

cron 每年执行一次_crontab服务执行定时脚本,在指定时间内让php执行处理业务逻辑...

技小白 2019-12-19 11:45:33crontab-e编辑某个用户的cron服务设置执行脚本crontab-l列出某个用户cron服务列表信息crontab-r删除某个用户的cron服务定时任务crontab格式分小时日月星期命令******0-590-231-311-120-6command注&#xff1a;“*”代表取值范围内的数字“/”代表每…

Fluid 给数据弹性一双隐形的翅膀 -- 自定义弹性伸缩

简介&#xff1a; 弹性伸缩作为 Kubernetes 的核心能力之一&#xff0c;但它一直是围绕这无状态的应用负载展开。而 Fluid 提供了分布式缓存的弹性伸缩能力&#xff0c;可以灵活扩充和收缩数据缓存。 它基于 Runtime 提供了缓存空间、现有缓存比例等性能指标, 结合自身对于 Run…