Go On Pi - July 2019
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