Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove host ports from the update demo and update tests #4791

Merged
merged 1 commit into from
Feb 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cluster/gce/util.sh
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ function test-setup {
detect-project

# Open up port 80 & 8080 so common containers on minions can be reached
# TODO(roberthbailey): Remove this once we are no longer relying on hostPorts.
gcloud compute firewall-rules create \
--project "${PROJECT}" \
--target-tags "${MINION_TAG}" \
Expand Down
16 changes: 4 additions & 12 deletions examples/update-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,20 @@ $ cd kubernetes
$ hack/dev-build-and-up.sh
```

If you are running your cluster on GCE (the default), you may need to open the firewall for port 8080 using the [console](https://console.developer.google.com) or the `gcloud` tool. The following command will allow traffic from any source to instances tagged `kubernetes-minion`:

```bash
$ gcloud compute firewall-rules create \
--allow tcp:8080 --target-tags=kubernetes-minion \
kubernetes-minion-8080
```

### Step One: Turn up the UX for the demo

You can use bash job control to run this in the background. This can sometimes spew to the output so you could also run it in a different terminal.
You can use bash job control to run this in the background (note that you must use the default port -- 8001 -- for the following demonstration to work properly). This can sometimes spew to the output so you could also run it in a different terminal.

```
$ ./cluster/kubectl.sh proxy --www=local/ &
+ ./cluster/kubectl.sh proxy --www=local/
$ ./cluster/kubectl.sh proxy --www=examples/update-demo/local/ &
+ ./cluster/kubectl.sh proxy --www=examples/update-demo/local/
I0218 15:18:31.623279 67480 proxy.go:36] Starting to serve on localhost:8001
```

Now visit the the [demo website](http://localhost:8001/static). You won't see anything much quite yet.

### Step Two: Run the controller
Now we will turn up two replicas of an image. They all serve on port 8080, mapped to internal port 80
Now we will turn up two replicas of an image. They all serve on internal port 80.

```bash
$ ./cluster/kubectl.sh create -f examples/update-demo/nautilus-rc.yaml
Expand Down
3 changes: 1 addition & 2 deletions examples/update-demo/kitten-rc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ desiredState:
- name: update-demo
image: kubernetes/update-demo:kitten
ports:
- hostPort: 8080
containerPort: 80
- containerPort: 80
protocol: TCP
labels:
name: update-demo
Expand Down
8 changes: 8 additions & 0 deletions examples/update-demo/local/angular.min.js.map

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions examples/update-demo/local/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
</head>
<body ng-controller="ButtonsCtrl">
<div ng-repeat="server in servers" class="pod">
<img src="http://{{server.ip}}:8080/{{server.image}}" height="100px" width="100px" />
<b>ID:</b> {{server.id}}<br>
<b>Host:</b> <a href="http://{{server.ip}}:8080/data.json">{{server.host}}</a><br>
<img src="http://localhost:8001/api/v1beta1/proxy/pods/{{server.podId}}/{{server.image}}" height="100px" width="100px" />
<b>ID:</b> {{server.podId}}<br>
<b>Host:</b> <a href="http://localhost:8001/api/v1beta1/proxy/pods/{{server.podId}}/data.json">{{server.host}}</a><br>
<b>Status:</b> {{server.status}}<br>
<b>Image:</b> {{server.dockerImage}}<br>
<b>Labels:</b>
Expand Down
16 changes: 7 additions & 9 deletions examples/update-demo/local/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,25 @@ limitations under the License.
var base = "http://localhost:8001/api/v1beta1/";

var updateImage = function($http, server) {
$http.get("http://" + server.ip + ":8080/data.json")
$http.get(base + "proxy/pods/" + server.podId + "/data.json")
.success(function(data) {
server.image = data.image;
console.log(data);
server.image = data.image;
})
.error(function(data) {
server.image = "";
console.log(data);
server.image = "";
});
};

var updateServer = function($http, server) {
$http.get(base + "pods/" + server.id)
$http.get(base + "pods/" + server.podId)
.success(function(data) {
console.log(data);
server.ip = data.currentState.hostIP;
server.labels = data.labels;
server.host = data.currentState.host.split('.')[0];
server.status = data.currentState.status;

server.dockerImage = data.currentState.info["update-demo"].Image;
server.dockerImage = data.currentState.info["update-demo"].image;
updateImage($http, server);
})
.error(function(data) {
Expand All @@ -62,7 +60,7 @@ var ButtonsCtrl = function ($scope, $http, $interval) {
var getServer = function($scope, id) {
var servers = $scope.servers;
for (var i = 0; i < servers.length; ++i) {
if (servers[i].id == id) {
if (servers[i].podId == id) {
return servers[i];
}
}
Expand All @@ -89,7 +87,7 @@ var update = function($scope, $http) {
}
var server = getServer($scope, pod.id);
if (server == null) {
server = { "id": pod.id };
server = { "podId": pod.id };
}
newServers.push(server);
}
Expand Down
3 changes: 1 addition & 2 deletions examples/update-demo/nautilus-rc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ desiredState:
- name: update-demo
image: kubernetes/update-demo:nautilus
ports:
- hostPort: 8080
containerPort: 80
- containerPort: 80
protocol: TCP
labels:
name: update-demo
Expand Down
9 changes: 6 additions & 3 deletions hack/e2e-suite/update.sh
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@ function validate() {
continue
fi


host_ip=$($KUBECTL get pods "$id" -o template --template='{{.currentState.hostIP}}')
curl -s --max-time 5 --fail http://${host_ip}:8080/data.json \
curl -s --max-time 5 --fail http://localhost:8011/api/v1beta1/proxy/pods/${id}/data.json \
| grep -q ${container_image_version} || {
echo " ${id} is running the right image but curl to contents failed or returned wrong info"
continue
Expand All @@ -124,10 +122,15 @@ function teardown() {
echo "Cleaning up test artifacts"
${KUBECTL} stop rc update-demo-kitten || true
${KUBECTL} stop rc update-demo-nautilus || true
kill -TERM "${kubectl_proxy_pid:-}" &> /dev/null || true
}

trap "teardown" EXIT

# Launch a local proxy to the apiserver
${KUBECTL} proxy --port=8011 &
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 8011? If we have to change the default, we need to update the README.md to match.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the e2e tests I used a non-default port for proxying. When I originally tried using the default port, I saw a bunch of "Failed to bind to port 8001" in the logs.

kubectl_proxy_pid=$!

# Launch a container
${KUBECTL} create -f "${KUBE_ROOT}/examples/update-demo/nautilus-rc.yaml"
validate 2 nautilus
Expand Down
68 changes: 43 additions & 25 deletions test/e2e/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,34 @@ const (
kittenImage = "kubernetes/update-demo:kitten"
updateDemoSelector = "name=update-demo"
updateDemoContainer = "update-demo"
kubectlProxyPort = 8011
)

var _ = Describe("kubectl", func() {

updateDemoRoot := filepath.Join(root, "examples/update-demo")
nautilusPath := filepath.Join(updateDemoRoot, "nautilus-rc.yaml")
kittenPath := filepath.Join(updateDemoRoot, "kitten-rc.yaml")
// Constants.
var (
updateDemoRoot = filepath.Join(root, "examples/update-demo")
nautilusPath = filepath.Join(updateDemoRoot, "nautilus-rc.yaml")
kittenPath = filepath.Join(updateDemoRoot, "kitten-rc.yaml")
)

var cmd *exec.Cmd

BeforeEach(func() {
cmd = kubectlCmd("proxy", fmt.Sprintf("--port=%d", kubectlProxyPort))
if err := cmd.Start(); err != nil {
Failf("Unable to start kubectl proxy: %v", err)
}
})

AfterEach(func() {
// Kill the proxy
if cmd.Process != nil {
Logf("Stopping kubectl proxy (pid %d)", cmd.Process.Pid)
cmd.Process.Kill()
}
})

It("should create and stop a replication controller", func() {
defer cleanup(nautilusPath)
Expand Down Expand Up @@ -106,8 +127,6 @@ func validateController(image string, replicas int, timeout time.Duration) {

getImageTemplate := fmt.Sprintf(`--template={{(index .currentState.info "%s").image}}`, updateDemoContainer)

getHostIPTemplate := "--template={{.currentState.hostIP}}"

By(fmt.Sprintf("waiting for all containers in %s pods to come up.", updateDemoSelector))
for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) {
getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector)
Expand All @@ -117,32 +136,31 @@ func validateController(image string, replicas int, timeout time.Duration) {
continue
}
var runningPods []string
for _, podId := range pods {
running := runKubectl("get", "pods", podId, "-o", "template", getContainerStateTemplate)
for _, podID := range pods {
running := runKubectl("get", "pods", podID, "-o", "template", getContainerStateTemplate)
if running == "false" {
By(fmt.Sprintf("%s is created but not running", podId))
Logf("%s is created but not running", podID)
continue
}

currentImage := runKubectl("get", "pods", podId, "-o", "template", getImageTemplate)
currentImage := runKubectl("get", "pods", podID, "-o", "template", getImageTemplate)
if currentImage != image {
By(fmt.Sprintf("%s is created but running wrong image; expected: %s, actual: %s", podId, image, currentImage))
Logf("%s is created but running wrong image; expected: %s, actual: %s", podID, image, currentImage)
continue
}

hostIP := runKubectl("get", "pods", podId, "-o", "template", getHostIPTemplate)
data, err := getData(hostIP)
data, err := getData(podID)
if err != nil {
By(fmt.Sprintf("%s is running right image but fetching data failed: %v", podId, err))
Logf("%s is running right image but fetching data failed: %v", podID, err)
continue
}
if strings.Contains(data.image, image) {
By(fmt.Sprintf("%s is running right image but fetched data has the wrong info: %s", podId, data))
Logf("%s is running right image but fetched data has the wrong info: %s", podID, data)
continue
}

Logf("%s is verified up and running", podId)
runningPods = append(runningPods, podId)
Logf("%s is verified up and running", podID)
runningPods = append(runningPods, podID)
}
if len(runningPods) == replicas {
return
Expand All @@ -155,9 +173,8 @@ type updateDemoData struct {
image string `json:"image"`
}

func getData(hostIP string) (*updateDemoData, error) {
addr := fmt.Sprintf("http://%s:8080/data.json", hostIP)
resp, err := http.Get(fmt.Sprintf(addr))
func getData(podID string) (*updateDemoData, error) {
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/api/v1beta1/proxy/pods/%s/data.json", kubectlProxyPort, podID))
if err != nil || resp.StatusCode != 200 {
return nil, err
}
Expand All @@ -172,16 +189,17 @@ func getData(hostIP string) (*updateDemoData, error) {
return &data, err
}

func runKubectl(args ...string) string {
func kubectlCmd(args ...string) *exec.Cmd {
// TODO: use kubectl binary directly instead of shell wrapper
path := filepath.Join(root, "cluster/kubectl.sh")
cmdStr := path + " " + strings.Join(args, " ")
Logf("Running '%v'", cmdStr)
Logf("Running '%v'", path+" "+strings.Join(args, " "))
return exec.Command(path, args...)
}

cmd := exec.Command(path, args...)
func runKubectl(args ...string) string {
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
cmd := kubectlCmd(args...)
cmd.Stdout, cmd.Stderr = &stdout, &stderr

if err := cmd.Run(); err != nil {
Failf("Error running %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr)
Expand Down