From e0c9da5d959336bc43127433c7ad712e83d8bd57 Mon Sep 17 00:00:00 2001 From: Rita Zhang Date: Mon, 11 Dec 2017 20:25:54 -0800 Subject: [PATCH] Enable kubectl logs po --- providers/azure/aci.go | 50 +++++++++++++++++++++++++++++++++++- providers/hypersh/hypersh.go | 11 ++++++++ vkubelet/apiserver.go | 50 ++++++++++++++++++++++++++++++++++++ vkubelet/provider.go | 9 ++++++- vkubelet/vkubelet.go | 6 ++++- 5 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 vkubelet/apiserver.go diff --git a/providers/azure/aci.go b/providers/azure/aci.go index 76c3038a3..ef2301419 100644 --- a/providers/azure/aci.go +++ b/providers/azure/aci.go @@ -31,6 +31,7 @@ type ACIProvider struct { cpu string memory string pods string + internalIP string } // AuthConfig is the secret returned from an ImageRegistryCredential @@ -45,7 +46,7 @@ type AuthConfig struct { } // NewACIProvider creates a new ACIProvider. -func NewACIProvider(config string, rm *manager.ResourceManager, nodeName, operatingSystem string) (*ACIProvider, error) { +func NewACIProvider(config string, rm *manager.ResourceManager, nodeName, operatingSystem string, internalIP string) (*ACIProvider, error) { var p ACIProvider var err error @@ -89,6 +90,7 @@ func NewACIProvider(config string, rm *manager.ResourceManager, nodeName, operat p.operatingSystem = operatingSystem p.nodeName = nodeName + p.internalIP = internalIP return &p, err } @@ -193,6 +195,40 @@ func (p *ACIProvider) GetPod(namespace, name string) (*v1.Pod, error) { return containerGroupToPod(cg) } +// GetPodLogs returns the logs of a pod by name that is running inside ACI. +func (p *ACIProvider) GetPodLogs(namespace, name string) (string, error) { + logContent := "" + cg, err := p.aciClient.GetContainerGroup(p.resourceGroup, name) + if err != nil { + // Trap error for 404 and return gracefully + if strings.Contains(err.Error(), "ResourceNotFound") { + return logContent, nil + } + return logContent, err + } + + if cg.Tags["NodeName"] != p.nodeName { + return logContent, nil + } + // get logs from cg + retry := 10 + for i := 0; i < retry; i++ { + cLogs, err := p.aciClient.GetContainerLogs(p.resourceGroup, cg.Name, name, 10) + + if err != nil { + log.Println(err) + time.Sleep(5000 * time.Millisecond) + } else { + break + logContent = cLogs.Content + return logContent, nil + } + } + // create pod logs + + return logContent, err +} + // GetPodStatus returns the status of a pod by name that is running inside ACI // returns nil if a pod by that name is not found. func (p *ACIProvider) GetPodStatus(namespace, name string) (*v1.PodStatus, error) { @@ -290,6 +326,18 @@ func (p *ACIProvider) NodeConditions() []v1.NodeCondition { } } +// NodeAddresses returns a list of addresses for the node status +// within Kuberentes. +func (p *ACIProvider) NodeAddresses() []v1.NodeAddress { + // TODO: Make these dynamic and augment with custom ACI specific conditions of interest + return []v1.NodeAddress{ + { + Type: "InternalIP", + Address: p.internalIP, + }, + } +} + // OperatingSystem returns the operating system that was provided by the config. func (p *ACIProvider) OperatingSystem() string { return p.operatingSystem diff --git a/providers/hypersh/hypersh.go b/providers/hypersh/hypersh.go index 838da8732..8734c4249 100644 --- a/providers/hypersh/hypersh.go +++ b/providers/hypersh/hypersh.go @@ -139,6 +139,11 @@ func (p *HyperProvider) GetPod(namespace, name string) (*v1.Pod, error) { return nil, nil } +// GetPodLogs returns the logs of a pod by name. +func (p *HyperProvider) GetPodLogs(namespace, name string) (string, error) { + return "", nil +} + // GetPodStatus returns the status of a pod by name that is running inside hyper.sh // returns nil if a pod by that name is not found. func (p *HyperProvider) GetPodStatus(namespace, name string) (*v1.PodStatus, error) { @@ -224,6 +229,12 @@ func (p *HyperProvider) NodeConditions() []v1.NodeCondition { } +// NodeAddresses returns a list of addresses for the node status +// within Kuberentes. +func (p *HyperProvider) NodeAddresses() []v1.NodeAddress { + return nil +} + // OperatingSystem returns the operating system for this provider. // This is a noop to default to Linux for now. func (p *HyperProvider) OperatingSystem() string { diff --git a/vkubelet/apiserver.go b/vkubelet/apiserver.go new file mode 100644 index 000000000..65037d80d --- /dev/null +++ b/vkubelet/apiserver.go @@ -0,0 +1,50 @@ +package vkubelet + +import ( + "encoding/base64" + "io/ioutil" + "io" + "log" + "net/http" + "os" + //"k8s.io/api/core/v1" +) + +func ApiServerStart() error { + http.HandleFunc("/", HelloServer) + certValue64 := os.Getenv("APISERVER_CERT") + keyValue64 := os.Getenv("APISERVER_KEY") + certValue, err := base64.StdEncoding.DecodeString(certValue64) + if err != nil { + log.Fatal(err) + } + keyValue, err := base64.StdEncoding.DecodeString(keyValue64) + if err != nil { + log.Fatal(err) + } + cert := []byte(certValue) + key := []byte(keyValue) + certFilePath := "cert.pem" + keyFilePath := "key.pem" + err = ioutil.WriteFile(certFilePath, cert, 0644) + if err != nil { + log.Fatal(err) + } + err = ioutil.WriteFile(keyFilePath, key, 0644) + if err != nil { + log.Fatal(err) + } + + err = http.ListenAndServeTLS(":10250", certFilePath, keyFilePath, nil) + if err != nil { + log.Fatal(err) + } + return nil +} + +func HelloServer(w http.ResponseWriter, req *http.Request) { + log.Println("handler called") + ///containerLogs/{namespace}/{pd}/{container} + log.Println(req) + io.WriteString(w, "ack!\n") +} \ No newline at end of file diff --git a/vkubelet/provider.go b/vkubelet/provider.go index cfb3bf642..d9885b33e 100644 --- a/vkubelet/provider.go +++ b/vkubelet/provider.go @@ -24,7 +24,10 @@ type Provider interface { // GetPod retrieves a pod by name from the provider (can be cached). GetPod(namespace, name string) (*v1.Pod, error) - // GetPodStatus retrievesthe status of a pod by name from the provider. + // GetPodLogs retrieves the logs of a pod by name from the provider. + GetPodLogs(namespace, name string) (string, error) + + // GetPodStatus retrieves the status of a pod by name from the provider. GetPodStatus(namespace, name string) (*v1.PodStatus, error) // GetPods retrieves a list of all pods running on the provider (can be cached). @@ -37,6 +40,10 @@ type Provider interface { // within Kuberentes. NodeConditions() []v1.NodeCondition + // NodeAddresses returns a list of addresses for the node status + // within Kuberentes. + NodeAddresses() []v1.NodeAddress + // OperatingSystem returns the operating system the provider is for. OperatingSystem() string } diff --git a/vkubelet/vkubelet.go b/vkubelet/vkubelet.go index 2c8579cbe..94c2a4905 100644 --- a/vkubelet/vkubelet.go +++ b/vkubelet/vkubelet.go @@ -60,11 +60,14 @@ func New(nodeName, operatingSystem, namespace, kubeConfig, taint, provider, prov } rm := manager.NewResourceManager(clientset) + go ApiServerStart() + log.Println("vkubelet apiserver started") var p Provider switch provider { case "azure": - p, err = azure.NewACIProvider(providerConfig, rm, nodeName, operatingSystem) + internalIP := os.Getenv("VKUBELET_POD_IP") + p, err = azure.NewACIProvider(providerConfig, rm, nodeName, operatingSystem, internalIP) if err != nil { return nil, err } @@ -136,6 +139,7 @@ func (s *Server) registerNode() error { Capacity: s.provider.Capacity(), Allocatable: s.provider.Capacity(), Conditions: s.provider.NodeConditions(), + Addresses: s.provider.NodeAddresses(), }, }