开源云原生CI/CD框架Tekton国内部署方式
Tekton 是一款功能非常强大而灵活的 CI/CD 开源的云原生框架。致力于提供全功能、标准化的云原生 CI/CD 解决方案。【本文主要是通过流水线自动化的将tekton镜像同步到腾讯云仓库,并部署tekton】
应用镜像
阿里云镜像仓库居然有限制...这次转到腾讯云镜像仓库了;ccr.ccs.tencentyun.com/tektons/dashboard
Pipeline
借助GitHub Actions:
同步镜像并生成镜像映射文件(json): 收集镜像映射文件为制品;
This is a basic workflow to help you get started with Actions
name: Get Tekton Images
env:
VERSION: v0.29.0
on:
push:
paths:
- '.github/workflows/tekton.yaml'
- 'tekton/**'
jobs:
build:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: build
run: |
curl https://storage.googleapis.com/tekton-releases/pipeline/previous/${{ env.VERSION }}/release.yaml -o release.yaml
grep -v "#" release.yaml | grep -v "^$" > release1.yaml ; sed -i 's/\-\-\-/###/g' release1.yaml
python3 tekton/get_tekton_images.py ${{ secrets.DOCKER_USER}} ${{ secrets.DOCKER_PASSWD}}
- uses: actions/upload-artifact@v2
with:
name: ${{ env.VERSION }}-tekton-images
path: tekton_images.json
部署文件解析
下载release部署yaml; 解析Deployments对象中的images; tekton-pipelines-controller tekton-pipelines-webhook tekton-dashboard(最新tag)
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/controller:v0.29.0@sha256:72f79471f06d096cc53e51385017c9f0f7edbc87379bf415f99d4bd11cf7bc2b
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/kubeconfigwriter:v0.29.0@sha256:6d058f2203b9ab66f538cb586c7dc3b7cc31ae958a4135dd99e51799f24b06c9
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.29.0@sha256:c0b0ed1cd81090ce8eecf60b936e9345089d9dfdb6ebdd2fd7b4a0341ef4f2b9
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/entrypoint:v0.29.0@sha256:66958b78766741c25e31954f47bc9fd53eaa28263506b262bf2cc6df04f18561
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop:v0.29.0@sha256:6a037d5ba27d9c6be32a9038bfe676fb67d2e4145b4f53e9c61fb3e69f06e816
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/imagedigestexporter:v0.29.0@sha256:e38dd0d32253fce5aaf1e501c0bc71facc3720564b7e97055921cc5390d612e0
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/pullrequest-init:v0.29.0@sha256:d28202fb8b33a1d4c05f261ef8dcbcdcf3b469887d4dad256ce91f73c917420e
gcr.io/google.com/cloudsdktool/cloud-sdk@sha256:27b2c22bf259d9bc1a291e99c63791ba0c27a04d2db0a43241ba0f1f20f4067f
gcr.io/distroless/base@sha256:aa4fd987555ea10e1a4ec8765da8158b5ffdfef1e72da512c7ede509bc9966c4
mcr.microsoft.com/powershell:nanoserver@sha256:b6d5ff841b78bdf2dfed7550000fd4f3437385b8fa686ec0f010be24777654d6
gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/webhook:v0.29.0@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd
用Python编写一个数据解析脚本:
import yaml
import json
import sys
import os
class Tekton :
def __init__(self, file_name, registry_user, registry_passwd):
self.yaml_file = file_name
self.arg_imgs = ["gcr.io/tekton-releases/github.com/tektoncd/dashboard/cmd/dashboard@sha256:95f71a2568ced67ec370b5360f88bec3280601908cac9e62dfbb801114480437"]
self.split_str = "###"
self.deployments = ["tekton-pipelines-controller", "tekton-pipelines-webhook"]
self.kind_type = "Deployment"
self.target_registry = "ccr.ccs.tencentyun.com/tektons/"
self.repos = [ "controller", "kubeconfigwriter", "git-init",
"entrypoint","nop","imagedigestexporter",
"pullrequest-init", "cloud-sdk", "base", "powershell", "webhook"]
self.result = []
self.registry_user = registry_user
self.registry_passwd = registry_passwd
def load_yaml(self, data):
content = yaml.load(data)
return content
def load_json(self, data):
content = json.loads(data)
return content
def get_images(self):
f = open(self.yaml_file, 'r').read()
for i in f.split("###")[:-1]:
try:
content = self.load_yaml(i.replace("###", ""))
if content["kind"] == self.kind_type:
deploy_name = content["metadata"]["name"]
# 获取image
if deploy_name in self.deployments:
img = content["spec"]["template"]["spec"]["containers"][0]["image"]
self.arg_imgs.append(img)
# 获取参数中的images
if deploy_name == "tekton-pipelines-controller":
arg_img = content["spec"]["template"]["spec"]["containers"][0]["args"]
for a in arg_img:
if not a.startswith("-"):
self.arg_imgs.append(a)
except Exception as e:
print(e)
return self.arg_imgs
def save_json_file(self, data, file_name):
for i in self.arg_imgs:
self.result.append({
"s_image": i,
"t_image": self.target_registry + i.split("/")[-1].split("@")[0]
})
newdata = json.dumps(self.result, indent=4)
a=open(file_name, 'w')
a.write(newdata)
a.close()
def sync_images(self):
f = open("tekton_images.json", 'r').read()
content = self.load_json(f)
docker_login_cmd = "docker login -u {0} -p {1} {2}".format(
self.registry_user,
self.registry_passwd,
self.target_registry.split("/")[0])
os.system(docker_login_cmd)
for item in content:
print("[GetImages] {}".format(item))
docker_pull_cmd = "docker pull {0}".format(item["s_image"])
docker_tag_cmd = "docker tag {0} {1}".format(item["s_image"], item["t_image"])
docker_push_cmd = "docker push {0}".format(item["t_image"])
os.system(docker_pull_cmd + "&&" + docker_tag_cmd + "&&" + docker_push_cmd )
print("[GetImagesDone] {}".format(item))
if __name__ == '__main__':
tekton = Tekton("release1.yaml", sys.argv[1], sys.argv[2])
images = tekton.get_images()
tekton.save_json_file(images, "tekton_images.json")
tekton.sync_images()
镜像映射文件
s_image
原始镜像名称, t_image
目标镜像名称; 这里使用腾讯云的镜像仓库;
[
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/controller:v0.29.0@sha256:72f79471f06d096cc53e51385017c9f0f7edbc87379bf415f99d4bd11cf7bc2b",
"t_image": "ccr.ccs.tencentyun.com/tektons/controller:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/kubeconfigwriter:v0.29.0@sha256:6d058f2203b9ab66f538cb586c7dc3b7cc31ae958a4135dd99e51799f24b06c9",
"t_image": "ccr.ccs.tencentyun.com/tektons/kubeconfigwriter:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.29.0@sha256:c0b0ed1cd81090ce8eecf60b936e9345089d9dfdb6ebdd2fd7b4a0341ef4f2b9",
"t_image": "ccr.ccs.tencentyun.com/tektons/git-init:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/entrypoint:v0.29.0@sha256:66958b78766741c25e31954f47bc9fd53eaa28263506b262bf2cc6df04f18561",
"t_image": "ccr.ccs.tencentyun.com/tektons/entrypoint:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/nop:v0.29.0@sha256:6a037d5ba27d9c6be32a9038bfe676fb67d2e4145b4f53e9c61fb3e69f06e816",
"t_image": "ccr.ccs.tencentyun.com/tektons/nop:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/imagedigestexporter:v0.29.0@sha256:e38dd0d32253fce5aaf1e501c0bc71facc3720564b7e97055921cc5390d612e0",
"t_image": "ccr.ccs.tencentyun.com/tektons/imagedigestexporter:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/pullrequest-init:v0.29.0@sha256:d28202fb8b33a1d4c05f261ef8dcbcdcf3b469887d4dad256ce91f73c917420e",
"t_image": "ccr.ccs.tencentyun.com/tektons/pullrequest-init:v0.29.0"
},
{
"s_image": "gcr.io/google.com/cloudsdktool/cloud-sdk@sha256:27b2c22bf259d9bc1a291e99c63791ba0c27a04d2db0a43241ba0f1f20f4067f",
"t_image": "ccr.ccs.tencentyun.com/tektons/cloud-sdk"
},
{
"s_image": "gcr.io/distroless/base@sha256:aa4fd987555ea10e1a4ec8765da8158b5ffdfef1e72da512c7ede509bc9966c4",
"t_image": "ccr.ccs.tencentyun.com/tektons/base"
},
{
"s_image": "mcr.microsoft.com/powershell:nanoserver@sha256:b6d5ff841b78bdf2dfed7550000fd4f3437385b8fa686ec0f010be24777654d6",
"t_image": "ccr.ccs.tencentyun.com/tektons/powershell:nanoserver"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/webhook:v0.29.0@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd",
"t_image": "ccr.ccs.tencentyun.com/tektons/webhook:v0.29.0"
},
{
"s_image": "gcr.io/tekton-releases/github.com/tektoncd/dashboard/cmd/dashboard@sha256:95f71a2568ced67ec370b5360f88bec3280601908cac9e62dfbb801114480437",
"t_image": "ccr.ccs.tencentyun.com/tektons/dashboard"
}
]
镜像映射文件可以在GitHubActions页面下载:
下载镜像脚本
解析上面生成的镜像文件,docker pull
下载对应的镜像到本地;
import json
import os
class Tekton:
def __init__(self):
self.json_file = "tekton_images.json"
self.target_registry = "ccr.ccs.tencentyun.com/tektons/"
# self.registry_user = registry_user
# self.registry_passwd = registry_passwd
def load_json(self, data):
content = json.loads(data)
return content
def down_images(self):
f = open(self.json_file, 'r').read()
content = self.load_json(f)
# docker_login_cmd = "docker login -u {0} -p {1} {2}".format(
# self.registry_user,
# self.registry_passwd,
# self.target_registry.split("/")[0])
for item in content:
print("[GetImages] {}".format(item["t_image"]))
docker_pull_cmd = "docker pull {0}".format(item["t_image"])
# docker_tag_cmd = "docker tag {0} {1}".format(item["t_image"], item["s_image"].split("@")[0])
os.system(docker_pull_cmd + "&&" + docker_tag_cmd )
print("[GetImagesDone] {}".format(item))
if __name__ == '__main__':
t = Tekton().down_images()
部署Tekton
手动更新 release.yaml
中的镜像;然后kubectl apply release.yaml
部署(后续有时间再优化脚本,实现自动更新release.yaml)手动更新tekton-dashboard-release.yaml中的镜像;然后部署;
[root@master ~]# kubectl -n tekton-pipelines get pod
NAME READY STATUS RESTARTS AGE
tekton-dashboard-5c4b89d9-2z8g7 1/1 Running 0 21m
tekton-pipelines-controller-b96f647bb-gff69 1/1 Running 0 13h
tekton-pipelines-webhook-76bc9c97b9-cd2m4 1/1 Running 0 13h
编写一个Ingress来暴露tekton dashboard:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: tekton-service
namespace: tekton-pipelines
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: 256m
spec:
rules:
- host: tekton.idevops.site
http:
paths:
- path: /
backend:
serviceName: tekton-dashboard
servicePort: 9097
访问UI页面:
编写Pipeline
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: tektoncd-task
spec:
resources:
inputs:
- name: repo
type: git
steps:
- name: run-test
image: maven:3-jdk-8
workingDir: /workspace/repo
command: ["mvn"]
args: ["clean", "package"]
---
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: tektoncd-resource
spec:
type: git
params:
- name: url
value: http://192.168.1.200/devops/devops-maven-service.git
- name: revision
value: master
---
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
name: cdpipeline
spec:
taskRef:
name: tektoncd-task
resources:
inputs:
- name: repo
resourceRef:
name: tektoncd-resource
评论