Merge pull request #10557 from zetaab/feature/hashname

[OpenStack] Use new hash format in instance names
This commit is contained in:
Kubernetes Prow Robot 2021-01-13 09:24:36 -08:00 committed by GitHub
commit fb0fbb5280
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 168 additions and 18 deletions

View File

@ -153,7 +153,7 @@ func (m *MockClient) listServers(w http.ResponseWriter, vals url.Values) {
serverName := strings.Trim(vals.Get("name"), "^$")
matched := make([]servers.Server, 0)
for _, server := range m.servers {
if server.Name == serverName {
if strings.HasPrefix(server.Name, serverName) {
matched = append(matched, server)
}
}

View File

@ -100,6 +100,8 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
securityGroups = append(securityGroups, b.LinkToSecurityGroup(b.Cluster.Spec.MasterPublicName))
}
r := strings.NewReplacer("_", "-", ".", "-")
groupName := r.Replace(strings.ToLower(ig.Name))
// In the future, OpenStack will use Machine API to manage groups,
// for now create d.InstanceGroups.Spec.MinSize amount of servers
for i := int32(0); i < *ig.Spec.MinSize; i++ {
@ -141,8 +143,14 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
}
c.AddTask(portTask)
metaWithName := make(map[string]string)
for k, v := range igMeta {
metaWithName[k] = v
}
metaWithName[openstack.TagKopsName] = fi.StringValue(instanceName)
instanceTask := &openstacktasks.Instance{
Name: instanceName,
GroupName: s(groupName),
Region: fi.String(b.Cluster.Spec.Subnets[0].Region),
Flavor: fi.String(ig.Spec.MachineType),
Image: fi.String(ig.Spec.Image),
@ -151,7 +159,7 @@ func (b *ServerGroupModelBuilder) buildInstances(c *fi.ModelBuilderContext, sg *
Role: fi.String(string(ig.Spec.Role)),
Port: portTask,
UserData: startupScript,
Metadata: igMeta,
Metadata: metaWithName,
SecurityGroups: ig.Spec.AdditionalSecurityGroups,
AvailabilityZone: az,
}

View File

@ -4,11 +4,13 @@ AvailabilityZone: zone-1
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -4,11 +4,13 @@ AvailabilityZone: zone-1
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -4,11 +4,13 @@ AvailabilityZone: zone-1
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -54,11 +54,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-1-cluster
ForAPIServer: false
GroupName: master
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -130,11 +132,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-2-cluster
ForAPIServer: false
GroupName: master
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-2-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -206,11 +210,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-3-cluster
ForAPIServer: false
GroupName: master
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-3-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -282,11 +288,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-1-cluster
ForAPIServer: false
GroupName: node
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -351,11 +359,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-2-cluster
ForAPIServer: false
GroupName: node
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-2-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -420,11 +430,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-3-cluster
ForAPIServer: false
GroupName: node
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-3-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -55,11 +55,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-a
KopsName: master-a-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -119,11 +121,13 @@ AvailabilityZone: zone-2
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-b
KopsName: master-b-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -183,11 +187,13 @@ AvailabilityZone: zone-3
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-c
KopsName: master-c-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -253,11 +259,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-a-1-cluster
ForAPIServer: false
GroupName: node-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-a
KopsName: node-a-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -322,11 +330,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-b-1-cluster
ForAPIServer: false
GroupName: node-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-b
KopsName: node-b-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -391,11 +401,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-c-1-cluster
ForAPIServer: false
GroupName: node-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-c
KopsName: node-c-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -62,11 +62,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-a-1-cluster
ForAPIServer: false
GroupName: master-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-a
KopsName: master-a-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -138,11 +140,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-b-1-cluster
ForAPIServer: false
GroupName: master-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-b
KopsName: master-b-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -214,11 +218,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-c-1-cluster
ForAPIServer: false
GroupName: master-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-c
KopsName: master-c-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -290,11 +296,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-a-1-cluster
ForAPIServer: false
GroupName: node-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-a
KopsName: node-a-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -359,11 +367,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-b-1-cluster
ForAPIServer: false
GroupName: node-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-b
KopsName: node-b-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -428,11 +438,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-c-1-cluster
ForAPIServer: false
GroupName: node-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-c
KopsName: node-c-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -14,11 +14,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-a
KopsName: master-a-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -84,11 +86,13 @@ AvailabilityZone: zone-2
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-b
KopsName: master-b-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -154,11 +158,13 @@ AvailabilityZone: zone-3
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master-c
KopsName: master-c-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -224,11 +230,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: node-a
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-a
KopsName: node-a-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -287,11 +295,13 @@ AvailabilityZone: zone-2
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: node-b
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-b
KopsName: node-b-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster
@ -350,11 +360,13 @@ AvailabilityZone: zone-3
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: node-c
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node-c
KopsName: node-c-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -8,11 +8,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: bastion
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: bastion
KopsName: bastion-1-cluster
KopsNetwork: cluster
KopsRole: Bastion
cluster_generation: "0"
@ -70,11 +72,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -140,11 +144,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -28,11 +28,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-bastion-1-cluster
ForAPIServer: false
GroupName: bastion
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: bastion
KopsName: bastion-1-cluster
KopsNetwork: cluster
KopsRole: Bastion
cluster_generation: "0"
@ -96,11 +98,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-1-cluster
ForAPIServer: false
GroupName: master
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -166,11 +170,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -6,11 +6,13 @@ AvailabilityZone: zone-1
Flavor: blc.1-2
FloatingIP: null
ForAPIServer: false
GroupName: master
ID: null
Image: image-master
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -76,11 +78,13 @@ AvailabilityZone: zone-1
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -26,11 +26,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-master-1-cluster
ForAPIServer: false
GroupName: master
ID: null
Image: image-master
Lifecycle: null
Metadata:
KopsInstanceGroup: master
KopsName: master-1-cluster
KopsNetwork: cluster
KopsRole: Master
KubernetesCluster: cluster
@ -102,11 +104,13 @@ FloatingIP:
Lifecycle: Sync
Name: fip-node-1-cluster
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -4,11 +4,13 @@ AvailabilityZone: subnet
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -4,11 +4,13 @@ AvailabilityZone: zone-a
Flavor: blc.2-4
FloatingIP: null
ForAPIServer: false
GroupName: node
ID: null
Image: image-node
Lifecycle: null
Metadata:
KopsInstanceGroup: node
KopsName: node-1-cluster
KopsNetwork: cluster
KopsRole: Node
KubernetesCluster: cluster

View File

@ -17,6 +17,7 @@ limitations under the License.
package openstack
import (
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
l3floatingip "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
"k8s.io/kops/pkg/resources"
"k8s.io/kops/upup/pkg/fi"
@ -55,14 +56,16 @@ func (os *clusterDiscoveryOS) listL3FloatingIPs(routerID string) ([]*resources.R
return resourceTrackers, nil
}
func (os *clusterDiscoveryOS) listFloatingIPs(instanceID string) ([]*resources.Resource, error) {
func (os *clusterDiscoveryOS) listFloatingIPs(instance servers.Server) ([]*resources.Resource, error) {
var resourceTrackers []*resources.Resource
instance, err := os.osCloud.GetInstance(instanceID)
if err != nil {
return resourceTrackers, err
// we can find real instance name from instance name in old format
// however, in new format the real name can be found in metadata
name := instance.Name
if val, ok := instance.Metadata[openstack.TagKopsName]; ok {
name = val
}
floatingIPs, err := os.osCloud.ListL3FloatingIPs(l3floatingip.ListOpts{
Description: "fip-" + instance.Name,
Description: "fip-" + name,
})
if err != nil {
return resourceTrackers, err

View File

@ -38,7 +38,7 @@ func (os *clusterDiscoveryOS) ListInstances() ([]*resources.Resource, error) {
val, ok := instance.Metadata["k8s"]
if ok && val == os.clusterName {
// Clean up any bound floating IP's
floatingIPs, err := os.listFloatingIPs(instance.ID)
floatingIPs, err := os.listFloatingIPs(instance)
if err != nil {
return resourceTrackers, err
}

View File

@ -65,6 +65,7 @@ const (
TagClusterName = "KubernetesCluster"
TagRoleMaster = "master"
TagKopsNetwork = "KopsNetwork"
TagKopsName = "KopsName"
ResourceTypePort = "ports"
ResourceTypeNetwork = "networks"
ResourceTypeSubnet = "subnets"

View File

@ -19,6 +19,7 @@ package openstacktasks
import (
"fmt"
"strconv"
"strings"
l3floatingip "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
@ -36,6 +37,7 @@ import (
type Instance struct {
ID *string
Name *string
GroupName *string
Port *Port
Region *string
Flavor *string
@ -118,31 +120,51 @@ func (e *Instance) Find(c *fi.Context) (*Instance, error) {
cloud := c.Cloud.(openstack.OpenstackCloud)
computeClient := cloud.ComputeClient()
serverPage, err := servers.List(computeClient, servers.ListOpts{
Name: fmt.Sprintf("^%s$", fi.StringValue(e.Name)),
Name: fmt.Sprintf("^%s", fi.StringValue(e.GroupName)),
}).AllPages()
if err != nil {
return nil, fmt.Errorf("error finding server with name %s: %v", fi.StringValue(e.Name), err)
return nil, fmt.Errorf("error listing servers: %v", err)
}
serverList, err := servers.ExtractServers(serverPage)
if err != nil {
return nil, fmt.Errorf("error extracting server page: %v", err)
}
if len(serverList) == 0 {
var filteredList []servers.Server
for _, server := range serverList {
val, ok := server.Metadata["k8s"]
if !ok || val != fi.StringValue(e.ServerGroup.ClusterName) {
continue
}
metadataName := ""
val, ok = server.Metadata[openstack.TagKopsName]
if ok {
metadataName = val
}
// name or metadata tag should match to instance name
// this is needed for backwards compatibility
if server.Name == fi.StringValue(e.Name) || metadataName == fi.StringValue(e.Name) {
filteredList = append(filteredList, server)
}
}
if filteredList == nil {
return nil, nil
}
if len(serverList) > 1 {
if len(filteredList) > 1 {
return nil, fmt.Errorf("Multiple servers found with name %s", fi.StringValue(e.Name))
}
server := serverList[0]
server := filteredList[0]
actual := &Instance{
ID: fi.String(server.ID),
Name: fi.String(server.Name),
Name: e.Name,
SSHKey: fi.String(server.KeyName),
Lifecycle: e.Lifecycle,
Metadata: server.Metadata,
Role: fi.String(server.Metadata["KopsRole"]),
AvailabilityZone: e.AvailabilityZone,
GroupName: e.GroupName,
}
ports, err := cloud.ListPorts(ports.ListOpts{
@ -235,10 +257,30 @@ func (_ *Instance) ShouldCreate(a, e, changes *Instance) (bool, error) {
return false, nil
}
// generateInstanceName generates name for the instance
// the instance format is [GroupName]-[6 character hash]
func generateInstanceName(e *Instance) (string, error) {
secret, err := fi.CreateSecret()
if err != nil {
return "", err
}
hash, err := secret.AsString()
if err != nil {
return "", err
}
return strings.ToLower(fmt.Sprintf("%s-%s", fi.StringValue(e.GroupName), hash[0:6])), nil
}
func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *Instance) error {
cloud := t.Cloud.(openstack.OpenstackCloud)
if a == nil {
klog.V(2).Infof("Creating Instance with name: %q", fi.StringValue(e.Name))
serverName, err := generateInstanceName(e)
if err != nil {
return err
}
klog.V(2).Infof("Creating Instance with name: %q", serverName)
imageName := fi.StringValue(e.Image)
image, err := cloud.GetImage(imageName)
@ -253,7 +295,7 @@ func (_ *Instance) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, change
}
opt := servers.CreateOpts{
Name: fi.StringValue(e.Name),
Name: serverName,
ImageRef: image.ID,
FlavorRef: flavor.ID,
Networks: []servers.Network{

View File

@ -144,13 +144,31 @@ func (_ *ServerGroup) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, cha
iName := strings.ToLower(fmt.Sprintf("%s-%d.%s", fi.StringValue(a.IGName), currentLastIndex, fi.StringValue(a.ClusterName)))
instanceName := strings.Replace(iName, ".", "-", -1)
opts := servers.ListOpts{
Name: fmt.Sprintf("^%s$", instanceName),
Name: fmt.Sprintf("^%s", fi.StringValue(a.IGName)),
}
instances, err := t.Cloud.ListInstances(opts)
allInstances, err := t.Cloud.ListInstances(opts)
if err != nil {
return fmt.Errorf("error fetching instance list: %v", err)
}
instances := []servers.Server{}
for _, server := range allInstances {
val, ok := server.Metadata["k8s"]
if !ok || val != fi.StringValue(a.ClusterName) {
continue
}
metadataName := ""
val, ok = server.Metadata[openstack.TagKopsName]
if ok {
metadataName = val
}
// name or metadata tag should match to instance name
// this is needed for backwards compatibility
if server.Name == instanceName || metadataName == instanceName {
instances = append(instances, server)
}
}
if len(instances) == 1 {
klog.V(2).Infof("Openstack task ServerGroup scaling down instance %s", instanceName)
err := t.Cloud.DeleteInstanceWithID(instances[0].ID)