Remove host ports from the update demo and update tests

This commit is contained in:
Robert Bailey 2015-02-24 14:51:33 -08:00
parent fdf371dc96
commit dd87c247a5
9 changed files with 74 additions and 56 deletions

View File

@ -803,6 +803,7 @@ function test-setup {
detect-project detect-project
# Open up port 80 & 8080 so common containers on minions can be reached # 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 \ gcloud compute firewall-rules create \
--project "${PROJECT}" \ --project "${PROJECT}" \
--target-tags "${MINION_TAG}" \ --target-tags "${MINION_TAG}" \

View File

@ -26,28 +26,20 @@ $ cd kubernetes
$ hack/dev-build-and-up.sh $ 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 ### 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=examples/update-demo/local/ &
+ ./cluster/kubectl.sh proxy --www=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 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. Now visit the the [demo website](http://localhost:8001/static). You won't see anything much quite yet.
### Step Two: Run the controller ### 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 ```bash
$ ./cluster/kubectl.sh create -f examples/update-demo/nautilus-rc.yaml $ ./cluster/kubectl.sh create -f examples/update-demo/nautilus-rc.yaml

View File

@ -12,8 +12,7 @@ desiredState:
- name: update-demo - name: update-demo
image: kubernetes/update-demo:kitten image: kubernetes/update-demo:kitten
ports: ports:
- hostPort: 8080 - containerPort: 80
containerPort: 80
protocol: TCP protocol: TCP
labels: labels:
name: update-demo name: update-demo

File diff suppressed because one or more lines are too long

View File

@ -22,9 +22,9 @@ limitations under the License.
</head> </head>
<body ng-controller="ButtonsCtrl"> <body ng-controller="ButtonsCtrl">
<div ng-repeat="server in servers" class="pod"> <div ng-repeat="server in servers" class="pod">
<img src="http://{{server.ip}}:8080/{{server.image}}" height="100px" width="100px" /> <img src="http://localhost:8001/api/v1beta1/proxy/pods/{{server.podId}}/{{server.image}}" height="100px" width="100px" />
<b>ID:</b> {{server.id}}<br> <b>ID:</b> {{server.podId}}<br>
<b>Host:</b> <a href="http://{{server.ip}}:8080/data.json">{{server.host}}</a><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>Status:</b> {{server.status}}<br>
<b>Image:</b> {{server.dockerImage}}<br> <b>Image:</b> {{server.dockerImage}}<br>
<b>Labels:</b> <b>Labels:</b>

View File

@ -17,27 +17,25 @@ limitations under the License.
var base = "http://localhost:8001/api/v1beta1/"; var base = "http://localhost:8001/api/v1beta1/";
var updateImage = function($http, server) { 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) { .success(function(data) {
server.image = data.image;
console.log(data); console.log(data);
server.image = data.image;
}) })
.error(function(data) { .error(function(data) {
server.image = "";
console.log(data); console.log(data);
server.image = "";
}); });
}; };
var updateServer = function($http, server) { var updateServer = function($http, server) {
$http.get(base + "pods/" + server.id) $http.get(base + "pods/" + server.podId)
.success(function(data) { .success(function(data) {
console.log(data); console.log(data);
server.ip = data.currentState.hostIP;
server.labels = data.labels; server.labels = data.labels;
server.host = data.currentState.host.split('.')[0]; server.host = data.currentState.host.split('.')[0];
server.status = data.currentState.status; server.status = data.currentState.status;
server.dockerImage = data.currentState.info["update-demo"].image;
server.dockerImage = data.currentState.info["update-demo"].Image;
updateImage($http, server); updateImage($http, server);
}) })
.error(function(data) { .error(function(data) {
@ -62,7 +60,7 @@ var ButtonsCtrl = function ($scope, $http, $interval) {
var getServer = function($scope, id) { var getServer = function($scope, id) {
var servers = $scope.servers; var servers = $scope.servers;
for (var i = 0; i < servers.length; ++i) { for (var i = 0; i < servers.length; ++i) {
if (servers[i].id == id) { if (servers[i].podId == id) {
return servers[i]; return servers[i];
} }
} }
@ -89,7 +87,7 @@ var update = function($scope, $http) {
} }
var server = getServer($scope, pod.id); var server = getServer($scope, pod.id);
if (server == null) { if (server == null) {
server = { "id": pod.id }; server = { "podId": pod.id };
} }
newServers.push(server); newServers.push(server);
} }

View File

@ -13,8 +13,7 @@ desiredState:
- name: update-demo - name: update-demo
image: kubernetes/update-demo:nautilus image: kubernetes/update-demo:nautilus
ports: ports:
- hostPort: 8080 - containerPort: 80
containerPort: 80
protocol: TCP protocol: TCP
labels: labels:
name: update-demo name: update-demo

View File

@ -103,9 +103,7 @@ function validate() {
continue continue
fi fi
curl -s --max-time 5 --fail http://localhost:8011/api/v1beta1/proxy/pods/${id}/data.json \
host_ip=$($KUBECTL get pods "$id" -o template --template='{{.currentState.hostIP}}')
curl -s --max-time 5 --fail http://${host_ip}:8080/data.json \
| grep -q ${container_image_version} || { | grep -q ${container_image_version} || {
echo " ${id} is running the right image but curl to contents failed or returned wrong info" echo " ${id} is running the right image but curl to contents failed or returned wrong info"
continue continue
@ -124,10 +122,15 @@ function teardown() {
echo "Cleaning up test artifacts" echo "Cleaning up test artifacts"
${KUBECTL} stop rc update-demo-kitten || true ${KUBECTL} stop rc update-demo-kitten || true
${KUBECTL} stop rc update-demo-nautilus || true ${KUBECTL} stop rc update-demo-nautilus || true
kill -TERM "${kubectl_proxy_pid:-}" &> /dev/null || true
} }
trap "teardown" EXIT trap "teardown" EXIT
# Launch a local proxy to the apiserver
${KUBECTL} proxy --port=8011 &
kubectl_proxy_pid=$!
# Launch a container # Launch a container
${KUBECTL} create -f "${KUBE_ROOT}/examples/update-demo/nautilus-rc.yaml" ${KUBECTL} create -f "${KUBE_ROOT}/examples/update-demo/nautilus-rc.yaml"
validate 2 nautilus validate 2 nautilus

View File

@ -35,13 +35,34 @@ const (
kittenImage = "kubernetes/update-demo:kitten" kittenImage = "kubernetes/update-demo:kitten"
updateDemoSelector = "name=update-demo" updateDemoSelector = "name=update-demo"
updateDemoContainer = "update-demo" updateDemoContainer = "update-demo"
kubectlProxyPort = 8011
) )
var _ = Describe("kubectl", func() { var _ = Describe("kubectl", func() {
updateDemoRoot := filepath.Join(root, "examples/update-demo") // Constants.
nautilusPath := filepath.Join(updateDemoRoot, "nautilus-rc.yaml") var (
kittenPath := filepath.Join(updateDemoRoot, "kitten-rc.yaml") 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() { It("should create and stop a replication controller", func() {
defer cleanup(nautilusPath) defer cleanup(nautilusPath)
@ -106,8 +127,6 @@ func validateController(image string, replicas int, timeout time.Duration) {
getImageTemplate := fmt.Sprintf(`--template={{(index .currentState.info "%s").image}}`, updateDemoContainer) 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)) 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) { for start := time.Now(); time.Since(start) < timeout; time.Sleep(5 * time.Second) {
getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector) getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector)
@ -117,32 +136,31 @@ func validateController(image string, replicas int, timeout time.Duration) {
continue continue
} }
var runningPods []string var runningPods []string
for _, podId := range pods { for _, podID := range pods {
running := runKubectl("get", "pods", podId, "-o", "template", getContainerStateTemplate) running := runKubectl("get", "pods", podID, "-o", "template", getContainerStateTemplate)
if running == "false" { if running == "false" {
By(fmt.Sprintf("%s is created but not running", podId)) Logf("%s is created but not running", podID)
continue continue
} }
currentImage := runKubectl("get", "pods", podId, "-o", "template", getImageTemplate) currentImage := runKubectl("get", "pods", podID, "-o", "template", getImageTemplate)
if currentImage != image { 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 continue
} }
hostIP := runKubectl("get", "pods", podId, "-o", "template", getHostIPTemplate) data, err := getData(podID)
data, err := getData(hostIP)
if err != nil { 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 continue
} }
if strings.Contains(data.image, image) { 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 continue
} }
Logf("%s is verified up and running", podId) Logf("%s is verified up and running", podID)
runningPods = append(runningPods, podId) runningPods = append(runningPods, podID)
} }
if len(runningPods) == replicas { if len(runningPods) == replicas {
return return
@ -155,9 +173,8 @@ type updateDemoData struct {
image string `json:"image"` image string `json:"image"`
} }
func getData(hostIP string) (*updateDemoData, error) { func getData(podID string) (*updateDemoData, error) {
addr := fmt.Sprintf("http://%s:8080/data.json", hostIP) resp, err := http.Get(fmt.Sprintf("http://localhost:%d/api/v1beta1/proxy/pods/%s/data.json", kubectlProxyPort, podID))
resp, err := http.Get(fmt.Sprintf(addr))
if err != nil || resp.StatusCode != 200 { if err != nil || resp.StatusCode != 200 {
return nil, err return nil, err
} }
@ -172,16 +189,17 @@ func getData(hostIP string) (*updateDemoData, error) {
return &data, err return &data, err
} }
func runKubectl(args ...string) string { func kubectlCmd(args ...string) *exec.Cmd {
// TODO: use kubectl binary directly instead of shell wrapper // TODO: use kubectl binary directly instead of shell wrapper
path := filepath.Join(root, "cluster/kubectl.sh") path := filepath.Join(root, "cluster/kubectl.sh")
cmdStr := path + " " + strings.Join(args, " ") Logf("Running '%v'", path+" "+strings.Join(args, " "))
Logf("Running '%v'", cmdStr) return exec.Command(path, args...)
}
cmd := exec.Command(path, args...) func runKubectl(args ...string) string {
var stdout, stderr bytes.Buffer var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout cmd := kubectlCmd(args...)
cmd.Stderr = &stderr cmd.Stdout, cmd.Stderr = &stdout, &stderr
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
Failf("Error running %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr) Failf("Error running %v:\nCommand stdout:\n%v\nstderr:\n%v\n", cmd, cmd.Stdout, cmd.Stderr)