Commit 23c97160 authored by Brendan Burns's avatar Brendan Burns

Initial add of cloud-demo

parent 14838df5
......@@ -130,12 +130,6 @@ func main() {
}
method := flag.Arg(0)
if len(flag.Args()) < 1 {
usage()
os.Exit(1)
}
method := flag.Arg(0)
matchFound := executeAPIRequest(method, auth) || executeControllerRequest(method, auth)
if matchFound == false {
glog.Fatalf("Unknown command %s", method)
......
<!--
Copyright 2014 Google Inc. 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.
-->
# Live update example
This example demonstrates the usage of Kubernetes to perform a live update on a running group of pods.
### Step Zero: Prerequisites
This example assumes that you have forked the repository and [turned up a Kubernetes cluster](https://github.com/GoogleCloudPlatform/kubernetes-new#setup):
$ cd kubernetes
$ hack/dev-build-and-up.sh
$ hack/build-go.sh
This example also assumes that you have [Docker](http://docker.io) installed on your local machine.
It also assumes that ```$DOCKER_USER``` is set to your docker user id.
### Step One: Build the image
$ cd kubernetes/examples/update-demo/image
$ docker build -t $DOCKER_USER/data .
$ docker push $DOCKER_USER/data
### Step Two: Run the controller
Now we will turn up two replicas of that image. They all serve on port 8080, mapped to internal port 80
$ cd kubernetes
$ cluster/cloudcfg.sh -p 8080:80 run $DOCKER_USER/data 2 dataController
### Step Three: Turn up the UX for the demo
In a different terminal:
$ cd kubernetes
$ cluster/cloudcfg.sh -proxy -www examples/update-demo/local/
Now visit the the [demo website](http://localhost:8001/static/index.html). You should see two light blue squares with pod IDs and ip addresses.
### Step Four: Try resizing the controller
Now we will increase the number of replicas from two to four:
$ cd kubernetes
$ cluster/cloudcfg.sh resize dataController 4
If you go back to the [demo website](http://localhost:8001/static/index.html) you should eventually see four boxes, one for each pod.
### Step Five: Update the docker image
We will now update the docker image to serve a different color.
$ cd kubernetes/examples/update-demo/image
$ ${EDITOR} data.json
Edit the ```color``` value so that it is a new color. For example:
```js
{
"color": "#F00"
}
```
Will set the color to red.
Once you are happy with the color, build a new image:
$ docker build -t $DOCKER_USER/data .
$ docker push $DOCKER_USER/data
### Step Six: Roll the update out to your servers
We will now update the servers that are running out in your cluster.
$ cd kubernetes
$ cluster/cloudcfg.sh -u=30s rollingupdate dataController
Watch the UX, it will update one pod every 30 seconds until all of the pods have the new color.
FROM dockerfile/nginx
ADD data.json /usr/share/nginx/html/data.json
ADD default /etc/nginx/sites-available/default
RUN chmod a+r /usr/share/nginx/html/data.json
CMD ["nginx"]
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
# Make site accessible from http://localhost/
server_name localhost;
location / {
try_files $uri $uri/ =404;
expires 0;
add_header Cache-Control private;
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
}
}
The MIT License
Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This source diff could not be displayed because it is too large. You can view the blob instead.
<!--
Copyright 2014 Google Inc. 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.
-->
<html ng-app>
<head>
<script src="angular.min.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" href="style.css"></link>
</head>
<body ng-controller="ButtonsCtrl">
<div ng-repeat="server in servers" class="server" style="background: #FFF">
<b>{{server.id}}</b>
<div class="img" style="background: {{server.color}};"> </div>
<a href="http://{{server.ip}}:8080/data.json">{{server.ip}}</a>
</div>
</body>
</html>
/*
Copyright 2014 Google Inc. 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.
*/
var base = "http://localhost:8001/api/v1beta1/";
var updateColor = function($http, server) {
$http.get("http://" + server.ip + ":8080/data.json")
.success(function(data) {
server.color = data.color;
console.log(data);
})
.error(function(data) {
console.log(data);
});
};
var updateServer = function($http, server) {
$http.get(base + "pods/" + server.id)
.success(function(data) {
console.log(data);
server.ip = data.currentState.hostIP;
updateColor($http, server);
})
.error(function(data) {
console.log(data);
});
};
var updateData = function($scope, $http) {
var servers = $scope.servers
for (var i = 0; i < servers.length; ++i) {
var server = servers[i];
updateServer($http, server);
}
};
var ButtonsCtrl = function ($scope, $http, $interval) {
$scope.servers = [];
update($scope, $http);
$interval(angular.bind({}, update, $scope, $http), 2000);
};
var getServer = function($scope, id) {
var servers = $scope.servers;
for (var i = 0; i < servers.length; ++i) {
if (servers[i].id == id) {
return servers[i];
}
}
return null;
};
var update = function($scope, $http) {
if (!$http) {
console.log("No HTTP!");
return;
}
$http.get(base + "pods")
.success(function(data) {
console.log(data);
var newServers = [];
for (var i = 0; i < data.items.length; ++i) {
var server = getServer($scope, data.items[i].id);
if (server == null) {
server = { "id": data.items[i].id };
}
newServers.push(server);
}
$scope.servers = newServers;
updateData($scope, $http)
})
.error(function(data) { console.log("ERROR: " + data); })
};
/*
Copyright 2014 Google Inc. 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.
*/
.img {
height: 100px;
width: 100px;
background-size: 100px 100px;
margin-left: 25px;
}
.server {
font-family: Roboto, Open Sans, arial;
width: 150px;
height: 150px;
border: 1px solid black;
margin: 10px;
display: inline-block;
padding: 3px;
}
......@@ -234,4 +234,3 @@ func (r Result) Into(obj interface{}) error {
func (r Result) Error() error {
return r.err
}
......@@ -71,7 +71,7 @@ func (s *ProxyServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
s.doError(w, err)
return
}
w.WriteHeader(http.StatusOK)
w.Header().Add("Content-type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(data)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment