Skip to content

Commit

Permalink
created reinstall script, and install-status
Browse files Browse the repository at this point in the history
  • Loading branch information
gpillon committed Sep 14, 2024
1 parent 69112bf commit 3bdf6ab
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 63 deletions.
52 changes: 23 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ The `k4all` ISO provides a pre-configured Fedora CoreOS environment tailored for
**Warning: The installation process is fully unattended and will format the entire `/dev/sda|vda|mmcblk device`. Ensure that your data is backed up before proceeding.**

Key features include:
- **Kubernetes Dashboard**: Easily manage your kubernetes cluster.
- **Metrics Server**: Enables resource usage metrics collection for Kubernetes.
- **Calico**: Provides a robust networking solution.
- **TOPOLVM Volume Manager**: Facilitates Persistent Volume Claims (PVCs) using logical volume management.
- **Calico / Cilium + Multus**: Provides a robust networking solution.
- **TopoLVM Volume Manager**: Facilitates Persistent Volume Claims (PVCs) using logical volume management.
- **NGINX Ingress Controller**: Manages external access to services in the cluster.
- **Multus**: Advanced network configurations.
- **Kubevirt**: run VM inside Kubernetes managed by [kubevirt-manager](https://kubevirt-manager.io/).
- **ARGOCD**: CI/CD for your installation.

## Why k4all?
- 1st time, it's ok.
Expand All @@ -20,7 +22,7 @@ Key features include:

## Requirements:
- 2 CPU Cores.
- 4GB Ram (8G for running workloads).
- 4GB Ram (2G used by K8all).
- 20 Minutes.
- Coffee, Sugar, Milk (not required).

Expand All @@ -37,29 +39,14 @@ First version you want to install is the boostrap image: i'ts a single node, wit
5. Take the Coffee (for about 5 to 15 minutes, depending on the hardware, 13 mins on a dual core Intel NUC DN2820FYK - 2013's Hardware).
6. Follow next steps

### Building the ISO

1. Ensure all dependencies (Podman, Docker) are installed.
2. Run the build script or the GitHub workflow to generate the `k4all` ISO.
3. The process will embed the required configurations and scripts into the Fedora CoreOS image.

### Using the ISO

0. Prepare a good Coffee (Espresso or American, depending on the hardware).
1. Boot the ISO on the target system.
2. The installation is fully automated and will format the entire `dev/sda|vda|mmcblk` disk.
3. Once completed, the system will reboot into the new environment.
4. Take the Coffee (for about 5 to 15 minutes, depending on the hardware, 13 mins on a dual core Intel NUC DN2820FYK - 11yo Hardware).
5. Follow next steps

## Default Setup

- **Default Password**: The default password is `core`. **Change it immediately upon login.**
- After login, use `passwd` to set a new password for the `core` user.

## Post-Install
- **Access Dashboard and Token**:
- `ssh` in your newly installed machine with `ssh core@<MACHINE IP>` (default password: core)
- Access the system with `sudo -i` (if credentials are not shown, wait for the end of the installation process).
- if credentials are not show, you can connect to the k8s dashboard, at https://\<your-ip\>:32323/ using the token retrived by `kubectl get secret admin-user -n kubernetes-dashboard -o jsonpath={".data.token"} | base64 -d)` (remember to `sudo -i`)

- **Default Password**: The default password is `core`. **Change it immediately upon login.**
- After login, use `passwd` to set a new password for the `core` user.
## Post-Installation Notes

- **Sample Pod**: A sample pod will be created in the `default` namespace if the LVM setup is successful. You can safely delete this pod.
Expand All @@ -80,21 +67,24 @@ To create a bootable USB device with the `k4all` ISO:
3. Use Rufus on Windows:
- Download [Rufus](https://rufus.ie/)
- Select the `k4all` ISO, choose your USB device, and click `Start`.

## Debugging Failed Setup

Sometimes, the installation, could give you errors. When you login you may see some failed units. Run the command `journalctl -xu <failed_unit>` to see error details. _Feel free to comtibute, opening an issue_ :)

## Known issues
FIXED ~~ATM the VDI and the QCOW self-installing images are not booting correctly. Need to investigate on it.~~
## Building the ISO

1. Ensure all dependencies (Podman or Docker) are installed.
2. Run the `build.sh` script or the GitHub workflow to generate the `k4all` ISO.
3. The process will embed the required configurations and scripts into the Fedora CoreOS image.

## Development
Next features:

- [ ] k8s & services Updates
- [ ] k8s & services [Updates](https://github.com/gpillon/k4all/wiki/Kubernetes-updates)
- [ ] Fancy UI to manage your k4all installation
- [ ] Applications catalog
- [ ] Argocd (?)
- [ ] Argocd Based installation ([?](https://github.com/gpillon/k4all/issues/12))
- [ ] Multi node (WIP)
- [ ] ARM platform

Expand All @@ -103,6 +93,10 @@ Next features:
**Multi-Node Cluster:** ATM, the installtion is tested for a single node cluster. _Feel free to contribute!_
I added the script to add more nodes, (on the boostrap node you can run `generate_join.sh` script, to get a base64 code, to use in combination with `join_cluster.sh` script. It was not heavily tested, but ATM it looks working...

## Thanks!
Many thanks to:
- [Manustar](https://github.com/manustars) For all the betatesting!

## Looking for an enterprise solution?
Let's take a look to [Openshift Single Node](https://docs.openshift.com/container-platform/latest/installing/installing_sno/install-sno-installing-sno.html)

Expand Down
4 changes: 2 additions & 2 deletions repo/kubernetes.repo
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
baseurl=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key
110 changes: 104 additions & 6 deletions scripts/reinstall.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,108 @@
#!/bin/bash
set -euxo pipefail
set -euo pipefail

source /usr/local/bin/k4all-utils
# Function to display the help message
show_help() {
echo "Usage: $0 [OPTIONS]"
echo
echo "This script resets the Kubernetes setup by removing specific done files and rebooting the system."
echo
echo "Options:"
echo " --network Delete the /opt/k4all/setup-ph2.done file (related to network configuration)."
echo " --kubernetes Delete the /opt/k4all/k8s-setup-init.done file (related to Kubernetes initialization)."
echo " --hostname Delete the /opt/k4all/setup-hostname.done file (related to Hostname)."
echo " --help Show this help message and exit."
echo
echo "WARNING: Reinstalling the cluster could be dangerous if several modifications have been made."
}

NET_DEV=$(get_network_device)
mv -f "/etc/NetworkManager/system-connections/${NET_DEV}.nmconnection.backup" "/etc/NetworkManager/system-connections/${NET_DEV}.nmconnection"
# Function to display a warning and ask for user confirmation
ask_for_confirmation() {
echo "WARNING: Reinstalling the cluster could be dangerous if several modifications have been made."
echo "This action may result in data loss or misconfiguration. Do you want to proceed? (yes/no)"
read -r confirmation
if [[ "$confirmation" != "yes" ]]; then
echo "Aborted by user."
exit 0
fi
}

rm -rf /opt/k4all/*.done
systemctl reboot
# Initialize flag variables
network_flag=false
kubernetes_flag=false
hostname_flag=false

# Parse command-line options
for arg in "$@"; do
case $arg in
--network)
network_flag=true
shift
;;
--kubernetes)
kubernetes_flag=true
shift
;;
--hostname)
hostname_flag=true
shift
;;
--help)
show_help
exit 0
;;
*)
echo "Unknown option: $arg"
show_help
exit 1
;;
esac
done

# Ask for confirmation before proceeding
ask_for_confirmation

# Delete all other *.done files except the ones specifically handled by flags
for file in /opt/k4all/*.done; do
if [[ "$file" != "/opt/k4all/setup-ph3.done" && "$file" != "/opt/k4all/setup-ph2.done" && "$file" != "/opt/k4all/k8s-setup-init.done" && "$file" != "/opt/k4all/setup-hostname.done" ]]; then
echo "Deleting $file"
rm -f "$file"
fi
done

# Delete specific files based on flags
if [ "$network_flag" = true ]; then
if [ -f "/opt/k4all/setup-ph2.done" ]; then
echo "Deleting /opt/k4all/setup-ph2.done"
rm -f /opt/k4all/setup-ph2.done
else
echo "/opt/k4all/setup-ph2.done does not exist"
fi
if [ -f "/opt/k4all/setup-ph3.done" ]; then
echo "Deleting /opt/k4all/setup-ph3.done"
rm -f /opt/k4all/setup-ph3.done
else
echo "/opt/k4all/setup-ph3.done does not exist"
fi
fi

if [ "$kubernetes_flag" = true ]; then
if [ -f "/opt/k4all/k8s-setup-init.done" ]; then
echo "Deleting /opt/k4all/k8s-setup-init.done"
rm -f /opt/k4all/k8s-setup-init.done
else
echo "/opt/k4all/k8s-setup-init.done does not exist"
fi
fi

if [ "$hostname_flag" = true ]; then
if [ -f "/opt/k4all/setup-hostname.done" ]; then
echo "Deleting /opt/k4all/setup-hostname.done"
rm -f /opt/k4all/setup-hostname.done
else
echo "/opt/k4all/setup-hostname.done does not exist"
fi
fi

# Reboot the system
systemctl reboot
4 changes: 2 additions & 2 deletions scripts/set-hostname.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Enable strict mode and pipefail for robust error handling
set -euo pipefail

if [ -f "/opt/k4all/hostname-setup.done" ]; then
if [ -f "/opt/k4all/setup-hostname.done" ]; then
echo "Hostname setup already done. Exiting."
exit 0
fi
Expand Down Expand Up @@ -67,4 +67,4 @@ fi
hostnamectl set-hostname "$FULL_HOSTNAME"

echo "Hostname set to $FULL_HOSTNAME"
touch /opt/k4all/hostname-setup.done
touch /opt/k4all/setup-hostname.done
7 changes: 5 additions & 2 deletions scripts/setup-cni-calico.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ source /usr/local/bin/k4all-utils

#calico_manifest_url="https://raw.githubusercontent.com/projectcalico/calico/$CALICO_VERSION/manifests/custom-resources.yaml"

# Deploy a network add-on
kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f https://raw.githubusercontent.com/projectcalico/calico/$CALICO_VERSION/manifests/tigera-operator.yaml
# Deploy the Tigera operator for Calico
kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f https://raw.githubusercontent.com/projectcalico/calico/$CALICO_VERSION/manifests/tigera-operator.yaml || {
echo "Failed to create Tigera operator. Trying with replace..."
kubectl --kubeconfig=/etc/kubernetes/admin.conf replace -f https://raw.githubusercontent.com/projectcalico/calico/$CALICO_VERSION/manifests/tigera-operator.yaml
}
#retry_command "curl -O $calico_manifest_url" 10 5
#kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f custom-resources.yaml
#kubectl --kubeconfig=/etc/kubernetes/admin.conf create -f custom-resources.yaml
Expand Down
32 changes: 13 additions & 19 deletions scripts/setup-feature-argocd.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
set -euxo pipefail
set -euo pipefail

if [ -f "/opt/k4all/feature-argocd-setup.done" ]; then
echo "ArgoCD setup already done. Exiting."
Expand All @@ -12,40 +12,34 @@ export HOME=/root/
source /usr/local/bin/k4all-utils

namespace="argocd"


helm repo add argo https://argoproj.github.io/argo-helm
helm repo update

helm upgrade --install argocd argo/argo-cd --create-namespace -n $namespace -f /usr/local/share/argocd-values.yaml --set "global.domain=\"argo.$(get_ip).nip.io\"" --set-json "server.ingress.extraHosts=[{\"name\": \"argo.$(get_fqdn)\", \"path\": \"\/\"}]"
ARGO_JSON="server.ingress.extraHosts=[{\"name\": \"argo.$(get_fqdn)\", \"path\": \"/\"}]"

# Use single quotes around the helm command to avoid early variable expansion
retry_command "helm upgrade --install argocd argo/argo-cd --create-namespace -n $namespace -f /usr/local/share/argocd-values.yaml --set \"global.domain=argo.$(get_ip).nip.io\" --set-json '$ARGO_JSON'" 30 10

# kubectl get namespace argocd || kubectl create namespace argocd
# kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Wait for ArgoCD server to be available
kubectl -n $namespace wait deployment/argocd-server --for condition=Available --timeout=3600s

ARGO_ADMIN_SECRET=$(kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode)

# route_host_prefix="argocd"
ingress_name="argocd-server"


# kubectl apply -f /usr/local/share/argocd-ingress-routes.yaml
# patch_ingress "$(get_ip).nip.io" 0 $route_host_prefix $ingress_name $namespace
# patch_ingress "$(get_fqdn)" 1 $route_host_prefix $ingress_name $namespace

# Fetch ingress URLs
urls=$(get_ingress_urls "$ingress_name" $namespace)

if [[ -z "$urls" ]]; then
echo "No URLs found or error occurred." >&2
exit 1
else
IFS=$'\n' # Imposta il separatore interno del campo su nuova linea
urls_array=($urls) # Crea un array con gli URL
joined_urls=$(IFS=", "; echo "${urls_array[*]}") # Unisce gli URL con virgole
IFS=$'\n' # Set field separator to newline
urls_array=($urls) # Create an array with the URLs
joined_urls=$(IFS=", "; echo "${urls_array[*]}") # Join URLs with commas
fi

echo -e "You can now login to argo using credentials admin:${ARGO_ADMIN_SECRET} using one of those: $joined_urls"

echo -e "You can now login to Argo using credentials admin:${ARGO_ADMIN_SECRET} using one of those: $joined_urls"

# Done
touch /opt/k4all/feature-argocd-setup.done
# Mark setup as done
touch /opt/k4all/feature-argocd-setup.done
36 changes: 34 additions & 2 deletions scripts/setup-k8s-ph2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,40 @@ add_firewalld_rule_if_not_exists() {
fi
}

# Function to get the first available physical network interface
get_first_physical_interface() {
ip link show | awk '/^[0-9]+: [^lo]/ {print $2}' | grep -v 'ovs-bridge' | sed 's/://g' | head -n 1
}

# Function to get the physical interface from the Open vSwitch bridge
get_physical_interface_for_ovs_port() {
local ovs_port=$1
ovs-vsctl list interface "$ovs_port" 2>/dev/null | grep 'type.*system' >/dev/null && echo "$ovs_port" || echo ""
}

# Function to find the original physical interface used in the bridge
get_original_physical_interface() {
for port in $(ovs-vsctl list-ports ovs-bridge); do
physical_interface=$(get_physical_interface_for_ovs_port "$port")
if [ -n "$physical_interface" ]; then
echo "$physical_interface"
return
fi
done
# If no physical interface is found, return the first physical interface available
get_first_physical_interface
}


NET_DEV=$(get_network_device)
MAC_ADDR=$(ip link show "${NET_DEV}" | awk '/ether/ {print $2}')

if [ "$NET_DEV" == "ovs-bridge" ]; then
PHYS_NET_DEV=$(get_original_physical_interface)
else
PHYS_NET_DEV=$NET_DEV
fi

MAC_ADDR=$(ip link show "${PHYS_NET_DEV}" | awk '/ether/ {print $2}')

# Retrieve IP, Gateway, DNS, and Domain information from the original network device
IP_ADDR=$(nmcli -g IP4.ADDRESS dev show "${NET_DEV}")
Expand All @@ -70,7 +102,7 @@ add_nmcli_connection_if_not_exists ovs-bridge type ovs-bridge conn.interface ovs
add_nmcli_connection_if_not_exists ovs-bridge-port type ovs-port conn.interface port-ovs-bridge master ovs-bridge con-name ovs-bridge-port
add_nmcli_connection_if_not_exists ovs-bridge-int type ovs-interface slave-type ovs-port conn.interface ovs-bridge master ovs-bridge-port con-name ovs-bridge-int
add_nmcli_connection_if_not_exists ovs-port-eth type ovs-port conn.interface ovs-port-eth master ovs-bridge con-name ovs-port-eth
add_nmcli_connection_if_not_exists ovs-port-eth-int type ethernet conn.interface "${NET_DEV}" master ovs-port-eth con-name ovs-port-eth-int
add_nmcli_connection_if_not_exists ovs-port-eth-int type ethernet conn.interface "${PHYS_NET_DEV}" master ovs-port-eth con-name ovs-port-eth-int

# Modify ovs-bridge and ovs-bridge-int settings only if needed
modify_nmcli_connection_if_needed ovs-bridge 802-3-ethernet.cloned-mac-address "${MAC_ADDR}"
Expand Down
5 changes: 5 additions & 0 deletions scripts/setup-taint-master-scheduleable.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ if [ -f "/opt/k4all/setup-taint-master-schedulable.done" ]; then
exit 0
fi

source /usr/local/bin/k4all-utils

#Wait for k8s nodes endpoint
retry_command "kubectl --kubeconfig=/etc/kubernetes/admin.conf get nodes" 30 10

# Aspetta che il nodo sia Ready
while true; do
# Ottieni lo stato del nodo e verifica se è Ready
Expand Down
2 changes: 1 addition & 1 deletion scripts/wait-default-service-account.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euxo pipefail
# Controlla se il file di stato esiste

if [ -f "/opt/k4all/default-service-account.done" ]; then
echo "Master Already Untained. Exiting."
echo "Default Service Accound Already checked. Exiting."
exit 0
fi

Expand Down

0 comments on commit 3bdf6ab

Please sign in to comment.