Created
December 22, 2021 18:50
-
-
Save dnviti/f18b59f20d8735e4de1bacc784692d23 to your computer and use it in GitHub Desktop.
Almalinux Post Install
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
#set -o xtrace | |
if [[ $USER != "root" ]] | |
then | |
echo "Script must be run as root" | |
exit 1 | |
fi | |
sed -i "s/#Port/Port/g" /etc/ssh/sshd_config | |
S=$(grep "Port " /etc/ssh/sshd_config) | |
OLD_SSH_PORT=${S:5:99} | |
NEW_SSH_PORT=$(( $RANDOM % 999 + 22000 )) | |
SSH_GW_IP=$(ip route | grep default | awk '{print $3}') | |
## Use the first sudoer user available post-install | |
SCRIPT_USER=$(id -nu 1000) | |
## by default script will not install kubernetes | |
KUBE_INSTALL="n" | |
KUBE_MASTER="n" | |
NETINTERFACE="ens0" | |
MACHINE_IP="" | |
DOCKER_DIRECTORY="/docker" | |
DHCP_FORCE="n" | |
SSH_CHANGE_PORT="n" | |
# if no arguments are provided, return usage function | |
# maybe no need | |
# if [ $# -eq 0 ]; then | |
# usage # run usage function | |
# exit 1 | |
# fi | |
usage () { | |
echo "RHEL Docker + Kubernetes Post-Install usage" | |
echo "----" | |
echo " Kubernetes Installer:" | |
echo " -kn | --kube-node -> Install Kubernetes Node" | |
echo " -km | --kube-master -> Install Kubernetes Master" | |
echo " -do | --docker-only -> Install Docker Only" | |
echo "----" | |
echo " Optional Parameters:" | |
echo "" | |
echo " -u -> Specify non-root user to run the script" | |
echo " -a -> Specify a network gateway address to be used for firewalling purposes" | |
echo "----" | |
echo "Version: 0.9.3" | |
echo "Release Date: 08/12/2021" | |
echo "Author: dnviti@gmail.com" | |
} | |
firewall_rules() { | |
echo "Selinux setting..." | |
echo "SSH Port" | |
semanage port -a -t ssh_port_t -p tcp $NEW_SSH_PORT | |
firewall-cmd --remove-service=ssh --zone=public --permanent | |
firewall-cmd --remove-service=cockpit --zone=public --permanent | |
firewall-cmd --remove-service=dhcpv6-client --zone=public --permanent | |
firewall-cmd --permanent --zone=work --add-port=$NEW_SSH_PORT/tcp | |
firewall-cmd --permanent --zone=work --add-source=$NETWORK_IP/24 | |
if [[ $KUBE_INSTALL == "y" || $KUBE_INSTALL == "Y" ]] | |
then | |
semanage port -a -t http_port_t -p tcp 8080 | |
semanage port -a -t kubehc1_port_t -p tcp 6443 | |
semanage port -a -t kubehc2_port_t -p tcp 10250 | |
firewall-cmd --add-port=8080/tcp --permanent --zone=work | |
firewall-cmd --add-port=6443/tcp --permanent --zone=work | |
firewall-cmd --add-port=10248/tcp --permanent --zone=work | |
firewall-cmd --add-port=10250/tcp --permanent --zone=work | |
fi | |
} | |
while [ "$1" != "" ]; do | |
case $1 in | |
-kn | --kube-node) | |
shift | |
KUBE_INSTALL="y" | |
KUBE_MASTER="n" | |
if [[ $KUBE_MASTER == "y" || $KUBE_MASTER == "Y" ]] | |
then | |
echo "Kubernetes cannot be Master and Node at the same time!" | |
exit 1 | |
fi | |
KUBE_MASTER_HOST=$1 | |
echo "Checking Kubernetes Master at $KUBE_MASTER_HOST..." | |
ping -c 5 $KUBE_MASTER_HOST &> /dev/null | |
PING_ERR=$? | |
echo "Ping Error: $PING_ERR" | |
if [[ $PING_ERR == 0 ]] | |
then | |
echo "Host Succesfully Found at $KUBE_MASTER_HOST" | |
echo "Kubernetes Node installation configuration successfull" | |
else | |
echo "Error! Cannot enstablish a stable connection to the Kubernetes Master at $KUBE_MASTER_HOST" | |
echo "Exiting Script with error $PING_ERR" | |
KUBE_INSTALL="n" | |
exit 1 | |
fi | |
rm -f kubecheck.log | |
echo "Checking Kubernetes Master Health Check..." | |
curl -k https://$KUBE_MASTER_HOST:6443/livez?verbose -o kubecheck.log | |
KUBECHECK_RESULT=$(tail -n 1 kubecheck.log) | |
if [[ KUBECHECK_RESULT == "healthz check passed" ]] | |
then | |
echo "Kubernetes Master Health-Check passed..." | |
echo "Resuming Installation..." | |
rm -r kubecheck.log | |
else | |
echo "Kubernetes Master Health-Check error, see below or kubecheck.log" | |
echo $(cat kubecheck.log) | |
echo "Quitting Installation..." | |
KUBE_INSTALL="n" | |
exit 1 | |
fi | |
### To be tested after master installation | |
;; | |
-km | --kube-master) | |
shift | |
KUBE_INSTALL="y" | |
KUBE_MASTER="y" | |
if [[ $KUBE_NODE == "y" || $KUBE_NODE == "Y" ]] | |
then | |
echo "Kubernetes cannot be Master and Node at the same time!" | |
KUBE_INSTALL="n" | |
KUBE_MASTER="n" | |
exit 1 | |
fi | |
;; | |
-do | --docker-only) | |
shift | |
KUBE_INSTALL="n" | |
KUBE_MASTER="n" | |
;; | |
-dd | --docker-directory) | |
shift | |
DOCKER_DIRECTORY=$1 | |
;; | |
-hs | --hostname-change) | |
shift | |
HOSTNAME=$1 | |
echo "$HOSTNAME" > /etc/hostname | |
;; | |
-u | --user) | |
shift | |
## Specify a manual Script user | |
SCRIPT_USER=$1 | |
## Script User Check | |
if [[ $SCRIPT_USER == "" ]] | |
then | |
echo "No user defined" | |
exit 1 | |
fi | |
if id "$SCRIPT_USER" &>/dev/null; then | |
USER_EXISTS="y" | |
else | |
USER_EXISTS="n" | |
fi | |
;; | |
-a | --gateway-address) | |
shift | |
## Specify a manual SSH Gateway IP | |
SSH_GW_IP=$1 | |
;; | |
-ni | --network-interface) | |
shift | |
NETINTERFACE=$1 | |
;; | |
-fwd | --enable-firewall) | |
shift | |
ENABLE_FIREWALL="y" | |
;; | |
-dhcp | --force-dhcp-renew) | |
shift | |
DHCP_FORCE="y" | |
;; | |
-sp | --change-ssh-port) | |
shift | |
SSH_CHANGE_PORT="y" | |
;; | |
-h | --help) | |
usage # run usage function | |
;; | |
*) | |
usage | |
exit 1 | |
;; | |
esac | |
shift # remove the current value for '$1' and use the next | |
done | |
### START SCRIPT | |
## For Kubernetes the following link was references (adapted to Red Hat from Debian/Ubuntu) | |
## https://www.dgline.it/digitalroots/guida-per-la-costruzione-di-un-cluster-kubernetes-con-ubuntu/ | |
## Check if ip and net interface are correct | |
if [[ $(ip addr | grep $NETINTERFACE) == "" ]] | |
then | |
echo "Error: Network interface [$NETINTERFACE] not found." | |
exit 1 | |
fi | |
MACHINE_IP=$(ip -4 addr show $NETINTERFACE | grep -oP '(?<=inet\s)\d+(\.\d+){3}') | |
if [[ $MACHINE_IP == "" ]] | |
then | |
echo "IPv4 address not found for interface [$NETINTERFACE]" | |
exit 1 | |
fi | |
HOSTNAME=$(cat /etc/hostname) | |
echo "Hostname is set to: $HOSTNAME" | |
if [[ $SSH_GW_IP == "" ]] | |
then | |
echo "You must enter the Gateway IP to allow connections" | |
exit 1 | |
fi | |
## Find network address from gateway | |
NETWORK_IP=$(awk -F"." '{print $1"."$2"."$3".2"}'<<<$SSH_GW_IP) | |
if [[ $SCRIPT_USER == "" ]] | |
then | |
echo "You must enter a non root user as parameter" | |
exit 1 | |
fi | |
if id "$SCRIPT_USER" &>/dev/null; then | |
USER_EXISTS="y" | |
else | |
USER_EXISTS="n" | |
fi | |
## Replace current HOME variable with new one for script user selected | |
HOME="/home/$SCRIPT_USER" | |
## Adding the new user if not exists | |
if [[ $USER_EXISTS == "n" ]] | |
then | |
read -p "The User specified [$SCRIPT_USER] does not exists, should i create it? (N/y)" CREATE_USER_CHOICE | |
if [[ $CREATE_USER_CHOICE = "" || $CREATE_USER_CHOICE == "n" || $CREATE_USER_CHOICE == "N" ]] | |
then | |
echo "Error: User [$SCRIPT_USER] does not exists and you do not automatically want to create it. Aborting" | |
exit 1 | |
fi | |
echo "User $SCRIPT_USER does not exists, adding..." | |
adduser $SCRIPT_USER | |
## Create a new home and set permissions | |
mkdir "$HOME" | |
chown $SCRIPT_USER:$SCRIPT_USER "$HOME" -R | |
chmod u+rwx "$HOME" -R | |
fi | |
## System Utilities Install | |
dnf install -y nano ca-certificates curl epel-release policycoreutils-python-utils dhclient | |
dnf install -y fail2ban fail2ban-firewalld | |
## Security Prep | |
## SSH Config | |
if [[ $SSH_CHANGE_PORT = "y" ]] | |
then | |
sed -i "s/Port $OLD_SSH_PORT/Port $NEW_SSH_PORT/g" /etc/ssh/sshd_config | |
sed -i "s/PermitRootLogin yes/PermitRootLogin no/g" /etc/ssh/sshd_config | |
else | |
NEW_SSH_PORT="$OLD_SSH_PORT" | |
fi | |
systemctl enable --now firewalld | |
if [[ $ENABLE_FIREWALL == "y" ]] | |
then | |
firewall_rules | |
systemctl enable --now firewalld | |
else | |
echo "Warning! Firewall has been opened to public!" | |
firewall-cmd --permanent --zone=public --add-port=$NEW_SSH_PORT/tcp | |
firewall-cmd --permanent --zone=public --set-target=ACCEPT | |
fi | |
systemctl enable --now fail2ban | |
tee -a /etc/fail2ban/jail.conf > /dev/null <<EOT | |
[ssh] | |
enabled = true | |
port = $NEW_SSH_PORT | |
filter = sshd | |
logpath = /var/log/auth.log | |
EOT | |
## Forza DHCP | |
if [[ $DHCP_FORCE == "y" ]] | |
then | |
dhclient -v | |
fi | |
## Docker Install | |
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo | |
dnf remove podman buildah | |
dnf install -y docker-ce docker-ce-cli containerd.io | |
usermod -aG docker $SCRIPT_USER | |
curl -L "https://github.com/docker/compose/releases/download/v2.1.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose | |
chmod +x /usr/local/bin/docker-compose | |
## Install Docker 2 Retro-Compatibility Command (Compose Switch) | |
curl -fL https://raw.githubusercontent.com/docker/compose-cli/main/scripts/install/install_linux.sh | sh | |
## Docker Post-Install | |
groupadd docker | |
usermod -aG docker $SCRIPT_USER | |
install -d -m 0755 -o $SCRIPT_USER -g docker "$DOCKER_DIRECTORY" | |
sed '/ExecStart=\/usr\/bin\/dockerd -H fd:\/\/ --containerd=\/run\/containerd\/containerd.sock/ s/$/ --exec-opt native.cgroupdriver=systemd/' /lib/systemd/system/docker.service | |
systemctl enable --now docker.service | |
## Install Kubernetes | |
if [[ $KUBE_INSTALL == "y" || $KUBE_INSTALL == "Y" ]] | |
then | |
## Prepare repository | |
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo | |
[kubernetes] | |
name=Kubernetes | |
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 | |
enabled=1 | |
gpgcheck=1 | |
repo_gpgcheck=1 | |
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg | |
EOF | |
## Prepare docker configuration | |
mkdir /etc/docker | |
cat <<EOF | sudo tee /etc/docker/daemon.json | |
{ | |
"exec-opts": ["native.cgroupdriver=systemd"], | |
"log-driver": "json-file", | |
"log-opts": { | |
"max-size": "100m" | |
}, | |
"storage-driver": "overlay2" | |
} | |
EOF | |
## Installing Kubernetes Tools | |
dnf install -y kubeadm kubectl kubelet | |
## start and enable kubelet service | |
systemctl enable kubelet.service | |
systemctl start kubelet.service | |
## Disable SWAP | |
sudo swapoff -a | |
## also disable permanently | |
SWAP_LINE=$(tail -n 1 /etc/fstab) | |
sed "s/$SWAP_LINE/#$SWAP_LINE/" /etc/fstab | |
if [[ $KUBE_MASTER == "y" || $KUBE_MASTER == "Y" ]] | |
then | |
kubeadm reset -f | |
kubeadm init | |
echo "Kubernetes Master initialized, see kubemaster.log for additional information" | |
cp /etc/kubernetes/admin.conf $HOME/ | |
chown $(id -u):$(id -g) $HOME/admin.conf | |
export KUBECONFIG=$HOME/admin.conf | |
echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc | |
## First POD Installation | |
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml | |
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml | |
kubectl get pods -all-namespaces | |
## Master can join itself | |
# kubectl taint nodes –all node-role.kubernetes.io/master- | |
fi | |
fi | |
NEW_SCRIPT_USER_PASSWORD=$(tr -cd "[:alnum:]" < /dev/urandom | fold -w32 | head -n 1) | |
NEW_ROOT_PASSWORD=$(tr -cd "[:alnum:]" < /dev/urandom | fold -w32 | head -n 1) | |
echo "Setting secure password for user $SCRIPT_USER" | |
echo "$SCRIPT_USER:$NEW_SCRIPT_USER_PASSWORD"|chpasswd | |
echo "Setting secure password for user root" | |
echo "root:$NEW_ROOT_PASSWORD"|chpasswd | |
echo "Script end - User Information" | |
## User Output | |
echo "New $SCRIPT_USER password is: $NEW_SCRIPT_USER_PASSWORD" | |
echo "New root password is: $NEW_ROOT_PASSWORD" | |
echo "Connect via SSH: ssh $SCRIPT_USER@$MACHINE_IP -p $NEW_SSH_PORT" | |
echo "Warning! System will be restarted, please save all the info before" | |
read -p "Press [Enter] to reboot system" | |
reboot |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment