diff --git a/README.md b/README.md index 446888c1..e3d82291 100644 --- a/README.md +++ b/README.md @@ -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/): diff --git a/hack/build.sh b/hack/build.sh index b0260091..1b66d674 100755 --- a/hack/build.sh +++ b/hack/build.sh @@ -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=$? @@ -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") @@ -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" @@ -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 <=1024 for rootless container runtimes like Podman)") +} diff --git a/internal/command/kind.go b/internal/command/kind.go index 0c28c6cc..3f557b4d 100644 --- a/internal/command/kind.go +++ b/internal/command/kind.go @@ -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 @@ -39,6 +39,7 @@ func NewKindCommand() *cobra.Command { installKindRegistryOption(kindCmd) installKindExtraMountHostPathOption(kindCmd) installKindExtraMountContainerPathOption(kindCmd) + kindHostPortOption(kindCmd) return kindCmd } diff --git a/pkg/kind/kind.go b/pkg/kind/kind.go index 536e5acb..5cbe8c0f 100644 --- a/pkg/kind/kind.go +++ b/pkg/kind/kind.go @@ -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, @@ -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 { @@ -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 @@ -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) } @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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()) @@ -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 { @@ -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: @@ -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)