Course contentsShow
← Docker, Kubernetes & CI/CD
Lesson 606 of 8029. CI/CD Pipeline EngineeringFree lesson

Implementing Self-Hosted Runners for Private Networks

Set up and manage private runner clusters to execute CI/CD jobs within restricted network environments while maintaining platform integration.

In this lesson, you will learn how to architect self-hosted runners to execute CI/CD jobs securely within isolated, private network segments without exposing your internal infrastructure to the public internet.

When working in highly regulated environments, your build systems often need direct access to private package repositories, internal databases, or non-routable staging environments. Using public, SaaS-based runners is often a violation of security policy, as they cannot traverse your firewalls. To solve this, we deploy self-hosted runners directly into a private Kubernetes cluster.

The Connectivity Pattern

Unlike standard public runners that poll a central CI/CD platform (like GitHub or GitLab) via an inbound-facing webhook, self-hosted runners function via outbound-only connectivity.

The runner agent, running as a pod inside your private Kubernetes cluster, initiates a long-lived connection to the CI/CD platform's API/message bus. Because the runner only makes outbound requests, you can enforce strict egress policies while keeping your internal network ports entirely closed to the outside world.

Implementation Concept

You typically deploy these runners using a controller—such as the Actions Runner Controller (ARC) for Kubernetes—which manages the lifecycle of ephemeral runner pods. To ensure the runner stays within the private network, ensure your Deployment configuration points to a private image registry and uses internal DNS for any service discovery:

apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
  name: private-runner-set
spec:
  template:
    spec:
      containers:
      - name: runner
        image: internal-registry.corp/runner:latest
        env:
        - name: RUNNER_SCOPE
          value: "enterprise"
      # Ensure pod is constrained to the private network namespace
      nodeSelector:
        network-segment: "private-isolated"

By leveraging Kubernetes NetworkPolicies, you can further isolate these runners, ensuring they can only reach the specific internal resources required for the build (e.g., your Artifactory or database) and nothing else. This setup maintains platform integration for job orchestration while keeping your data, artifacts, and build processes within your hardened perimeter.

Key Takeaway: By utilizing outbound-only polling runners in a private cluster, you eliminate the need for inbound firewall holes, allowing your CI/CD pipelines to interact securely with sensitive internal infrastructure.