Skip to content

feat(project): add KinD configuration options and DinD support - #395

Draft
nkzk wants to merge 9 commits into
crossplane:mainfrom
nkzk:feat-project-closed-networks
Draft

nkzk wants to merge 9 commits into
crossplane:mainfrom
nkzk:feat-project-closed-networks

Conversation

@nkzk

@nkzk nkzk commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Description of your changes

This PR adds support for running crossplane project in devcontainers and closed company networks with the following changes:

  1. Add configuration options for KinD in crossplane-project.yaml.

    • Allow the user to specify their own kind-config (to avoid the need for more updates and flags to support other kind options later, ref. Adam's comment in this issue)
    • Add options to:
      • specify docker-network
      • use internal KinD kubeconfig.
      • specify registry storage type (ref explanation below)
    Example crossplane-project file
     apiVersion: dev.crossplane.io/v1alpha1
     kind: Project
     metadata:
       name: example
     spec:
       dependencies:
         - type: xpkg
           xpkg:
             apiVersion: pkg.crossplane.io/v1
             kind: Function
             package: xpkg.crossplane.io/crossplane-contrib/function-go-templating
             version: "v0.12.4"
         - type: xpkg
           xpkg:
             apiVersion: pkg.crossplane.io/v1
             kind: Provider
             package: xpkg.crossplane.io/crossplane-contrib/provider-kubernetes
             version: "v1.3.1"
       repository: example.com/my-org/example
      # New runtime field 
       runtime:
         registry:
           storage:
             type: volume
         kind:
           config:
             path: kind-config.yaml
           internal: true
           network:
             name: my-network
  1. Support registry data sideloading when running crossplane project in Docker-in-Docker

    When running crossplane project in a container, bind-mounting the CLI’s local registry directory into the registry container mounts an empty host path, leaving the registry without its certificates and package data.
    This happens because the generated files are only in the container where the command was ran, and not on the host.

    I added a storage interface where the bind-mount implementation ensures we keep old behavior, and a config-flag to use a volume-implementation. This required some refactoring of the code, for example where certs are created.

Fixes #313

With these changes, a user in a closed company network and devcontainer can run crossplane project with the following files and command:

./crossplane-project.yaml
apiVersion: dev.crossplane.io/v1alpha1
kind: Project
metadata:
  name: example
spec:
  dependencies:
    - type: xpkg
      xpkg:
        apiVersion: pkg.crossplane.io/v1
        kind: Function
        package: xpkg.crossplane.io/crossplane-contrib/function-go-templating
        version: "v0.12.4"
    - type: xpkg
      xpkg:
        apiVersion: pkg.crossplane.io/v1
        kind: Provider
        package: xpkg.crossplane.io/crossplane-contrib/provider-kubernetes
        version: "v1.3.1"
  repository: example.com/my-org/example
    runtime:
      registry:
        storage:
          type: volume
    kind:
      config:
        path: kind-config.yaml
      internal: true
      network:
        name: my-network
./kind-config.yaml
apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
containerdConfigPatches:
  - |
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
        endpoint = ["https://docker-remote.my-registry.com"]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
        endpoint = ["https://ghcr-remote.my-registry.com"]
./image-configs.yaml
---
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name: docker.io
spec:
  matchImages:
    - prefix: docker.io
  rewriteImage:
    prefix: docker-remote.my-registry.com
---
apiVersion: pkg.crossplane.io/v1beta1
kind: ImageConfig
metadata:
  name:  ghcr.io
spec:
  matchImages:
    - prefix: ghcr.io
  rewriteImage:
    prefix: ghcr-remote.my-registry.com
crossplane project run --init-resources=image-configs.yaml

I have:

Need help with this checklist? See the cheat sheet.

@nkzk
nkzk force-pushed the feat-project-closed-networks branch 2 times, most recently from 7b34bc4 to 450403a Compare October 1, 2026 11:13
nkzk added 6 commits October 1, 2026 13:30
Bind-mounting the local registry directory into the registry container
relies on the CLI's filesystem being visible to the Docker daemon. That
breaks when Crossplane itself runs inside a container, since the mount
path only exists in the CLI's own filesystem, not the daemon's.

Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Signed-off-by: Nikita Z <nkzk95@gmail.com>
@nkzk
nkzk force-pushed the feat-project-closed-networks branch from 450403a to e272f26 Compare October 1, 2026 11:30
Signed-off-by: Nikita Z <nkzk95@gmail.com>
@nkzk

nkzk commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Before review, I want to refactor this again so that the registry-storage works like before by default, and add a config flag for the docker-volume method. I think that will be cleaner and better.

Comment thread cmd/crossplane/project/run.go Outdated
Comment thread cmd/crossplane/project/run.go Outdated
Comment thread internal/docker/docker.go Outdated
Comment thread internal/docker/storage.go Outdated
Comment thread internal/docker/storage.go Outdated
Comment thread internal/docker/storage.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
Comment thread internal/project/controlplane/controlplane.go Outdated
@nkzk
nkzk force-pushed the feat-project-closed-networks branch from d87dd05 to 4d44ebc Compare October 2, 2026 14:56
Comment thread apis/dev/v1alpha1/project_types.go Outdated
Comment thread apis/dev/v1alpha1/project_types.go Outdated
Comment thread apis/dev/v1alpha1/project_types.go Outdated
Comment thread cmd/crossplane/project/run.go Outdated
Comment thread cmd/crossplane/project/run.go Outdated
@nkzk
nkzk force-pushed the feat-project-closed-networks branch from 5b4ba76 to 93f6845 Compare October 2, 2026 15:17
Comment thread internal/docker/docker.go Outdated
…o select stoarge-type

the bindmount implementation ensures that we keep old behavior, and the volume implementation is for DinD support

Signed-off-by: Nikita Z <nkzk95@gmail.com>
@nkzk
nkzk force-pushed the feat-project-closed-networks branch from f2657dd to 2b1280e Compare October 2, 2026 15:20
Signed-off-by: Nikita Z <nkzk95@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

proposal(crossplane project): add configuration options to support users in closed networks and devcontainers

2 participants