Skip to content
Open
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
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,31 @@ Kind can also be configured with an [extra mount](https://kind.sigs.k8s.io/docs/
kn quickstart kind --extraMountHostPath /home/myname/foo --extraMountContainerPath /foo
```

#### Using a non-privileged host port (Podman / rootless runtimes)

By default, Kourier ingress is exposed on host port `80`. Rootless container runtimes like Podman on macOS cannot bind privileged ports (`<1024`) without additional setup, which causes cluster creation to fail with `rootlessport cannot expose privileged port 80`.

Use `--host-port` to pick an unprivileged port instead:

```bash
kn quickstart kind --host-port 8080
```

When you use a non-default host port, the URL Knative prints for a Service (e.g. `http://hello.default.127.0.0.1.sslip.io`) will not include the port. You'll need to add it yourself when calling the service:

```bash
URL=$(kubectl get ksvc hello -o jsonpath='{.status.url}')
HOST=${URL#http://}
curl -H "Host: ${HOST}" http://127.0.0.1:8080
```

To use Podman, you'll also want to make sure the Podman socket is reachable and tell Kind to use the Podman provider:

```bash
unset DOCKER_HOST # if set to a path inside the Podman VM
export KIND_EXPERIMENTAL_PROVIDER=podman
```

### Quickstart with Minikube

Set up a local Knative cluster using [Minikube](https://minikube.sigs.k8s.io/):
Expand Down
30 changes: 3 additions & 27 deletions hack/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ go_test() {
reset=""
fi

echo "🧪 ${X}Test"
echo "🧪 Test"
set +e
go test -v ./pkg/... >$test_output 2>&1
local err=$?
Expand All @@ -209,7 +209,7 @@ go_test() {
}

check_license() {
echo "⚖️ ${S}License"
echo "⚖️ License"
local required_keywords=("Authors" "Apache License" "LICENSE-2.0")
local extensions_to_check=("sh" "go" "yaml" "yml" "json")

Expand Down Expand Up @@ -284,7 +284,7 @@ cross_build() {
local ld_flags="$(build_flags $basedir)"
local failed=0

echo "⚔️ ${S}Compile"
echo "⚔️ Compile"

export CGO_ENABLED=0
echo " 🐧 ${PLUGIN}-linux-amd64"
Expand All @@ -297,27 +297,6 @@ cross_build() {
return ${failed}
}

# Spaced fillers needed for certain emojis in certain terminals
S=""
X=""

# Calculate space fixing variables S and X
apply_emoji_fixes() {
# Temporary fix for iTerm issue https://gitlab.com/gnachman/iterm2/issues/7901
if [ -n "${ITERM_PROFILE:-}" ]; then
S=" "
# This issue has been fixed with iTerm2 3.3.7, so let's check for this
# We can remove this code altogether if iTerm2 3.3.7 is in common usage everywhere
if [ -n "${TERM_PROGRAM_VERSION}" ]; then
args=$(echo $TERM_PROGRAM_VERSION | sed -e 's#[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)#\1 \2 \3#')
expanded=$(printf '%03d%03d%03d' $args)
if [ $expanded -lt "003003007" ]; then
X=" "
fi
fi
fi
}

# Display a help message.
display_help() {
cat <<EOT
Expand Down Expand Up @@ -358,7 +337,4 @@ if $(has_flag --debug); then
set -x
fi

# Fixe emoji labels for certain terminals
apply_emoji_fixes

run $*
5 changes: 5 additions & 0 deletions internal/command/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ var installEventing bool
var installKindRegistry bool
var installKindExtraMountHostPath string
var installKindExtraMountContainerPath string
var kindHostPort int

func clusterNameOption(targetCmd *cobra.Command, flagDefault string) {
targetCmd.Flags().StringVarP(
Expand Down Expand Up @@ -66,3 +67,7 @@ func installKindExtraMountHostPathOption(targetCmd *cobra.Command) {
func installKindExtraMountContainerPathOption(targetCmd *cobra.Command) {
targetCmd.Flags().StringVarP(&installKindExtraMountContainerPath, "extraMountContainerPath", "", "", "set the extraMount containerPath on Kind quickstart cluster")
}

func kindHostPortOption(targetCmd *cobra.Command) {
targetCmd.Flags().IntVar(&kindHostPort, "host-port", 80, "host port to expose Kourier ingress on (use a non-privileged port >=1024 for rootless container runtimes like Podman)")
}
3 changes: 2 additions & 1 deletion internal/command/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewKindCommand() *cobra.Command {
Short: "Quickstart with Kind",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Running Knative Quickstart using Kind")
return kind.SetUp(name, kubernetesVersion, installServing, installEventing, installKindRegistry, installKindExtraMountHostPath, installKindExtraMountContainerPath)
return kind.SetUp(name, kubernetesVersion, installServing, installEventing, installKindRegistry, installKindExtraMountHostPath, installKindExtraMountContainerPath, kindHostPort)
},
}
// Set kindCmd options
Expand All @@ -39,6 +39,7 @@ func NewKindCommand() *cobra.Command {
installKindRegistryOption(kindCmd)
installKindExtraMountHostPathOption(kindCmd)
installKindExtraMountContainerPathOption(kindCmd)
kindHostPortOption(kindCmd)

return kindCmd
}
24 changes: 12 additions & 12 deletions pkg/kind/kind.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var (
)

// SetUp creates a local Kind cluster and installs all the relevant Knative components
func SetUp(name, kVersion string, installServing, installEventing, installKindRegistry bool, installKindExtraMountHostPath string, installKindExtraMountContainerPath string) error {
func SetUp(name, kVersion string, installServing, installEventing, installKindRegistry bool, installKindExtraMountHostPath string, installKindExtraMountContainerPath string, hostPort int) error {
start := time.Now()

// if neither the "install-serving" or "install-eventing" flags are set,
Expand All @@ -72,7 +72,7 @@ func SetUp(name, kVersion string, installServing, installEventing, installKindRe
}
}

if err := createKindCluster(installKindRegistry, installKindExtraMountHostPath, installKindExtraMountContainerPath); err != nil {
if err := createKindCluster(installKindRegistry, installKindExtraMountHostPath, installKindExtraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("failed to create kind cluster: %w", err)
}
if installKnative {
Expand Down Expand Up @@ -107,7 +107,7 @@ func SetUp(name, kVersion string, installServing, installEventing, installKindRe
return nil
}

func createKindCluster(registry bool, extraMountHostPath string, extraMountContainerPath string) error {
func createKindCluster(registry bool, extraMountHostPath string, extraMountContainerPath string, hostPort int) error {
dcli, err := checkDocker()
if err != nil {
return err
Expand All @@ -131,7 +131,7 @@ func createKindCluster(registry bool, extraMountHostPath string, extraMountConta
fmt.Print(" To create a local registry, use the --registry flag.\n\n")
}

if err := checkForExistingCluster(registry, extraMountHostPath, extraMountContainerPath); err != nil {
if err := checkForExistingCluster(registry, extraMountHostPath, extraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("failed while handling or checking for existing kind cluster: %w", err)
}

Expand Down Expand Up @@ -267,7 +267,7 @@ func checkKindVersion() error {
// checkForExistingCluster checks if the user already has a Kind cluster. If so, it provides
// the option of deleting the existing cluster and recreating it. If not, it proceeds to
// creating a new cluster
func checkForExistingCluster(registry bool, extraMountHostPath string, extraMountContainerPath string) error {
func checkForExistingCluster(registry bool, extraMountHostPath string, extraMountContainerPath string, hostPort int) error {
getClusters := exec.Command("kind", "get", "clusters", "-q")
out, err := getClusters.CombinedOutput()
if err != nil {
Expand All @@ -281,7 +281,7 @@ func checkForExistingCluster(registry bool, extraMountHostPath string, extraMoun
fmt.Print("\nKnative Cluster kind-" + clusterName + " already installed.\nDelete and recreate [y/N]: ")
fmt.Scanf("%s", &resp)
if resp == "y" || resp == "Y" {
if err := recreateCluster(registry, extraMountHostPath, extraMountContainerPath); err != nil {
if err := recreateCluster(registry, extraMountHostPath, extraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("failed while recreating kind cluster %s: %w", clusterName, err)
}
} else {
Expand All @@ -297,7 +297,7 @@ func checkForExistingCluster(registry bool, extraMountHostPath string, extraMoun
fmt.Print("Knative installation already exists.\nDelete and recreate the cluster [y/N]: ")
fmt.Scanf("%s", &resp)
if resp == "y" || resp == "Y" {
if err := recreateCluster(registry, extraMountHostPath, extraMountContainerPath); err != nil {
if err := recreateCluster(registry, extraMountHostPath, extraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("failed to recreate kind cluster: %w", err)
}
} else {
Expand All @@ -314,7 +314,7 @@ func checkForExistingCluster(registry bool, extraMountHostPath string, extraMoun
return fmt.Errorf("failed to initialize new api client: %w", err)
}

if err := createNewCluster(extraMountHostPath, extraMountContainerPath); err != nil {
if err := createNewCluster(extraMountHostPath, extraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("%w", err)
}
if registry {
Expand All @@ -331,7 +331,7 @@ func checkForExistingCluster(registry bool, extraMountHostPath string, extraMoun
}

// recreateCluster recreates a Kind cluster
func recreateCluster(registry bool, extraMountHostPath string, extraMountContainerPath string) error {
func recreateCluster(registry bool, extraMountHostPath string, extraMountContainerPath string, hostPort int) error {
fmt.Println("\n Deleting cluster...")

dcli, err := dclient.NewClientWithOpts(dclient.FromEnv, dclient.WithAPIVersionNegotiation())
Expand All @@ -346,7 +346,7 @@ func recreateCluster(registry bool, extraMountHostPath string, extraMountContain
if err := deleteContainerRegistry(dcli); err != nil {
return fmt.Errorf("failed to delete container registry: %w", err)
}
if err := createNewCluster(extraMountHostPath, extraMountContainerPath); err != nil {
if err := createNewCluster(extraMountHostPath, extraMountContainerPath, hostPort); err != nil {
return fmt.Errorf("%w", err)
}
if registry {
Expand All @@ -361,7 +361,7 @@ func recreateCluster(registry bool, extraMountHostPath string, extraMountContain
}

// createNewCluster creates a new Kind cluster
func createNewCluster(extraMountHostPath string, extraMountContainerPath string) error {
func createNewCluster(extraMountHostPath string, extraMountContainerPath string, hostPort int) error {
extraMount := ""
if extraMountHostPath != "" && extraMountContainerPath != "" {
extraMount = fmt.Sprintf(`extraMounts:
Expand Down Expand Up @@ -395,7 +395,7 @@ nodes:
extraPortMappings:
- containerPort: 31080
listenAddress: 0.0.0.0
hostPort: 80`, clusterName, imageString, extraMount)
hostPort: %d`, clusterName, imageString, extraMount, hostPort)

createCluster := exec.Command("kind", "create", "cluster", "--wait=120s", "--config=-")
createCluster.Stdin = strings.NewReader(config)
Expand Down
Loading