Deploy Applications on Kubernetes Cluster with GitLab CI/CD Tunnel

原始來源與檔名:2026-06-02T093143+0800-Deploy Applications on Kubernetes Cluster with GitLab CICD Tunnel.md


NAPKIN | 餐巾纸

餐巾纸公式

安全的 K8s 部署 = GitLab KAS (Kubernetes Agent Server) + 內網 K8s Agent + CI/CD Tunnel

透過在 K8s 叢集內部署 Agent 主動連線至 GitLab (Pull-based),無須對外曝露 Kubernetes API 即可在 CI/CD 流水線中安全地推送部署指令。

一句话

GitLab CI/CD Tunnel 讓開發者能透過部署在內網 K8s 叢集中的 Agent,在不開放 K8s API 對外連線的前提下,安全地執行 kubectlhelm 部署應用程式。

餐巾纸草图

[ GitLab CI/CD Pipeline ]         [ 企業防火牆 / 內網 K8s 叢集 ]
           |                                  |
           | (CI/CD Tunnel)                   v
           | <--------------------- [ GitLab Agent (Pod) ]
           |        (主動建立連線)            |
           v                                  v
[ GitLab KAS (Agent Server) ]          [ K8s API Server ]

ROUND 1: SKELETON | 骨架掃描

“这本书在说什么”

章节骨架

  1. Connect K8s Cluster to GitLab: 啟用 KAS,建立 Agent 配置專屬 Repo (Repo A) 並在 K8s 中安裝 Agent Pod。
  2. Create application repository: 在應用程式 Repo (Repo B) 撰寫 .gitlab-ci.yml,透過 CI/CD Tunnel 切換 Kube Context 並執行 kubectl apply
  3. Authorize application repo: 在 Agent Repo (Repo A) 中設定 ci_access,授權 Repo B 能夠使用該 Agent 連線。
  4. Deploy using helmfile: 展示另一種部署方式,使用 gl-helmfile 在 Pipeline 中自動套用 Helm Chart。

ROUND 2: DISSECTION | 血肉解剖

“凭什么这么说”

论证链

暴露 K8s API 存在高風險 --> 需要一種將外部 Push 轉為內部 Pull 的機制 --> GitLab KAS 與 Cluster-side Agent 之間建立長連線 (Tunnel) --> CI 流水線透過這個安全的 Tunnel 直接與目標叢集對話 --> 達成兼顧自動化與網路安全 (Zero Inbound) 的部署架構。

关键证据

  1. GitLab KAS 整合: 自 GitLab 14.5 起免費提供此功能,Agent 會在 gitlab-kubernetes-agent namespace 中運行,主動連線 GitLab,免除 Inbound 網路配置。
  2. KUBE_CONTEXT 變數: 在 .gitlab-ci.yml 中,只要設定 KUBE_CONTEXT: org/agent-repo:agent-name,就能無縫切換 kubectl config use-context,證明 Tunnel 的透通性。
  3. 權限隔離設計: 透過區分 Agent 配置專案 (Repo A) 與 應用程式專案 (Repo B),並透過 config.yaml 顯式聲明 ci_access,確保只有被授權的專案能部署到該叢集。

隐形假设与边界

ROUND 3: SOUL | 靈魂提取

“还能怎么用”

跨域映射


Deploy Applications on Kubernetes Cluster with GitLab CI/CD Tunnel (Architectural Deep Dive)

前言/背景

在實踐 CI/CD 的過程中,將應用程式自動部署至 Kubernetes 叢集是最後一哩路。然而,傳統做法要求將 K8s API Server 暴露在網際網路上以接收來自 CI 系統的部署指令,這帶來了極大的資安風險。本文介紹了 GitLab CI/CD Tunnel 功能,透過在叢集內部安裝主動連外 (Pull-based) 的 Agent,實現在 不暴露 K8s API 的前提下完成安全部署。

章節詳細總結

1. 啟用 KAS 與連接 K8s 叢集 (Connect K8s Cluster to GitLab)

要建立 Tunnel,首先需要依賴 GitLab Kubernetes Agent Server (KAS)。 對於 Self-managed GitLab,必須先在底層配置 /etc/gitlab/gitlab.rb 中啟用 KAS:

gitlab_kas['enable'] = true

建立配置專案 (Repo A) GitLab 的設計將「環境設定」與「應用程式碼」分離。你需要建立一個專屬的 Repository (文中稱為 kubernetes-cluster) 來存放 Agent 配置。 路徑必須嚴格遵循:.gitlab/agents/<agentname>/config.yaml

註冊與安裝 Agent 在 GitLab UI (Infrastructure → Kubernetes Cluster) 註冊該 Agent 後,會獲得一串註冊 Token 與 Helm/Docker 安裝指令。在目標 K8s 的 Bastion Host 執行後,Agent 會被部署至 gitlab-kubernetes-agent namespace 中,並主動與 GitLab KAS 建立長連線 (Tunnel)。

2. 授權與配置 CI/CD 流水線 (Create & Authorize Application Repository)

建立完 Tunnel 後,應用程式專案 (Repo B) 並不能隨便使用它,必須經過顯式授權,這是良好的安全邊界設計。

配置存取權限 (CI Access) 在 Repo A 的 Agent config.yaml 中,必須指明哪些專案可以存取此叢集:

ci_access:
  projects:
  - id: linuxshots/k8s-applications # 授權 Repo B

撰寫 .gitlab-ci.yml 進行部署 在 Repo B 中,透過指定 KUBE_CONTEXT 環境變數,GitLab Runner 會自動透過 Tunnel 將 kubectl 指令導向目標叢集:

variables:
  # 格式: 專案路徑:Agent名稱
  KUBE_CONTEXT: linuxshots/kubernetes-cluster:mygitlabagent

.kube-context:
  before_script:
  - if [ -n "$KUBE_CONTEXT" ]; then kubectl config use-context "$KUBE_CONTEXT"; fi

deploy:
  extends: [.kube-context]
  image:
    name: bitnami/kubectl:latest
    entrypoint: [""]
  script:
  - kubectl apply -f $CI_PROJECT_DIR/sampleapps/.

架構考量:這種做法保留了開發者熟悉的 “Push” 部署體驗 (在 CI 看到部署 Log),同時享有類似 “Pull” 模式的安全網路架構。

3. 進階:使用 Helmfile 部署 (Deploy using helmfile)

除了原生 kubectl,GitLab 官方也提供包裝好的 Image 來支援 Helm 部署。 利用 registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications 映像檔,可以直接執行 gl-helmfile 工具:

deploy:
  extends: [.kube-context]
  stage: deploy
  image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v1.3.2"
  script:
  # 自動確保 namespace 存在
  - gl-ensure-namespace vault 
  # 套用 helmfile.yaml
  - gl-helmfile --file $CI_PROJECT_DIR/helmfile.yaml apply --suppress-secrets

這種方式有利於管理複雜的 Chart 依賴與多環境的 values.yaml

總結與結論