mirror of https://github.com/kubernetes/kops.git
ARM64 support - Side-load multi-arch images
This commit is contained in:
parent
c51a811c21
commit
331d223043
|
@ -56,7 +56,7 @@ func (t *ProtokubeBuilder) Build(c *fi.ModelBuilderContext) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if protokubeImage := t.NodeupConfig.ProtokubeImage; protokubeImage != nil {
|
||||
if protokubeImage := t.NodeupConfig.ProtokubeImage[t.Architecture]; protokubeImage != nil {
|
||||
c.AddTask(&nodetasks.LoadImageTask{
|
||||
Name: "protokube",
|
||||
Sources: protokubeImage.Sources,
|
||||
|
@ -166,8 +166,8 @@ func (t *ProtokubeBuilder) buildSystemdService() (*nodetasks.Service, error) {
|
|||
// ProtokubeImageName returns the docker image for protokube
|
||||
func (t *ProtokubeBuilder) ProtokubeImageName() string {
|
||||
name := ""
|
||||
if t.NodeupConfig.ProtokubeImage != nil && t.NodeupConfig.ProtokubeImage.Name != "" {
|
||||
name = t.NodeupConfig.ProtokubeImage.Name
|
||||
if t.NodeupConfig.ProtokubeImage[t.Architecture] != nil && t.NodeupConfig.ProtokubeImage[t.Architecture].Name != "" {
|
||||
name = t.NodeupConfig.ProtokubeImage[t.Architecture].Name
|
||||
}
|
||||
if name == "" {
|
||||
// use current default corresponding to this version of nodeup
|
||||
|
@ -179,8 +179,8 @@ func (t *ProtokubeBuilder) ProtokubeImageName() string {
|
|||
// ProtokubeImagePullCommand returns the command to pull the image
|
||||
func (t *ProtokubeBuilder) ProtokubeImagePullCommand() (string, error) {
|
||||
var sources []string
|
||||
if t.NodeupConfig.ProtokubeImage != nil {
|
||||
sources = t.NodeupConfig.ProtokubeImage.Sources
|
||||
if t.NodeupConfig.ProtokubeImage[t.Architecture] != nil {
|
||||
sources = t.NodeupConfig.ProtokubeImage[t.Architecture].Sources
|
||||
}
|
||||
if len(sources) == 0 {
|
||||
// Nothing to pull; return dummy value
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"k8s.io/kops/pkg/apis/nodeup"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/util/pkg/architectures"
|
||||
)
|
||||
|
||||
func TestProtokubeBuilder_Docker(t *testing.T) {
|
||||
|
@ -43,7 +44,10 @@ func populateImage(ctx *NodeupModelContext) {
|
|||
if ctx.NodeupConfig == nil {
|
||||
ctx.NodeupConfig = &nodeup.Config{}
|
||||
}
|
||||
ctx.NodeupConfig.ProtokubeImage = &nodeup.Image{
|
||||
if ctx.NodeupConfig.ProtokubeImage == nil {
|
||||
ctx.NodeupConfig.ProtokubeImage = make(map[architectures.Architecture]*nodeup.Image)
|
||||
}
|
||||
ctx.NodeupConfig.ProtokubeImage[architectures.ArchitectureAmd64] = &nodeup.Image{
|
||||
Name: "protokube image name",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ type Config struct {
|
|||
// ClusterName is the name of the cluster
|
||||
ClusterName string `json:",omitempty"`
|
||||
// ProtokubeImage is the docker image to load for protokube (bootstrapping)
|
||||
ProtokubeImage *Image `json:"protokubeImage,omitempty"`
|
||||
ProtokubeImage map[architectures.Architecture]*Image `json:"protokubeImage,omitempty"`
|
||||
// Channels is a list of channels that we should apply
|
||||
Channels []string `json:"channels,omitempty"`
|
||||
// ApiserverAdditionalIPs are additional IP address to put in the apiserver server cert.
|
||||
|
|
|
@ -1043,7 +1043,6 @@ func (c *ApplyClusterCmd) validateKubernetesVersion() error {
|
|||
func (c *ApplyClusterCmd) addFileAssets(assetBuilder *assets.AssetBuilder) error {
|
||||
|
||||
var baseURL string
|
||||
var err error
|
||||
if components.IsBaseURL(c.Cluster.Spec.KubernetesVersion) {
|
||||
baseURL = c.Cluster.Spec.KubernetesVersion
|
||||
} else {
|
||||
|
@ -1101,17 +1100,17 @@ func (c *ApplyClusterCmd) addFileAssets(assetBuilder *assets.AssetBuilder) error
|
|||
}
|
||||
c.NodeUpSource[arch] = strings.Join(asset.Locations, ",")
|
||||
c.NodeUpHash[arch] = asset.Hash.Hex()
|
||||
}
|
||||
|
||||
// TODO: Update Kops version in integration tests to 1.19.0 after it is released
|
||||
// Integration tests fake the Kops version to 1.19.0-alpha.1 and will not be able to find Protokube
|
||||
if kopsbase.Version != "1.19.0-alpha.1" {
|
||||
// Explicitly add the protokube image,
|
||||
// otherwise when the Target is DryRun this asset is not added
|
||||
// Is there a better way to call this?
|
||||
_, _, err = ProtokubeImageSource(assetBuilder)
|
||||
if err != nil {
|
||||
return err
|
||||
// TODO: Update Kops version in integration tests to 1.19.0 after it is released
|
||||
// Integration tests fake the Kops version to 1.19.0-alpha.1 and will not be able to find Protokube
|
||||
if kopsbase.Version != "1.19.0-alpha.1" {
|
||||
// Explicitly add the protokube image,
|
||||
// otherwise when the Target is DryRun this asset is not added
|
||||
// Is there a better way to call this?
|
||||
_, _, err = ProtokubeImageSource(assetBuilder, arch)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1155,7 +1154,7 @@ type nodeUpConfigBuilder struct {
|
|||
cluster *kops.Cluster
|
||||
etcdManifests map[kops.InstanceGroupRole][]string
|
||||
images map[kops.InstanceGroupRole]map[architectures.Architecture][]*nodeup.Image
|
||||
protokubeImage map[kops.InstanceGroupRole]*nodeup.Image
|
||||
protokubeImage map[kops.InstanceGroupRole]map[architectures.Architecture]*nodeup.Image
|
||||
}
|
||||
|
||||
func (c *ApplyClusterCmd) newNodeUpConfigBuilder(assetBuilder *assets.AssetBuilder) (model.NodeUpConfigBuilder, error) {
|
||||
|
@ -1178,7 +1177,7 @@ func (c *ApplyClusterCmd) newNodeUpConfigBuilder(assetBuilder *assets.AssetBuild
|
|||
|
||||
etcdManifests := map[kops.InstanceGroupRole][]string{}
|
||||
images := map[kops.InstanceGroupRole]map[architectures.Architecture][]*nodeup.Image{}
|
||||
protokubeImage := map[kops.InstanceGroupRole]*nodeup.Image{}
|
||||
protokubeImage := map[kops.InstanceGroupRole]map[architectures.Architecture]*nodeup.Image{}
|
||||
|
||||
for _, role := range kops.AllInstanceGroupRoles {
|
||||
isMaster := role == kops.InstanceGroupRoleMaster
|
||||
|
@ -1218,18 +1217,13 @@ func (c *ApplyClusterCmd) newNodeUpConfigBuilder(assetBuilder *assets.AssetBuild
|
|||
// don't need to push/pull from a registry
|
||||
if os.Getenv("KOPS_BASE_URL") != "" && isMaster {
|
||||
for _, arch := range architectures.GetSupported() {
|
||||
// TODO: Build multi-arch Kops images
|
||||
if arch != architectures.ArchitectureAmd64 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, name := range []string{"kops-controller", "dns-controller", "kube-apiserver-healthcheck"} {
|
||||
baseURL, err := url.Parse(os.Getenv("KOPS_BASE_URL"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
baseURL.Path = path.Join(baseURL.Path, "/images/"+name+".tar.gz")
|
||||
baseURL.Path = path.Join(baseURL.Path, "/images/"+name+"-"+string(arch)+".tar.gz")
|
||||
|
||||
u, hash, err := assetBuilder.RemapFileAndSHA(baseURL)
|
||||
if err != nil {
|
||||
|
@ -1249,17 +1243,20 @@ func (c *ApplyClusterCmd) newNodeUpConfigBuilder(assetBuilder *assets.AssetBuild
|
|||
// TODO: Update Kops version in integration tests to 1.19.0 after it is released
|
||||
// Integration tests fake the Kops version to 1.19.0-alpha.1 and will not be able to find Protokube
|
||||
if kopsbase.Version != "1.19.0-alpha.1" {
|
||||
u, hash, err := ProtokubeImageSource(assetBuilder)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
protokubeImage[role] = make(map[architectures.Architecture]*nodeup.Image)
|
||||
for _, arch := range architectures.GetSupported() {
|
||||
u, hash, err := ProtokubeImageSource(assetBuilder, arch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
asset := BuildMirroredAsset(u, hash)
|
||||
asset := BuildMirroredAsset(u, hash)
|
||||
|
||||
protokubeImage[role] = &nodeup.Image{
|
||||
Name: kopsbase.DefaultProtokubeImageName(),
|
||||
Sources: asset.Locations,
|
||||
Hash: asset.Hash.Hex(),
|
||||
protokubeImage[role][arch] = &nodeup.Image{
|
||||
Name: kopsbase.DefaultProtokubeImageName(),
|
||||
Sources: asset.Locations,
|
||||
Hash: asset.Hash.Hex(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,10 +61,10 @@ var kopsBaseURL *url.URL
|
|||
var nodeUpAsset map[architectures.Architecture]*MirroredAsset
|
||||
|
||||
// protokubeLocation caches the protokubeLocation url
|
||||
var protokubeLocation *url.URL
|
||||
var protokubeLocation map[architectures.Architecture]*url.URL
|
||||
|
||||
// protokubeHash caches the hash for protokube
|
||||
var protokubeHash *hashing.Hash
|
||||
var protokubeHash map[architectures.Architecture]*hashing.Hash
|
||||
|
||||
// BaseURL returns the base url for the distribution of kops - in particular for nodeup & docker images
|
||||
func BaseURL() (*url.URL, error) {
|
||||
|
@ -122,7 +122,8 @@ func SetKopsAssetsLocations(assetsBuilder *assets.AssetBuilder) error {
|
|||
func NodeUpAsset(assetsBuilder *assets.AssetBuilder, arch architectures.Architecture) (*MirroredAsset, error) {
|
||||
if nodeUpAsset == nil {
|
||||
nodeUpAsset = make(map[architectures.Architecture]*MirroredAsset)
|
||||
} else if nodeUpAsset[arch] != nil {
|
||||
}
|
||||
if nodeUpAsset[arch] != nil {
|
||||
// Avoid repeated logging
|
||||
klog.V(8).Infof("Using cached nodeup location for %s: %v", arch, nodeUpAsset[arch].Locations)
|
||||
return nodeUpAsset[arch], nil
|
||||
|
@ -168,34 +169,44 @@ func NodeUpAsset(assetsBuilder *assets.AssetBuilder, arch architectures.Architec
|
|||
// ProtokubeImageSource returns the source for the docker image for protokube.
|
||||
// Either a docker name (e.g. gcr.io/protokube:1.4), or a URL (https://...) in which case we download
|
||||
// the contents of the url and docker load it
|
||||
func ProtokubeImageSource(assetsBuilder *assets.AssetBuilder) (*url.URL, *hashing.Hash, error) {
|
||||
// Avoid repeated logging
|
||||
if protokubeLocation != nil && protokubeHash != nil {
|
||||
klog.V(8).Infof("Using cached protokube location: %q", protokubeLocation)
|
||||
return protokubeLocation, protokubeHash, nil
|
||||
func ProtokubeImageSource(assetsBuilder *assets.AssetBuilder, arch architectures.Architecture) (*url.URL, *hashing.Hash, error) {
|
||||
if protokubeLocation == nil {
|
||||
protokubeLocation = make(map[architectures.Architecture]*url.URL)
|
||||
}
|
||||
if protokubeHash == nil {
|
||||
protokubeHash = make(map[architectures.Architecture]*hashing.Hash)
|
||||
}
|
||||
if nodeUpAsset[arch] != nil && protokubeHash[arch] != nil {
|
||||
// Avoid repeated logging
|
||||
klog.V(8).Infof("Using cached protokube location for %s: %q", arch, protokubeLocation[arch])
|
||||
return protokubeLocation[arch], protokubeHash[arch], nil
|
||||
}
|
||||
// Use multi-arch env var, but fall back to well known env var
|
||||
env := os.Getenv(fmt.Sprintf("PROTOKUBE_IMAGE_%s", strings.ToUpper(string(arch))))
|
||||
if env == "" {
|
||||
env = os.Getenv("PROTOKUBE_IMAGE")
|
||||
}
|
||||
env := os.Getenv("PROTOKUBE_IMAGE")
|
||||
var err error
|
||||
if env == "" {
|
||||
protokubeLocation, protokubeHash, err = KopsFileURL("images/protokube.tar.gz", assetsBuilder)
|
||||
protokubeLocation[arch], protokubeHash[arch], err = KopsFileURL(fmt.Sprintf("images/protokube-%s.tar.gz", arch), assetsBuilder)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
klog.V(8).Infof("Using default protokube location: %q", protokubeLocation)
|
||||
klog.V(8).Infof("Using default protokube location: %q", protokubeLocation[arch])
|
||||
} else {
|
||||
protokubeImageSource, err := url.Parse(env)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to parse env var PROTOKUBE_IMAGE %q as a url: %v", env, err)
|
||||
return nil, nil, fmt.Errorf("unable to parse env var PROTOKUBE_IMAGE(_%s) %q as a url: %v", strings.ToUpper(string(arch)), env, err)
|
||||
}
|
||||
|
||||
protokubeLocation, protokubeHash, err = assetsBuilder.RemapFileAndSHA(protokubeImageSource)
|
||||
protokubeLocation[arch], protokubeHash[arch], err = assetsBuilder.RemapFileAndSHA(protokubeImageSource)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
klog.Warningf("Using protokube location from PROTOKUBE_IMAGE env var: %q", protokubeLocation)
|
||||
klog.Warningf("Using protokube location from PROTOKUBE_IMAGE(_%s) env var: %q", strings.ToUpper(string(arch)), protokubeLocation[arch])
|
||||
}
|
||||
|
||||
return protokubeLocation, protokubeHash, nil
|
||||
return protokubeLocation[arch], protokubeHash[arch], nil
|
||||
}
|
||||
|
||||
// KopsFileURL returns the base url for the distribution of kops - in particular for nodeup & docker images
|
||||
|
|
Loading…
Reference in New Issue