[OK!] Chapter 13. Building a Deployment Pipeline
Делаю:
2026.01.27
Если не будет работать, смотреть содержимое коммита: e75e6863a4bc644ef40a79ac7507b1cfd2ea63ea
// Использую
$ LATEST_KUBERNETES_VERSION=v1.32.2
Подготовка
Установка gitea в minikube
$ kubectl create ns my-pipelines-ns
$ export TEKTON_SECRET_TOKEN=$(head -c 24 /dev/random | base64)
$ echo ${TEKTON_SECRET_TOKEN}
$ kubectl create secret generic git-secret --from-literal=secretToken=${TEKTON_SECRET_TOKEN} -n my-pipelines-ns
// username: gitea_admin
// password: r8sA8CPHD9!bt6d
http://gitea.192.168.49.2.nip.io/
New Migration -> https://github.com/PacktPublishing/tekton-book-app
gitea_admin / tekton-book-app -> MyProject -> Settings -> Webhooks -> Add webhook -> Gitea
• Target URL: (http://tekton-events.192.168.49.2.nip.io) • Content type: application/json. • Secret: Use the secret token you created earlier. You can view your token with the echo ${TEKTON_SECRET_TOKEN} command.
Trigger On:
- Push event
Add Webhook
Нужно развернуть приложение на стенде. см предыдущий шаг.
// Поправить
$ cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: tekton-deployment
spec:
selector:
matchLabels:
app: trigger-demo
template:
metadata:
labels:
app: trigger-demo
spec:
containers:
- name: tekton-pod
image: <YOUR_USERNAME>/tekton-lab-app
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: tekton-svc
spec:
selector:
app: trigger-demo
ports:
- port: 3000
protocol: TCP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-ingress
spec:
rules:
- http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: tekton-svc
port:
number: 3000
EOF
$ export PROFILE=${USER}-minikube
$ echo ${PROFILE}
$ curl $(minikube --profile ${PROFILE} ip)
response:
{"message":"Hello","change":"here"}
Основная часть
Let’s think about what operations are needed every time you perform a commit on your source code:
- Clone the repository.
- Install the required libraries.
- Test the code.
- Lint the code.
- Build and push the image.
- Deploy the application.
Adding an additional task
$ {
export REGISTRY_SERVER=https://index.docker.io/v1/
export REGISTRY_USER=webmakaka
export REGISTRY_PASSWORD=webmakaka-password
echo ${REGISTRY_SERVER}
echo ${REGISTRY_USER}
echo ${REGISTRY_PASSWORD}
}
$ kubectl create secret docker-registry dockerhub-secret -n my-pipelines-ns \
--docker-server=${REGISTRY_SERVER} \
--docker-username=${REGISTRY_USER} \
--docker-password=${REGISTRY_PASSWORD}
$ kubectl create serviceaccount tekton-sa -n my-pipelines-ns
$ kubectl patch serviceaccount tekton-sa \
-n my-pipelines-ns \
-p '{"secrets": [{"name": "dockerhub-secret"}]}'
$ cat << 'EOF' | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Task
metadata:
name: build-push
namespace: my-pipelines-ns
spec:
params:
- name: image
description: Ссылка на образ (например, docker.io/user/app:latest)
workspaces:
- name: source
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v1.23.2
env:
- name: DOCKER_CONFIG
value: /kaniko/.docker
args:
- --dockerfile=Dockerfile
- --context=$(workspaces.source.path)
- --destination=$(params.image)
- --digest-file=$(results.IMAGE_DIGEST.path)
volumeMounts:
- name: docker-config
mountPath: /kaniko/.docker
volumes:
- name: docker-config
secret:
# Секрет должен быть создан командой:
# kubectl create secret docker-registry dockerhub-secret ...
secretName: dockerhub-secret
items:
- key: .dockerconfigjson
path: config.json
results:
- name: IMAGE_DIGEST
description: Digest собранного образа
EOF
Using the task catalog
https://hub.tekton.dev/ was officially shut down in January 2026
Нужно использовать:
https://artifacthub.io/packages/tekton-task/tekton-catalog-tasks/git-clone
https://artifacthub.io/packages/tekton-task/tekton-catalog-tasks/npm
https://artifacthub.io/packages/tekton-task/tekton-catalog-tasks/kubernetes-actions
Creating the pipeline
Для теста
$ cat << 'EOF' | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: tekton-deploy
namespace: my-pipelines-ns
spec:
params:
- name: repo-url
workspaces:
- name: source
tasks:
- name: clone
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: git-clone
- name: version
value: "0.9"
params:
- name: url
value: $(params.repo-url)
workspaces:
- name: output
workspace: source
EOF
$ tkn pipeline start tekton-deploy --use-param-defaults -n my-pipelines-ns
? Value for param `repo-url` of type `string`? http://gitea.192.168.49.2.nip.io/gitea_admin/tekton-book-app.git
? Name for the workspace : source
? Value of the Sub Path :
? Type of the Workspace : emptyDir
? Type of EmptyDir :
$ tkn pipelineruns ls tekton-deploy
NAME STARTED DURATION STATUS
tekton-deploy-run-kc2z2 50 seconds ago 19s Succeeded
$ cat << 'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: tekton-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
// Шаг тестирования и линтинга пришлось отключить, т.к. в них ошибки.
$ cat << 'EOF' | kubectl apply -f -
apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
name: tekton-deploy
namespace: my-pipelines-ns
spec:
params:
- name: repo-url
- name: deployment-name
- name: image
workspaces:
- name: source
tasks:
- name: clone
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: git-clone
- name: version
value: "0.9"
params:
- name: url
value: $(params.repo-url)
workspaces:
- name: output
workspace: source
- name: install
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: npm
- name: version
value: "0.1"
params:
- name: ARGS
value: ["install"]
- name: IMAGE
value: "node:20-alpine"
workspaces:
- name: source
workspace: source
runAfter:
- clone
- name: lint
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: npm
- name: version
value: "0.1"
params:
- name: ARGS
value:
- run
- lint
workspaces:
- name: source
workspace: source
runAfter:
- install
- name: test
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: npm
- name: version
value: "0.1"
params:
- name: ARGS
value:
- run
- test
workspaces:
- name: source
workspace: source
runAfter:
- install
- name: build-push
taskRef:
name: build-push
params:
- name: image
value: $(params.image)
workspaces:
- name: source
workspace: source
runAfter:
- test
- lint
- name: deploy
taskRef:
resolver: hub
params:
- name: catalog
value: tekton-catalog-tasks
- name: type
value: artifact
- name: name
value: kubernetes-actions
- name: version
value: "0.2"
params:
- name: args
value:
- rollout
- restart
- deployment/$(params.deployment-name)
- -n
- default
runAfter:
- build-push
EOF
$ tkn pipeline start tekton-deploy --use-param-defaults -n my-pipelines-ns
? Value for param `repo-url` of type `string`? http://gitea.192.168.49.2.nip.io/gitea_admin/tekton-book-app.git
? Value for param `deployment-name` of type `string`? tekton-deployment
? Value for param `image` of type `string`? webmakaka/tekton-lab-app
? Value for param `docker-username` of type `string`? webmakaka
? Value for param `docker-password` of type `string`?
Please give specifications for the workspace: source
? Name for the workspace : source
? Value of the Sub Path :
? Type of the Workspace : pvc
? Value of Claim Name : tekton-pvc
$ tkn pipelineruns ls tekton-deploy -n my-pipelines-ns
NAME STARTED DURATION STATUS
tekton-deploy-run-nbx4f 2 minutes ago 2m3s Succeeded
$ tkn pipelinerun logs tekton-deploy-run-nbx4f -n my-pipelines-ns
****
[deploy : kubectl] deployment.apps/tekton-deployment restarted
Настраиваем обновление по коммиту
Creating the trigger
**Нужно поменять
$ export DOCKER_USERNAME=<YOUR_DOCKER_USERNAME>
$ cat << 'EOF' | envsubst | kubectl apply -f -
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: commit-tt
namespace: my-pipelines-ns
spec:
params:
- name: gitrepositoryurl
description: The git repository url
resourcetemplates:
- apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
generateName: tekton-deploy-
spec:
serviceAccountName: tekton-sa
pipelineRef:
name: tekton-deploy
params:
- name: repo-url
value: "$(tt.params.gitrepositoryurl)"
- name: deployment-name
value: "tekton-deployment"
- name: image
value: "docker.io/${DOCKER_USERNAME}/tekton-lab-app:latest"
workspaces:
- name: source
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
$ cat << 'EOF' | kubectl apply -f -
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerBinding
metadata:
name: event-binding
namespace: my-pipelines-ns
spec:
params:
- name: gitrepositoryurl
value: $(body.repository.clone_url)
EOF
$ cat << 'EOF' | kubectl apply -f -
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
name: listener
namespace: my-pipelines-ns
spec:
serviceAccountName: tekton-triggers-example-sa
triggers:
- name: trigger
bindings:
- ref: event-binding
template:
ref: commit-tt
interceptors:
- github:
secretRef:
secretName: git-secret
secretKey: secretToken
eventTypes:
- push
EOF
$ cat << 'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-gitea-ingress
namespace: my-pipelines-ns
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host: tekton-events.192.168.49.2.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: el-listener
port:
number: 8080
EOF
// Не нужно создавать! (Скорее всего)
$ kubectl create clusterrolebinding \
serviceaccounts-cluster-admin \
--clusterrole=cluster-admin \
--group=system:serviceaccounts \
--namespace=my-pipelines-ns
$ kubectl create sa tekton-triggers-example-sa -n my-pipelines-ns
$ kubectl create rolebinding el-admin \
--clusterrole=cluster-admin \
--serviceaccount=my-pipelines-ns:tekton-triggers-example-sa \
--namespace=my-pipelines-ns
Проверка работы
Вносим изменения в исходный код.
http://gitea.192.168.49.2.nip.io/gitea_admin/tekton-book-app/src/branch/main/server.js
change: "here"
Меняем на
change: "the end"
Commit changes
Проверяем
$ kubectl logs -l eventlistener=listener -n my-pipelines-ns
$ kubectl logs -l app=tekton-triggers-controller --tail=20 -n tekton-pipelines
$ tkn pipelineruns ls tekton-deploy -n my-pipelines-ns
NAME STARTED DURATION STATUS
tekton-deploy-69n84 4 minutes ago 4m37s Succeeded
$ tkn pipelinerun -n my-pipelines-ns logs tekton-deploy-rp6kl
****
[deploy : kubectl] deployment.apps/tekton-deployment restarted
Появился image:
https://hub.docker.com/r/webmakaka/tekton-lab-app
$ export PROFILE=${USER}-minikube
$ echo ${PROFILE}
$ curl $(minikube --profile ${PROFILE} ip)
response:
{"message":"Hello","change":"the end"}