Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Commit

Permalink
Add Environment Guide example.
Browse files Browse the repository at this point in the history
This example shows a simple two tier setup in Kubernetes, and
simply prints the environment information that each pod sees.
Querying the service multiple times will show services at work
load balancing requests.
  • Loading branch information
jeffmendoza committed Jun 9, 2015
1 parent dafe79e commit c2a3e4e
Show file tree
Hide file tree
Showing 11 changed files with 341 additions and 0 deletions.
92 changes: 92 additions & 0 deletions examples/environment-guide/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Environment Guide Example
=========================
This example demonstrates running pods, replication controllers, and
services. It shows two types of pods: frontend and backend, with
services on top of both. Accessing the frontend pod will return
environment information about itself, and a backend pod that it has
accessed through the service. The goal is to illuminate the
environment metadata available to running containers inside the
Kubernetes cluster. The documentation for the kubernetes environment
is [here](/docs/container-environment.md).

![Diagram](diagram.png)

Prerequisites
-------------
This example assumes that you have a Kubernetes cluster installed and
running, and that you have installed the `kubectl` command line tool
somewhere in your path. Please see the [getting
started](/docs/getting-started-guides) for installation instructions
for your platform.

Optional: Build your own containers
-----------------------------------
The code for the containers is under
[containers/](containers)

Get everything running
----------------------

kubectl create -f ./backend-rc.yaml
kubectl create -f ./backend-srv.yaml
kubectl create -f ./show-rc.yaml
kubectl create -f ./show-srv.yaml

Query the service
-----------------
Use `kubectl describe service show-srv` to determine the public IP of
your service.

> Note: If your platform does not support external load balancers,
you'll need to open the proper port and direct traffic to the
internal IP shown for the frontend service with the above command

Run `curl <public ip>:80` to query the service. You should get
something like this back:

```
Pod Name: show-rc-xxu6i
Pod Namespace: default
USER_VAR: important information
Kubenertes environment variables
BACKEND_SRV_SERVICE_HOST = 10.147.252.185
BACKEND_SRV_SERVICE_PORT = 5000
KUBERNETES_RO_SERVICE_HOST = 10.147.240.1
KUBERNETES_RO_SERVICE_PORT = 80
KUBERNETES_SERVICE_HOST = 10.147.240.2
KUBERNETES_SERVICE_PORT = 443
KUBE_DNS_SERVICE_HOST = 10.147.240.10
KUBE_DNS_SERVICE_PORT = 53
Found backend ip: 10.147.252.185 port: 5000
Response from backend
Backend Container
Backend Pod Name: backend-rc-6qiya
Backend Namespace: default
```

First the frontend pod's information is printed. The pod name and
[namespace](/docs/design/namespaces.md) are retreived from the
[Downward API](/docs/downward_api.md). Next, `USER_VAR` is the name of
an environment variable set in the [pod
definition](show-rc.yaml). Then, the dynamic kubernetes environment
variables are scanned and printed. These are used to find the backend
service, named `backend-srv`. Finally, the frontend pod queries the
backend service and prints the information returned. Again the backend
pod returns its own pod name and namespace.

Try running the `curl` command a few times, and notice what
changes. Ex: `watch -n 1 curl -s <ip>` Firstly, the frontend service
is directing your request to different frontend pods each time. The
frontend pods are always contacting the backend through the backend
service. This results in a different backend pod servicing each
request as well.

Cleanup
-------
kubectl delete rc,service -l type=show-type
kubectl delete rc,service -l type=backend-type


[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/environment-guide/README.md?pixel)]()
30 changes: 30 additions & 0 deletions examples/environment-guide/backend-rc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
apiVersion: v1
kind: ReplicationController
metadata:
name: backend-rc
labels:
type: backend-type
spec:
replicas: 3
template:
metadata:
labels:
type: backend-type
spec:
containers:
- name: backend-container
image: gcr.io/google-samples/env-backend:1.1
imagePullPolicy: Always
ports:
- containerPort: 5000
protocol: TCP
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
13 changes: 13 additions & 0 deletions examples/environment-guide/backend-srv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: v1
kind: Service
metadata:
name: backend-srv
labels:
type: backend-type
spec:
ports:
- port: 5000
protocol: TCP
selector:
type: backend-type
23 changes: 23 additions & 0 deletions examples/environment-guide/containers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Building
--------
For each container, the build steps are the same. The examples below
are for the `show` container. Replace `show` with `backend` for the
backend container.

GCR
---
docker build -t gcr.io/<project-name>/show .
gcloud preview docker push gcr.io/<project-name>/show

Docker Hub
----------
docker build -t <username>/show .
docker push <username>/show

Change Pod Definitions
----------------------
Edit both `show-rc.yaml` and `backend-rc.yaml` and replace the
specified `image:` with the one that you built.


[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/examples/environment-guide/containers/README.md?pixel)]()
2 changes: 2 additions & 0 deletions examples/environment-guide/containers/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM golang:onbuild
EXPOSE 8080
37 changes: 37 additions & 0 deletions examples/environment-guide/containers/backend/backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"fmt"
"log"
"net/http"
"os"
)

func printInfo(resp http.ResponseWriter, req *http.Request) {
name := os.Getenv("POD_NAME")
namespace := os.Getenv("POD_NAMESPACE")
fmt.Fprintf(resp, "Backend Container\n")
fmt.Fprintf(resp, "Backend Pod Name: %v\n", name)
fmt.Fprintf(resp, "Backend Namespace: %v\n", namespace)
}

func main() {
http.HandleFunc("/", printInfo)
log.Fatal(http.ListenAndServe(":5000", nil))
}
2 changes: 2 additions & 0 deletions examples/environment-guide/containers/show/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
FROM golang:onbuild
EXPOSE 8080
95 changes: 95 additions & 0 deletions examples/environment-guide/containers/show/show.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
Copyright 2015 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"fmt"
"io"
"log"
"net/http"
"os"
"sort"
"strings"
)

func getKubeEnv() (map[string]string, error) {
environS := os.Environ()
environ := make(map[string]string)
for _, val := range environS {
split := strings.Split(val, "=")
if len(split) != 2 {
return environ, fmt.Errorf("Some weird env vars")
}
environ[split[0]] = split[1]
}
for key := range environ {
if !(strings.HasSuffix(key, "_SERVICE_HOST") ||
strings.HasSuffix(key, "_SERVICE_PORT")) {
delete(environ, key)
}
}
return environ, nil
}

func printInfo(resp http.ResponseWriter, req *http.Request) {
kubeVars, err := getKubeEnv()
if err != nil {
http.Error(resp, err.Error(), http.StatusInternalServerError)
return
}

backendHost := os.Getenv("BACKEND_SRV_SERVICE_HOST")
backendPort := os.Getenv("BACKEND_SRV_SERVICE_PORT")
backendRsp, backendErr := http.Get(fmt.Sprintf(
"http://%v:%v/",
backendHost,
backendPort))
if backendErr == nil {
defer backendRsp.Body.Close()
}

name := os.Getenv("POD_NAME")
namespace := os.Getenv("POD_NAMESPACE")
fmt.Fprintf(resp, "Pod Name: %v \n", name)
fmt.Fprintf(resp, "Pod Namespace: %v \n", namespace)

envvar := os.Getenv("USER_VAR")
fmt.Fprintf(resp, "USER_VAR: %v \n", envvar)

fmt.Fprintf(resp, "\nKubenertes environment variables\n")
var keys []string
for key := range kubeVars {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
fmt.Fprintf(resp, "%v = %v \n", key, kubeVars[key])
}

fmt.Fprintf(resp, "\nFound backend ip: %v port: %v\n", backendHost, backendPort)
if backendErr == nil {
fmt.Fprintf(resp, "Response from backend\n")
io.Copy(resp, backendRsp.Body)
} else {
fmt.Fprintf(resp, "Error from backend: %v", backendErr.Error())
}
}

func main() {
http.HandleFunc("/", printInfo)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Binary file added examples/environment-guide/diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions examples/environment-guide/show-rc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
apiVersion: v1
kind: ReplicationController
metadata:
name: show-rc
labels:
type: show-type
spec:
replicas: 3
template:
metadata:
labels:
type: show-type
spec:
containers:
- name: show-container
image: gcr.io/google-samples/env-show:1.1
imagePullPolicy: Always
ports:
- containerPort: 8080
protocol: TCP
env:
- name: USER_VAR
value: important information
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
15 changes: 15 additions & 0 deletions examples/environment-guide/show-srv.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
apiVersion: v1
kind: Service
metadata:
name: show-srv
labels:
type: show-type
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
type: show-type

0 comments on commit c2a3e4e

Please sign in to comment.