mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Add missing node name entry to apiserver SAN list
Also honor node-ip when adding the node address to the SAN list, instead of hardcoding the autodetected IP address. Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
This commit is contained in:
parent
74196acaea
commit
cf12a13175
@ -9,7 +9,7 @@ import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
sysnet "net"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -31,7 +31,6 @@ import (
|
||||
"github.com/rancher/wrangler/pkg/slice"
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/net"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -89,7 +88,7 @@ func Request(path string, info *clientaccess.Info, requester HTTPRequester) ([]b
|
||||
return requester(u.String(), clientaccess.GetHTTPClient(info.CACerts), info.Username, info.Password)
|
||||
}
|
||||
|
||||
func getNodeNamedCrt(nodeName string, nodeIPs []sysnet.IP, nodePasswordFile string) HTTPRequester {
|
||||
func getNodeNamedCrt(nodeName string, nodeIPs []net.IP, nodePasswordFile string) HTTPRequester {
|
||||
return func(u string, client *http.Client, username, password string) ([]byte, error) {
|
||||
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||
if err != nil {
|
||||
@ -169,7 +168,7 @@ func upgradeOldNodePasswordPath(oldNodePasswordFile, newNodePasswordFile string)
|
||||
}
|
||||
}
|
||||
|
||||
func getServingCert(nodeName string, nodeIPs []sysnet.IP, servingCertFile, servingKeyFile, nodePasswordFile string, info *clientaccess.Info) (*tls.Certificate, error) {
|
||||
func getServingCert(nodeName string, nodeIPs []net.IP, servingCertFile, servingKeyFile, nodePasswordFile string, info *clientaccess.Info) (*tls.Certificate, error) {
|
||||
servingCert, err := Request("/v1-"+version.Program+"/serving-kubelet.crt", info, getNodeNamedCrt(nodeName, nodeIPs, nodePasswordFile))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -232,7 +231,7 @@ func splitCertKeyPEM(bytes []byte) (certPem []byte, keyPem []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
func getNodeNamedHostFile(filename, keyFile, nodeName string, nodeIPs []sysnet.IP, nodePasswordFile string, info *clientaccess.Info) error {
|
||||
func getNodeNamedHostFile(filename, keyFile, nodeName string, nodeIPs []net.IP, nodePasswordFile string, info *clientaccess.Info) error {
|
||||
basename := filepath.Base(filename)
|
||||
fileBytes, err := Request("/v1-"+version.Program+"/"+basename, info, getNodeNamedCrt(nodeName, nodeIPs, nodePasswordFile))
|
||||
if err != nil {
|
||||
@ -249,42 +248,6 @@ func getNodeNamedHostFile(filename, keyFile, nodeName string, nodeIPs []sysnet.I
|
||||
return nil
|
||||
}
|
||||
|
||||
func getHostnameAndIPs(info cmds.Agent) (string, []sysnet.IP, error) {
|
||||
ips := []sysnet.IP{}
|
||||
if len(info.NodeIP) == 0 {
|
||||
hostIP, err := net.ChooseHostInterface()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
ips = append(ips, hostIP)
|
||||
} else {
|
||||
for _, hostIP := range info.NodeIP {
|
||||
for _, v := range strings.Split(hostIP, ",") {
|
||||
ip := sysnet.ParseIP(v)
|
||||
if ip == nil {
|
||||
return "", nil, fmt.Errorf("invalid node-ip %s", v)
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name := info.NodeName
|
||||
if name == "" {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
name = hostname
|
||||
}
|
||||
|
||||
// Use lower case hostname to comply with kubernetes constraint:
|
||||
// https://github.com/kubernetes/kubernetes/issues/71140
|
||||
name = strings.ToLower(name)
|
||||
|
||||
return name, ips, nil
|
||||
}
|
||||
|
||||
func isValidResolvConf(resolvConfFile string) bool {
|
||||
file, err := os.Open(resolvConfFile)
|
||||
if err != nil {
|
||||
@ -297,7 +260,7 @@ func isValidResolvConf(resolvConfFile string) bool {
|
||||
for scanner.Scan() {
|
||||
ipMatch := nameserver.FindStringSubmatch(scanner.Text())
|
||||
if len(ipMatch) == 2 {
|
||||
ip := sysnet.ParseIP(ipMatch[1])
|
||||
ip := net.ParseIP(ipMatch[1])
|
||||
if ip == nil || !ip.IsGlobalUnicast() {
|
||||
return false
|
||||
}
|
||||
@ -350,9 +313,9 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
}
|
||||
}
|
||||
|
||||
var flannelIface *sysnet.Interface
|
||||
var flannelIface *net.Interface
|
||||
if !envInfo.NoFlannel && len(envInfo.FlannelIface) > 0 {
|
||||
flannelIface, err = sysnet.InterfaceByName(envInfo.FlannelIface)
|
||||
flannelIface, err = net.InterfaceByName(envInfo.FlannelIface)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to find interface")
|
||||
}
|
||||
@ -384,7 +347,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
newNodePasswordFile := filepath.Join(nodeConfigPath, "password")
|
||||
upgradeOldNodePasswordPath(oldNodePasswordFile, newNodePasswordFile)
|
||||
|
||||
nodeName, nodeIPs, err := getHostnameAndIPs(*envInfo)
|
||||
nodeName, nodeIPs, err := util.GetHostnameAndIPs(envInfo.NodeName, envInfo.NodeIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -498,7 +461,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
|
||||
for _, externalIP := range envInfo.NodeExternalIP {
|
||||
for _, v := range strings.Split(externalIP, ",") {
|
||||
ip := sysnet.ParseIP(v)
|
||||
ip := net.ParseIP(v)
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("invalid node-external-ip %s", v)
|
||||
}
|
||||
@ -546,7 +509,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
|
||||
if controlConfig.ClusterIPRange != nil {
|
||||
nodeConfig.AgentConfig.ClusterCIDR = controlConfig.ClusterIPRange
|
||||
nodeConfig.AgentConfig.ClusterCIDRs = []*sysnet.IPNet{controlConfig.ClusterIPRange}
|
||||
nodeConfig.AgentConfig.ClusterCIDRs = []*net.IPNet{controlConfig.ClusterIPRange}
|
||||
}
|
||||
|
||||
if len(controlConfig.ClusterIPRanges) > 0 {
|
||||
@ -555,7 +518,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
|
||||
if controlConfig.ServiceIPRange != nil {
|
||||
nodeConfig.AgentConfig.ServiceCIDR = controlConfig.ServiceIPRange
|
||||
nodeConfig.AgentConfig.ServiceCIDRs = []*sysnet.IPNet{controlConfig.ServiceIPRange}
|
||||
nodeConfig.AgentConfig.ServiceCIDRs = []*net.IPNet{controlConfig.ServiceIPRange}
|
||||
}
|
||||
|
||||
if len(controlConfig.ServiceIPRanges) > 0 {
|
||||
@ -567,7 +530,7 @@ func get(ctx context.Context, envInfo *cmds.Agent, proxy proxy.Proxy) (*config.N
|
||||
}
|
||||
|
||||
if len(controlConfig.ClusterDNSs) == 0 {
|
||||
nodeConfig.AgentConfig.ClusterDNSs = []sysnet.IP{controlConfig.ClusterDNS}
|
||||
nodeConfig.AgentConfig.ClusterDNSs = []net.IP{controlConfig.ClusterDNS}
|
||||
} else {
|
||||
nodeConfig.AgentConfig.ClusterDNSs = controlConfig.ClusterDNSs
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
|
||||
serverConfig.ControlConfig.KubeConfigOutput = cfg.KubeConfigOutput
|
||||
serverConfig.ControlConfig.KubeConfigMode = cfg.KubeConfigMode
|
||||
serverConfig.Rootless = cfg.Rootless
|
||||
serverConfig.ControlConfig.SANs = knownIPs(cfg.TLSSan)
|
||||
serverConfig.ControlConfig.SANs = cfg.TLSSan
|
||||
serverConfig.ControlConfig.BindAddress = cfg.BindAddress
|
||||
serverConfig.ControlConfig.SupervisorPort = cfg.SupervisorPort
|
||||
serverConfig.ControlConfig.HTTPSPort = cfg.HTTPSPort
|
||||
@ -215,6 +215,18 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
|
||||
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, serverConfig.ControlConfig.AdvertiseIP)
|
||||
}
|
||||
|
||||
// Ensure that we add the localhost name/ip and node name/ip to the SAN list. This list is shared by the
|
||||
// certs for the supervisor, kube-apiserver cert, and etcd. DNS entries for the in-cluster kubernetes
|
||||
// service endpoint are added later when the certificates are created.
|
||||
nodeName, nodeIPs, err := util.GetHostnameAndIPs(cmds.AgentConfig.NodeName, cmds.AgentConfig.NodeIP)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, "127.0.0.1", "localhost", nodeName)
|
||||
for _, ip := range nodeIPs {
|
||||
serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, ip.String())
|
||||
}
|
||||
|
||||
// configure ClusterIPRanges
|
||||
if len(cmds.ServerConfig.ClusterCIDR) == 0 {
|
||||
cmds.ServerConfig.ClusterCIDR.Set("10.42.0.0/16")
|
||||
@ -464,15 +476,6 @@ func validateNetworkConfiguration(serverConfig server.Config) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func knownIPs(ips []string) []string {
|
||||
ips = append(ips, "127.0.0.1")
|
||||
ip, err := utilnet.ChooseHostInterface()
|
||||
if err == nil {
|
||||
ips = append(ips, ip.String())
|
||||
}
|
||||
return ips
|
||||
}
|
||||
|
||||
func getArgValueFromList(searchArg string, argList []string) string {
|
||||
var value string
|
||||
for _, arg := range argList {
|
||||
|
@ -45,7 +45,7 @@ func (c *Cluster) newListener(ctx context.Context) (net.Listener, http.Handler,
|
||||
return dynamiclistener.NewListener(tcp, storage, cert, key, dynamiclistener.Config{
|
||||
ExpirationDaysCheck: config.CertificateRenewDays,
|
||||
Organization: []string{version.Program},
|
||||
SANs: append(c.config.SANs, "localhost", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc."+c.config.ClusterDomain),
|
||||
SANs: append(c.config.SANs, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc."+c.config.ClusterDomain),
|
||||
CN: version.Program,
|
||||
TLSConfig: &tls.Config{
|
||||
ClientAuth: tls.RequestClientCert,
|
||||
|
@ -25,7 +25,6 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
apiserverconfigv1 "k8s.io/apiserver/pkg/apis/config/v1"
|
||||
"k8s.io/kubernetes/pkg/controlplane"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -370,14 +369,8 @@ func genServerCerts(config *config.Control, runtime *config.ControlRuntime) erro
|
||||
return err
|
||||
}
|
||||
|
||||
_, apiServerServiceIP, err := controlplane.ServiceIPRange(*config.ServiceIPRange)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
altNames := &certutil.AltNames{
|
||||
DNSNames: []string{"localhost", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc." + config.ClusterDomain},
|
||||
IPs: []net.IP{apiServerServiceIP},
|
||||
DNSNames: []string{"kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc." + config.ClusterDomain},
|
||||
}
|
||||
|
||||
addSANs(altNames, config.SANs)
|
||||
@ -402,9 +395,7 @@ func genETCDCerts(config *config.Control, runtime *config.ControlRuntime) error
|
||||
return err
|
||||
}
|
||||
|
||||
altNames := &certutil.AltNames{
|
||||
DNSNames: []string{"localhost"},
|
||||
}
|
||||
altNames := &certutil.AltNames{}
|
||||
addSANs(altNames, config.SANs)
|
||||
|
||||
if _, err := createClientCertKey(regen, "etcd-server", nil,
|
||||
|
@ -2,8 +2,13 @@ package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
apinet "k8s.io/apimachinery/pkg/util/net"
|
||||
)
|
||||
|
||||
// JoinIPs stringifies and joins a list of IP addresses with commas.
|
||||
@ -85,3 +90,41 @@ func JoinIP6Nets(elems []*net.IPNet) string {
|
||||
}
|
||||
return strings.Join(strs, ",")
|
||||
}
|
||||
|
||||
// GetHostnameAndIPs takes a node name and list of IPs, usually from CLI args.
|
||||
// If set, these are used to return the node's name and addresses. If not set,
|
||||
// the system hostname and primary interface address are returned instead.
|
||||
func GetHostnameAndIPs(name string, nodeIPs cli.StringSlice) (string, []net.IP, error) {
|
||||
ips := []net.IP{}
|
||||
if len(nodeIPs) == 0 {
|
||||
hostIP, err := apinet.ChooseHostInterface()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
ips = append(ips, hostIP)
|
||||
} else {
|
||||
for _, hostIP := range nodeIPs {
|
||||
for _, v := range strings.Split(hostIP, ",") {
|
||||
ip := net.ParseIP(v)
|
||||
if ip == nil {
|
||||
return "", nil, fmt.Errorf("invalid node-ip %s", v)
|
||||
}
|
||||
ips = append(ips, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if name == "" {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
name = hostname
|
||||
}
|
||||
|
||||
// Use lower case hostname to comply with kubernetes constraint:
|
||||
// https://github.com/kubernetes/kubernetes/issues/71140
|
||||
name = strings.ToLower(name)
|
||||
|
||||
return name, ips, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user