Skip to content

Commit

Permalink
Add cluster_name to proxy kubernetes config
Browse files Browse the repository at this point in the history
Cluster name from this field plug all clusters from kubeconfig are
stored on the auth server via heartbeats.
This info will later be used to route k8s requests back to proxies.

Updates #3952
  • Loading branch information
Andrew Lytvynov committed Sep 21, 2020
1 parent 8d1903d commit c3535e3
Show file tree
Hide file tree
Showing 9 changed files with 495 additions and 358 deletions.
3 changes: 3 additions & 0 deletions lib/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ func applyProxyConfig(fc *FileConfig, cfg *service.Config) error {
if fc.Proxy.Kube.KubeconfigFile != "" {
cfg.Proxy.Kube.KubeconfigPath = fc.Proxy.Kube.KubeconfigFile
}
if fc.Proxy.Kube.ClusterName != "" {
cfg.Proxy.Kube.ClusterName = fc.Proxy.Kube.ClusterName
}
if fc.Proxy.Kube.ListenAddress != "" {
addr, err := utils.ParseHostPortAddr(fc.Proxy.Kube.ListenAddress, int(defaults.KubeProxyListenPort))
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions lib/config/fileconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -829,6 +829,9 @@ type Kube struct {
// if specified, teleport will use API server address and
// trusted certificate authority information from it
KubeconfigFile string `yaml:"kubeconfig_file,omitempty"`
// ClusterName is the name of a kubernetes cluster this proxy is running
// in. If set, this proxy will handle kubernetes requests for the cluster.
ClusterName string `yaml:"cluster_name,omitempty"`
}

// ReverseTunnel is a SSH reverse tunnel maintained by one cluster's
Expand Down
26 changes: 26 additions & 0 deletions lib/service/cfg.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/gravitational/teleport/lib/bpf"
"github.com/gravitational/teleport/lib/defaults"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/kube/kubeconfig"
"github.com/gravitational/teleport/lib/limiter"
"github.com/gravitational/teleport/lib/pam"
"github.com/gravitational/teleport/lib/services"
Expand Down Expand Up @@ -368,6 +369,31 @@ type KubeProxyConfig struct {

// KubeconfigPath is a path to kubeconfig
KubeconfigPath string

// ClusterName is the name of a kubernetes cluster this proxy is running
// in. If set, this proxy will handle kubernetes requests for the cluster.
ClusterName string
}

// ClusterNames returns the complete list of kubernetes clusters from
// ClusterName and kubeconfig.
func (c KubeProxyConfig) ClusterNames() ([]string, error) {
var clusters []string
if c.ClusterName != "" {
clusters = append(clusters, c.ClusterName)
}
if c.KubeconfigPath != "" {
cfg, err := kubeconfig.Load(c.KubeconfigPath)
if err != nil {
return nil, trace.Wrap(err, "failed parsing kubeconfig file %q", c.KubeconfigPath)
}
for n := range cfg.Contexts {
if n != "" {
clusters = append(clusters, n)
}
}
}
return clusters, nil
}

// AuthConfig is a configuration of the auth server
Expand Down
5 changes: 5 additions & 0 deletions lib/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,10 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
if err != nil {
return trace.Wrap(err)
}
kubeClusterNames, err := cfg.Proxy.Kube.ClusterNames()
if err != nil {
return trace.Wrap(err)
}
sshProxy, err := regular.New(cfg.Proxy.SSHAddr,
cfg.Hostname,
[]ssh.Signer{conn.ServerIdentity.KeySigner},
Expand All @@ -2212,6 +2216,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
process.BroadcastEvent(Event{Name: TeleportOKEvent, Payload: teleport.ComponentProxy})
}
}),
regular.SetKubernetesClusters(kubeClusterNames),
)
if err != nil {
return trace.Wrap(err)
Expand Down
28 changes: 27 additions & 1 deletion lib/services/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ type Server interface {
SetRotation(Rotation)
// GetUseTunnel gets if a reverse tunnel should be used to connect to this node.
GetUseTunnel() bool
// GetKubernetesClusters gets kubernetes clusters accessible through this
// proxy.
GetKubernetesClusters() []string
// SetUseTunnel sets if a reverse tunnel should be used to connect to this node.
SetUseTunnel(bool)
// String returns string representation of the server
Expand All @@ -67,6 +70,9 @@ type Server interface {
SetPublicAddr(string)
// SetNamespace sets server namespace
SetNamespace(namespace string)
// SetKubernetesClusters sets kubernetes clusters accessible through this
// proxy.
SetKubernetesClusters([]string)
// V1 returns V1 version for backwards compatibility
V1() *ServerV1
// MatchAgainst takes a map of labels and returns True if this server
Expand Down Expand Up @@ -271,6 +277,18 @@ func (s *ServerV2) GetAllLabels() map[string]string {
return lmap
}

// GetKubernetesClusters gets kubernetes clusters accessible through this
// proxy.
func (s *ServerV2) GetKubernetesClusters() []string {
return s.Spec.KubernetesClusters
}

// SetKubernetesClusters sets kubernetes clusters accessible through this
// proxy.
func (s *ServerV2) SetKubernetesClusters(clusters []string) {
s.Spec.KubernetesClusters = clusters
}

// MatchAgainst takes a map of labels and returns True if this server
// has ALL of them
//
Expand Down Expand Up @@ -313,6 +331,10 @@ func (s *ServerV2) CheckAndSetDefaults() error {
}
}

if len(s.Spec.KubernetesClusters) > 0 && s.Kind != KindProxy {
return trace.BadParameter("KubernetesClusters are only allowed on Proxy servers; got clusters %q set on a %q server %q", s.Spec.KubernetesClusters, s.Kind, s.Metadata.Name)
}

return nil
}

Expand Down Expand Up @@ -362,6 +384,9 @@ func CompareServers(a, b Server) int {
if a.GetTeleportVersion() != b.GetTeleportVersion() {
return Different
}
if !utils.StringSlicesEqual(a.GetKubernetesClusters(), b.GetKubernetesClusters()) {
return Different
}
return Equal
}

Expand Down Expand Up @@ -416,7 +441,8 @@ const ServerSpecV2Schema = `{
}
}
},
"rotation": %v
"rotation": %v,
"kubernetes_clusters": {"type": "array", "items": {"type": "string"}}
}
}`

Expand Down
12 changes: 9 additions & 3 deletions lib/services/servers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ func (s *ServerSuite) TestServersCompare(c *check.C) {
Labels: map[string]string{"a": "b"},
},
Spec: ServerSpecV2{
Addr: "localhost:3022",
CmdLabels: map[string]CommandLabelV2{"a": CommandLabelV2{Period: Duration(time.Minute), Command: []string{"ls", "-l"}}},
Version: "4.0.0",
Addr: "localhost:3022",
CmdLabels: map[string]CommandLabelV2{"a": CommandLabelV2{Period: Duration(time.Minute), Command: []string{"ls", "-l"}}},
Version: "4.0.0",
KubernetesClusters: []string{"kube-a"},
},
}
node.SetExpiry(time.Date(2018, 1, 2, 3, 4, 5, 6, time.UTC))
Expand Down Expand Up @@ -110,6 +111,11 @@ func (s *ServerSuite) TestServersCompare(c *check.C) {
},
}
c.Assert(CompareServers(node, &node2), check.Equals, Different)

// KubernetesServers have changed
node2 = *node
node2.Spec.KubernetesClusters = []string{"kube-a", "kube-b"}
c.Assert(CompareServers(node, &node2), check.Equals, Different)
}

// TestGuessProxyHostAndVersion checks that the GuessProxyHostAndVersion
Expand Down
Loading

0 comments on commit c3535e3

Please sign in to comment.