This repo contains the exercises and examples described in the online course "Getting Started with Cloud Native Go"
In order to build the Docker image you'll first need to build Linux executable so that it can be copied into the image.
Change into the json_marshalling directory and run
env GOOS=linux GOARCH=amd64 go build -v .
Change into the json_marshalling directory
docker build -t cloud-native-go:1.0.0-alpine .
In order to push to DockerHub you'll need to have a DockerHub account which is free to create.
First of all, you'll need to use the docker tag command to tag the image you want to push up
Assuming that my DockerHub username is: torrios , then the command would be...
docker tag cloud-native-go:1.0.0-alpine torrios/cloud-native-go:1.0.0-alpine
which takes the existing cloud-native-go:1.0.0-alpine image and tags it as torrios/cloud-native-go:1.0.0-alpine and in the process creates a new image or clones the original image
In order to push to DockerHub you'll need to login which you can do via the docker login command.
docker login
Once you've successfully provided your credentials you can use the docker push to push the image up to DockerHub
docker push torrios/cloud-native-go:1.0.0-alpine
In the course the instructor demonstrated several concepts related to Kubernetes using Minikube, which is a single Node Kubernetes cluster that you can run locally.
Start Minikube by issuing the following command:
minikube start
Minikube will start and you should see output similar to
Starting local Kubernetes v1.10.0 cluster...
Starting VM...
Getting VM IP address...
Moving files into cluster...
Setting up certs...
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.
Once started, one of the first things you'll want to do is to switch your local Docker environment to the Minikube Docker environment. Therefore you can first issue the following command:
minikube docker-env
which should return something like this...
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/hectorrios/.minikube/certs"
export DOCKER_API_VERSION="1.35"
# Run this command to configure your shell:
# eval $(minikube docker-env)
which displays the environment variables that would be set to switch to the Minikube Docker registry in the Minikube VM. In addition it also gives you the command to enter into the terminal to perform the switch. So to actually perform the switch run the following:
eval $(minikube docker-env)
Once complete, if you were to run a
docker ps
Then you should get a listing of all running Kubernetes containers.
The command to display which Kubernetes cluster you're working against is...
kubectl cluster-info
A "Pod" represents either a single container or set of containers but I believe that the best practice is to deploy a container per Pod.
One way of deploying resources in Kubernetes is via a YAML configuration file. For our "Pod" we can use the file,
k8s-pod.yml
Without going into much detail, some of the important bits are
- kind This is the resource type and for our pod the value is Pod
- labels represent key value pair and you are free to decide what these should be.
- spec -> containers Defines the image that will be used to create the container for this Pod
In order to deploy the Pod you would issue the following command:
kubectl create -f k8s-pod.yml
Once deployed you can issue a
kubectl get pods
to see a list of all running Pods. You should see an entry for a Pod called cloud-native-go
You can also some more detailed information on the Pod by issuing a
kubectl describe pod cloud-native-go
which should provide a plethora of information on the running Pod.
In order to access the running Pod you can use "port-forward" command. Be aware that this command blocks when issued. For example lets listen locally on port 8080 from the Pod's port 8080
kubectl port-forward <Pod Name> 8080:8080
In our case the "Pod Name" is cloud-native-go
In order to get the labels on a Pod issue something like
kubectl get pods cloud-native-go --show-labels
To add a new label dynamically you can issue the following:
kubectl label pod cloud-native-go hello=world
Which adds a new key (hello) value (world) pair to the cloud-native-go Pod.
You can also change existing label values such as changing the value of our "hello" label...
kubectl label pod cloud-native-go-844dcb4dd5-jlf7z hello=hector --overwrite
A Namespace is kind of like a "package" in Java and namespaces in PHP
To see all existing namespaces you can issue:
kubectl get ns
On my system I get:
NAME STATUS AGE
default Active 5d
kube-public Active 5d
kube-system Active 5d
If I want to see all Pods in the "kube-system" name space then I could issue:
kubectl get pods --namespace kube-system
The fallback namespace for resource is the default namespace. If you issue a describe command on our cloud-native-go Pod then you'll see that it's in the default namespace.
kubectl describe pod cloud-native-go | grep Namespace
In order to create a new Namespace you need a YAML file which declares the new Namespace. For example, check out the k8s-namespace.yml file to see how to delcare a Namespace.
We use the create to create one once we have the YAML file defined.
kubectl create -f k8s-namespace.yml
With our newly created Namespace we can create our cloud-native-go Pod again but this time in our new namespace
$ kubectl create -f k8s-pod.yml --namespace cloud-native-go
and now if we have a look at our Namespace again we'll see a Pod in there. In addition, our original Pod in the default is still present so we have two Pods but in different namespaces
$ kubectl get pods --namespace cloud-native-go
NAME READY STATUS RESTARTS AGE
cloud-native-go 1/1 Running 0 50s
The interesting thing about namespaces is that if you delete a namespace, then everything in the Namespace will be deleted as well
$ kubectl delete -f k8s-namespace.yml
namespace "cloud-native-go" deleted
Sooooo, be careful when deleting Namespaces because the CLI will not warn you that the resources within the namespace will also be deleted.