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

Script to ease etcd set up #164

Merged
merged 2 commits into from
Apr 12, 2021
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
248 changes: 248 additions & 0 deletions docs/ai-developers/etcdscript.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
#! /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 Host has to be mapped to a particular domain and should be accessible."
echo -e "${blue}\t 4. 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 $user | grep sudo
if [ "$?" -ne 0 ];
then
echo -e "${red}ERROR: User lacks sudo previliges. Switch to Root User"
exit 1
fi

echo -e "${blue}Domain Name of the Host:${grey}"
read domain_name
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))

curl -V
if [ "$?" -ne 0 ];
then
sudo apt-get update
sudo apt-get install curl -y
fi

public_ip=`curl ifconfig.me`
private_ip=`hostname -I | awk '{print $1}'`

getent hosts ${domain_name} | awk '{ print $1 }' | grep ${public_ip}
if [ "$?" -ne 0 ];
then
getent hosts ${domain_name} | awk '{ print $1 }' | grep ${private_ip}
if [ "$?" -ne 0 ];
then
echo -e "${red}ERROR: Domain is not mapped to the current host."
exit 1
fi
fi

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 chmod 777 -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\": [
\"${domain_name}\",
\"${public_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}
wget https://github.com/etcd-io/etcd/releases/download/v3.1.20/etcd-v3.1.20-linux-amd64.tar.gz
tar -zxvf etcd-v3.1.20-linux-amd64.tar.gz
cd etcd-v3.1.20-linux-amd64/
sudo mv etcd etcdctl /usr/bin/
cd ${current_path}
rm -rf etcd-v3.1.20-linux-amd64*

echo "[Unit]
Description=etcd service
Documentation=https://github.com/coreos/etcd

[Service]
User=root
Type=notify
ExecStart=/usr/bin/etcd \\
--name member-1 \\
--data-dir /var/lib/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-token etcd-cluster-1 \\
--initial-cluster member-1=https://${private_ip}:2380 \\
--client-cert-auth --trusted-ca-file=${cert_folder}/ca.pem \\
--cert-file=${cert_folder}/server.pem --key-file=${cert_folder}/server-key.pem \\
--peer-client-cert-auth --peer-trusted-ca-file=${cert_folder}/ca.pem \\
--peer-cert-file=${cert_folder}/member-1.pem --peer-key-file=${cert_folder}/member-1-key.pem \\
--initial-cluster-state new
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target " | sudo tee -a /lib/systemd/system/etcd.service

sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd.service
sleep 30s


curl --cacert ${cert_folder}/ca.pem --cert ${cert_folder}/client.pem --key ${cert_folder}/client-key.pem "https://${domain_name}:2379/health"
if [ "$?" -ne 0 ];
then
echo -e "${red}ERROR: Port 2379 & 2380 seems to be not accessible from the host."
rm -rf ~/bin
sudo rm -rf ${cert_folder}
sudo systemctl disable etcd
sudo service etcd stop
sudo rm /lib/systemd/system/etcd.service
sudo rm /usr/bin/etcd /usr/bin/etcdctl
sudo systemctl daemon-reload
echo -e "${red}<---------- ETCD INSTALLATION FAILED---------->"
else
echo -e "${green}"
echo -e "<---------- ETCD INSTALLATED SUCCESSFULLY---------->"
echo -e "${blue} 1. ETCD ENDPOINT: ${grey} https://${domain_name}: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://${domain_name}:2379/health"
echo -e "${blue} 4. TO START ETCD: ${grey} sudo systemctl start etcd.service"
echo -e "${blue} 5. TO STOP ETCD: ${grey} sudo systemctl start etcd.service"
echo -e "${blue} 6. TO CHECK STATUS OF ETCD: ${grey} sudo systemctl status etcd.service"
fi
5 changes: 5 additions & 0 deletions docs/ai-developers/etcdsetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ Following are the example nodes for our reference.
Infrastural diagram of ETCD Cluster setup on AWS.
![Etcd Cluster Infrastructure](/assets/img/etcd/etcd-cluster.png)

## ETCD set up Script
<a id="raw-url" href="https://raw.githubusercontent.com/singnet/dev-portal/master/docs/ai-developers/etcdscript.sh">Download script</a>

For detailed explanation on every step , reference the sections below

## Generating Certificates

To setup the cluster, use three types of certificate, such as:
Expand Down