Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions hack/test-container-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ run_test() {
"${bink_args[@]}" --help

echo "--- bink cluster start ---"
local verbose_flag=""
[ "${mode}" = "nested" ] && verbose_flag="-v"
"${bink_args[@]}" cluster start --cluster-name "${cluster_name}" --api-port 0 ${verbose_flag}
local start_extra_flags=""
if [ "${mode}" = "nested" ]; then
start_extra_flags="-v --host-network-populator"
fi
"${bink_args[@]}" cluster start --cluster-name "${cluster_name}" --api-port 0 ${start_extra_flags}

echo "--- bink api expose ---"
"${bink_args[@]}" api expose --cluster-name "${cluster_name}"
Expand Down
13 changes: 8 additions & 5 deletions internal/cli/cluster/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ func newStartCmd() *cobra.Command {
var memory int
var maxMemory int
var exposePath string
var hostNetworkPopulator bool

cmd := &cobra.Command{
Use: "start",
Short: "Start a new Kubernetes cluster",
Long: "Create network, control plane node, and initialize Kubernetes cluster with kubeadm",
RunE: func(cmd *cobra.Command, args []string) error {
logger := logrus.New()
return runStart(cmd.Context(), logger, nodeName, nodeImage, apiPort, memory, maxMemory, exposePath)
return runStart(cmd.Context(), logger, nodeName, nodeImage, apiPort, memory, maxMemory, exposePath, hostNetworkPopulator)
},
}

Expand All @@ -45,11 +46,12 @@ func newStartCmd() *cobra.Command {
cmd.Flags().IntVar(&memory, "memory", 0, "VM memory in MB (0 = use role default: 1900 for control-plane, 768 for worker)")
cmd.Flags().IntVar(&maxMemory, "max-memory", 0, "VM max memory in MB for balloon (0 = use role default: 4096 for control-plane, 2048 for worker)")
cmd.Flags().StringVar(&exposePath, "expose", "", "Expose API and save kubeconfig to PATH after cluster is up")
cmd.Flags().BoolVar(&hostNetworkPopulator, "host-network-populator", false, "Use host networking for the image populator container (fixes DNS in nested podman)")

return cmd
}

func runStart(ctx context.Context, logger *logrus.Logger, nodeName string, nodeImage string, apiPort int, memory int, maxMemory int, exposePath string) error {
func runStart(ctx context.Context, logger *logrus.Logger, nodeName string, nodeImage string, apiPort int, memory int, maxMemory int, exposePath string, hostNetworkPopulator bool) error {
logger.Info("=== Creating Kubernetes cluster ===")
logger.Info("")

Expand Down Expand Up @@ -102,9 +104,10 @@ func runStart(ctx context.Context, logger *logrus.Logger, nodeName string, nodeI

logger.Info("Step 5: Preparing cluster images volume...")
clusterMgr := cluster.New(cluster.Config{
Name: clusterName,
ControlPlane: nodeName,
Logger: logger,
Name: clusterName,
ControlPlane: nodeName,
HostNetworkPopulator: hostNetworkPopulator,
Logger: logger,
})

clusterImagesVolume, err := clusterMgr.EnsureImagesVolume(ctx, nodeImage)
Expand Down
13 changes: 8 additions & 5 deletions internal/cli/node/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func newAddCmd() *cobra.Command {
var role string
var memory int
var maxMemory int
var hostNetworkPopulator bool

cmd := &cobra.Command{
Use: "add <node-name>",
Expand All @@ -33,7 +34,7 @@ func newAddCmd() *cobra.Command {
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
logger := logrus.New()
return runAdd(cmd.Context(), args[0], controlPlane, nodeImage, role, memory, maxMemory, logger)
return runAdd(cmd.Context(), args[0], controlPlane, nodeImage, role, memory, maxMemory, hostNetworkPopulator, logger)
},
}

Expand All @@ -42,11 +43,12 @@ func newAddCmd() *cobra.Command {
cmd.Flags().StringVarP(&role, "role", "r", "worker", "Node role: worker or control-plane")
cmd.Flags().IntVar(&memory, "memory", 0, "VM memory in MB (0 = use role default: 1900 for control-plane, 768 for worker)")
cmd.Flags().IntVar(&maxMemory, "max-memory", 0, "VM max memory in MB for balloon (0 = use role default: 4096 for control-plane, 2048 for worker)")
cmd.Flags().BoolVar(&hostNetworkPopulator, "host-network-populator", false, "Use host networking for the image populator container (fixes DNS in nested podman)")

return cmd
}

func runAdd(ctx context.Context, nodeName, controlPlane, nodeImage, role string, memory int, maxMemory int, logger *logrus.Logger) error {
func runAdd(ctx context.Context, nodeName, controlPlane, nodeImage, role string, memory int, maxMemory int, hostNetworkPopulator bool, logger *logrus.Logger) error {
// Validate and convert role to boolean
var isControlPlane bool
switch role {
Expand Down Expand Up @@ -74,9 +76,10 @@ func runAdd(ctx context.Context, nodeName, controlPlane, nodeImage, role string,
// Ensure images volume exists for this node image version
logger.Infof("Step 0: Ensuring cluster images volume...")
clusterMgr := cluster.New(cluster.Config{
Name: clusterName,
ControlPlane: controlPlane,
Logger: logger,
Name: clusterName,
ControlPlane: controlPlane,
HostNetworkPopulator: hostNetworkPopulator,
Logger: logger,
})

clusterImagesVolume, err := clusterMgr.EnsureImagesVolume(ctx, nodeImage)
Expand Down
27 changes: 15 additions & 12 deletions internal/cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,20 @@ type PodmanClient interface {

// Cluster represents a Kubernetes cluster
type Cluster struct {
name string
controlPlane string
logger *logrus.Logger
podmanClient PodmanClient
name string
controlPlane string
hostNetworkPopulator bool
logger *logrus.Logger
podmanClient PodmanClient
}

// Config holds cluster configuration
type Config struct {
Name string // Cluster name (default: "bink")
ControlPlane string // Control plane node name (default: "node1")
Logger *logrus.Logger
PodmanClient PodmanClient
Name string // Cluster name (default: "bink")
ControlPlane string // Control plane node name (default: "node1")
HostNetworkPopulator bool // Use host networking for the image populator container
Logger *logrus.Logger
PodmanClient PodmanClient
}

// New creates a new Cluster
Expand All @@ -69,10 +71,11 @@ func New(cfg Config) *Cluster {
}

return &Cluster{
name: cfg.Name,
controlPlane: cfg.ControlPlane,
logger: cfg.Logger,
podmanClient: client,
name: cfg.Name,
controlPlane: cfg.ControlPlane,
hostNetworkPopulator: cfg.HostNetworkPopulator,
logger: cfg.Logger,
podmanClient: client,
}
}

Expand Down
8 changes: 6 additions & 2 deletions internal/cluster/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,15 @@ func (c *Cluster) populateImagesVolume(ctx context.Context, volumeName, nodeImag
Destination: "/images",
}},
Volumes: []*specgen.NamedVolume{{Name: volumeName, Dest: "/var/lib/containers/storage"}},
CapAdd: []string{"SYS_ADMIN"},
Devices: []specs.LinuxDevice{{Path: "/dev/fuse"}},
CapAdd: []string{"SYS_ADMIN"},
Devices: []specs.LinuxDevice{{Path: "/dev/fuse"}},
SelinuxOpts: []string{"disable"},
}

if c.hostNetworkPopulator {
opts.Network = "host"
}

_, err := c.podmanClient.ContainerCreate(ctx, opts)
if err != nil {
return fmt.Errorf("starting populator container (another process may be populating): %w", err)
Expand Down
15 changes: 10 additions & 5 deletions internal/podman/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,16 @@ func (c *Client) ContainerCreate(ctx context.Context, opts *ContainerCreateOptio
}
spec.Networks = opts.NetworkOptions
} else if opts.Network != "" {
spec.NetNS = specgen.Namespace{
NSMode: specgen.Bridge,
}
spec.Networks = map[string]nettypes.PerNetworkOptions{
opts.Network: {},
switch opts.Network {
case "host":
spec.NetNS = specgen.Namespace{NSMode: specgen.Host}
default:
spec.NetNS = specgen.Namespace{
NSMode: specgen.Bridge,
}
spec.Networks = map[string]nettypes.PerNetworkOptions{
opts.Network: {},
}
}
}

Expand Down
Loading