--- name: mirrord-ci description: Help users set up mirrord in CI pipelines for testing against real Kubernetes environments. Use when users want to run end-to-end tests, integration tests, or automated tests in CI using mirrord to connect to staging/shared clusters. metadata: author: MetalBear version: "1.0" --- # Mirrord CI Skill ## Purpose Help users integrate mirrord into CI pipelines for testing against real Kubernetes environments: - **Configure** CI runners to connect to Kubernetes clusters - **Set up** `mirrord ci start/stop` commands in CI workflows - **Generate** CI workflow files for GitHub Actions, GitLab CI, etc. - **Troubleshoot** CI-specific mirrord issues ## When to Use This Skill Trigger on questions like: - "How do I use mirrord in CI?" - "Set up mirrord for GitHub Actions" - "Run tests against staging in CI" - "mirrord ci start not working" - "Configure mirrord for GitLab CI" ## Critical First Steps **Step 1: Load references** Read the reference files from this skill's `references/` directory: - `references/schema.json` - Authoritative mirrord JSON Schema - `references/troubleshooting.md` - Common issues and solutions The schema defines all valid configuration options for mirrord, including CI-specific settings. The troubleshooting guide helps diagnose and fix common mirrord issues. If using absolute paths, search for them using patterns like `**/mirrord-ci/references/*`. **Step 2: Validate configs before presenting** When generating mirrord configuration files for CI, ALWAYS validate against the schema: ```bash mirrord verify-config /path/to/config.json ``` ## Key Benefits of mirrord for CI - **Speed**: ~50% faster CI pipelines by eliminating test environment setup - **Cost**: No need to spin up ephemeral clusters for each CI run - **Accuracy**: Test against real services, dependencies, and configurations - **Isolation**: Safe, isolated test execution that doesn't interfere with other workloads ## Prerequisites ### Required 1. **mirrord CLI version 3.181.0 or later** 2. **Kubernetes cluster access** from the CI runner 3. **kubeconfig** configured in CI environment ### Verification commands ```bash # Check mirrord version mirrord --version # Verify cluster access kubectl cluster-info kubectl get pods -n ``` ## Core Commands ### Starting a CI session ```bash mirrord ci start --target -- ``` This starts your application with mirrord in the background, allowing tests to run against it. **Examples:** ```bash # Node.js application mirrord ci start --target deployment/api-server -- npm run start # Python application mirrord ci start --target pod/backend-abc123 -- python main.py # With config file mirrord ci start --config-file mirrord.json -- ./my-app # Run in foreground (blocks until stopped) mirrord ci start --foreground --target deployment/api -- npm start ``` ### Stopping CI sessions ```bash mirrord ci stop ``` This stops all running mirrord CI sessions. **Always run this after tests complete.** ### Multiple sessions You can start multiple mirrord sessions in a single CI job: ```bash mirrord ci start --target deployment/service-a -- ./service-a & mirrord ci start --target deployment/service-b -- ./service-b & # Run tests npm test # Stop all sessions mirrord ci stop ``` ## CI API Key (for mirrord Teams/Enterprise) If using mirrord Operator, generate a CI API key to avoid consuming seats: ```bash # Generate the key (run locally, not in CI) mirrord ci api-key ``` Store this as a **secret** environment variable named `MIRRORD_CI_API_KEY` in your CI platform. ## Configuration ### CI-specific config options ```json { "target": "deployment/my-app", "ci": { "output_dir": "/var/log/mirrord" } } ``` | Option | Description | Default | |--------|-------------|---------| | `ci.output_dir` | Directory for stdout/stderr logs | OS temp dir (e.g., `/tmp/mirrord`) | ### Application logs By default, application stdout/stderr are saved to: ``` /tmp/mirrord/-/ ``` ## CI Platform Examples ### GitHub Actions ```yaml name: Integration Tests on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up kubeconfig run: | mkdir -p ~/.kube echo "${{ secrets.KUBECONFIG }}" | base64 -d > ~/.kube/config - name: Install mirrord run: | curl -fsSL https://raw.githubusercontent.com/metalbear-co/mirrord/main/scripts/install.sh | bash - name: Start app with mirrord run: | mirrord ci start --target deployment/api-server -- npm run start env: MIRRORD_CI_API_KEY: ${{ secrets.MIRRORD_CI_API_KEY }} - name: Run tests run: npm test - name: Stop mirrord if: always() run: mirrord ci stop ``` ### GitLab CI ```yaml integration-tests: stage: test image: node:20 before_script: - curl -fsSL https://raw.githubusercontent.com/metalbear-co/mirrord/main/scripts/install.sh | bash - mkdir -p ~/.kube - echo "$KUBECONFIG_CONTENT" | base64 -d > ~/.kube/config script: - mirrord ci start --target deployment/api-server -- npm run start - npm test after_script: - mirrord ci stop variables: MIRRORD_CI_API_KEY: $MIRRORD_CI_API_KEY ``` ### CircleCI ```yaml version: 2.1 jobs: integration-test: docker: - image: cimg/node:20.0 steps: - checkout - run: name: Setup kubeconfig command: | mkdir -p ~/.kube echo "$KUBECONFIG_B64" | base64 -d > ~/.kube/config - run: name: Install mirrord command: | curl -fsSL https://raw.githubusercontent.com/metalbear-co/mirrord/main/scripts/install.sh | bash - run: name: Start mirrord CI session command: mirrord ci start --target deployment/api -- npm start environment: MIRRORD_CI_API_KEY: ${MIRRORD_CI_API_KEY} - run: name: Run tests command: npm test - run: name: Stop mirrord command: mirrord ci stop when: always ``` ### Jenkins Pipeline ```groovy pipeline { agent any environment { KUBECONFIG = credentials('kubeconfig-staging') MIRRORD_CI_API_KEY = credentials('mirrord-ci-api-key') } stages { stage('Setup') { steps { sh 'curl -fsSL https://raw.githubusercontent.com/metalbear-co/mirrord/main/scripts/install.sh | bash' } } stage('Test') { steps { sh 'mirrord ci start --target deployment/api -- npm start' sh 'npm test' } post { always { sh 'mirrord ci stop' } } } } } ``` ## Kubernetes Access Setup The CI runner must have access to your Kubernetes cluster. Common approaches: ### 1. Service Account (Recommended) Create a dedicated service account for CI: ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: ci-runner namespace: staging --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: mirrord-ci-role namespace: staging rules: - apiGroups: [""] resources: ["pods", "pods/log"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: mirrord-ci-binding namespace: staging subjects: - kind: ServiceAccount name: ci-runner namespace: staging roleRef: kind: Role name: mirrord-ci-role apiGroup: rbac.authorization.k8s.io ``` ### 2. Cloud Provider Authentication - **GKE**: Use Workload Identity or service account key - **EKS**: Use IAM roles for service accounts (IRSA) - **AKS**: Use Azure AD pod identity or managed identity ## Common Issues For detailed troubleshooting, refer to `references/troubleshooting.md`. ### CI-Specific Issues | Issue | Solution | |-------|----------| | "kubectl not found" | Install kubectl in CI runner | | "Cannot connect to cluster" | Check kubeconfig is properly configured | | "mirrord ci start hangs" | Ensure target pod exists and is running | | "Permission denied" | Check RBAC permissions for CI service account | | "Session not stopping" | Use `mirrord ci stop` in `after_script` or `post` block | | "Logs not found" | Check `ci.output_dir` config or default `/tmp/mirrord` | | "Seats being consumed" | Set `MIRRORD_CI_API_KEY` environment variable | ### General mirrord Issues | Issue | Solution | |-------|----------| | mirrord seems to have no effect | Binary may be statically linked. For Go: use `go build -ldflags='-linkmode external'` | | Go DNS/outgoing filters not working | Build with `GODEBUG=netdns=cgo` | | Traffic doesn't reach local process | Check port mapping - local may listen on different port than remote | | Traffic stops reaching remote target | With service mesh, try `{"agent": {"flush_connections": false}}` | | DNS resolution fails for K8s services | Change `feature.fs.mode` from `local` to `localwithoverrides` | | Permission (EACCES) errors | Enable privileged mode: `{"agent": {"privileged": true}}` | | Agent pods not cleaned up | Run: `kubectl delete jobs --selector=app=mirrord --field-selector=status.successful=1` | | Certificate validation errors (macOS) | Use `{"experimental": {"trust_any_certificate": true}}` | | Service mesh drops agent connection | Set static `agent.port` and add port exclusion in mesh config | ### Framework-Specific Issues **Turbo (monorepo):** ```json // turbo.json { "globalPassThroughEnv": ["MIRRORD_*", "LD_PRELOAD", "DYLD_INSERT_LIBRARIES"] } ``` **Remix/Vite/Next.js** - Override NODE_ENV to avoid production config: ```json { "feature": { "env": { "override": { "NODE_ENV": "development" } } } } ``` **Next.js with Nx** - Exclude conflicting variables: ```json { "feature": { "env": { "exclude": ["NODE_ENV", "NX_NEXT_DIR"] } } } ``` ### Multi-Container Pods If your pod has multiple containers, specify the target container explicitly: ```json { "target": { "path": "pod/my-pod", "container": "my-app-container" } } ``` ## Response Guidelines 1. **Ask about their CI platform** - GitHub Actions, GitLab, CircleCI, Jenkins, etc. 2. **Verify prerequisites** - kubectl access, mirrord version 3. **Provide platform-specific examples** - Use the appropriate YAML/Groovy syntax 4. **Include cleanup steps** - Always show `mirrord ci stop` in appropriate hooks 5. **Mention API key** - Remind about `MIRRORD_CI_API_KEY` for Teams users ## Example Interaction **User:** "How do I run my tests against staging in GitHub Actions?" **Response:** 1. Ask: What's your target (deployment/pod name)? 2. Check: Do you have kubeconfig set up as a secret? 3. Provide: GitHub Actions workflow with: - kubeconfig setup - mirrord installation - `mirrord ci start` with their target - Test execution - `mirrord ci stop` in `if: always()` block 4. Mention: `MIRRORD_CI_API_KEY` if using Teams/Enterprise ## Learn More - [mirrord for CI Overview](https://metalbear.com/mirrord-for-ci/) - [mirrord CI Documentation](https://mirrord.dev/docs/using-mirrord/mirrord-for-ci/) - [mirrord Installation](https://mirrord.dev/docs/overview/quick-start/)