Welcome!
Go for ops
This is the Go for ops playground.
Kudos to the Go community
Congratulations!
You've completed the scenario!
Scenario Rating
Congrats, you've mastered Go for ops! Here are some directions:
Your environment is currently being packaged as a Docker container and the download will begin shortly. To run the image locally, once Docker has been installed, use the commands
cat scrapbook_mhausenblas_go-containers_container.tar | docker load
docker run -it /mhausenblas_go-containers:
Oops!! Sorry, it looks like this scenario doesn't currently support downloads. We'll fix that shortly.

Steps
Go for ops
Content
The content of mhausenblas/go4ops is available here:
cd /root/work/src/github.com/mhausenblas/go4ops/
This playground supports Go, Docker, and Kubernetes.
Basics
Let's start off with the obligatory Hello World program:
go run $G4OHOME/code/hello-world/main.go
Now let's move on to a more realistic Hello World program that uses the environment variable G4O_LANG
to customize the response:
go run $G4OHOME/code/hello-world-for-real/main.go
G4O_LANG=nl go run $G4OHOME/code/hello-world-for-real/main.go
Compare the output with and without the environment variable G4O_LANG
set.
Next we look at some data types. First, let's see a slice
in action:
go run $G4OHOME/code/slices/main.go
Now a map
:
go run $G4OHOME/code/maps/main.go
Basics
Now we have a look at a user-defined datatype, a struct
:
go run $G4OHOME/code/structs/main.go
Next, we learn how to use a function
:
go run $G4OHOME/code/functions/main.go
Go also supports methods
, essentially a function with a defined receiver:
go run $G4OHOME/code/methods/main.go
In Go, errors are first class citizens:
go run $G4OHOME/code/errors/main.go
Sometimes it's useful to extract common behavior into an interface
:
go run $G4OHOME/code/interfaces/main.go
Basics
Go supports modules and they are called packages
, here we define and use github.com/mhausenblas/go4ops/code/modules/something
:
go run $G4OHOME/code/modules/main.go
Next we move on to some basic I/O, let's start with reading user input from stdin
:
go run $G4OHOME/code/userin/main.go
How about reading a file? Here we go, we read $G4OHOME/data/simple.txt
all at once an print the content:
cd $G4OHOME/code/files-reading/ && go run main.go
Now, let's write to $G4OHOME/data/out.txt
:
cd $G4OHOME/code/files-writing/ && go run main.go
Basics
Now we shell out, that is execute ps -f
using exec.Command()
, and print the result:
go run $G4OHOME/code/shell-out/main.go
Testing is also super easy and part of the Go tool chain:
cd $G4OHOME/code/testing/
go test -v
Advanced
Now we move on to some slightly more advanced topics. First, we read the file $GO4HOME/data/project.json
and deserialize the JSON into a struct which we then print without and with the fields:
cd $G4OHOME/code/files-advanced/ && go run main.go
Next we have some fun with the time
package:
go run $G4OHOME/code/time/main.go
How about some concurrent programming using go routines and channels?
go run $G4OHOME/code/concurrency/main.go
Advanced
Now we have a look at a service with an HTTP API. On the endpoint /metrics
it serves a JSON payload with some system metrics using the github.com/shirou/gopsutil
package to gather those metrics, so let's first install the dependencies:
go get github.com/shirou/gopsutil && go get golang.org/x/sys/unix
Now we can execute the service in the background:
cd $G4OHOME/code/metricsrv/
go run main.go &
And we can query it like so:
curl localhost:9876/metrics
Advanced
Now we have a look at how to pass arguments to a program.
If no arguments are supplied:
go run $G4OHOME/code/cli/main.go
List all arguments:
go run $G4OHOME/code/cli/main.go -h
Use arguments:
go run $G4OHOME/code/cli/main.go --target=Dan --repeat=2
Note that the github.com/spf13/cobra package can be used as a drop-in replacement and offers a lot more flexibility.
Advanced
Next we move on to dependency management with dep
. So first we need to install it:
go get -u github.com/golang/dep/cmd/dep
Now we can use dep
to resolve the dependencies stated in $G4OHOME/code/dependency/Gopkg.toml
:
cd $G4OHOME/code/dependency/
$GOPATH/bin/dep ensure
If you now look into $G4OHOME/code/dependency/vendor
you'll find the github.com/Sirupsen/logrus
package in version 1.0.3
there. Now we can execute the program using this version:
go run main.go
Containers
Now we have a look at how to use Go with containers. First, we will create a containerized version of a simple HTTP ping service in $G4OHOME/code/containers
using two strategies.
cd $G4OHOME/code/containers
Build the container image using the full-blown approach:
docker build --tag=quay.io/mhausenblas/pingsvc:1 --file=fbDockerfile .
Launch the container image we just built as a container named fbping
:
docker run --rm --name fbping -d -p 8888:8888 quay.io/mhausenblas/pingsvc:1
Call it:
curl localhost:8888/ping
Clean up:
docker kill fbping && clear
Now, using the the light-weight approach. First, build the executable:
GOOS=linux GOARCH=amd64 go build
And now the container image:
docker build --tag=quay.io/mhausenblas/pingsvc:2 --file=lwDockerfile .
Launch the container image we just built as a container named lwping
:
docker run --rm --name lwping -d -p 8888:8888 quay.io/mhausenblas/pingsvc:2
Call it:
curl localhost:8888/ping
Clean up:
docker kill lwping && clear
Compare the container images (note the resulting sizes!):
docker images "quay.io/mhausenblas/*"
If you have access to a container registry then you can now also push the container image. For example, using Quay, just replace $USERNAME
with your username:
docker push quay.io/$USERNAME/pingsvc:2
Containers
Now let's deploy our pingsvc
in Kubernetes.
First, create a deployment using:
kubectl run pingsvc --image=quay.io/mhausenblas/pingsvc:2 --port=8888
Now, create a service by exposing the deployment so that it is available cluster-internally via pingsvc:8888
:
kubectl expose deploy/pingsvc
List all the resources we've created:
kubectl get deploy,po,svc
Wait until the pod the deployment created (something like pingsvc-58fc565c9c-h5znn
) shows Running
in the STATUS
column and then
call pingsvc
using a jump pod like so:
kubectl run -i -t --rm jumpod --restart=Never --image=quay.io/mhausenblas/jump:0.2 curl pingsvc:8888/ping
That's it!