Tekton on a Homelab: What GitHub Actions Won't Tell You
1. Why Homelab CI ≠ Cloud CI
The allure of CI/CD is universal, but the journey from cloud to homelab can be fraught with challenges. For those running Kubernetes in a personal or small-scale environment, the traditional cloud-based CI solutions like GitHub Actions can seem like a distant dream. The primary reasons for this are the cost of cloud runners, the complexity of hairpin NAT, the need for internal registry DNS, and the operational burden on a single administrator.
Cost of Cloud Runners
Cloud runners, while convenient, come at a cost. For small projects, the recurring charges can add up quickly. In a homelab setting, where resources are limited and budget is often non-existent, cloud runners are often out of the question. Moreover, the cost of cloud runners can vary significantly depending on the provider and the region, making it difficult to predict or budget for.
Hairpin NAT and Internal Registry DNS
Hairpin NAT is a common issue in homelab environments. When a pod needs to access an internal registry, it often requires a workaround due to the way Kubernetes handles network traffic. This can be particularly challenging when trying to set up a webhook to push images to an internal registry. The lack of a proper DNS resolution for internal services can lead to connectivity issues, making it difficult to establish reliable CI pipelines.
Single-Admin Ops Burden
In a homelab, the burden of managing CI/CD pipelines falls on a single administrator. This means that the solution needs to be robust, yet straightforward enough to manage without the need for extensive technical expertise. The complexity of setting up and maintaining CI/CD pipelines in a cloud environment can be overwhelming, and the need for a single point of contact can make troubleshooting and maintenance a significant challenge.
Example Scenario
Consider a scenario where you have a small Kubernetes cluster running in your home lab. You want to set up a CI pipeline for a series of applications, but you don't want to spend money on cloud runners. You also need to ensure that your internal registry is accessible from the CI pipeline. The lack of proper DNS resolution and the complexity of hairpin NAT can make this a daunting task.
# Example of a problematic setup
kubectl apply -f https://example.com/tekton-crd.yaml
kubectl apply -f https://example.com/tekton-pipelines.yaml
2. Tekton vs ARC: When Actions Runner Controller is Enough vs When Tekton Pipelines + Triggers Fit a Multi-Repo Homelab
GitHub Actions Runner Controller (ARC) is a popular choice for CI in homelab environments because it is simple to set up and manage. However, for more complex scenarios, such as multi-repo environments, Tekton pipelines with Triggers can provide a more robust solution. Let's explore the differences between these two approaches.
GitHub Actions Runner Controller (ARC)
ARC is a lightweight solution that allows you to run GitHub Actions on your Kubernetes cluster. It is easy to set up and manage, making it a popular choice for small-scale projects. However, it has limitations when it comes to more complex CI/CD workflows.
# Example of ARC setup
kubectl apply -f https://github.com/actions/runner-controller/releases/download/v1.0.12/runner-controller.yaml
Tekton Pipelines + Triggers
Tekton pipelines offer more flexibility and power for complex CI/CD workflows. They allow you to define custom pipelines and triggers, making it easier to manage multi-repo environments. However, setting up Tekton can be more complex and requires a deeper understanding of Kubernetes and CI/CD concepts.
# Example of Tekton setup
kubectl apply -f https://github.com/tektoncd/pipeline/releases/download/v0.27.0/tekton-pipelines.yaml
When to Use ARC
ARC is a good choice when you have a simple CI/CD workflow and don't need the advanced features of Tekton. It is easy to set up and manage, making it a good fit for small-scale projects.
When to Use Tekton
Tekton is a better choice when you have a multi-repo environment and need more advanced CI/CD workflows. It allows you to define custom pipelines and triggers, making it easier to manage complex workflows.
Example Scenario
Consider a scenario where you have a multi-repo environment with multiple developers contributing to different projects. You want to set up a CI pipeline that triggers builds and tests for each repository. In this case, Tekton pipelines with Triggers would be a better choice than ARC.
# Example Tekton pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: multi-repo-ci
spec:
workspaces:
- name: source
tasks:
- name: build-and-test
taskRef:
name: build-and-test-task
workspaces:
- name: source
workspace: source
3. Layout: Namespaces (ci-triggers, ci-tenant-*), EventListener, GPU Node Avoidance for CI Pods
To set up a reliable CI pipeline in a homelab environment, it is essential to organize your resources and avoid common pitfalls. This section will cover the layout of your Kubernetes cluster, including namespaces, EventListener, and GPU node avoidance.
Namespaces
Namespaces are a powerful feature in Kubernetes that allow you to organize your resources. In a CI/CD environment, it is a good practice to use separate namespaces for different components. This makes it easier to manage and troubleshoot your pipelines.
# Create namespaces
kubectl create namespace ci-triggers
kubectl create namespace ci-tenant-infra-bootstrap
EventListener
EventListener is a Kubernetes resource that watches for events and triggers actions based on those events. In a CI/CD environment, you can use EventListener to trigger builds and tests when changes are pushed to your repositories.
# Example EventListener
apiVersion: eventing.knative.dev/v1
kind: EventListener
metadata:
name: ci-trigger
namespace: ci-triggers
spec:
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: ci-trigger-subscriber
GPU Node Avoidance
In a homelab environment, it is common to have a mix of CPU and GPU nodes. However, CI/CD pods should be run on CPU nodes to avoid any potential issues with GPU drivers or conflicts. To avoid running CI/CD pods on GPU nodes, you can use node selectors or affinity rules.
# Example node selector
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: NotIn
values:
- nvidia
containers:
- name: ci-pod
image: <image:tag>
Example Scenario
Consider a scenario where you have a mix of CPU and GPU nodes in your Kubernetes cluster. You want to ensure that your CI/CD pods are run on CPU nodes to avoid any potential issues. In this case, you can use node selectors or affinity rules to avoid running CI/CD pods on GPU nodes.
# Example node selector
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: NotIn
values:
- nvidia
containers:
- name: ci-pod
image: <image:tag>
4. Kaniko / Build → registry-internal.*: Push Pattern, Tag Discipline, Tie-In to ImagePullBackOff Prevention
Kaniko is a powerful tool for building container images directly on your Kubernetes cluster. In a homelab environment, it is essential to use Kaniko to build images and push them to an internal registry. This section will cover the push pattern, tag discipline, and how to tie it in with ImagePullBackOff prevention.
Push Pattern
The push pattern involves building images using Kaniko and pushing them to an internal registry. This pattern is essential in a homelab environment because it allows you to avoid the overhead of cloud runners and ensures that your images are stored locally.
# Example Kaniko build
kubectl run -it --rm --image=gcr.io/kaniko-project/executor:latest --restart=Never \
--env=REGISTRY=<registry-host> \
--env=IMAGE=<image:tag> \
-- /bin/sh -c "export REGISTRY_PASSWORD=$(kubectl get secret -n ci-tenant-infra-bootstrap registry-credentials -o jsonpath='{.data.password}' | base64 --decode); \
export REGISTRY_USERNAME=$(kubectl get secret -n ci-tenant-infra-bootstrap registry-credentials -o jsonpath='{.data.username}' | base64 --decode); \
/kaniko/executor --dockerfile=Dockerfile --destination=<registry-host>/<image:tag>"
Tag Discipline
Tag discipline is essential in a CI/CD environment because it ensures that your images are always up-to-date and can be easily rolled back. In a homelab environment, it is a good practice to use semantic versioning for your tags.
# Example tag discipline
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
containers:
- name: ci-pod
image: <registry-host>/<image:tag>:<version>
Tie-In to ImagePullBackOff Prevention
ImagePullBackOff is a common issue in Kubernetes when a pod cannot pull an image from a registry. To prevent this issue, you can use a combination of tag discipline and a custom webhook to ensure that the correct image is always available.
# Example webhook
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
Example Scenario
Consider a scenario where you have a CI/CD pipeline that builds and pushes images to an internal registry. You want to ensure that the correct image is always available and prevent ImagePullBackOff issues. In this case, you can use a combination of tag discipline and a custom webhook to ensure that the correct image is always available.
# Example webhook
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
5. L0 Before Webhooks: run-pilot-l0.sh Smoke on Current HEAD — Why Manual PipelineRun Beats Debugging GitHub Delivery First
Before setting up webhooks, it is essential to perform a manual smoke test to ensure that your CI/CD pipeline is working correctly. This section will cover the run-pilot-l0.sh script and why a manual PipelineRun beats debugging GitHub delivery first.
run-pilot-l0.sh Script
The run-pilot-l0.sh script is a simple script that runs a manual PipelineRun to ensure that your CI/CD pipeline is working correctly. This script is particularly useful in a homelab environment because it allows you to test your pipeline without relying on external triggers.
# Example run-pilot-l0.sh
#!/bin/bash
# Set environment variables
export REGISTRY=<registry-host>
export IMAGE=<image:tag>
# Run PipelineRun
kubectl apply -f - <<EOF
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pilot-l0
spec:
pipelineRef:
name: ci-pipeline
workspaces:
- name: source
workspace: source
params:
- name: registry
value: $REGISTRY
- name: image
value: $IMAGE
EOF
Why Manual PipelineRun Beats Debugging GitHub Delivery First
Debugging GitHub delivery can be a complex and time-consuming process. In a homelab environment, it is often easier to perform a manual PipelineRun to ensure that your pipeline is working correctly. This approach allows you to test your pipeline without relying on external triggers, making it easier to identify and fix any issues.
Example Scenario
Consider a scenario where you have a CI/CD pipeline that builds and pushes images to an internal registry. You want to ensure that the pipeline is working correctly before setting up webhooks. In this case, you can use the run-pilot-l0.sh script to perform a manual PipelineRun and ensure that the pipeline is working correctly.
# Example run-pilot-l0.sh
#!/bin/bash
# Set environment variables
export REGISTRY=<registry-host>
export IMAGE=<image:tag>
# Run PipelineRun
kubectl apply -f - <<EOF
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pilot-l0
spec:
pipelineRef:
name: ci-pipeline
workspaces:
- name: source
workspace: source
params:
- name: registry
value: $REGISTRY
- name: image
value: $IMAGE
EOF
6. Failure Modes: Webhook Signature, Ingress Port 8080 Mismatch, Task Pod Stuck Init on Bad runc Nodes, Status Token RBAC
In a CI/CD environment, failure modes can arise from various sources. This section will cover common failure modes such as webhook signature issues, ingress port mismatches, task pod stuck in Init state, and RBAC issues.
Webhook Signature
Webhook signatures are used to ensure that webhooks are coming from a trusted source. In a homelab environment, it is essential to ensure that webhook signatures are correctly configured to prevent unauthorized access.
# Example webhook signature
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
webhookClientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
Ingress Port 8080 Mismatch
Ingress port mismatches can cause issues with webhooks. In a homelab environment, it is essential to ensure that the ingress port is correctly configured to prevent any issues with webhooks.
# Example ingress port mismatch
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ci-ingress
spec:
rules:
- host: <hostname>
http:
paths:
- path: /webhook
pathType: Prefix
backend:
service:
name: ci-webhook
port:
number: 8080
Task Pod Stuck Init on Bad runc Nodes
Task pods can get stuck in the Init state on bad runc nodes. In a homelab environment, it is essential to ensure that your runc nodes are healthy and up-to-date to prevent any issues with task pods.
# Example runc node health
apiVersion: node.k8s.io/v1
kind: Node
metadata:
name: <node-name>
spec:
taints:
- key: "runc-node"
effect: "NoSchedule"
value: "true"
Status Token RBAC
RBAC (Role-Based Access Control) is essential in a CI/CD environment to ensure that only authorized users can access resources. In a homelab environment, it is essential to ensure that RBAC is correctly configured to prevent any unauthorized access.
# Example RBAC
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ci-webhook
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["create", "update"]
Example Scenario
Consider a scenario where you have a CI/CD pipeline that uses webhooks to trigger builds and tests. You want to ensure that the pipeline is working correctly and prevent any issues with webhook signatures, ingress port mismatches, task pod stuck in Init state, and RBAC issues. In this case, you can use the above examples to configure your webhook, ingress, runc nodes, and RBAC to prevent any issues.
# Example webhook signature
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
webhookClientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
7. Runbook Pointer
If you encounter any issues with your CI/CD pipeline, you can refer to the runbook for detailed instructions on how to troubleshoot and resolve common issues. The runbook is available at the following URL:
Runbook URL: https://example.com/runbook/tekton-homelab-ci
By following the runbook, you can ensure that your CI/CD pipeline is working correctly and prevent any issues from arising.
Example Runbook
# Runbook: Tekton on a Homelab
## Troubleshooting
- **Webhook Signature Issues:** Ensure that webhook signatures are correctly configured.
- **Ingress Port Mismatch:** Check the ingress port configuration.
- **Task Pod Stuck Init:** Ensure that runc nodes are healthy and up-to-date.
- **RBAC Issues:** Ensure that RBAC is correctly configured.
## Next Steps
<figure class="figure">
<img src="/media/articles/tekton-homelab-ci/fig-03-next-steps.svg" alt="Next Steps" loading="lazy" />
<figcaption>Next Steps</figcaption>
</figure>
- Perform a manual PipelineRun using `run-pilot-l0.sh` to ensure that your pipeline is working correctly.
- Set up webhooks to trigger builds and tests.
- Monitor your pipeline for any issues and refer to the runbook for troubleshooting.
By following the above steps and referring to the runbook, you can ensure that your CI/CD pipeline is working correctly and prevent any issues from arising.
Tekton在家庭實驗室中的應用:GitHub Actions沒有告訴你的事
1. 何為 Homelab CI ≠ Cloud CI
CI/CD 的吸引力無所不在,但從雲端轉移到家用實驗室(Homelab)的過程可能會充滿挑戰。對於在個人或小型環境中運行 Kubernetes 的用戶來說,傳統的雲端基於 CI 的解決方案如 GitHub Actions 似乎遙不可及。造成這種情況的主要原因包括雲端執行員的成本、Hairpin NAT 的複雜性、內部註冊表 DNS 的需求,以及單一管理員的運維負擔。
雲端執行員的成本
雲端執行員雖然方便,但成本也不低。對於小型專案來說,反覆的費用會很快累積起來。在 Homelab 環境中,資源有限且預算往往不存在,因此雲端執行員往往是不可能的。此外,雲端執行員的成本會根據提供商和地區而有所不同,這使得預測或預算變得困難。
Hairpin NAT 和內部註冊表 DNS
Hairpin NAT 是 Homelab 環境中常見的問題。當一個 pod 需要訪問內部註冊表時,由於 Kubernetes 處理網絡流量的方式,往往需要工作-around。當嘗試設置推送圖像到內部註冊表的 webhook 時,這可能會特別具有挑戰性。內部服務缺乏適當的 DNS 解決方案可能會導致連接問題,使得建立可靠的 CI 管道變得困難。
単一管理員的運維負擔
在 Homelab 中,管理 CI/CD 管道的負擔落在單一管理員身上。這意味著解決方案需要既強大又簡潔,不需要大量的技術專長即可管理。在雲端環境中設置和維護 CI/CD 管道的複雜性可能會令人生畏,而需要單一聯繫點可能會使故障排除和維護成為一個重大挑戰。
示例場景
考慮一個場景,在這個場景中,您在家中運行一個小型的 Kubernetes 集群。您希望為一系列應用程式設置 CI 管道,但又不想花錢在雲端執行員上。您還需要確保您的內部註冊表可以從 CI 管道訪問。缺乏適當的 DNS 解決方案和 Hairpin NAT 的複雜性可能使這成為一個令人頭痛的任務。
# 有問題的設置示例
kubectl apply -f https://example.com/tekton-crd.yaml
kubectl apply -f https://example.com/tekton-pipelines.yaml
2. Tekton vs ARC:當 Actions Runner Controller 足夠時 vs 應用 Tekton Pipelines + Triggers 的多 Repository 家用實驗室環境
GitHub Actions Runner Controller (ARC) 是在家用實驗室環境中進行 CI 的一個流行選擇,因為它設定和管理都很簡單。然而,對於更複雜的場景,例如多 Repository 環境,Tekton Pipelines 配上 Triggers 可以提供更為穩健的解決方案。讓我們來探討這兩種方法的差異。
GitHub Actions Runner Controller (ARC)
ARC 是一個輕量級的解決方案,允許你在 Kubernetes 集群上執行 GitHub Actions。它設定和管理都很簡單,因此對於小型專案來說是一個流行的選擇。然而,當涉及到更複雜的 CI/CD 工作流程時,它有一些限制。
# ARC 設置範例
kubectl apply -f https://github.com/actions/runner-controller/releases/download/v1.0.12/runner-controller.yaml
Tekton Pipelines + Triggers
Tekton Pipelines 提供了更多的靈活性和力量,適用於複雜的 CI/CD 工作流程。它允許你定義自訂的 Pipelines 和 Triggers,使得管理多 Repository 環境更加容易。然而,設定 Tekton 可能會更加複雜,需要對 Kubernetes 和 CI/CD 概念有更深的理解。
# Tekton 設置範例
kubectl apply -f https://github.com/tektoncd/pipeline/releases/download/v0.27.0/tekton-pipelines.yaml
何時使用 ARC
ARC 是一個適合簡單 CI/CD 工作流程且不需要 Tekton 的進階功能的選擇。它設定和管理都很簡單,因此對於小型專案來說是一個很好的選擇。
何時使用 Tekton
Tekton 是一個適合多 Repository 環境且需要更進階 CI/CD 工作流程的選擇。它允許你定義自訂的 Pipelines 和 Triggers,使得管理複雜工作流程更加容易。
範例場景
考慮一個多 Repository 環境的情況,有多個開發人員為不同的專案貢獻。你想設置一個 CI 管道,觸發每個 Repository 的建立和測試。在這種情況下,Tekton Pipelines 配上 Triggers 會是一個比 ARC 更好的選擇。
# Tekton 管道範例
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: multi-repo-ci
spec:
workspaces:
- name: source
tasks:
- name: build-and-test
taskRef:
name: build-and-test-task
workspaces:
- name: source
workspace: source
3. 布局: 命名空間(ci-triggers,ci-tenant-*),事件監聽器,CI 執行器避開 GPU 节點
在家庭實驗室環境中建立可靠的 CI 管道,組織資源和避免常見錯誤是至關重要的。本節將覆蓋 Kubernetes 集群的佈局,包括命名空間、事件監聽器和 CI 執行器避開 GPU 节點。
命名空間
Kubernetes 中的命名空間是一種強大的功能,允許您組織資源。在 CI/CD 環境中,為不同的組件使用不同的命名空間是一種良好的實踐。這樣可以讓您更容易地管理並排除問題。
# 創建命名空間
kubectl create namespace ci-triggers
kubectl create namespace ci-tenant-infra-bootstrap
事件監聽器
事件監聽器是 Kubernetes 中的一種資源,用於監視事件並根據這些事件觸發動作。在 CI/CD 環境中,您可以使用事件監聽器在推送更改到您的存儲庫時觸發構建和測試。
# 事件監聽器範例
apiVersion: eventing.knative.dev/v1
kind: EventListener
metadata:
name: ci-trigger
namespace: ci-triggers
spec:
subscriber:
ref:
apiVersion: serving.knative.dev/v1
kind: Service
name: ci-trigger-subscriber
CI 執行器避開 GPU 节點
在家庭實驗室環境中,通常會有一種 CPU 和 GPU 节點混搭的情況。然而,CI/CD 執行器應該在 CPU 节點上運行,以避免任何潛在的 GPU 驅動程式問題或衝突。要避免在 GPU 节點上運行 CI/CD 執行器,您可以使用節點選擇器或親和性規則。
# 节點選擇器範例
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: NotIn
values:
- nvidia
containers:
- name: ci-pod
image: <image:tag>
範例場景
考慮這樣一個場景:您的 Kubernetes 集群中有一種 CPU 和 GPU 节點混搭的情況。您希望確保 CI/CD 執行器在 CPU 节點上運行,以避免任何潛在問題。在這種情況下,您可以使用節點選擇器或親和性規則來避免在 GPU 节點上運行 CI/CD 執行器。
# 节點選擇器範例
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: NotIn
values:
- nvidia
containers:
- name: ci-pod
image: <image:tag>
4. Kaniko / 建構 → registry-internal.*: 推送模式、標記紀律、與 ImagePullBackOff 防範的結合
Kaniko 是一個強大的工具,可以直接在您的 Kubernetes 集群上建立容器影像。在家庭實驗室環境中,使用 Kaniko 建構影像並推送到內部註冊表單是至關重要的。本節將介紹推送模式、標記紀律,以及如何將其與 ImagePullBackOff 防範結合起來。
推送模式
推送模式涉及使用 Kaniko 建構影像並推送到內部註冊表單。在家庭實驗室環境中,這種模式是必要的,因為它可以避免雲端執行器的開銷,並且確保您的影像儲存於本地端。
# Kaniko 建構範例
kubectl run -it --rm --image=gcr.io/kaniko-project/executor:latest --restart=Never \
--env=REGISTRY=<registry-host> \
--env=IMAGE=<image:tag> \
-- /bin/sh -c "export REGISTRY_PASSWORD=$(kubectl get secret -n ci-tenant-infra-bootstrap registry-credentials -o jsonpath='{.data.password}' | base64 --decode); \
export REGISTRY_USERNAME=$(kubectl get secret -n ci-tenant-infra-bootstrap registry-credentials -o jsonpath='{.data.username}' | base64 --decode); \
/kaniko/executor --dockerfile=Dockerfile --destination=<registry-host>/<image:tag>"
標記紀律
在 CI/CD 環境中,標記紀律是必要的,因為它可以確保您的影像始終是最新的,並且可以輕鬆地回滾。在家庭實驗室環境中,使用語義版本控制來管理您的標記是一個好習慣。
# 標記紀律範例
apiVersion: batch/v1
kind: Job
metadata:
name: ci-pod
spec:
template:
spec:
containers:
- name: ci-pod
image: <registry-host>/<image:tag>:<version>
與 ImagePullBackOff 防範的結合
ImagePullBackOff 是 Kubernetes 中一個常見的問題,當 pod 不能從註冊表單拉取影像時會發生。要防止這個問題,可以使用標記紀律和自訂 webhook 的組合,以確保始終可用正確的影像。
# 自訂 webhook 範例
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
範例場景
考慮一個 CI/CD 管道的場景,該管道會建立並推送到內部註冊表單的影像。您希望確保始終可用正確的影像,並防止 ImagePullBackOff 問題。在這種情況下,可以使用標記紀律和自訂 webhook 的組合來確保始終可用正確的影像。
# 自訂 webhook 範例
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
5. L0 未設定Webhooks前:run-pilot-l0.sh 燒燙測試當前的HEAD — 何以手動PipelineRun比首先調試GitHub交付更勝一籌
在設定Webhooks之前,進行手動燒燙測試以確保CI/CD管道正常運作是至關重要的。本節將介紹run-pilot-l0.sh腳本,並解釋為何手動PipelineRun比首先調試GitHub交付更勝一籌。
run-pilot-l0.sh 腳本
run-pilot-l0.sh腳本是一個簡單的腳本,用於手動執行PipelineRun以確保CI/CD管道正常運作。在家庭實驗室環境中,這個腳本特別有用,因為它允許您在不依賴外部觸發器的情況下測試您的管道。
# 範例 run-pilot-l0.sh
#!/bin/bash
# 設置環境變數
export REGISTRY=<registry-host>
export IMAGE=<image:tag>
# 執行PipelineRun
kubectl apply -f - <<EOF
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pilot-l0
spec:
pipelineRef:
name: ci-pipeline
workspaces:
- name: source
workspace: source
params:
- name: registry
value: $REGISTRY
- name: image
value: $IMAGE
EOF
何以手動PipelineRun比首先調試GitHub交付更勝一籌
調試GitHub交付可能是一個複雜且耗時的過程。在家庭實驗室環境中,手動執行PipelineRun以確保管道正常運作往往更容易。這種方法允許您在不依賴外部觸發器的情況下測試您的管道,使您更容易識別和解決任何問題。
範例場景
考慮一個場景,您的CI/CD管道負責構建並推送圖像到內部註冊表。您希望在設定Webhooks之前確保管道正常運作。在此情況下,您可以使用run-pilot-l0.sh腳本執行手動PipelineRun,確保管道正常運作。
# 範例 run-pilot-l0.sh
#!/bin/bash
# 設置環境變數
export REGISTRY=<registry-host>
export IMAGE=<image:tag>
# 執行PipelineRun
kubectl apply -f - <<EOF
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pilot-l0
spec:
pipelineRef:
name: ci-pipeline
workspaces:
- name: source
workspace: source
params:
- name: registry
value: $REGISTRY
- name: image
value: $IMAGE
EOF
6. 失敗模式:Webhook 簽章、Ingress埠8080不匹配、Task Pod 在不良 runc 节點上卡在Init狀態、Status Token RBAC
在CI/CD環境中,可能會出現各種失敗模式。本節將介紹一些常見的失敗模式,例如Webhook簽章問題、Ingress埠8080不匹配、Task Pod 在不良 runc 节點上卡在Init狀態,以及RBAC問題。
Webhook 簽章
Webhook簽章用於確保Webhook來自可信的來源。在家庭實驗室環境中,確保Webhook簽章正確配置以防止未授權存取至關重要。
# Webhook 簽章範例
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
webhookClientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
Ingress埠8080不匹配
Ingress埠8080不匹配可能會導致Webhook問題。在家庭實驗室環境中,確保Ingress埠正確配置以防止任何Webhook問題至關重要。
# Ingress埠8080不匹配範例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ci-ingress
spec:
rules:
- host: <hostname>
http:
paths:
- path: /webhook
pathType: Prefix
backend:
service:
name: ci-webhook
port:
number: 8080
Task Pod 在不良 runc 节點上卡在Init狀態
Task Pod可能會在不良 runc 节點上卡在Init狀態。在家庭實驗室環境中,確保您的runc節點健康且更新至最新版本,以防止任何Task Pod問題。
# 不良 runc 节點健康範例
apiVersion: node.k8s.io/v1
kind: Node
metadata:
name: <node-name>
spec:
taints:
- key: "runc-node"
effect: "NoSchedule"
value: "true"
Status Token RBAC
RBAC(基於角色的存取控制)在CI/CD環境中至關重要,確保只有授權用戶才能訪問資源。在家庭實驗室環境中,確保RBAC正確配置以防止任何未授權存取。
# RBAC範例
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ci-webhook
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["create", "update"]
範例場景
考慮一個場景,您的CI/CD流水線使用Webhook觸發建構和測試。您希望確保流水線正常運作並防止任何Webhook簽章問題、Ingress埠8080不匹配、Task Pod卡在Init狀態以及RBAC問題。在這種情況下,您可以使用上述範例配置您的Webhook、Ingress、runc節點和RBAC,以防止任何問題。
# Webhook 簽章範例
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: ci-webhook
webhooks:
- name: ci-webhook.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["batch"]
apiVersions: ["v1"]
resources: ["jobs"]
clientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
failurePolicy: Ignore
sideEffects: None
timeoutSeconds: 30
matchPolicy: Exact
webhookClientConfig:
service:
namespace: ci-triggers
name: ci-webhook-service
caBundle: <base64-encoded-certificate>
7. Runbook指引
如果您遇到 CI/CD 管道的問題,可以參考runbook以獲得詳細的排錯和解決常見問題的指示。runbook位於以下網址:
Runbook網址: https://example.com/runbook/tekton-homelab-ci
透過遵循runbook,您可以確保CI/CD管道運作正確,並預防任何問題發生。
範例Runbook
# Runbook: Tekton在家庭實驗室環境中使用
排除錯誤
- Webhook 簽章問題: 確保 webhook 簽章正確設定。
- Ingress Port 不符: 檢查 ingress port 設定。
- Task Pod 初始化卡住: 確保 runc 节點健康且為最新版本。
- RBAC 問題: 確保 RBAC 正確設定。
接下來的步驟
- 使用
run-pilot-l0.sh手動執行 PipelineRun,確保您的流水線運作正常。 - 設定 webhooks 以觸發建構和測試。
- 監控您的流水線,以發現任何問題,並參照手冊進行排錯。
按照上述步驟和參照手冊,您可以確保您的 CI/CD 流水線運作正常,並預防任何問題發生。
Related internal runbook: tekton-homelab-ci (VPN) 相關內部 runbook:tekton-homelab-ci(VPN)