Deploying TeamCity CI/CD Infrastructure on Kubernetes Using YAML Manifests

Provisioning a continuous integration and delivery pipeline on a Kubernetes cluster requires coordinated manifests for both the orchestration server and distributed build workers. The following configurations establish a functional JetBrains TeamCity environment using modern Kubernetes API standards. To apply these definitions, execute kubectl apply -f <manifest-file> for each respective file.

Server Deployment and Service

The control plane manifest provisions a single-instance server with persistent local storage for project metadata and execution logs. A Recreate strategy guarantees consistent state transitions during upgrades, while the asociated NodePort service exposes the management interface to external networks.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ci-server-deployment
  labels:
    component: tc-server
spec:
  replicas: 1
  revisionHistoryLimit: 2
  strategy:
    type: Recreate
  selector:
    matchLabels:
      component: tc-server
  template:
    metadata:
      labels:
        component: tc-server
    spec:
      nodeName: worker-node-1
      hostNetwork: true
      terminationGracePeriodSeconds: 30
      containers:
      - name: main-server
        image: jetbrains/teamcity-server
        imagePullPolicy: Always
        ports:
        - containerPort: 8111
        resources:
          requests:
            memory: "2Gi"
            cpu: "100m"
          limits:
            memory: "4Gi"
            cpu: "1"
        volumeMounts:
        - name: server-data
          mountPath: /data/teamcity_server/datadir
        - name: server-logs
          mountPath: /opt/teamcity/logs
      volumes:
      - name: server-data
        hostPath:
          path: /opt/k8s-storage/teamcity
          type: DirectoryOrCreate
      - name: server-logs
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: ci-server-nodeport
spec:
  type: NodePort
  selector:
    component: tc-server
  ports:
  - port: 8111
    targetPort: 8111
    nodePort: 30001
    protocol: TCP

Agent Pool Deployment and Service

Build workers are scaled across three replicas using a rolling update strategy to maintain continuous pipeline availability during maintenance windows. Each container operates with privileged security context to enable nested Docker execution, and is allocated substantial compute capacity for resource-intensive compilation tasks.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: build-agent-pool
  labels:
    component: tc-agent
spec:
  replicas: 3
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  selector:
    matchLabels:
      component: tc-agent
  template:
    metadata:
      labels:
        component: tc-agent
    spec:
      nodeName: worker-node-3
      hostNetwork: true
      dnsPolicy: ClusterFirst
      terminationGracePeriodSeconds: 30
      containers:
      - name: build-worker
        image: jetbrains/teamcity-agent
        imagePullPolicy: Always
        env:
        - name: TEAMCITY_SERVER
          value: "http://172.16.2.202:30001"
        - name: AGENT_IDENTIFIER
          value: "BuildNode-Primary"
        - name: DOCKER_IN_DOCKER
          value: "start"
        resources:
          requests:
            cpu: "1"
            memory: "4Gi"
          limits:
            cpu: "4"
            memory: "10Gi"
        securityContext:
          privileged: true
        volumeMounts:
        - name: agent-config
          mountPath: /data/teamcity_agent/conf
        - name: docker-storage
          mountPath: /var/lib/docker
      volumes:
      - name: agent-config
        emptyDir: {}
      - name: docker-storage
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: agent-cluster-service
  labels:
    component: tc-agent
spec:
  type: ClusterIP
  sessionAffinity: None
  selector:
    component: tc-agent
  ports:
  - name: agent-tcp
    protocol: TCP
    port: 9090
    targetPort: 9090

Operational Notes

  • API Group Stability: All definitions utilize the apps/v1 API group, replacing deprecated beta versions to ensure compatibility with modern Kubernetes distribusions.
  • Node Targeting: The nodeName field enforces strict pod placement. For dynamic scaling, replace this with nodeSelector labels or affinity rules.
  • Persistent Storage: Local hostPath volumes simplify initial setup in bare-metal clusters. Production environments should transition to PersistentVolumeClaim objects backed by distributed storage systems.
  • Network Configuration: Enabling hostNetwork bypasses the CNI overlay, reducing latency between server and agents but requiring manual port conflict resolution across the cluster.

Tags: kubernetes teamcity cicd yaml-manifests docker-in-docker

Posted on Wed, 24 Jun 2026 16:37:26 +0000 by erichar11