Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release #22

Merged
merged 3 commits into from
Sep 14, 2024
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
58 changes: 28 additions & 30 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/). (Optional)
- **ARGOCD**: CI/CD for your installation. (Optional)

## 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,28 @@ 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.~~
During installation you can run `install-status.sh` to monitor the installation status. When the installation is completed, all the services should be in `loaded active exited` state. take a look to te pods also with `kubectl get pods -A`

Be Aware: during the installation phase, some failing logs are normal!

## 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,8 +97,12 @@ 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)

## References
- [kubevirt-manager.io](https://kubevirt-manager.io/)
- [kubevirt-manager.io](https://kubevirt-manager.io/)
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
6 changes: 0 additions & 6 deletions scripts/install-status

This file was deleted.

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
Loading