Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spec.api.bindAddress configuration #1038

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/controller/certificates.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func (c *Certificates) Init(ctx context.Context) error {
return fmt.Errorf("failed to read ca cert: %w", err)
}
c.CACert = string(cert)
kubeConfigAPIUrl := fmt.Sprintf("https://localhost:%d", c.ClusterSpec.API.Port)
kubeConfigAPIUrl := fmt.Sprintf("https://%s:%d", c.ClusterSpec.API.APIServerAddress(), c.ClusterSpec.API.Port)
eg.Go(func() error {
// Front proxy CA
if err := c.CertManager.EnsureCA("front-proxy-ca", "kubernetes-front-proxy-ca"); err != nil {
Expand Down
1 change: 1 addition & 0 deletions cmd/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ func (c *CmdOpts) startController(ctx context.Context) error {
}

logrus.Infof("using api address: %s", c.NodeConfig.Spec.API.Address)
logrus.Infof("using api bind-address: %s", c.NodeConfig.Spec.API.BindAddress)
logrus.Infof("using listen port: %d", c.NodeConfig.Spec.API.Port)
logrus.Infof("using sans: %s", c.NodeConfig.Spec.API.SANs)
dnsAddress, err := c.NodeConfig.Spec.Network.DNSAddress()
Expand Down
4 changes: 3 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ spec:
api:
address: 192.168.68.104
port: 6443
bindAddress: 0.0.0.0
k0sApiPort: 9443
externalAddress: my-lb-address.example.com
sans:
Expand Down Expand Up @@ -125,7 +126,8 @@ spec:
| Element | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `externalAddress` | The loadbalancer address (for k0s controllers running behind a loadbalancer). Configures all cluster components to connect to this address and also configures this address for use when joining new nodes to the cluster. |
| `address` | Local address on which to bind an API. Also serves as one of the addresses pushed on the k0s create service certificate on the API. Defaults to first non-local address found on the node. |
| `address` | Local address on which to bind an API. Also serves as one of the addresses pushed on the k0s create service certificate on the API. Defaults to first non-local address found on the node. |
| `bindAddress` | Local address on which to bind the kube-apiserver. Defaults to 0.0.0.0. |
| `sans` | List of additional addresses to push to API servers serving the certificate. |
| `extraArgs` | Map of key-values (strings) for any extra arguments to pass down to Kubernetes api-server process. |
| `port`¹ | Custom port for kube-api server to listen on (default: 6443) |
Expand Down
18 changes: 18 additions & 0 deletions pkg/apis/k0s.k0sproject.io/v1beta1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ type APISpec struct {
// Local address on which to bind an API
Address string `json:"address"`

// Local address on which to bind the kube-apiserver. Defaults to 0.0.0.0.
BindAddress string `json:"bindAddress,omitempty"`

// The loadbalancer address (for k0s controllers running behind a loadbalancer)
ExternalAddress string `json:"externalAddress,omitempty"`
// TunneledNetworkingMode indicates if we access to KAS through konnectivity tunnel
Expand All @@ -56,6 +59,7 @@ func DefaultAPISpec() *APISpec {
return &APISpec{
Port: 6443,
K0sAPIPort: 9443,
BindAddress: "0.0.0.0",
SANs: addresses,
Address: publicAddress,
ExtraArgs: make(map[string]string),
Expand Down Expand Up @@ -98,10 +102,20 @@ func (a *APISpec) getExternalURIForPort(port int) string {
return fmt.Sprintf("https://%s:%d", addr, port)
}

// APIServerAddress returns the address the API is listening on
func (a *APISpec) APIServerAddress() string {
return a.getAPIServerAddress(a.BindAddress)
}

func (a *APISpec) getAPIServerAddress(address string) string {
return address
}

// Sans return the given SANS plus all local adresses and externalAddress if given
func (a *APISpec) Sans() []string {
sans, _ := iface.AllAddresses()
sans = append(sans, a.Address)
sans = append(sans, a.BindAddress)
sans = append(sans, a.SANs...)
if a.ExternalAddress != "" {
sans = append(sans, a.ExternalAddress)
Expand All @@ -128,5 +142,9 @@ func (a *APISpec) Validate() []error {
errors = append(errors, fmt.Errorf("spec.api.address: %q is not IP address", a.Address))
}

if !govalidator.IsIP(a.BindAddress) {
errors = append(errors, fmt.Errorf("spec.api.bindAddress: %q is not IP address", a.BindAddress))
}

return errors
}
15 changes: 15 additions & 0 deletions pkg/apis/k0s.k0sproject.io/v1beta1/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (s *APISuite) TestValidation() {
s.T().Run("accepts_ipv6_as_address", func(t *testing.T) {
a := APISpec{
Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
BindAddress: "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
}

s.Nil(a.Validate())
Expand All @@ -45,6 +46,7 @@ func (s *APISuite) TestValidation() {
s.T().Run("invalid_api_address", func(t *testing.T) {
a := APISpec{
Address: "somehting.that.is.not.valid//(())",
BindAddress: "0.0.0.0",
}

errors := a.Validate()
Expand All @@ -56,6 +58,7 @@ func (s *APISuite) TestValidation() {
s.T().Run("invalid_sans_address", func(t *testing.T) {
a := APISpec{
Address: "1.2.3.4",
BindAddress: "0.0.0.0",
SANs: []string{
"somehting.that.is.not.valid//(())",
},
Expand All @@ -66,6 +69,18 @@ func (s *APISuite) TestValidation() {
s.Len(errors, 1)
s.Contains(errors[0].Error(), "is not a valid address for sans")
})

s.T().Run("invalid_api_bind_address", func(t *testing.T) {
a := APISpec{
Address: "1.2.3.4",
BindAddress: "somehting.that.is.not.valid//(())",
}

errors := a.Validate()
s.NotNil(errors)
s.Len(errors, 1)
s.Contains(errors[0].Error(), "is not IP address")
})
}

func TestApiSuite(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion pkg/component/controller/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ func (a *APIServer) Run(_ context.Context) error {
logrus.Info("Starting kube-apiserver")
args := stringmap.StringMap{
"advertise-address": a.ClusterConfig.Spec.API.Address,
"bind-address": a.ClusterConfig.Spec.API.BindAddress,
"secure-port": fmt.Sprintf("%d", a.ClusterConfig.Spec.API.Port),
"authorization-mode": "Node,RBAC",
"client-ca-file": path.Join(a.K0sVars.CertRootDir, "ca.crt"),
Expand Down Expand Up @@ -223,7 +224,7 @@ func (a *APIServer) Healthy() error {
TLSClientConfig: tlsConfig,
}
client := &http.Client{Transport: tr}
resp, err := client.Get(fmt.Sprintf("https://localhost:%d/readyz?verbose", a.ClusterConfig.Spec.API.Port))
resp, err := client.Get(fmt.Sprintf("https://%s:%d/readyz?verbose", a.ClusterConfig.Spec.API.APIServerAddress(), a.ClusterConfig.Spec.API.Port))
if err != nil {
return err
}
Expand Down