mirror of https://github.com/kubernetes/kops.git
Add IPs to kubelet server cert
Since AWS does not resolve instance hostnames to ipv6, ipv6-only pods that talk to kubelet API has to use node IP, not hostname. Thus we need to add IPs to kubelet server cert.
This commit is contained in:
parent
20e472eded
commit
ad16042a1f
|
@ -203,7 +203,7 @@ func (s *Server) issueCert(name string, pubKey string, id *fi.VerifyResult, vali
|
|||
issueReq.Subject = pkix.Name{
|
||||
CommonName: id.NodeName,
|
||||
}
|
||||
issueReq.AlternateNames = []string{id.NodeName}
|
||||
issueReq.AlternateNames = id.CertificateNames
|
||||
issueReq.Type = "server"
|
||||
case "kube-proxy":
|
||||
issueReq.Subject = pkix.Name{
|
||||
|
|
|
@ -18,6 +18,8 @@ package model
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -25,6 +27,7 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/aws/ec2metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/klog/v2"
|
||||
|
@ -560,7 +563,7 @@ func (b *KubeletBuilder) buildKubeletServingCertificate(c *fi.ModelBuilderContex
|
|||
name := "kubelet-server"
|
||||
dir := b.PathSrvKubernetes()
|
||||
|
||||
nodeName, err := b.NodeName()
|
||||
names, err := b.kubeletNames()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -594,9 +597,9 @@ func (b *KubeletBuilder) buildKubeletServingCertificate(c *fi.ModelBuilderContex
|
|||
KeypairID: b.NodeupConfig.KeypairIDs[fi.CertificateIDCA],
|
||||
Type: "server",
|
||||
Subject: nodetasks.PKIXName{
|
||||
CommonName: nodeName,
|
||||
CommonName: names[0],
|
||||
},
|
||||
AlternateNames: []string{nodeName},
|
||||
AlternateNames: names,
|
||||
}
|
||||
c.AddTask(issueCert)
|
||||
return issueCert.AddFileTasks(c, dir, name, "", nil)
|
||||
|
@ -605,3 +608,27 @@ func (b *KubeletBuilder) buildKubeletServingCertificate(c *fi.ModelBuilderContex
|
|||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (b *KubeletBuilder) kubeletNames() ([]string, error) {
|
||||
if kops.CloudProviderID(b.Cluster.Spec.CloudProvider) != kops.CloudProviderAWS {
|
||||
name, err := os.Hostname()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrs, _ := net.LookupHost(name)
|
||||
|
||||
return append(addrs, name), nil
|
||||
}
|
||||
|
||||
cloud := b.Cloud.(awsup.AWSCloud)
|
||||
|
||||
result, err := cloud.EC2().DescribeInstances(&ec2.DescribeInstancesInput{
|
||||
InstanceIds: []*string{&b.InstanceID},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error describing instances: %v", err)
|
||||
}
|
||||
|
||||
return awsup.GetInstanceCertificateNames(result)
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ type VerifyResult struct {
|
|||
|
||||
// InstanceGroupName is the name of the kops InstanceGroup this node is a member of.
|
||||
InstanceGroupName string
|
||||
|
||||
// CertificateNames is the names the node is authorized to use for certificates.
|
||||
CertificateNames []string
|
||||
}
|
||||
|
||||
// Verifier verifies authentication credentials for requests.
|
||||
|
|
|
@ -2069,3 +2069,40 @@ func GetRolesInInstanceProfile(c AWSCloud, profileName string) ([]string, error)
|
|||
}
|
||||
return roleNames, nil
|
||||
}
|
||||
|
||||
// GetInstanceCertificateNames returns the instance hostname and addresses that should go into certificates.
|
||||
// The first value is the node name and any additional values are IP addresses.
|
||||
func GetInstanceCertificateNames(instances *ec2.DescribeInstancesOutput) (addrs []string, err error) {
|
||||
|
||||
if len(instances.Reservations) != 1 {
|
||||
return nil, fmt.Errorf("too many reservations returned for the single instance-id")
|
||||
}
|
||||
|
||||
if len(instances.Reservations[0].Instances) != 1 {
|
||||
return nil, fmt.Errorf("too many instances returned for the single instance-id")
|
||||
}
|
||||
|
||||
instance := instances.Reservations[0].Instances[0]
|
||||
|
||||
name := *instance.PrivateDnsName
|
||||
|
||||
addrs = append(addrs, name)
|
||||
|
||||
// We only use data for the first interface, and only the first IP
|
||||
for _, iface := range instance.NetworkInterfaces {
|
||||
if iface.Attachment == nil {
|
||||
continue
|
||||
}
|
||||
if *iface.Attachment.DeviceIndex != 0 {
|
||||
continue
|
||||
}
|
||||
addrs = append(addrs, *iface.PrivateIpAddress)
|
||||
if iface.Ipv6Addresses != nil && len(iface.Ipv6Addresses) > 0 {
|
||||
addrs = append(addrs, *iface.Ipv6Addresses[0].Ipv6Address)
|
||||
}
|
||||
if iface.Association.PublicIp != nil {
|
||||
addrs = append(addrs, *iface.Association.PublicIp)
|
||||
}
|
||||
}
|
||||
return addrs, nil
|
||||
}
|
||||
|
|
|
@ -232,8 +232,14 @@ func (a awsVerifier) VerifyToken(token string, body []byte) (*fi.VerifyResult, e
|
|||
|
||||
instance := instances.Reservations[0].Instances[0]
|
||||
|
||||
addrs, err := GetInstanceCertificateNames(instances)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := &fi.VerifyResult{
|
||||
NodeName: aws.StringValue(instance.PrivateDnsName),
|
||||
NodeName: addrs[0],
|
||||
CertificateNames: addrs,
|
||||
}
|
||||
|
||||
for _, tag := range instance.Tags {
|
||||
|
|
Loading…
Reference in New Issue