From 0bb3db7f20b2c98d1d057bc7fa03132330da6dc0 Mon Sep 17 00:00:00 2001 From: francostellari Date: Sun, 4 Feb 2024 13:00:47 -0500 Subject: [PATCH 1/2] Add install script Signed-off-by: francostellari update sudo Signed-off-by: francostellari update sudo Signed-off-by: francostellari --- README.md | 26 +++--- docs/users.md | 98 +++++++++++----------- scripts/install-kubeflex.sh | 156 ++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 55 deletions(-) create mode 100755 scripts/install-kubeflex.sh diff --git a/README.md b/README.md index e593329..bf58f39 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Go Report Card](https://goreportcard.com/badge/github.com/kubestellar/kubeflex)](https://goreportcard.com/report/github.com/kubestellar/kubeflex) +[![Go Report Card](https://goreportcard.com/badge/github.com/kubestellar/kubeflex)](https://goreportcard.com/report/github.com/kubestellar/kubeflex) [![GitHub release](https://img.shields.io/github/release/kubestellar/kubeflex/all.svg?style=flat-square)](https://github.com/kubestellar/kubeflex/releases) [![CI](https://github.com/kubestellar/kubeflex/actions/workflows/ci.yaml/badge.svg)](https://github.com/kubestellar/kubeflex/actions/workflows/ci.yaml) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=kubestellar_kubeflex&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=kubestellar_kubeflex) @@ -16,21 +16,27 @@ A flexible and scalable platform for running Kubernetes control plane APIs. - dedicated DB for each API server, - etcd DB or Kine + Postgres DB - Flexibility in choice of API Server build: - - upstream Kube (e.g. `registry.k8s.io/kube-apiserver:v1.27.1`), + - upstream Kube (e.g. `registry.k8s.io/kube-apiserver:v1.27.1`), - trimmed down API Server builds (e.g. [multicluster control plane](https://github.com/open-cluster-management-io/multicluster-controlplane)) - Single binary CLI for improved user experience: - initialize, install operator, manage lifecycle of control planes and contexts. ## Installation -[kind](https://kind.sigs.k8s.io) and [kubectl](https://kubernetes.io/docs/tasks/tools/) are +[kind](https://kind.sigs.k8s.io) and [kubectl](https://kubernetes.io/docs/tasks/tools/) are required. A kind hosting cluster is created automatically by the kubeflex CLI. You may also install KubeFlex on other Kube distros, as long as they support an nginx ingress with SSL passthru, or on OpenShift. See the [User's Guide](docs/users.md) for more details. -Download the latest kubeflex CLI binary release for your OS/Architecture from the +Download the latest kubeflex CLI binary release for your OS/Architecture from the [release page](https://github.com/kubestellar/kubeflex/releases) and copy it -to `/usr/local/bin` or another location in your `$PATH`. +to `/usr/local/bin` using the following command: + +```shell +sudo su <` command, e.g: ```shell @@ -97,9 +103,9 @@ kflex delete cp1 ## Next Steps Read the [User's Guide](docs/users.md) to learn more about using KubeFlex for your project -and how to create and interact with different types of control planes, such as +and how to create and interact with different types of control planes, such as [vcluster](https://www.vcluster.com) and [Open Cluster Management](https://github.com/open-cluster-management-io/multicluster-controlplane). ## Architecture -![image info](./docs/images/kubeflex-high-level-arch.png) \ No newline at end of file +![image info](./docs/images/kubeflex-high-level-arch.png) diff --git a/docs/users.md b/docs/users.md index 2798b2d..acca568 100644 --- a/docs/users.md +++ b/docs/users.md @@ -2,11 +2,11 @@ ## Installation -[kind](https://kind.sigs.k8s.io) and [kubectl](https://kubernetes.io/docs/tasks/tools/) are -required. Note that we plan to add support for other Kube distros. A hosting kind cluster +[kind](https://kind.sigs.k8s.io) and [kubectl](https://kubernetes.io/docs/tasks/tools/) are +required. Note that we plan to add support for other Kube distros. A hosting kind cluster is created automatically by the kubeflex CLI. -Download the latest kubeflex CLI binary release for your OS/Architecture from the +Download the latest kubeflex CLI binary release for your OS/Architecture from the [release page](https://github.com/kubestellar/kubeflex/releases) and copy it to `/usr/local/bin` or another location in your `$PATH`. For example, on linux amd64: @@ -18,6 +18,14 @@ tar xzvf $(basename $LATEST_RELEASE_URL) sudo install -o root -g root -m 0755 bin/kflex /usr/local/bin/kflex ``` +Alternatively use the the single command below which will automatically detect the host OS type and architecture: + +```shell +sudo su <) +To use a different domain for DNS resolution, you can specify the `--domain` option when +you run `kflex init`. This domain should point to the IP address of your ingress controller, +which handles the routing of requests to different control plane instances based on the hostname. +A wildcard DNS service is recommended, so that any subdomain of your domain (such as *.) will resolve to the same IP address. The default domain in KubeFlex is localtest.me, which is a -wildcard DNS service that always resolves to 127.0.0.1. +wildcard DNS service that always resolves to 127.0.0.1. For example, `cp1.localtest.me` and `cp2.localtest.me` will both resolve to your local machine. Note that this option is ignored if you are installing on OpenShift. @@ -162,7 +170,7 @@ You can create a new control plane using the KubeFlex CLI or using any Kubernete To create a new control plane with name `cp1` using the KubeFlex CLI: -```shell +```shell kflex create cp1 ``` @@ -182,7 +190,7 @@ to switch the context back to the hosting cluster context, you may use the `ctx` kflex ctx ``` -To switch back to a control plane context, use the +To switch back to a control plane context, use the `ctx ` command, e.g: ```shell @@ -242,10 +250,10 @@ kubectl get secrets -n ${NAMESPACE} admin-kubeconfig -o jsonpath='{.data.kubecon ### Accessing the control plane from within a kind cluster -For control plane of type k8s, the Kube API client can only use the 127.0.0.1 address. The DNS name +For control plane of type k8s, the Kube API client can only use the 127.0.0.1 address. The DNS name `.localtest.me`` is convenient for local test and dev but always resolves to 127.0.0.1, that does not work in a container. For accessing the control plane from within the KubeFlex hosting cluster, you may use the controller manager Kubeconfig, which is maintained in the secret with name -`cm-kubeconfig` in the namespace hosting the control plane, or you may use the Kubeconfig in the +`cm-kubeconfig` in the namespace hosting the control plane, or you may use the Kubeconfig in the `admin-kubeconfig` secret with the address for the server `https://.:9443`. To access the control plane API server from another kind cluster on the same docker network, you @@ -258,7 +266,7 @@ the URL for the server as `https://kubeflex-control-plane:` At this time KubFlex supports the following control plane types: - k8s: this is the stock Kube API server with a subset of controllers running in the controller manager. -- ocm: this is the [Open Cluster Management Multicluster Control Plane](https://github.com/open-cluster-management-io/multicluster-controlplane), which provides a basic set of capabilities such as +- ocm: this is the [Open Cluster Management Multicluster Control Plane](https://github.com/open-cluster-management-io/multicluster-controlplane), which provides a basic set of capabilities such as clusters registration and support for the [`ManifestWork` API](https://open-cluster-management.io/concepts/manifestwork/). - vcluster: this is based on the [vcluster project](https://www.vcluster.com) and provides the ability to create pods in the hosting namespace of the hosting cluster. - host: this control plane type exposes the underlying hosting cluster with the same control plane abstraction @@ -267,7 +275,7 @@ used by the other control plane types. ## Control Plane Backends KubeFlex roadmap aims to provide different types of backends: shared, dedicated, and for -each type the ability to choose if etcd or sql. At this time only the following +each type the ability to choose if etcd or sql. At this time only the following combinations are supported based on control plane type: - k8s: shared postgresql @@ -339,7 +347,7 @@ used to register managed clusters: ```shell $ clusteradm get token --use-bootstrap-token -clusteradm join --hub-token --hub-apiserver https://cp3.localtest.me:9443/ --cluster-name +clusteradm join --hub-token --hub-apiserver https://cp3.localtest.me:9443/ --cluster-name ``` The command returns the command to run on the managed cluster (actual token value not shown in example). @@ -440,7 +448,7 @@ kflex ctx kind-cluster1 ``` ```shell -$ kubectl get deployments.apps +$ kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 20s ``` @@ -473,7 +481,7 @@ nginx 1/1 Running 0 24s Access the pod logs: ```shell -$ kubectl logs nginx +$ kubectl logs nginx /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ ... @@ -496,7 +504,7 @@ kflex ctx ``` ```shell -$ kubectl get pods -n cp2-system +$ kubectl get pods -n cp2-system NAME READY STATUS RESTARTS AGE coredns-64c4b4d78f-2w9bx-x-kube-system-x-vcluster 1/1 Running 0 6m58s nginx-x-default-x-vcluster 1/1 Running 0 4m26s @@ -507,7 +515,7 @@ The nginx pod is the one with the name `nginx-x-default-x-vcluster`. ## Post-create hooks -With post-create hooks you can automate applying kubernetes templates on the hosting cluster or on +With post-create hooks you can automate applying kubernetes templates on the hosting cluster or on a hosted control plane right after the creation of a control plane. Some relevant use cases are: - Applying OpenShift CRDs on a control plane to be used as a Workload Description Space (WDS) for deplying @@ -548,9 +556,9 @@ spec: backoffLimit: 1 ``` -This hook will launch a job in the same namespace of the control plane that will print +This hook will launch a job in the same namespace of the control plane that will print "Hello World" to the standard output. Typically, a hook runs a job that by default -interacts with the hosting cluster API server. To make the job interact with the hosted +interacts with the hosting cluster API server. To make the job interact with the hosted control plane API server you can mount the secret with the in-cluster kubeconfig for that API server. For example, for a control plane of type `k8s` you can define a volume for a secret as follows: @@ -567,11 +575,11 @@ Then, you can mount the volume and define the `KUBECONFIG` env variable as follo ```yaml env: - name: KUBECONFIG - value: "/etc/kube/kubeconfig-incluster" + value: "/etc/kube/kubeconfig-incluster" volumeMounts: - name: kubeconfig mountPath: "/etc/kube" - readOnly: true + readOnly: true ``` A complete example for installing OpenShift CRDs on a control plane is available @@ -593,13 +601,13 @@ Currently avilable built-in objects are: - "{{.Namespace}}" - the namespace hosting the control plane - "{{.ControlPlaneName}}" - the name of the control plane -- "{{.HookName}}" - the name of the hook. +- "{{.HookName}}" - the name of the hook. ### Labels propagation -There are scenarios where you may need to setup labels on control planes based on the -features that the control plane acquires after the hook runs. For example you may want -to label a control plane where the OpenShift CRDs have been applied as a control plane +There are scenarios where you may need to setup labels on control planes based on the +features that the control plane acquires after the hook runs. For example you may want +to label a control plane where the OpenShift CRDs have been applied as a control plane with OpenShift flavor. To propagate labels, simply set the labels on the PostCreateHook as shown in the example @@ -615,7 +623,7 @@ kflex ctx kubectl apply -f # e.g. kubectl apply -f hello.yaml ``` -You can then reference the hook by name when you create a new control plane. +You can then reference the hook by name when you create a new control plane. With kflex CLI (you can use --postcreate-hook or -p): @@ -641,14 +649,14 @@ EOF ## Initial Context -The KubeFlex CLI (kflex) relies on the extensions field in the kubeconfig -file to store the initial context of the hosting cluster. This context is -needed for kflex to switch back to the hosting cluster when performing +The KubeFlex CLI (kflex) relies on the extensions field in the kubeconfig +file to store the initial context of the hosting cluster. This context is +needed for kflex to switch back to the hosting cluster when performing lifecycle operations. -If the extensions field is deleted or overwritten by other apps, you -need to restore it manually in the kubeconfig file. Otherwise, kflex -context switching may not work properly. Here is an example of an +If the extensions field is deleted or overwritten by other apps, you +need to restore it manually in the kubeconfig file. Otherwise, kflex +context switching may not work properly. Here is an example of an extension for a hosting cluster with the default context name `kind-kubeflex`: ```yaml diff --git a/scripts/install-kubeflex.sh b/scripts/install-kubeflex.sh new file mode 100755 index 0000000..0bbcd94 --- /dev/null +++ b/scripts/install-kubeflex.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash + +# Copyright 2023 The KubeStellar Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: $0 + +# This script installs kubeflex binaries and plugins to a folder of choice +# +# Arguments: +# [--version release] set a specific kubeflex release version, default: latest +# [--os linux|darwin] set a specific OS type, default: autodetect +# [--arch amd64|arm64] set a specific architecture type, default: autodetect +# [--ensure-folder name] sets the installation folder, default: $PWD/kubeflex +# [--strip-bin] remove the bin sub-folder +# [-V|--verbose] verbose output +# [-X] `set -x` + +set -e + +version="" +os="" +arch="" +folder="" +strip_bin="false" +verbose="false" + +get_os_type() { + case "$OSTYPE" in + linux*) echo "linux" ;; + darwin*) echo "darwin" ;; + *) echo "Unsupported operating system type: $OSTYPE" >&2 ; exit 1 ;; + esac +} + +get_arch_type() { + case "$HOSTTYPE" in + x86_64*) echo "amd64" ;; + aarch64*) echo "arm64" ;; + arm64*) echo "arm64" ;; + *) echo "Unsupported architecture type: $HOSTTYPE" >&2 ; exit 1 ;; + esac +} + +get_latest_version() { + curl -sL https://github.com/kubestellar/kubeflex/releases/latest | grep "" | tail -n 1 | sed -e 's/<[^>]*>//g' | xargs +} + +get_full_path() { + echo "$(cd "$1"; pwd)" +} + +while (( $# > 0 )); do + case "$1" in + (--version) + if (( $# > 1 )); + then { version="$2"; shift; } + else { echo "$0: missing release version" >&2; exit 1; } + fi;; + (--os) + if (( $# > 1 )); + then { os="$2"; shift; } + else { echo "$0: missing OS type" >&2; exit 1; } + fi;; + (--arch) + if (( $# > 1 )); + then { arch="$2"; shift; } + else { echo "$0: missing architecture type" >&2; exit 1; } + fi;; + (--ensure-folder) + if (( $# > 1 )); + then { folder="$2"; shift; } + else { echo "$0: missing installation folder" >&2; exit 1; } + fi;; + (--strip-bin) + strip_bin="true";; + (--verbose|-V) + verbose="true";; + (-X) + set -x;; + (-h|--help) + echo "Usage: $0 [--version release] [--os linux|darwin] [--arch amd64|arm64] [--ensure-folder name] [--strip-bin] [-V|--verbose] [-X]" + exit 0;; + (-*) + echo "$0: unknown flag" >&2 + exit 1;; + (*) + echo "$0: unknown positional argument" >&2 + exit 1;; + esac + shift +done + +if [ "$version" == "" ]; then + version=$(get_latest_version) +fi + +if [ "$os" == "" ]; then + os=$(get_os_type) +fi + +if [ "$arch" == "" ]; then + arch=$(get_arch_type) +fi + +if [ "$folder" == "" ]; then + folder="$PWD/kubeflex" +fi + +if [ -d "$folder" ]; then : +else + if [ $verbose == "true" ]; then + echo "Creating folder: $folder" + fi + mkdir -p "$folder" +fi + +if [ $verbose == "true" ]; then + echo "Downloading kubeflex $version $os/$arch..." + curl -SL -o kubeflex.tar.gz "https://github.com/kubestellar/kubeflex/releases/download/${version}/kubeflex_${version//v}_${os}_${arch}.tar.gz" +else + curl -sSL -o kubeflex.tar.gz "https://github.com/kubestellar/kubeflex/releases/download/${version}/kubeflex_${version//v}_${os}_${arch}.tar.gz" +fi + +if [ $verbose == "true" ]; then + echo "Extracting archive to: $folder" +fi + +if [ $strip_bin == "true" ]; then + tar -C $folder -zxf kubeflex.tar.gz --wildcards --strip-components=1 bin/* + bin_folder=$(get_full_path "$folder") +else + tar -C $folder -zxf kubeflex.tar.gz + bin_folder=$(get_full_path "$folder/bin") +fi + +if [ $verbose == "true" ]; then + echo "Removing downloaded archives..." +fi + +rm kubeflex.tar.gz + +if [[ ! ":$PATH:" == *":$bin_folder:"* ]]; then + echo "Add kubeflex folder to the path: export PATH="\$PATH:$bin_folder"" +fi From f5fa7db9c42b6fecdaf0dc5bc630c66aa4fee988 Mon Sep 17 00:00:00 2001 From: francostellari Date: Thu, 8 Feb 2024 15:21:50 -0500 Subject: [PATCH 2/2] Remove flag, which is not supported by bsdtar on Mac Signed-off-by: francostellari --- scripts/install-kubeflex.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install-kubeflex.sh b/scripts/install-kubeflex.sh index 0bbcd94..705ea51 100755 --- a/scripts/install-kubeflex.sh +++ b/scripts/install-kubeflex.sh @@ -138,7 +138,7 @@ if [ $verbose == "true" ]; then fi if [ $strip_bin == "true" ]; then - tar -C $folder -zxf kubeflex.tar.gz --wildcards --strip-components=1 bin/* + tar -C $folder -zxf kubeflex.tar.gz --strip-components=1 bin/kflex bin_folder=$(get_full_path "$folder") else tar -C $folder -zxf kubeflex.tar.gz