{"id":18151026,"url":"https://github.com/gmrezah/airgapped-kubespray","last_synced_at":"2026-02-07T22:02:40.408Z","repository":{"id":259234193,"uuid":"875979290","full_name":"GmrezaH/airgapped-kubespray","owner":"GmrezaH","description":"This repository provides documentation and scripts to help you install a production-ready Kubernetes cluster using Kubespray in air-gapped (offline) environments.","archived":false,"fork":false,"pushed_at":"2024-10-21T13:35:55.000Z","size":19,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-01T12:02:12.619Z","etag":null,"topics":["air-gapped","ansible","kubernetes","kubernetes-cluster","kubernetes-setup","kubespray"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GmrezaH.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-21T07:44:31.000Z","updated_at":"2024-10-23T14:01:47.000Z","dependencies_parsed_at":"2024-10-23T18:52:23.632Z","dependency_job_id":"5e7753c8-3d67-4431-9a76-ed0e858365e3","html_url":"https://github.com/GmrezaH/airgapped-kubespray","commit_stats":null,"previous_names":["gmrezah/airgapped-kubespray"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/GmrezaH/airgapped-kubespray","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GmrezaH%2Fairgapped-kubespray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GmrezaH%2Fairgapped-kubespray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GmrezaH%2Fairgapped-kubespray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GmrezaH%2Fairgapped-kubespray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GmrezaH","download_url":"https://codeload.github.com/GmrezaH/airgapped-kubespray/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GmrezaH%2Fairgapped-kubespray/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262959564,"owners_count":23391057,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["air-gapped","ansible","kubernetes","kubernetes-cluster","kubernetes-setup","kubespray"],"created_at":"2024-11-02T01:06:10.340Z","updated_at":"2026-02-07T22:02:40.359Z","avatar_url":"https://github.com/GmrezaH.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Air-gapped Kubespray\n\nThis repository provides documentation and scripts to help you install a production-ready Kubernetes cluster using Kubespray in air-gapped (offline) environments. It has been tested with the following versions:\n\n- Kubernetes: v1.29.3\n- Kubespray: v2.24.1\n\nThis setup is particularly useful in restricted environments where nodes, including the Ansible master, do not have internet access.\n\n---\n\n## What is Kubespray?\n\nKubernetes clusters can be created using various automation tools, and **Kubespray** is one of the most flexible options. Kubespray is a set of Ansible playbooks, along with inventory, provisioning tools, and domain knowledge that simplify the configuration and management of Kubernetes clusters. Kubespray allows you to use Ansible to set up and configure Kubernetes in a streamlined, reproducible way.\n\n### Why Use Kubespray?\n\n- **Deployment Flexibility**: Kubespray allows you to deploy Kubernetes clusters quickly with full customization of implementation.\n- **Ease of Use**: Kubespray strikes the perfect balance between flexibility and simplicity, making it accessible while still offering extensive customization.\n- **Single Playbook Execution**: You only need to run one Ansible playbook, and your cluster is ready to serve production workloads.\n\nThe diagram below illustrates the deployment architecture used by Kubespray:\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://bbs-img.huaweicloud.com/blogs/img/20230607/1686127981065342881.png?raw=true\" alt=\"Kubespray Architecture\" /\u003e\n\u003c/div\u003e\n\n---\n\n## Disclaimer\n\nThis repository is focused on creating Kubernetes clusters in air-gapped environments where both your Kubernetes nodes and your Ansible control machine have no direct internet access. The solution assumes you are working with Red Hat-based distributions, though it can be adapted to other Linux distributions with minor changes.\n\nTo achieve this setup, you'll need an internet-connected machine (e.g., your laptop, a VM, or even a container) that will download the necessary resources for Kubespray. This includes container images, RPMs, PyPi packages, and other required files. The downloaded files will be stored in a local repository (such as Nexus or Nginx), which will be accessible by your Kubernetes nodes.\n\n\u003e **Note:** While this documentation focuses on Red Hat-based distributions, adapting it for other distributions like Ubuntu is relatively straightforward. The primary differences lie in the package management tools (e.g., `yum/dnf` for Red Hat vs `apt` for Ubuntu), but the overall Kubespray and Kubernetes deployment process remains similar.\n\n---\n\n## Requirements\n\nBefore you begin, ensure that you have the following infrastructure set up:\n\n1. **Repository VM**: A virtual machine running Nginx and Nexus to act as a local repository for Kubernetes nodes to access the necessary resources (container images, RPMs, PyPi packages, etc.).\n2. **Download VM (Online Machine)**: A machine with internet access to download RPMs, container images, PyPi packages, and other raw files needed for the cluster setup. This can be your local machine or a dedicated VM.\n3. **Ansible Control VM**: A virtual machine running Ansible that can communicate with all Kubernetes nodes and the local repository. This can be a dedicated VM or the same VM as the repository.\n4. **Kubernetes Nodes**:\n   - At least two VMs for Highly-Available (HA) Kubernetes masters.\n   - At least one VM for a worker node.\n5. **Load Balancer IP**: One free IP address in the same subnet as the Kubernetes nodes, dedicated for the Kubernetes API server load balancer.\n\n---\n\n## Steps to Deploy the Cluster\n\n### 1. Online Machine Setup\n\nOn the Online VM (which has internet access), follow these steps to set up Docker, download the necessary files, and prepare them for the Repository VM:\n\n```bash\n# Install Docker and related packages\nsudo yum install -y yum-utils\nsudo yum-config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo\n\n# Download Docker packages for offline installation\nyumdownloader --assumeyes --destdir=./docker --resolve docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\n\n# Install Docker\nsudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin\nsudo groupadd docker\nsudo usermod -aG docker $USER\n\n# Log in to Docker and download Nexus and Nginx images\ndocker login\ndocker pull sonatype/nexus3\ndocker pull nginx\n\n# Save the Docker images as tar.gz files\ndocker save sonatype/nexus3:latest | gzip \u003e ./docker/nexus.tar.gz\ndocker save nginx:latest | gzip \u003e ./docker/nginx.tar.gz\n\n# Move the ./docker directory to the /opt/docker directory of the Repository VM.\n```\n\n### 2. Nexus Setup\n\nOn the Repository VM, install Docker and configure Nexus to act as a repository for Docker images, raw files, and PyPi packages.\n\n```bash\n# Install Docker on the Repository VM\nsudo yum localinstall /opt/docker/*.rpm\nsudo groupadd docker\nsudo usermod -aG docker $USER\n\n# Create Nexus Docker Compose file and run it\ncat \u003c\u003cEOF \u003e nexus-docker-compose.yml\nversion: \"3\"\nservices:\n  nexus:\n    image: sonatype/nexus3\n    container_name: nexus\n    restart: always\n    volumes:\n      - \"nexus-data:/sonatype-work\"\n    ports:\n      - \"8081:8081\"\n      - \"8082:8082\"\nvolumes:\n  nexus-data: {}\nEOF\n\n# Load the Nexus Docker image and start Nexus\ndocker load \u003c /opt/docker/nexus.tar.gz\ndocker compose -f nexus-docker-compose.yml up -d\n\n# Get the admin password for Nexus\nsudo docker exec -it nexus cat /nexus-data/admin.password\n\n# Access the Nexus web UI at http://\u003cRepository_VM_IP\u003e:8081\n# Create a Docker hosted repository on port 8082 (named \"image\"),\n# a raw hosted repo (named \"raw\"), and a PyPi hosted repo (named \"pypi\").\n```\n\n### 3. Nginx RPM Repository Setup\n\nNexus does not support modular RPMs (yet!), so we'll set up Nginx to serve RPM packages.\n\n```bash\n# Create the Nginx configuration file\ncat \u003c\u003cEOF \u003e /opt/docker/nginx.conf\nuser nginx;\nworker_processes auto;\nerror_log /var/log/nginx/error.log;\npid /run/nginx.pid;\ninclude /usr/share/nginx/modules/*.conf;\n\nevents {\n    worker_connections 1024;\n}\n\nhttp {\n    log_format main '$remote_addr - $remote_user [$time_local] \"$request\" '\n                     '$status $body_bytes_sent \"$http_referer\" '\n                     '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n    access_log /var/log/nginx/access.log main;\n    sendfile on;\n    tcp_nopush on;\n    tcp_nodelay on;\n    keepalive_timeout 65;\n    types_hash_max_size 2048;\n    default_type application/octet-stream;\n    include /etc/nginx/conf.d/*.conf;\n\n    server {\n        listen 80 default_server;\n        listen [::]:80 default_server;\n        server_name _;\n        include /etc/nginx/default.d/*.conf;\n\n        location / {\n            root /usr/share/nginx/html/download;\n            autoindex on;\n            autoindex_exact_size off;\n            autoindex_localtime on;\n        }\n\n        error_page 404 /404.html;\n        location = /40x.html {}\n\n        error_page 500 502 503 504 /50x.html;\n        location = /50x.html {}\n    }\n}\nEOF\n\n# Create Nginx Docker Compose file and run it\ncat \u003c\u003cEOF \u003e nginx-docker-compose.yml\nversion: \"3\"\nservices:\n  nginx:\n    image: nginx\n    container_name: nginx\n    restart: always\n    volumes:\n      - /opt/repos:/usr/share/nginx/html/download/rocky8\n      - nginx.conf:/etc/nginx/nginx.conf\n    ports:\n      - \"8080:80\"\nEOF\n\n# Load the Nginx Docker image and start the container\ndocker load \u003c /opt/docker/nginx.tar.gz\ndocker compose -f nginx-docker-compose.yml up -d\n```\n\n### 4. Download Kubernetes Resources\n\nOn the Online VM, follow these steps to download all the necessary resources for Kubespray, including RPM packages, PyPi packages, and container images.\n\n```bash\n# Download the Kubespray project and its dependencies\ncd /opt\ngit clone https://github.com/kubernetes-sigs/kubespray.git\nVENVDIR=kubespray-venv\npython3.11 -m venv $VENVDIR\nsource $VENVDIR/bin/activate\n\n# Download PyPi packages required by Kubespray\npip download -r kubespray/requirements.txt -d /opt/pip-req\npip download twine -d /opt/pip-req\n\n# Archive the downloaded PyPi packages\ntar cvfz pypi.tar.gz ./pip-req\n```\n\n#### Generate List of Required Files and Container Images\n\nKubespray provides a script to generate lists of the required files and container images for offline installation.\n\n```bash\n# Generate the list of files and container images needed for the cluster\ncd kubespray\n./contrib/offline/generate_list.sh\n# This will generate files.list and images.list in kubespray/contrib/offline/temp.\n```\n\n#### Download Files from `files.list`\n\nUse the following script to download the required files as listed in the generated `files.list` file:\n\n```bash\n#!/bin/bash\n\nCURRENT_DIR=$( dirname \"$(readlink -f \"$0\")\" )\nOFFLINE_FILES_DIR_NAME=\"offline-files\"\nOFFLINE_FILES_DIR=\"${CURRENT_DIR}/${OFFLINE_FILES_DIR_NAME}\"\nOFFLINE_FILES_ARCHIVE=\"${CURRENT_DIR}/offline-files.tar.gz\"\nFILES_LIST=${FILES_LIST:-\"${CURRENT_DIR}/kubespray/contrib/offline/temp/files.list\"}\n\n# Ensure the files list exists\nif [ ! -f \"${FILES_LIST}\" ]; then\n    echo \"${FILES_LIST} should exist, run ./generate_list.sh first.\"\n    exit 1\nfi\n\n# Clean up previous files and directories\nrm -rf \"${OFFLINE_FILES_DIR}\"\nrm -f \"${OFFLINE_FILES_ARCHIVE}\"\nmkdir \"${OFFLINE_FILES_DIR}\"\n\n# Download each file from the list\nwhile read -r url; do\n  if ! wget -x -P \"${OFFLINE_FILES_DIR}\" \"${url}\"; then\n    exit 1\n  fi\ndone \u003c \"${FILES_LIST}\"\n\n# Archive the downloaded files\ntar -czvf \"${OFFLINE_FILES_ARCHIVE}\" \"${OFFLINE_FILES_DIR_NAME}\"\n```\n\n#### Download and Save Container Images\n\nNext, use the following script to download and save the required container images:\n\n```bash\n#!/bin/bash\n\nNEXUS_REPO=\"192.168.1.20:8082\"  # Update this with your Nexus repository IP and port\nIMAGES_ARCHIVE=\"${CURRENT_DIR}/container-images.tar.gz\"\nIMAGES_DIR=\"${CURRENT_DIR}/container-images\"\nIMAGES_LIST=${IMAGES_LIST:-\"${CURRENT_DIR}/kubespray/contrib/offline/temp/images.list\"}\n\n# Ensure the images list exists\nif [ ! -f \"${IMAGES_LIST}\" ]; then\n    echo \"${IMAGES_LIST} should exist, run ./generate_list.sh first.\"\n    exit 1\nfi\n\n# Clean up previous images\nrm -f \"${IMAGES_ARCHIVE}\"\nrm -rf \"${IMAGES_DIR}\"\nmkdir \"${IMAGES_DIR}\"\n\n# Pull each image from the list\nwhile read -r image; do\n  if ! docker pull \"${image}\"; then\n    exit 1\n  fi\ndone \u003c \"${IMAGES_LIST}\"\n\n# Tag and save each image to a tar.gz file\nIMAGES=$(docker images --format \"{{.Repository}}:{{.Tag}}\")\nfor i in $IMAGES; do\n  NEW_IMAGE=${NEXUS_REPO}/${i}\n  TAR_FILE=$(echo ${i} | sed 's/[\\/:]/-/g')\n  docker tag $i ${NEW_IMAGE}\n  docker save ${NEW_IMAGE} | gzip \u003e \"${IMAGES_DIR}/${TAR_FILE}.tar.gz\"\ndone\n\n# Archive the saved images\ntar cvfz \"${IMAGES_ARCHIVE}\" \"${IMAGES_DIR}\"\n```\n\n#### Download RPM Repositories\n\nIf RPM repositories are required (e.g., for Red Hat-based distributions), use the following script to sync them:\n\n```bash\n#!/bin/bash\n\nyum install -y reposync epel-release\n\n# Sync required RPM repositories\nreposync --repoid=appstream --downloaddir=./repos --download-metadata --newest-only\nreposync --repoid=baseos --downloaddir=./repos  --download-metadata  --newest-only\nreposync --repoid=epel --downloaddir=./repos --download-metadata  --newest-only\nreposync --repoid=extras --downloaddir=./repos  --download-metadata  --newest-only\nreposync --repoid=docker-ce-stable --downloaddir=./repos  --download-metadata\nreposync --repoid=kubernetes-1.29-stable --downloaddir=./repos  --download-metadata\n\n# Archive the RPM repositories\ntar cvfz ./rpm-repos.tar.gz ./repos\n```\n\n### 5. Upload Resources to Repository VM\n\nAfter downloading all the necessary resources (RPMs, container images, and other files), transfer the files to the Repository VM and upload them to Nexus and Nginx.\n\n#### Upload RPM Packages to Nginx\n\n```bash\n# Extract and upload RPM packages to Nginx\ntar xvfz /opt/rpm-repos.tar.gz\nrm -rf /etc/yum.repos.d/*\ncat \u003c\u003cEOF \u003e /etc/yum.repos.d/local.repo\n[appstream]\nname=Nginx Local RockyLinux 8.8 Appstream Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/appstream/\"\ngpgcheck=0\nenabled=1\n\n[baseos]\nname=Nginx Local RockyLinux 8.8 Baseos Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/baseos/\"\ngpgcheck=0\nenabled=1\n\n[docker-ce-stable]\nname=Nginx Local Docker-CE Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/docker-ce-stable/\"\ngpgcheck=0\nenabled=1\n\n[epel]\nname=Nginx Local EPEL Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/epel/\"\ngpgcheck=0\nenabled=1\n\n[extras]\nname=Nginx Local Extras Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/extras/\"\ngpgcheck=0\nenabled=1\n\n[kubernetes-1.29-stable]\nname=Nginx Local Kubernetes 1.29 Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/kubernetes-1.29-stable/\"\ngpgcheck=0\nenabled=1\nEOF\n\nyum clean all\n```\n\n#### Upload Docker Images to Nexus\n\n```bash\n# Extract and upload Docker images to Nexus\ntar xvfz /opt/container-images.tar.gz\nIMAGE_ARCHIVES=$(ls ./container-images)\n\n# Load each Docker image from the archive\nfor i in ${IMAGE_ARCHIVES}; do docker load -i $i; done\n\n# Push the images to Nexus\nIMAGES=$(docker images --format \"{{.Repository}}:{{.Tag}}\" | grep 8082)\nfor image in $IMAGES; do docker push \"$image\"; done\n```\n\n#### Upload Raw Files to Nexus\n\n```bash\n# Extract and upload raw files to the raw repository in Nexus\ntar xvfz /opt/offline-files.tar.gz\nmv /opt/offline-files /opt/raw  # Ensure the folder name matches the raw repository name in Nexus\n\nRAW_FILES=$(find /opt/raw/ -type f)\nfor file in $RAW_FILES; do\n  curl -v --user '\u003cNexus_User\u003e:\u003cNexus_Password\u003e' --upload-file \"$file\" http://\u003cNexus_IP\u003e:8081/repository/raw/\ndone\n```\n\n#### Upload PyPi Packages to Nexus\n\n```bash\n# Extract PyPi packages and upload them to Nexus\ntar xvfz /opt/pypi.tar.gz\nyum install python3.11 python3.11-pip\nVENVDIR=kubespray-venv\npython3.11 -m venv $VENVDIR\nsource $VENVDIR/bin/activate\npip3.11 install --no-index --find-links /opt/pip-req/ twine\n\n# Create a .pypirc file for Nexus configuration\ncat \u003c\u003cEOF \u003e $HOME/.pypirc\n[distutils]\nindex-servers =\n    nexus\n\n[nexus]\nrepository: http://\u003cNexus_IP\u003e:8081/repository/pypi/\nusername: admin\npassword: admin\nEOF\n\n# Upload each PyPi package to Nexus\nfor file in /opt/pip-req/*.whl; do\n    twine upload --repository nexus \"$file\"\ndone\n```\n\n### 6. Kubernetes Nodes Setup\n\nOn each Kubernetes node, configure the local repository and prepare the system for Kubernetes installation.\n\n#### Add Local RPM Repository\n\nReplace existing repositories with the local Nexus and Nginx repositories:\n\n```bash\n# Remove existing repositories and add local ones\nrm -rf /etc/yum.repos.d/*\ncat \u003c\u003cEOF \u003e /etc/yum.repos.d/local.repo\n[appstream]\nname=Nexus Local RockyLinux 8.8 Appstream Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/appstream/\"\ngpgcheck=0\nenabled=1\n\n[baseos]\nname=Nexus Local RockyLinux 8.8 Baseos Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/baseos/\"\ngpgcheck=0\nenabled=1\n\n[docker-ce-stable]\nname=Nexus Local RockyLinux 8.8 Docker-CE Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/docker-ce-stable/\"\ngpgcheck=0\nenabled=1\n\n[epel]\nname=Nexus Local RockyLinux 8.8 EPEL Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/epel/\"\ngpgcheck=0\nenabled=1\n\n[extras]\nname=Nexus Local RockyLinux 8.8 Extras Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/extras/\"\ngpgcheck=0\nenabled=1\n\n[kubernetes-1.29-stable]\nname=Nexus Local Kubernetes 1.29 Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/kubernetes-1.29-stable/\"\ngpgcheck=0\nenabled=1\nEOF\n\n# Clean YUM cache\nyum clean all\n```\n\n#### Disable Firewall and SELinux\n\nTo ensure smooth operation, disable the firewall and SELinux on the Kubernetes nodes:\n\n```bash\n# Disable firewall\nsystemctl stop firewalld\nsystemctl disable firewalld\n\n# Disable SELinux\nsetenforce 0\nsed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config\n\n# Reboot the node\nreboot\n```\n\n#### Update DNS Settings\n\nAdd a DNS record if necessary:\n\n```bash\n# Add DNS server\necho \"nameserver 192.168.0.1\" \u003e\u003e /etc/resolv.conf\n```\n\n### 7. Ansible Control Machine Setup\n\nOn the Ansible control machine, install the necessary packages and configure the environment for running Kubespray.\n\n#### Install Required Packages\n\n```bash\n# Remove existing repositories and add local ones\nrm -rf /etc/yum.repos.d/*\ncat \u003c\u003cEOF \u003e /etc/yum.repos.d/local.repo\n[appstream]\nname=Nexus Local RockyLinux 8.8 Appstream Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/appstream/\"\ngpgcheck=0\nenabled=1\n\n[baseos]\nname=Nexus Local RockyLinux 8.8 Baseos Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/baseos/\"\ngpgcheck=0\nenabled=1\n\n[docker-ce-stable]\nname=Nexus Local RockyLinux 8.8 Docker-CE Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/docker-ce-stable/\"\ngpgcheck=0\nenabled=1\n\n[epel]\nname=Nexus Local RockyLinux 8.8 EPEL Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/epel/\"\ngpgcheck=0\nenabled=1\n\n[extras]\nname=Nexus Local RockyLinux 8.8 Extras Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/extras/\"\ngpgcheck=0\nenabled=1\n\n[kubernetes-1.29-stable]\nname=Nexus Local Kubernetes 1.29 Repository\nbaseurl=\"http://\u003cRepository_VM_IP\u003e:8080/kubernetes-1.29-stable/\"\ngpgcheck=0\nenabled=1\nEOF\n\n# Clean YUM cache and install required packages\nyum clean all\ndnf install -y git python3.11 python3.11-pip python3.11-netaddr yum-utils container-selinux rsync unzip bash-completion ipvsadm socat\n```\n\n#### Set Up Kubespray Environment\n\n```bash\n# Change directory to where Kubespray is located\ncd /opt/ansible\n\n# Set up a Python virtual environment for Kubespray\nVENVDIR=kubespray-venv\nKUBESPRAYDIR=kubespray\npython3.11 -m venv $VENVDIR\nsource $VENVDIR/bin/activate\n\n# Configure pip to use the local Nexus PyPi repository\ncat \u003c\u003cEOF \u003e /etc/pip.conf\n[global]\nindex-url = http://\u003cRepository_VM_IP\u003e:8081/repository/pypi/simple\ntrusted-host = \u003cRepository_VM_IP\u003e\nEOF\n\n# Install Kubespray dependencies\ncd $KUBESPRAYDIR\npip3.11 install -r requirements.txt --trusted-host \u003cRepository_VM_IP\u003e\n\n# Set up Docker to use the local Nexus image registry\nvim /etc/docker/daemon.json   # Add the following line: { \"insecure-registries\": [\"\u003cRepository_VM_IP\u003e:8082\"] }\ndocker login \u003cRepository_VM_IP\u003e:8082\n```\n\n#### Configure Kubernetes Inventory\n\n```bash\n# Copy the sample inventory to a new cluster configuration\ncp -rfp inventory/sample inventory/mycluster\n\n# Define the IP addresses of the Kubernetes nodes\ndeclare -a IPS=(\u003cK8s_node1_IP\u003e \u003cK8s_node2_IP\u003e \u003cK8s_node3_IP\u003e)\n\n# Generate the inventory file based on the node IPs\nCONFIG_FILE=inventory/mycluster/hosts.yml KUBE_CONTROL_HOSTS=2 python3.11 contrib/inventory_builder/inventory.py ${IPS[@]}\n\n# Review and modify the group variables as necessary\nvim inventory/mycluster/group_vars/all/all.yml\nvim inventory/mycluster/group_vars/all/containerd.yml\nvim inventory/mycluster/group_vars/all/offline.yml\nvim inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml\nvim inventory/mycluster/group_vars/k8s_cluster/addons.yml\n```\n\n### 8. Deploy the Kubernetes Cluster\n\nOnce everything is set up, run the Ansible playbook to deploy the Kubernetes cluster.\n\n```bash\n# Reset any existing cluster on the nodes (if applicable)\nansible-playbook -i inventory/mycluster/hosts.yml -b --become-user root reset.yml\n\n# Run the main playbook to create your Kubernetes cluster\nansible-playbook -i inventory/mycluster/hosts.yml -b --become-user root cluster.yml\n```\n\nIf you're deploying a high-availability cluster with kube-vip, run the cluster playbook without kube-vip first, then install kube-vip afterward.\n\n### 9. Post-Deployment Tasks\n\nOnce the playbook finishes successfully, the cluster should be up and running. To prevent Kubernetes pods from scheduling on the master nodes, you can apply a \"NoSchedule\" taint:\n\n```bash\nkubectl taint nodes \u003ccontrol-plane_node_name\u003e node-role.kubernetes.io/control-plane:NoSchedule\n```\n\n---\n\n## Contributions and Support\n\nFeel free to open issues or contribute to this repository. For further questions or support, refer to the [Kubespray documentation](https://kubespray.io) or contact the maintainers of this project.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgmrezah%2Fairgapped-kubespray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgmrezah%2Fairgapped-kubespray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgmrezah%2Fairgapped-kubespray/lists"}