#! /bin/bash green="\033[0;32m" blue="\033[1;34m" red="\033[0;31m" grey="\033[1;37m" current_path=`pwd` echo -e "${green}<---------- ETCD INSTALLATION ---------->" echo -e "${blue}Here is the list of prerequisite for the installation" echo -e "${blue}\t 1. The Operating System has to be Ubuntu." echo -e "${blue}\t 2. User should have root previliges." echo -e "${blue}\t 3. The Ports 2379 & 2380 should be accessible by Daemon and the Host" echo -e "${green}" awk -F= '/^NAME/{print $2}' /etc/os-release | grep -i ubuntu if [ "$?" -ne 0 ]; then echo -e "${red}ERROR: The ETCD installation is currently supported for Ubuntu OS." exit 1 fi groups `whoami` | grep sudo if [ "$?" -ne 0 ]; then echo -e "${red}ERROR: User lacks sudo previliges. Switch to Root User" exit 1 fi echo -e "${blue}Oragnization Name:${grey}" read org_name echo -e "${blue}Validity of the certificates in years:${grey}" read years echo -e "${green}" validity=$((years*365*24)) cur_user=`whoami` sudo apt-get update sudo apt-get install ca-certificates curl gnupg lsb-release -y sudo mkdir -m 0755 -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y sudo usermod -aG docker $cur_user public_ip=`curl ifconfig.me` private_ip=`hostname -I | awk '{print $1}'` mkdir ~/bin curl -s -L -o ~/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 curl -s -L -o ~/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod +x ~/bin/{cfssl,cfssljson} export PATH=$PATH:~/bin cert_folder="/var/lib/etcd/cfssl" sudo mkdir -p ${cert_folder} sudo chown -R ${cur_user} ${cert_folder} sudo chmod 755 -R ${cert_folder} cd ${cert_folder} echo "{ \"signing\": { \"default\": { \"expiry\": \"${validity}h\" }, \"profiles\": { \"server\": { \"expiry\": \"${validity}h\", \"usages\": [ \"signing\", \"key encipherment\", \"server auth\" ] }, \"client\": { \"expiry\": \"${validity}h\", \"usages\": [ \"signing\", \"key encipherment\", \"client auth\" ] }, \"peer\": { \"expiry\": \"${validity}h\", \"usages\": [ \"signing\", \"key encipherment\", \"server auth\", \"client auth\" ] } } } }" > ca-config.json echo "{ \"CN\": \"${org_name} CA\", \"key\": { \"algo\": \"rsa\", \"size\": 2048 }, \"names\": [ { \"C\": \"US\", \"L\": \"CA\", \"O\": \"${org_name} Name\", \"ST\": \"San Francisco\", \"OU\": \"Org Unit 1\", \"OU\": \"Org Unit 2\" } ] }" > ca-csr.json cfssl gencert -initca ca-csr.json | cfssljson -bare ca - echo "{ \"CN\": \"etcd-cluster\", \"hosts\": [ \"${public_ip}\", \"${private_ip}\", \"127.0.0.1\" ], \"key\": { \"algo\": \"ecdsa\", \"size\": 256 }, \"names\": [ { \"C\": \"US\", \"L\": \"CA\", \"ST\": \"San Francisco\" } ] }" > server.json cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server echo "{ \"CN\": \"member-1\", \"hosts\": [ \"member-1\", \"member-1.local\", \"${private_ip}\", \"127.0.0.1\" ], \"key\": { \"algo\": \"ecdsa\", \"size\": 256 }, \"names\": [ { \"C\": \"US\", \"L\": \"CA\", \"ST\": \"San Francisco\" } ] }" > member-1.json cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer member-1.json | cfssljson -bare member-1 echo "{ \"CN\": \"client\", \"hosts\": [\"\"], \"key\": { \"algo\": \"ecdsa\", \"size\": 256 }, \"names\": [ { \"C\": \"US\", \"L\": \"CA\", \"ST\": \"San Francisco\" } ] }" > client.json cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client cd ${current_path} echo "sudo -u $cur_user docker run -d --network host --restart on-failure --name docker-etcd-node-1 -v data:/data.etcd -v ${cert_folder}:/certs -d quay.io/coreos/etcd:v3.5.0 etcd --name=node-1 --data-dir=data.etcd --initial-advertise-peer-urls https://${private_ip}:2380 --listen-peer-urls https://${private_ip}:2380 --listen-client-urls https://${private_ip}:2379,https://127.0.0.1:2379 --advertise-client-urls https://${private_ip}:2379 --initial-cluster node-1=https://${private_ip}:2380 --initial-cluster-state=new --initial-cluster-token=etcd-cluster-1 --client-cert-auth --trusted-ca-file=/certs/ca.pem --cert-file=/certs/server.pem --key-file=/certs/server-key.pem --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem --peer-cert-file=/certs/member-1.pem --peer-key-file=/certs/member-1-key.pem" > create_etcd_node.sh bash create_etcd_node.sh sleep 30 curl --cacert ${cert_folder}/ca.pem --cert ${cert_folder}/client.pem --key ${cert_folder}/client-key.pem "https://${private_ip}:2379/health" if [ "$?" -ne 0 ]; then echo -e "${red}ERROR: Port 2379 & 2380 seems to be not accessible from the host." rm -rf ~/bin rm create_etcd_node.sh sudo rm -rf ${cert_folder} docker stop docker-etcd-node-1 docker rm docker-etcd-node-1 docker rmi quay.io/coreos/etcd:v3.5.0 sudo rm /etc/apt/keyrings/docker.gpg echo -e "${red}<---------- ETCD INSTALLATION FAILED---------->" else echo -e "${green}" echo -e "<---------- ETCD INSTALLATED SUCCESSFULLY---------->" echo -e "${blue} 1. ETCD ENDPOINT: ${grey} https://${private_ip}:2379/health" echo -e "${blue} 2. CERTIFICATES PATH: ${grey} ${cert_folder}" echo -e "${blue} 3. COMMAND TO TEST LOCALLY: ${grey} curl --cacert ${cert_folder}/ca.pem --cert ${cert_folder}/client.pem --key ${cert_folder}/client-key.pem https://${private_ip}:2379/health" echo -e "${blue} 4. TO START ETCD: ${grey} docker start docker-etcd-node-1" echo -e "${blue} 5. TO STOP ETCD: ${grey} docker stop docker-etcd-node-1" echo -e "${blue} 6. TO CHECK STATUS/LOGS OF ETCD: ${grey} docker logs docker-etcd-node-1" fi