mirror of https://github.com/k3s-io/k3s
Pipe through the ability to set the external hostname for swagger URLs.
parent
8183a4805e
commit
7c684e4331
|
@ -23,6 +23,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -45,6 +46,7 @@ import (
|
||||||
// APIServer runs a kubernetes api server.
|
// APIServer runs a kubernetes api server.
|
||||||
type APIServer struct {
|
type APIServer struct {
|
||||||
WideOpenPort int
|
WideOpenPort int
|
||||||
|
ExternalHost string
|
||||||
Address util.IP
|
Address util.IP
|
||||||
PublicAddressOverride util.IP
|
PublicAddressOverride util.IP
|
||||||
ReadOnlyPort int
|
ReadOnlyPort int
|
||||||
|
@ -151,6 +153,7 @@ func (s *APIServer) AddFlags(fs *pflag.FlagSet) {
|
||||||
client.BindKubeletClientConfigFlags(fs, &s.KubeletConfig)
|
client.BindKubeletClientConfigFlags(fs, &s.KubeletConfig)
|
||||||
fs.StringVar(&s.ClusterName, "cluster_name", s.ClusterName, "The instance prefix for the cluster")
|
fs.StringVar(&s.ClusterName, "cluster_name", s.ClusterName, "The instance prefix for the cluster")
|
||||||
fs.BoolVar(&s.EnableProfiling, "profiling", false, "Enable profiling via web interface host:port/debug/pprof/")
|
fs.BoolVar(&s.EnableProfiling, "profiling", false, "Enable profiling via web interface host:port/debug/pprof/")
|
||||||
|
fs.StringVar(&s.ExternalHost, "external_hostname", "", "The hostname to use when generating externalized URLs for this master (e.g. Swagger API Docs.)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Longer term we should read this from some config store, rather than a flag.
|
// TODO: Longer term we should read this from some config store, rather than a flag.
|
||||||
|
@ -227,6 +230,30 @@ func (s *APIServer) Run(_ []string) error {
|
||||||
admissionControlPluginNames := strings.Split(s.AdmissionControl, ",")
|
admissionControlPluginNames := strings.Split(s.AdmissionControl, ",")
|
||||||
admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile)
|
admissionController := admission.NewFromPlugins(client, admissionControlPluginNames, s.AdmissionControlConfigFile)
|
||||||
|
|
||||||
|
if len(s.ExternalHost) == 0 {
|
||||||
|
// TODO: extend for other providers
|
||||||
|
if s.CloudProvider == "gce" {
|
||||||
|
instances, supported := cloud.Instances()
|
||||||
|
if !supported {
|
||||||
|
glog.Fatalf("gce cloud provider has no instances. this shouldn't happen. exiting.")
|
||||||
|
}
|
||||||
|
name, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
glog.Fatalf("failed to get hostname: %v", err)
|
||||||
|
}
|
||||||
|
addrs, err := instances.NodeAddresses(name)
|
||||||
|
if err != nil {
|
||||||
|
glog.Warningf("unable to obtain external host address from cloud provider: %v", err)
|
||||||
|
} else {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.Type == api.NodeExternalIP {
|
||||||
|
s.ExternalHost = addr.Address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config := &master.Config{
|
config := &master.Config{
|
||||||
Cloud: cloud,
|
Cloud: cloud,
|
||||||
EtcdHelper: helper,
|
EtcdHelper: helper,
|
||||||
|
@ -249,6 +276,7 @@ func (s *APIServer) Run(_ []string) error {
|
||||||
EnableV1Beta3: v1beta3,
|
EnableV1Beta3: v1beta3,
|
||||||
MasterServiceNamespace: s.MasterServiceNamespace,
|
MasterServiceNamespace: s.MasterServiceNamespace,
|
||||||
ClusterName: s.ClusterName,
|
ClusterName: s.ClusterName,
|
||||||
|
ExternalHost: s.ExternalHost,
|
||||||
}
|
}
|
||||||
m := master.New(config)
|
m := master.New(config)
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,9 @@ type Config struct {
|
||||||
// Defaults to 6443 if not set.
|
// Defaults to 6443 if not set.
|
||||||
ReadWritePort int
|
ReadWritePort int
|
||||||
|
|
||||||
|
// ExternalHost is the host name to use for external (public internet) facing URLs (e.g. Swagger)
|
||||||
|
ExternalHost string
|
||||||
|
|
||||||
// If nil, the first result from net.InterfaceAddrs will be used.
|
// If nil, the first result from net.InterfaceAddrs will be used.
|
||||||
PublicAddress net.IP
|
PublicAddress net.IP
|
||||||
|
|
||||||
|
@ -141,7 +144,10 @@ type Master struct {
|
||||||
v1beta3 bool
|
v1beta3 bool
|
||||||
requestContextMapper api.RequestContextMapper
|
requestContextMapper api.RequestContextMapper
|
||||||
|
|
||||||
publicIP net.IP
|
// External host is the name that should be used in external (public internet) URLs for this master
|
||||||
|
externalHost string
|
||||||
|
// clusterIP is the IP address of the master within the cluster.
|
||||||
|
clusterIP net.IP
|
||||||
publicReadOnlyPort int
|
publicReadOnlyPort int
|
||||||
publicReadWritePort int
|
publicReadWritePort int
|
||||||
serviceReadOnlyIP net.IP
|
serviceReadOnlyIP net.IP
|
||||||
|
@ -277,7 +283,8 @@ func New(c *Config) *Master {
|
||||||
cacheTimeout: c.CacheTimeout,
|
cacheTimeout: c.CacheTimeout,
|
||||||
|
|
||||||
masterCount: c.MasterCount,
|
masterCount: c.MasterCount,
|
||||||
publicIP: c.PublicAddress,
|
externalHost: c.ExternalHost,
|
||||||
|
clusterIP: c.PublicAddress,
|
||||||
publicReadOnlyPort: c.ReadOnlyPort,
|
publicReadOnlyPort: c.ReadOnlyPort,
|
||||||
publicReadWritePort: c.ReadWritePort,
|
publicReadWritePort: c.ReadWritePort,
|
||||||
serviceReadOnlyIP: serviceReadOnlyIP,
|
serviceReadOnlyIP: serviceReadOnlyIP,
|
||||||
|
@ -494,14 +501,23 @@ func (m *Master) init(c *Config) {
|
||||||
// register their own web services into the Kubernetes mux prior to initialization
|
// register their own web services into the Kubernetes mux prior to initialization
|
||||||
// of swagger, so that other resource types show up in the documentation.
|
// of swagger, so that other resource types show up in the documentation.
|
||||||
func (m *Master) InstallSwaggerAPI() {
|
func (m *Master) InstallSwaggerAPI() {
|
||||||
webServicesUrl := ""
|
hostAndPort := m.externalHost
|
||||||
// Use the secure read write port, if available.
|
protocol := "https://"
|
||||||
if m.publicReadWritePort != 0 {
|
|
||||||
webServicesUrl = "https://" + net.JoinHostPort(m.publicIP.String(), strconv.Itoa(m.publicReadWritePort))
|
// TODO: this is kind of messed up, we should just pipe in the full URL from the outside, rather
|
||||||
} else {
|
// than guessing at it.
|
||||||
// Use the read only port.
|
if len(m.externalHost) == 0 && m.clusterIP != nil {
|
||||||
webServicesUrl = "http://" + net.JoinHostPort(m.publicIP.String(), strconv.Itoa(m.publicReadOnlyPort))
|
host := m.clusterIP.String()
|
||||||
|
if m.publicReadWritePort != 0 {
|
||||||
|
hostAndPort = net.JoinHostPort(host, strconv.Itoa(m.publicReadWritePort))
|
||||||
|
} else {
|
||||||
|
// Use the read only port.
|
||||||
|
hostAndPort = net.JoinHostPort(host, strconv.Itoa(m.publicReadOnlyPort))
|
||||||
|
protocol = "http://"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
webServicesUrl := protocol + hostAndPort
|
||||||
|
|
||||||
// Enable swagger UI and discovery API
|
// Enable swagger UI and discovery API
|
||||||
swaggerConfig := swagger.Config{
|
swaggerConfig := swagger.Config{
|
||||||
WebServicesUrl: webServicesUrl,
|
WebServicesUrl: webServicesUrl,
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (m *Master) serviceWriterLoop(stop chan struct{}) {
|
||||||
if err := m.createMasterServiceIfNeeded("kubernetes", m.serviceReadWriteIP, m.serviceReadWritePort); err != nil {
|
if err := m.createMasterServiceIfNeeded("kubernetes", m.serviceReadWriteIP, m.serviceReadWritePort); err != nil {
|
||||||
glog.Errorf("Can't create rw service: %v", err)
|
glog.Errorf("Can't create rw service: %v", err)
|
||||||
}
|
}
|
||||||
if err := m.ensureEndpointsContain("kubernetes", m.publicIP, m.publicReadWritePort); err != nil {
|
if err := m.ensureEndpointsContain("kubernetes", m.clusterIP, m.publicReadWritePort); err != nil {
|
||||||
glog.Errorf("Can't create rw endpoints: %v", err)
|
glog.Errorf("Can't create rw endpoints: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (m *Master) roServiceWriterLoop(stop chan struct{}) {
|
||||||
if err := m.createMasterServiceIfNeeded("kubernetes-ro", m.serviceReadOnlyIP, m.serviceReadOnlyPort); err != nil {
|
if err := m.createMasterServiceIfNeeded("kubernetes-ro", m.serviceReadOnlyIP, m.serviceReadOnlyPort); err != nil {
|
||||||
glog.Errorf("Can't create ro service: %v", err)
|
glog.Errorf("Can't create ro service: %v", err)
|
||||||
}
|
}
|
||||||
if err := m.ensureEndpointsContain("kubernetes-ro", m.publicIP, m.publicReadOnlyPort); err != nil {
|
if err := m.ensureEndpointsContain("kubernetes-ro", m.clusterIP, m.publicReadOnlyPort); err != nil {
|
||||||
glog.Errorf("Can't create ro endpoints: %v", err)
|
glog.Errorf("Can't create ro endpoints: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue