2020-08-11 22:20:05 -04:00
2020-08-10 15:45:52 -04:00
2020-08-10 15:45:52 -04:00
2020-08-11 22:20:05 -04:00

ETCD Config and Testing

Config

/etc/hosts

3.14.3.102  red
3.14.3.103  grey
3.14.3.107  purple

Generate Certs

Pick one server to act as the CA.

Install make

sudo apt install make

Install go

sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz
export PATH=$PATH:/usr/local/go/bin

Install cfssl

git clone https://github.com/cloudflare/cfssl
cd cfssl
make -j 4
sudo mkdir /usr/local/cfssl
sudo mv bin/ /usr/local/cfssl/bin
export PATH=$PATH:/usr/local/cfssl/bin

Create templates

mkdir ~/.cfssl
cd ~/.cfssl

vim ca-config.json

{
  "signing": {
    "default": {
        "usages": [
          "signing",
          "key encipherment",
          "server auth",
          "client auth"
        ],
        "expiry": "876000h"
    }
  }
}

vim ca-csr.json:

{
  "CN": "etcd",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "autogenerated",
      "OU": "etcd cluster",
      "L": "duconet"
    }
  ]
}

vim req-csr.json:

{
  "CN": "etcd",
  "hosts": [
    "3.14.3.102",
    "3.14.3.103",
    "3.14.3.107",
    "127.0.0.1"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "autogenerated",
      "OU": "etcd cluster",
      "L": "duconet"
    }
  ]
}

Generate CA:

sudo mkdir -p /certs
sudo chown -R pi:pi /certs
cfssl gencert -initca ca-csr.json | cfssljson -bare certs/ca

Generate a Peer and Client Cert:

cfssl gencert \
  -ca certs/ca.pem \
  -ca-key certs/ca-key.pem \
  -config ca-config.json \
  req-csr.json | cfssljson -bare certs/client

cfssl gencert \
  -ca certs/ca.pem \
  -ca-key certs/ca-key.pem \
  -config ca-config.json \
  req-csr.json | cfssljson -bare certs/red

cp certs/ca.pem certs/client-key.pem certs/client.pem certs/red-key.pem certs/red.pem /certs/

cfssl gencert \
  -ca certs/ca.pem \
  -ca-key certs/ca-key.pem \
  -config ca-config.json \
  req-csr.json | cfssljson -bare certs/purple

scp certs/ca.pem certs/client-key.pem certs/client.pem certs/purple-key.pem certs/purple.pem purple:/certs/

cfssl gencert \
  -ca certs/ca.pem \
  -ca-key certs/ca-key.pem \
  -config ca-config.json \
  req-csr.json | cfssljson -bare certs/grey

scp certs/ca.pem certs/client-key.pem certs/client.pem certs/grey-key.pem certs/grey.pem grey:/certs/

Install ETCD

Download the latest version

tar xf etcd.tar.gz
sudo cp etcd/etcd etcd/etcdctl /usr/local/bin/
sudo chmod +x /usr/local/bin/etcd /usr/local/bin/etcdctl

Start the server

Create folders:

sudo mkdir -p /certs/
sudo chown -R pi:pi /certs/
sudo mkdir -p /var/lib/etcd
sudo chown -R pi:pi /var/lib/etcd
sudo chmod -R 700 /var/lib/etcd

Unencrypted (testing only)

etcd --name red --initial-advertise-peer-urls http://3.14.3.102:2380 \
  --listen-peer-urls http://3.14.3.102:2380 \
  --listen-client-urls http://3.14.3.102:2379,http://127.0.0.1:2379 \
  --advertise-client-urls http://3.14.3.102:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster red=http://3.14.3.102:2380 \
  --initial-cluster-state new

TLS Encrypted

export ETCD_UNSUPPORTED_ARCH=arm64
etcd --name red --initial-advertise-peer-urls https://3.14.3.102:2380 \
  --listen-peer-urls https://3.14.3.102:2380 \
  --listen-client-urls https://3.14.3.102:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://3.14.3.102:2379 \
  --initial-cluster-token pi-cluster-1 \
  --initial-cluster red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380 \
  --initial-cluster-state new \
  --client-cert-auth --trusted-ca-file=/certs/ca.pem \
  --cert-file=/certs/client.pem --key-file=/certs/client-key.pem \
  --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem \
  --peer-cert-file=/certs/red.pem --peer-key-file=/certs/red-key.pem

export ETCD_UNSUPPORTED_ARCH=arm64
etcd --name purple --initial-advertise-peer-urls https://3.14.3.107:2380 \
  --listen-peer-urls https://3.14.3.107:2380 \
  --listen-client-urls https://3.14.3.107:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://3.14.3.107:2379 \
  --initial-cluster-token pi-cluster-1 \
  --initial-cluster red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380,grey=https://3.14.3.103:2380 \
  --initial-cluster-state new \
  --client-cert-auth --trusted-ca-file=/certs/ca.pem \
  --cert-file=/certs/client.pem --key-file=/certs/client-key.pem \
  --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem \
  --peer-cert-file=/certs/purple.pem --peer-key-file=/certs/purple-key.pem

export ETCD_UNSUPPORTED_ARCH=arm64
etcd --name grey --initial-advertise-peer-urls https://3.14.3.103:2380 \
  --listen-peer-urls https://3.14.3.103:2380 \
  --listen-client-urls https://3.14.3.103:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://3.14.3.103:2379 \
  --initial-cluster-token pi-cluster-1 \
  --initial-cluster red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380,grey=https://3.14.3.103:2380 \
  --initial-cluster-state new \
  --client-cert-auth --trusted-ca-file=/certs/ca.pem \
  --cert-file=/certs/client.pem --key-file=/certs/client-key.pem \
  --peer-client-cert-auth --peer-trusted-ca-file=/certs/ca.pem \
  --peer-cert-file=/certs/grey.pem --peer-key-file=/certs/grey-key.pem

Systemd

[Unit]
Description=etcd service
Documentation=https://github.com/etcd-io/etcd 
After=network.target

[Service]
User=pi
Type=notify
Environment=ETCD_UNSUPPORTED_ARCH=arm64
Environment=ETCD_DATA_DIR=/var/lib/etcd
Environment=ETCD_NAME=red
Environment=ETCD_INITIAL_ADVERTISE_PEER_URLS=https://$IP:2380
Environment=ETCD_LISTEN_PEER_URLS=https://$IP:2380
Environment=ETCD_LISTEN_CLIENT_URLS=https://$IP,https://127.0.0.1:2379
Environment=ETCD_ADVERTISE_CLIENT_URLS=https://$IP:2379
Environment=ETCD_INITIAL_CLUSTER_TOKEN=pi-cluster-1
Environment=ETCD_INITIAL_CLUSTER="red=https://3.14.3.102:2380,purple=https://3.14.3.107:2380,grey=https://3.14.3.103:2380"
Environment=ETCD_INITIAL_CLUSTER_STATE=new
Environment=ETCD_TRUSTED_CA_FILE=/certs/ca.pem
Environment=ETCD_CERT_FILE=/certs/client.pem
Environment=ETCD_KEY_FILE=/certs/client-key.pem
Environment=ETCD_PEER_TRUSTED_CA_FILE=/certs/ca.pem
Environment=ETCD_PEER_CERT_FILE=/certs/red.pem
Environment=ETCD_PEER_KEY_FILE=/certs/red-key.pem
ExecStart=/usr/local/bin/etcd --client-cert-auth --peer-client-cert-auth
Restart=on-failure
RestartSec=5
LimitNOFILE=40000

[Install]
WantedBy=multi-user.target
sudo systemctl start etcd
sudo systemctl enable etcd
journalctl -u etcd -f

Testing

scp red:/certs/client.pem red:/certs/client-key.pem red:/certs/ca.pem certs
export ETCDCTL_DIAL_TIMEOUT=3s;
export ETCDCTL_CACERT=./certs/ca.pem; # ca.pem
export ETCDCTL_CERT=./certs/client.pem; # 3.14.3.102.pem
export ETCDCTL_KEY=./certs/client-key.pem;  # 3.14.3.102-key.pem
export ETCDCTL_ENDPOINTS=https://3.14.3.102:2379,https://3.14.3.107:2379,https://3.14.3.103:2379;
etcdctl put foo bar
etcdctl get foo
while true; do etcdctl put foo $(( ( RANDOM % 1000 )  + 1 )) && etcdctl get foo; done;
Description
etcd cluster
Readme 30 KiB