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

Commit

Permalink
Instructions for OC Web example in Kubernetes (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
draffensperger committed Apr 5, 2019
1 parent 5cb6119 commit b89b7e7
Show file tree
Hide file tree
Showing 7 changed files with 256 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -43,3 +43,6 @@ dist/

#istanbul files
coverage/

#static JS files in examples
static/
31 changes: 31 additions & 0 deletions examples/initial_load/Dockerfile
@@ -0,0 +1,31 @@
# Copyright 2019, OpenCensus Authors
#
# 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.

# First build the server binary
FROM golang:alpine AS build
RUN apk update && apk add --no-cache git && apk add --no-cache ca-certificates
WORKDIR /root
ADD go.mod .
ADD go.sum .
ADD server.go .
RUN GO111MODULE=on go get -d -v
RUN GO111MODULE=on CGO_ENABLED=0 go build -o example_server

# Then put the server binary and needed files into an empty container
FROM scratch
COPY index.html /
COPY ./static/*.js /static/
COPY --from=build ./root/example_server /
ENTRYPOINT ["/example_server"]
EXPOSE 8000
86 changes: 83 additions & 3 deletions examples/initial_load/README.md
Expand Up @@ -24,7 +24,8 @@ Then create a `config.yaml` file following the
receivers:
opencensus:
address: "127.0.0.1:55678"

cors_allowed_origins:
- http://localhost:*
exporters:
# Pick and configure an exporter e.g. stackdriver, zipkin, aws-xray, honeycomb
```
Expand Down Expand Up @@ -63,6 +64,85 @@ the trace viewer for the exporter you set up and view the trace of your initial
page load. It will be named `Nav./index.html` (or just `Nav./` if you left off
the actual `index.html` part when you visited the URL).

## Deploying to Kubernetes
## Deploying to GKE (Kubernetes on Google Cloud Platform)

### 1. Install needed tools

Install [gcloud](https://cloud.google.com/sdk/install).
Then run `gcloud components install kubectl` to install `kubectl`.

### 2. Set up GKE cluster and configure container registry

To create a cluster with the following commands:

```bash
gcloud services enable container.googleapis.com
gcloud container clusters create opencensus-web-demo --enable-autoupgrade --num-nodes=1 --zone=us-central1-a
```
You also need to enable Google Container Registry (GCR) on your GCP project and configure the docker CLI to authenticate to GCR:

```bash
gcloud services enable containerregistry.googleapis.com
gcloud auth configure-docker -q
```

### 3. Deploy the OpenCensus Agent

To deploy the agent, run the following commands:

```bash
# Get the project you are using with gcloud
PROJECT_ID="$(gcloud config list --format 'value(core.project)')"

# Substitute the project ID in the k8s config and deploy it
cat ./kubernetes/oc-agent-cors.template.yaml | \
sed "s/{{PROJECT-ID}}/$PROJECT_ID/" | \
kubectl apply -f -
```
Note that this uses the [omnition/opencensus-agent](./kubernetes/agent-cors.yaml)
container from the Docker Hub. You can also build your own container by
following the
[OpenCensus Agent](https://github.com/census-instrumentation/opencensus-service#opencensus-agent)
docs.

### 5. Build the demo application container

First build the OpenCensus Web scripts that will be deployed with the
application:

```bash
npm run build:prod --prefix=../../packages/opencensus-web-all
mkdir -p static
cp ../../packages/opencensus-web-all/dist/*.js ./static
```
Then build the server container and push it to GCR:

```bash
PROJECT_ID="$(gcloud config list --format 'value(core.project)')"
docker build . -t gcr.io/$PROJECT_ID/oc-web-initial-load:latest
gcloud docker -- push gcr.io/$PROJECT_ID/oc-web-initial-load:latest
```

### 4. Deploy the demo application

Run the command `kubectl get svc oc-agent-service` to check if the
`EXTERNAL-IP` column has been filled in. If it is still pending, then wait a bit
and run it again until it's available.

Once the agent has an external IP, you can deploy the example service that uses
it by running the following commands:

```bash
PROJECT_ID="$(gcloud config list --format 'value(core.project)')"
AGENT_IP="$(kubectl get svc oc-agent-service \
-o=custom-columns="IP ADDRESS:.status.loadBalancer.ingress[*].ip" | \
tail -n 1)"
cat ./kubernetes/initial-load-demo.template.yaml | \
sed "s/{{PROJECT-ID}}/$PROJECT_ID/; s/{{AGENT-IP}}/$AGENT_IP/" | \
kubectl apply -f -
```

Then run `kubectl get svc oc-web-initial-load-service` to see the external IP
address for the demo app, which you can then visit in your browser.

TODO(draffensperger): develop example Kubernetes deployment instructions.
You can then view traces in the [Stackdriver Trace](https://console.cloud.google.com/traces/traces) console in GCP. The traces will be named `Nav./`.
2 changes: 1 addition & 1 deletion examples/initial_load/index.html
Expand Up @@ -23,7 +23,7 @@ <h1>OpenCensus Web Hello World!</h1>

<script>
traceparent = "{{.Traceparent}}";
ocwAgent = "{{.AgentEndpoint}}";
ocwAgent = "http://{{.AgentHostAndPort}}";
</script>
<script src="{{.OcwScriptEndpoint}}/initial-load-all.js" async></script>
<footer>
Expand Down
49 changes: 49 additions & 0 deletions examples/initial_load/kubernetes/initial-load-demo.template.yaml
@@ -0,0 +1,49 @@
# Copyright 2019, OpenCensus Authors
#
# 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.

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: oc-web-initial-load-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: oc-web-initial-load
spec:
containers:
- name: oc-web-initial-load-container
image: gcr.io/{{PROJECT-ID}}/oc-web-initial-load:latest
args: [
"--listen=:8000",
"--agent={{AGENT-IP}}:80",
"--ocw_script_prefix=/static",
]
ports:
- containerPort: 8000
---
apiVersion: v1
kind: Service
metadata:
name: oc-web-initial-load-service
spec:
type: LoadBalancer
selector:
app: oc-web-initial-load
ports:
- protocol: TCP
port: 80
targetPort: 8000
74 changes: 74 additions & 0 deletions examples/initial_load/kubernetes/oc-agent-cors.template.yaml
@@ -0,0 +1,74 @@
# Copyright 2019, OpenCensus Authors
#
# 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.

---
apiVersion: v1
kind: ConfigMap
metadata:
name: oc-agent-conf
namespace: default
data:
oc-agent-config: |
receivers:
opencensus:
address: ":55678"
cors_allowed_origins:
- "*"
exporters:
stackdriver:
project: {{PROJECT-ID}}
enable_tracing: true
enable_metrics: false
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: oc-agent-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: oc-agent-deployment
spec:
containers:
- name: oc-agent-container
image: omnition/opencensus-agent:latest
volumeMounts:
- name: oc-agent-config-vol
readOnly: true
mountPath: /conf
args: ["--config=/conf/oc-agent-config.yaml"]
ports:
- containerPort: 55678
volumes:
- name: oc-agent-config-vol
configMap:
name: oc-agent-conf
items:
- key: oc-agent-config
path: oc-agent-config.yaml
---
apiVersion: v1
kind: Service
metadata:
name: oc-agent-service
spec:
type: LoadBalancer
selector:
app: oc-agent-deployment
ports:
- protocol: TCP
port: 80
targetPort: 55678
24 changes: 15 additions & 9 deletions examples/initial_load/server.go
Expand Up @@ -31,22 +31,26 @@ import (
)

// Use a local agent by default to help in local development.
var agentEndpoint = flag.String("agent", "http://localhost:55678", "HTTP(S) endpoint of the OpenCensus agent")
var agentHostAndPort = flag.String("agent", "localhost:55678", "Host:port of OpenCensus agent")

// Use local webpack server on port 8080 by default.
var ocwScriptEndpoint = flag.String("ocw_script", "http://localhost:8080", "HTTP(S) endpoint that serves OpenCensus Web JS script")
var ocwScriptEndpoint = flag.String("ocw_script_prefix", "http://localhost:8080", "HTTP(S) endpoint that serves OpenCensus Web JS script")

var listenAddr = flag.String("listen", "localhost:8000", "")
var listenAddr = flag.String("listen", ":8000", "")

// Data rendered to the HTML template
type pageData struct {
Traceparent string
AgentEndpoint string
OcwScriptEndpoint string
AgentHostAndPort template.URL
OcwScriptEndpoint template.URL
}

func main() {
exp, err := ocagent.NewExporter(ocagent.WithInsecure(), ocagent.WithServiceName("hello-server"))
flag.Parse()
exp, err := ocagent.NewExporter(
ocagent.WithInsecure(),
ocagent.WithAddress(*agentHostAndPort),
ocagent.WithServiceName("hello-server"))
if err != nil {
log.Fatalf("Failed to create the agent exporter: %v", err)
}
Expand All @@ -61,6 +65,8 @@ func main() {

serveMux := http.NewServeMux()
serveMux.HandleFunc("/", handleRequest)
fs := http.FileServer(http.Dir("static"))
serveMux.Handle("/static/", http.StripPrefix("/static/", fs))

var handler http.Handler = serveMux
handler = &ochttp.Handler{
Expand All @@ -74,7 +80,7 @@ func main() {
handler = ensureTraceHeader(handler)

fmt.Printf("OC Web initial load example server listening on %v\n", *listenAddr)
http.ListenAndServe(*listenAddr, handler)
log.Fatal(http.ListenAndServe(*listenAddr, handler))
}

// Adds a random traceparent header if none is specified. This is needed
Expand Down Expand Up @@ -104,8 +110,8 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
_, renderSpan := trace.StartSpan(r.Context(), "Render template")
data := pageData{
Traceparent: r.Header.Get("traceparent"),
AgentEndpoint: *agentEndpoint,
OcwScriptEndpoint: *ocwScriptEndpoint,
AgentHostAndPort: template.URL(*agentHostAndPort),
OcwScriptEndpoint: template.URL(*ocwScriptEndpoint),
}
tmpl.Execute(w, data)
renderSpan.End()
Expand Down

0 comments on commit b89b7e7

Please sign in to comment.