Ultimate Go: Service with Kubernetes 4.1

24 June 2023

I attended recently a golang programming training. Our instructor is a respected Golang developer himself William Kennedy who has trained thousands of developers worldwide in Go.

The class I attended teaches how to build production-level services in Go leveraging the power of Kubernetes. From the beginning, you will pair program with the Bill Kennedy walking through the design philosophies and guidelines for building services in Go. With each new feature that is added to the service, you will learn how to deploy to and manage the Kubernetes environment used to run the service.

I will outline here my install experience for the starter service. I installed it on my Mac during our training but this time, this is my Linux experience.

Install brew

Dependecy installation scripts from makefile are calling brew so it's the first dependency to install. On Arch Linux, I tried the aur version of brew-git but it's installing its own ruby dependencies instead of using the available so I have to remove it.

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> Checking for `sudo` access (which may request your password)...
==> This script will install:
/home/linuxbrew/.linuxbrew/bin/brew
/home/linuxbrew/.linuxbrew/share/doc/homebrew
/home/linuxbrew/.linuxbrew/share/man/man1/brew.1
/home/linuxbrew/.linuxbrew/share/zsh/site-functions/_brew
/home/linuxbrew/.linuxbrew/etc/bash_completion.d/brew
/home/linuxbrew/.linuxbrew/Homebrew
==> The following new directories will be created:
/home/linuxbrew/.linuxbrew/bin
/home/linuxbrew/.linuxbrew/etc
/home/linuxbrew/.linuxbrew/include
/home/linuxbrew/.linuxbrew/lib
/home/linuxbrew/.linuxbrew/sbin
/home/linuxbrew/.linuxbrew/share
/home/linuxbrew/.linuxbrew/var
/home/linuxbrew/.linuxbrew/opt
/home/linuxbrew/.linuxbrew/share/zsh
/home/linuxbrew/.linuxbrew/share/zsh/site-functions
/home/linuxbrew/.linuxbrew/var/homebrew
/home/linuxbrew/.linuxbrew/var/homebrew/linked
/home/linuxbrew/.linuxbrew/Cellar
/home/linuxbrew/.linuxbrew/Caskroom
/home/linuxbrew/.linuxbrew/Frameworks

...
==> Installation successful!

==> Next steps:
$ (echo; echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"') >> /home/$USER/.zprofile
$ eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
$ sudo pacman -S base-devel
warning: base-devel-1-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...

Packages (1) base-devel-1-1
...
(1/1) reinstalling base-devel                   [###############################################] 100%
$ brew install gcc
...
==> Installing gcc
==> Pouring gcc--13.1.0.x86_64_linux.bottle.tar.gz
==> Creating the GCC specs file: /home/linuxbrew/.linuxbrew/Cellar/gcc/13.1.0/bin/../lib/gcc/current/gcc/x86_64-pc-linux-gnu/13/specs
đŸē  /home/linuxbrew/.linuxbrew/Cellar/gcc/13.1.0: 1,668 files, 320.2MB
==> Running `brew cleanup gcc`...

Install tooling and dependencies

$ make dev-brew-common
$ make dev-docker
$ make dev-gotooling
$ sudo curl -fL https://app.getambassador.io/download/tel2oss/releases/download/v2.14.0/telepresence-linux-amd64 -o /usr/local/bin/telepresence
$ sudo chmod a+x /usr/local/bin/telepresence

Verify you have properly installed the dependencies

$ make test
CGO_ENABLED=0 go test -count=1 ./...
...
ok  	github.com/ardanlabs/service/app/services/sales-api/tests/v1	5.634s
ok  	github.com/ardanlabs/service/business/core/product	6.418s
ok  	github.com/ardanlabs/service/business/core/user	5.633s
ok  	github.com/ardanlabs/service/business/core/usersummary	5.176s
ok  	github.com/ardanlabs/service/business/web/auth	0.108s
ok  	github.com/ardanlabs/service/foundation/vault	3.117s
ok  	github.com/ardanlabs/service/foundation/worker	0.303s

Start the project

$ make dev-up
kind create cluster \
	--image kindest/node:v1.27.3 \
	--name ardan-starter-cluster \
	--config zarf/k8s/dev/kind-config.yaml
Creating cluster "ardan-starter-cluster" ...
 ✓ Ensuring node image (kindest/node:v1.27.3) đŸ–ŧ 
 ✓ Preparing nodes đŸ“Ļ  
 ✓ Writing configuration 📜 
 ✓ Starting control-plane 🕹ī¸ 
 ✓ Installing CNI 🔌 
 ✓ Installing StorageClass 💾 
Set kubectl context to "kind-ardan-starter-cluster"
You can now use your cluster with:

kubectl cluster-info --context kind-ardan-starter-cluster

Thanks for using kind! 😊
kubectl wait --timeout=120s --namespace=local-path-storage --for=condition=Available deployment/local-path-provisioner
deployment.apps/local-path-provisioner condition met
kind load docker-image datawire/ambassador-telepresence-manager:2.14.1 --name ardan-starter-cluster
...
telepresence --context=kind-ardan-starter-cluster helm install
Launching Telepresence User Daemon

Traffic Manager installed successfully
telepresence --context=kind-ardan-starter-cluster connect
Launching Telepresence Root Daemon
Need root privileges to run: /usr/local/bin/telepresence daemon-foreground /home/$USER/.cache/telepresence/logs /home/$USER/.config/telepresence
[sudo] password for $USER: 
Connected to context kind-ardan-starter-cluster (https://127.0.0.1:38665)
$ make dev-update-apply
docker build \
	-f zarf/docker/dockerfile.service \
	-t ardanlabs/service/sales-api:0.0.1 \
	--build-arg BUILD_REF=0.0.1 \
	--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
	.
[+] Building 30.7s (18/18) FINISHED 
...

docker build \
	-f zarf/docker/dockerfile.metrics \
	-t ardanlabs/service/sales-api-metrics:0.0.1 \
	--build-arg BUILD_REF=0.0.1 \
	--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
	.
[+] Building 11.5s (14/14) FINISHED