mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #4963 from roberthbailey/kubectl-proxy
Remove host ports from the update demo and update tests (take 2).
This commit is contained in:
commit
66dfbe900a
@ -804,6 +804,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}" \
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
8
examples/update-demo/local/angular.min.js.map
Normal file
8
examples/update-demo/local/angular.min.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -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>
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -36,13 +37,50 @@ const (
|
|||||||
updateDemoSelector = "name=update-demo"
|
updateDemoSelector = "name=update-demo"
|
||||||
updateDemoContainer = "update-demo"
|
updateDemoContainer = "update-demo"
|
||||||
validateTimeout = 60 * time.Second
|
validateTimeout = 60 * time.Second
|
||||||
|
kubectlProxyPort = 8011
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("kubectl", func() {
|
var _ = Describe("kubectl", func() {
|
||||||
|
|
||||||
updateDemoRoot := filepath.Join(testContext.repoRoot, "examples/update-demo")
|
// Constants.
|
||||||
nautilusPath := filepath.Join(updateDemoRoot, "nautilus-rc.yaml")
|
var (
|
||||||
kittenPath := filepath.Join(updateDemoRoot, "kitten-rc.yaml")
|
updateDemoRoot = filepath.Join(testContext.repoRoot, "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() {
|
||||||
|
if cmd.Process == nil {
|
||||||
|
Logf("No process associated with the kubectl proxy")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Kill the proxy
|
||||||
|
errChan := make(chan error, 1)
|
||||||
|
go func() {
|
||||||
|
if err := cmd.Process.Signal(os.Interrupt); err != nil {
|
||||||
|
errChan <- err
|
||||||
|
}
|
||||||
|
_, err := cmd.Process.Wait()
|
||||||
|
errChan <- err
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-time.After(10 * time.Second):
|
||||||
|
Fail("Timed out waiting for kubectl proxy process to exit")
|
||||||
|
case err := <-errChan:
|
||||||
|
if err != nil {
|
||||||
|
Failf("Unable to kill kubectl proxy: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
It("should create and stop a replication controller", func() {
|
It("should create and stop a replication controller", func() {
|
||||||
defer cleanup(nautilusPath)
|
defer cleanup(nautilusPath)
|
||||||
@ -107,8 +145,6 @@ func validateController(image string, replicas int) {
|
|||||||
|
|
||||||
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) < validateTimeout; time.Sleep(5 * time.Second) {
|
for start := time.Now(); time.Since(start) < validateTimeout; time.Sleep(5 * time.Second) {
|
||||||
getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector)
|
getPodsOutput := runKubectl("get", "pods", "-o", "template", getPodsTemplate, "-l", updateDemoSelector)
|
||||||
@ -118,32 +154,31 @@ func validateController(image string, replicas int) {
|
|||||||
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
|
||||||
@ -156,9 +191,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
|
||||||
}
|
}
|
||||||
@ -173,7 +207,7 @@ func getData(hostIP string) (*updateDemoData, error) {
|
|||||||
return &data, err
|
return &data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func runKubectl(args ...string) string {
|
func kubectlCmd(args ...string) *exec.Cmd {
|
||||||
defaultArgs := []string{"--auth-path=" + testContext.authConfig}
|
defaultArgs := []string{"--auth-path=" + testContext.authConfig}
|
||||||
if testContext.certDir != "" {
|
if testContext.certDir != "" {
|
||||||
defaultArgs = append(defaultArgs,
|
defaultArgs = append(defaultArgs,
|
||||||
@ -186,9 +220,14 @@ func runKubectl(args ...string) string {
|
|||||||
if testContext.provider == "gke" {
|
if testContext.provider == "gke" {
|
||||||
kubectlArgs = append(kubectlArgs, "--server="+testContext.host)
|
kubectlArgs = append(kubectlArgs, "--server="+testContext.host)
|
||||||
}
|
}
|
||||||
Logf("Running 'kubectl %v'", strings.Join(kubectlArgs, " "))
|
|
||||||
cmd := exec.Command("kubectl", kubectlArgs...)
|
cmd := exec.Command("kubectl", kubectlArgs...)
|
||||||
|
Logf("Running '%s %s'", cmd.Path, strings.Join(cmd.Args, " "))
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func runKubectl(args ...string) string {
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd := kubectlCmd(args...)
|
||||||
cmd.Stdout, cmd.Stderr = &stdout, &stderr
|
cmd.Stdout, cmd.Stderr = &stdout, &stderr
|
||||||
|
|
||||||
if err := cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user