Before we start

cat /proc/cpuinfo | grep model
cat /etc/os-release

It’s useful!

Now for the content

For cost effective cloud compute ditch the JVM and message brokers (so long Scala, SQL, Hazelcast and Kafka). Which brings me to coding microservices in go, with grpc and mesh (linkerd) as the target state.

A hour in a beer celler in the City googling led me firmly to Etcd as the distributed data store, probably with json as the value format for my data.

Just purchased my GoLand lincense, so time to start. As ever the notes below are a reminder for my own use.

etcd install

Just go to the releases page, and run the script as root to download and install the image with local mount. ie click releases, scroll down to the docker section.

```docker: Error response from daemon: driver failed programming external connectivity on endpoint etcd-gcr-v3.3.13 (4ae9a6610e400a558f38cbcb353ff8f6aa760eef02b94eecb3a2f37f396063c3): Error starting userland proxy: listen tcp 0.0.0.0:2380: bind: address already in use. ERRO[0058] error waiting for container: context canceled


 Google some more, and etcd is already running!  Its use by K8s.

 ```sudo docker ps|grep etcd
 docker inspect 2eaaf70172e9
 kubectl get pods --all-namespaces
 kubectl logs --follow etcd-pi6 -n kube-system

BUT, you must not use this etcd for your own apps. Instead set up your own pod.

Which leads to the usual vendor crap about using Helm, Consul and blah blah. This link was kind of helpful https://hub.docker.com/r/bitnami/etcd/

which linked to https://github.com/etcd-io/etcd/blob/master/etcd.conf.yml.sample

BUT, another search gave me https://github.com/etcd-io/etcd/tree/master/hack/kubernetes-deploy

Kinda feel like giving up and just running it, but lets go back to the docker version, and change the port from 23XX to 25XX: https://github.com/etcd-io/etcd/releases ```rm -rf /tmp/etcd-data.tmp && mkdir -p /tmp/etcd-data.tmp &&
docker rmi gcr.io/etcd-development/etcd:v3.3.13 || true &&
docker run
-p 2579:2579
-p 2580:2580
–mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data
–name etcd-gcr-v3.3.13
gcr.io/etcd-development/etcd:v3.3.13
/usr/local/bin/etcd
–name s1
–data-dir /etcd-data
–listen-client-urls http://0.0.0.0:2579
–advertise-client-urls http://0.0.0.0:2579
–listen-peer-urls http://0.0.0.0:2580
–initial-advertise-peer-urls http://0.0.0.0:2580
–initial-cluster s1=http://0.0.0.0:2580
–initial-cluster-token tkn
–initial-cluster-state new

docker exec etcd-gcr-v3.3.13 /bin/sh -c “/usr/local/bin/etcd –version” docker exec etcd-gcr-v3.3.13 /bin/sh -c “ETCDCTL_API=3 /usr/local/bin/etcdctl version” docker exec etcd-gcr-v3.3.13 /bin/sh -c “ETCDCTL_API=3 /usr/local/bin/etcdctl endpoint health” docker exec etcd-gcr-v3.3.13 /bin/sh -c “ETCDCTL_API=3 /usr/local/bin/etcdctl put foo bar” docker exec etcd-gcr-v3.3.13 /bin/sh -c “ETCDCTL_API=3 /usr/local/bin/etcdctl get foo”


Didn't work because the previous image is in use by a container which is stopped.  What?

```docker ps -a
docker container ls -a
docker container rm xxxxxxxxxxxxxx

standard_init_linux.go:211

```standard_init_linux.go:211: exec user process caused “exec format error”

Which means I'm running the wrong build.  An image built for a different architecture.  So, consult:
https://github.com/golang/go/wiki/GoArm

```cat /proc/cpuinfo | grep model
model name      : ARMv7 Processor rev 3 (v7l)
model name      : ARMv7 Processor rev 3 (v7l)
model name      : ARMv7 Processor rev 3 (v7l)
model name      : ARMv7 Processor rev 3 (v7l)

So, looking here: https://console.cloud.google.com/gcr/images/etcd-development/GLOBAL/etcd?gcrImageListsize=30 There are no images in google cloud…I guess they don’t run Pi’s. So don’t use those.

```docker pull gcr.io/etcd-development/etcd:v3.3.10-arm64

docker run
-p 2579:2579
-p 2580:2580
–mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data
–name etcd-gcr-v3.3.10
gcr.io/etcd-development/etcd:v3.3.10-arm64
/usr/local/bin/etcd
–name s1
–data-dir /etcd-data
–listen-client-urls http://0.0.0.0:2579
–advertise-client-urls http://0.0.0.0:2579
–listen-peer-urls http://0.0.0.0:2580
–initial-advertise-peer-urls http://0.0.0.0:2580
–initial-cluster s1=http://0.0.0.0:2580
–initial-cluster-token tkn
–initial-cluster-state new

sadly all fail with
standard_init_linux.go:211: exec user process caused "exec format error"


Get used to this:

docker container ls -a docker container rm xxxxxx docker images docker image describe xxxxx


## Building from sources
We need go, so look Here
https://golang.org/dl/
and then
https://golang.org/doc/install

As discussed previously we know the Pi 4 is an ARM7 which means GoLang arm6l rather than arm64.

```wget https://dl.google.com/go/go1.12.6.linux-armv6l.tar.gz
sudo tar -C /usr/local -xzf go1.12.6.linux-armv6l.tar.gz
vi ~/.profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
export GOPATH=/opt/apps/go-work

# restart your session
mkdir $GOPATH
go version

Lets build etcd for ARM6, then get the latest stable etcdctl ```mkdir /opt/apps/go-downloads/etdc-io cd /opt/apps/go-downloads/etdc-io wget https://github.com/etcd-io/etcd/archive/release-3.3.zip cd .. unzip etdc-io/release-3.3.zip cd etcd-release-3.3 make

It won't run as you need
```export ETCD_UNSUPPORTED_ARCH=arm

So lets test it: ```export ETCD_UNSUPPORTED_ARCH=arm sudo mkdir /var/lib/etcd-data sudo chmod a+rw /var/lib/etcd-data cd bin ./etcd
–name s1
–data-dir /var/lib/etcd-data
–listen-client-urls http://0.0.0.0:2579
–advertise-client-urls http://0.0.0.0:2579
–listen-peer-urls http://0.0.0.0:2580
–initial-advertise-peer-urls http://0.0.0.0:2580
–initial-cluster s1=http://0.0.0.0:2580
–initial-cluster-token tkn
–initial-cluster-state new


Now to use the client, in another terminal
```export ETCD_UNSUPPORTED_ARCH=arm
cd /opt/apps/go-downloads/etcd-release-3.3/bin
./etcdctl --endpoints "http://0.0.0.0:2579" set mykey "this is awesome"  
./etcdctl --endpoints "http://0.0.0.0:2579" get mykey

So it works!

NEXT TIME WE DO THE DOCKER RUNTIME

To set as a service: eg link jhttps://github.com/robertojrojas/kubernetes-the-hard-way-raspberry-pi/blob/master/docs/03-etcd.md