mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-02 08:17:26 +00:00
Merge pull request #9092 from lavalamp/no-ro-nonbreaking
Nonbreaking changes working towards removing the RO port
This commit is contained in:
commit
6e3ff01fa7
@ -37,7 +37,6 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
@ -202,20 +201,11 @@ func main() {
|
|||||||
// Find all sibling pods in the service and post to their /write handler.
|
// Find all sibling pods in the service and post to their /write handler.
|
||||||
func contactOthers(state *State) {
|
func contactOthers(state *State) {
|
||||||
defer state.doneContactingPeers()
|
defer state.doneContactingPeers()
|
||||||
token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
|
client, err := client.NewInCluster()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Unable to read service account token: %v", err)
|
log.Fatalf("Unable to create client; error: %v\n", err)
|
||||||
}
|
|
||||||
cc := client.Config{
|
|
||||||
Host: "https://" + net.JoinHostPort(os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")),
|
|
||||||
Version: "v1beta3",
|
|
||||||
BearerToken: string(token),
|
|
||||||
Insecure: true, // TOOD: package certs along with the token
|
|
||||||
}
|
|
||||||
client, err := client.New(&cc)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Unable to create client:\nconfig: %#v\nerror: %v\n", err)
|
|
||||||
}
|
}
|
||||||
|
// Double check that that worked by getting the server version.
|
||||||
if v, err := client.ServerVersion(); err != nil {
|
if v, err := client.ServerVersion(); err != nil {
|
||||||
log.Fatalf("Unable to get server version: %v\n", err)
|
log.Fatalf("Unable to get server version: %v\n", err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,9 +29,7 @@
|
|||||||
"volumes": [
|
"volumes": [
|
||||||
{
|
{
|
||||||
"name": "test-volume",
|
"name": "test-volume",
|
||||||
"VolumeSorce": {
|
"emptyDir": {}
|
||||||
"EmptyDir": {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -166,6 +167,34 @@ func NewOrDie(c *Config) *Client {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InClusterConfig returns a config object which uses the service account
|
||||||
|
// kubernetes gives to pods. It's intended for clients that expect to be
|
||||||
|
// running inside a pod running on kuberenetes. It will return an error if
|
||||||
|
// called from a process not running in a kubernetes environment.
|
||||||
|
func InClusterConfig() (*Config, error) {
|
||||||
|
token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Config{
|
||||||
|
// TODO: switch to using cluster DNS.
|
||||||
|
Host: "https://" + net.JoinHostPort(os.Getenv("KUBERNETES_SERVICE_HOST"), os.Getenv("KUBERNETES_SERVICE_PORT")),
|
||||||
|
Version: "v1beta3",
|
||||||
|
BearerToken: string(token),
|
||||||
|
// TODO: package certs along with the token
|
||||||
|
Insecure: true,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewInCluster is a shortcut for calling InClusterConfig() and then New().
|
||||||
|
func NewInCluster() (*Client, error) {
|
||||||
|
cc, err := InClusterConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return New(cc)
|
||||||
|
}
|
||||||
|
|
||||||
// SetKubernetesDefaults sets default values on the provided client config for accessing the
|
// SetKubernetesDefaults sets default values on the provided client config for accessing the
|
||||||
// Kubernetes API or returns an error if any of the defaults are impossible or invalid.
|
// Kubernetes API or returns an error if any of the defaults are impossible or invalid.
|
||||||
func SetKubernetesDefaults(config *Config) error {
|
func SetKubernetesDefaults(config *Config) error {
|
||||||
|
@ -60,10 +60,10 @@ var _ = Describe("DNS", func() {
|
|||||||
// All the names we need to be able to resolve.
|
// All the names we need to be able to resolve.
|
||||||
// TODO: Spin up a separate test service and test that dns works for that service.
|
// TODO: Spin up a separate test service and test that dns works for that service.
|
||||||
namesToResolve := []string{
|
namesToResolve := []string{
|
||||||
"kubernetes-ro.default",
|
"kubernetes.default",
|
||||||
"kubernetes-ro.default.svc",
|
"kubernetes.default.svc",
|
||||||
"kubernetes-ro.default.svc.cluster.local",
|
"kubernetes.default.svc.cluster.local",
|
||||||
"kubernetes-ro.default.cluster.local",
|
"kubernetes.default.cluster.local",
|
||||||
"google.com",
|
"google.com",
|
||||||
}
|
}
|
||||||
// Added due to #8512. This is critical for GCE and GKE deployments.
|
// Added due to #8512. This is critical for GCE and GKE deployments.
|
||||||
|
@ -31,8 +31,8 @@ import (
|
|||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = Describe("New networking", func() {
|
var _ = Describe("Networking", func() {
|
||||||
f := NewFramework("nettestnew")
|
f := NewFramework("nettest")
|
||||||
|
|
||||||
var svcname = "nettest"
|
var svcname = "nettest"
|
||||||
|
|
||||||
@ -243,176 +243,3 @@ func LaunchNetTestPodPerNode(f *Framework, nodes *api.NodeList, name, version st
|
|||||||
}
|
}
|
||||||
return podNames
|
return podNames
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = Describe("Old networking", func() {
|
|
||||||
f := NewFramework("nettest")
|
|
||||||
|
|
||||||
var svcname = "nettest"
|
|
||||||
|
|
||||||
BeforeEach(func() {
|
|
||||||
//Assert basic external connectivity.
|
|
||||||
//Since this is not really a test of kubernetes in any way, we
|
|
||||||
//leave it as a pre-test assertion, rather than a Ginko test.
|
|
||||||
By("Executing a successful http request from the external internet")
|
|
||||||
resp, err := http.Get("http://google.com")
|
|
||||||
if err != nil {
|
|
||||||
Failf("Unable to connect/talk to the internet: %v", err)
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
Failf("Unexpected error code, expected 200, got, %v (%v)", resp.StatusCode, resp)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// First test because it has no dependencies on variables created later on.
|
|
||||||
It("should provide unchanging, static URL paths for kubernetes api services.", func() {
|
|
||||||
tests := []struct {
|
|
||||||
path string
|
|
||||||
}{
|
|
||||||
{path: "/validate"},
|
|
||||||
{path: "/healthz"},
|
|
||||||
// TODO: test proxy links here
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
By(fmt.Sprintf("testing: %s", test.path))
|
|
||||||
data, err := f.Client.RESTClient.Get().
|
|
||||||
Namespace(f.Namespace.Name).
|
|
||||||
AbsPath(test.path).
|
|
||||||
DoRaw()
|
|
||||||
if err != nil {
|
|
||||||
Failf("Failed: %v\nBody: %s", err, string(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
//Now we can proceed with the test.
|
|
||||||
It("should function for intra-pod communication", func() {
|
|
||||||
if testContext.Provider == "vagrant" {
|
|
||||||
By("Skipping test which is broken for vagrant (See https://github.com/GoogleCloudPlatform/kubernetes/issues/3580)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
By(fmt.Sprintf("Creating a service named %q in namespace %q", svcname, f.Namespace.Name))
|
|
||||||
svc, err := f.Client.Services(f.Namespace.Name).Create(&api.Service{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: svcname,
|
|
||||||
Labels: map[string]string{
|
|
||||||
"name": svcname,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Spec: api.ServiceSpec{
|
|
||||||
Ports: []api.ServicePort{{
|
|
||||||
Protocol: "TCP",
|
|
||||||
Port: 8080,
|
|
||||||
TargetPort: util.NewIntOrStringFromInt(8080),
|
|
||||||
}},
|
|
||||||
Selector: map[string]string{
|
|
||||||
"name": svcname,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
Failf("unable to create test service named [%s] %v", svc.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up service
|
|
||||||
defer func() {
|
|
||||||
defer GinkgoRecover()
|
|
||||||
By("Cleaning up the service")
|
|
||||||
if err = f.Client.Services(f.Namespace.Name).Delete(svc.Name); err != nil {
|
|
||||||
Failf("unable to delete svc %v: %v", svc.Name, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
By("Creating a webserver (pending) pod on each node")
|
|
||||||
|
|
||||||
nodes, err := f.Client.Nodes().List(labels.Everything(), fields.Everything())
|
|
||||||
if err != nil {
|
|
||||||
Failf("Failed to list nodes: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
podNames := LaunchNetTestPodPerNode(f, nodes, svcname, "1.3")
|
|
||||||
|
|
||||||
// Clean up the pods
|
|
||||||
defer func() {
|
|
||||||
defer GinkgoRecover()
|
|
||||||
By("Cleaning up the webserver pods")
|
|
||||||
for _, podName := range podNames {
|
|
||||||
if err = f.Client.Pods(f.Namespace.Name).Delete(podName, nil); err != nil {
|
|
||||||
Logf("Failed to delete pod %s: %v", podName, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
By("Waiting for the webserver pods to transition to Running state")
|
|
||||||
for _, podName := range podNames {
|
|
||||||
err = f.WaitForPodRunning(podName)
|
|
||||||
Expect(err).NotTo(HaveOccurred())
|
|
||||||
}
|
|
||||||
|
|
||||||
By("Waiting for connectivity to be verified")
|
|
||||||
passed := false
|
|
||||||
|
|
||||||
//once response OK, evaluate response body for pass/fail.
|
|
||||||
var body []byte
|
|
||||||
getDetails := func() ([]byte, error) {
|
|
||||||
return f.Client.Get().
|
|
||||||
Namespace(f.Namespace.Name).
|
|
||||||
Prefix("proxy").
|
|
||||||
Resource("services").
|
|
||||||
Name(svc.Name).
|
|
||||||
Suffix("read").
|
|
||||||
DoRaw()
|
|
||||||
}
|
|
||||||
|
|
||||||
getStatus := func() ([]byte, error) {
|
|
||||||
return f.Client.Get().
|
|
||||||
Namespace(f.Namespace.Name).
|
|
||||||
Prefix("proxy").
|
|
||||||
Resource("services").
|
|
||||||
Name(svc.Name).
|
|
||||||
Suffix("status").
|
|
||||||
DoRaw()
|
|
||||||
}
|
|
||||||
|
|
||||||
timeout := time.Now().Add(2 * time.Minute)
|
|
||||||
for i := 0; !passed && timeout.After(time.Now()); i++ {
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
Logf("About to make a proxy status call")
|
|
||||||
start := time.Now()
|
|
||||||
body, err = getStatus()
|
|
||||||
Logf("Proxy status call returned in %v", time.Since(start))
|
|
||||||
if err != nil {
|
|
||||||
Logf("Attempt %v: service/pod still starting. (error: '%v')", i, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Finally, we pass/fail the test based on if the container's response body, as to wether or not it was able to find peers.
|
|
||||||
switch {
|
|
||||||
case string(body) == "pass":
|
|
||||||
Logf("Passed on attempt %v. Cleaning up.", i)
|
|
||||||
passed = true
|
|
||||||
case string(body) == "running":
|
|
||||||
Logf("Attempt %v: test still running", i)
|
|
||||||
case string(body) == "fail":
|
|
||||||
if body, err = getDetails(); err != nil {
|
|
||||||
Failf("Failed on attempt %v. Cleaning up. Error reading details: %v", i, err)
|
|
||||||
} else {
|
|
||||||
Failf("Failed on attempt %v. Cleaning up. Details:\n%s", i, string(body))
|
|
||||||
}
|
|
||||||
case strings.Contains(string(body), "no endpoints available"):
|
|
||||||
Logf("Attempt %v: waiting on service/endpoints", i)
|
|
||||||
default:
|
|
||||||
Logf("Unexpected response:\n%s", body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !passed {
|
|
||||||
if body, err = getDetails(); err != nil {
|
|
||||||
Failf("Timed out. Cleaning up. Error reading details: %v", err)
|
|
||||||
} else {
|
|
||||||
Failf("Timed out. Cleaning up. Details:\n%s", string(body))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Expect(string(body)).To(Equal("pass"))
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
@ -67,26 +67,9 @@ var _ = Describe("Services", func() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
// TODO: We get coverage of TCP/UDP and multi-port services through the DNS test. We should have a simpler test for multi-port TCP here.
|
// TODO: We get coverage of TCP/UDP and multi-port services through the DNS test. We should have a simpler test for multi-port TCP here.
|
||||||
It("should provide RW and RO services", func() {
|
It("should provide secure master service", func() {
|
||||||
svc := api.ServiceList{}
|
_, err := c.Services(api.NamespaceDefault).Get("kubernetes")
|
||||||
err := c.Get().
|
Expect(err).NotTo(HaveOccurred())
|
||||||
AbsPath("/api/v1beta3/proxy/namespaces/default/services/kubernetes-ro/api/v1beta3/services").
|
|
||||||
Do().
|
|
||||||
Into(&svc)
|
|
||||||
if err != nil {
|
|
||||||
Failf("unexpected error listing services using ro service: %v", err)
|
|
||||||
}
|
|
||||||
var foundRW, foundRO bool
|
|
||||||
for i := range svc.Items {
|
|
||||||
if svc.Items[i].Name == "kubernetes" {
|
|
||||||
foundRW = true
|
|
||||||
}
|
|
||||||
if svc.Items[i].Name == "kubernetes-ro" {
|
|
||||||
foundRO = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Expect(foundRW).To(Equal(true))
|
|
||||||
Expect(foundRO).To(Equal(true))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
It("should serve a basic endpoint from pods", func(done Done) {
|
It("should serve a basic endpoint from pods", func(done Done) {
|
||||||
|
Loading…
Reference in New Issue
Block a user