mirror of https://github.com/kubernetes/kops.git
Merge pull request #15474 from scaleway/scw_use_kops_controller_for_bootstrap
scaleway: use kops controller for bootstrap
This commit is contained in:
commit
07627306ed
|
|
@ -46,6 +46,7 @@ import (
|
|||
"k8s.io/kops/upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/hetzner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
|
|
@ -146,6 +147,12 @@ func main() {
|
|||
setupLog.Error(err, "unable to create verifier")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else if opt.Server.Provider.Scaleway != nil {
|
||||
verifier, err = scaleway.NewScalewayVerifier(ctx, opt.Server.Provider.Scaleway)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "unable to create verifier")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
klog.Fatalf("server cloud provider config not provided")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
gcetpm "k8s.io/kops/upup/pkg/fi/cloudup/gce/tpm"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/hetzner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
|
|
@ -71,6 +72,7 @@ type ServerProviderOptions struct {
|
|||
Hetzner *hetzner.HetznerVerifierOptions `json:"hetzner,omitempty"`
|
||||
OpenStack *openstack.OpenStackVerifierOptions `json:"openstack,omitempty"`
|
||||
DigitalOcean *do.DigitalOceanVerifierOptions `json:"do,omitempty"`
|
||||
Scaleway *scaleway.ScalewayVerifierOptions `json:"scaleway,omitempty"`
|
||||
}
|
||||
|
||||
// DiscoveryOptions configures our support for discovery, particularly gossip DNS (i.e. k8s.local)
|
||||
|
|
|
|||
|
|
@ -1810,7 +1810,6 @@ func (i *integrationTest) runTestTerraformScaleway(t *testing.T) {
|
|||
"aws_s3_object_"+i.clusterName+"-addons-kubelet-api.rbac.addons.k8s.io-k8s-1.9_content",
|
||||
"aws_s3_object_"+i.clusterName+"-addons-limit-range.addons.k8s.io_content",
|
||||
"aws_s3_object_"+i.clusterName+"-addons-networking.cilium.io-k8s-1.16_content",
|
||||
"aws_s3_object_"+i.clusterName+"-addons-rbac.addons.k8s.io-k8s-1.8_content",
|
||||
"scaleway_instance_server_control-plane-fr-par-1_user_data",
|
||||
"scaleway_instance_server_nodes-fr-par-1_user_data",
|
||||
)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import (
|
|||
"k8s.io/kops/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/hetzner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
|
||||
)
|
||||
|
||||
|
|
@ -80,13 +81,18 @@ func (b BootstrapClientBuilder) Build(c *fi.NodeupModelBuilderContext) error {
|
|||
return err
|
||||
}
|
||||
authenticator = a
|
||||
|
||||
case kops.CloudProviderDO:
|
||||
a, err := do.NewAuthenticator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authenticator = a
|
||||
case kops.CloudProviderScaleway:
|
||||
a, err := scaleway.NewScalewayAuthenticator()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authenticator = a
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unsupported cloud provider for authenticator %q", b.CloudProvider())
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ func UseKopsControllerForNodeBootstrap(cluster *kops.Cluster) bool {
|
|||
return true
|
||||
case kops.CloudProviderDO:
|
||||
return true
|
||||
case kops.CloudProviderScaleway:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
|
@ -45,6 +47,8 @@ func UseChallengeCallback(cloudProvider kops.CloudProviderID) bool {
|
|||
return true
|
||||
case kops.CloudProviderDO:
|
||||
return true
|
||||
case kops.CloudProviderScaleway:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
|
@ -56,7 +60,7 @@ func UseKopsControllerForNodeConfig(cluster *kops.Cluster) bool {
|
|||
switch cluster.Spec.GetCloudProvider() {
|
||||
case kops.CloudProviderGCE:
|
||||
// We can use cloud-discovery here.
|
||||
case kops.CloudProviderHetzner:
|
||||
case kops.CloudProviderHetzner, kops.CloudProviderScaleway:
|
||||
// We don't have a cloud-discovery mechanism implemented in nodeup for hetzner,
|
||||
// but we assume that we're using a load balancer with a fixed IP address
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ func (b *BootstrapScript) buildEnvironmentVariables() (map[string]string, error)
|
|||
}
|
||||
}
|
||||
|
||||
if cluster.Spec.GetCloudProvider() == kops.CloudProviderScaleway {
|
||||
if cluster.Spec.GetCloudProvider() == kops.CloudProviderScaleway && (b.ig.IsControlPlane() || cluster.UsesLegacyGossip()) {
|
||||
profile, err := scaleway.CreateValidScalewayProfile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/scaleway/scaleway-sdk-go/api/lb/v1"
|
||||
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kops/pkg/apis/kops"
|
||||
"k8s.io/kops/pkg/dns"
|
||||
"k8s.io/kops/pkg/wellknownports"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scalewaytasks"
|
||||
|
|
@ -78,36 +80,48 @@ func (b *APILoadBalancerModelBuilder) Build(c *fi.CloudupModelBuilderContext) er
|
|||
|
||||
c.AddTask(loadBalancer)
|
||||
|
||||
lbBackend := &scalewaytasks.LBBackend{
|
||||
Name: fi.PtrTo("lb-backend"),
|
||||
Lifecycle: b.Lifecycle,
|
||||
lbBackendHttps, lbFrontendHttps := createLbBackendAndFrontend("https", wellknownports.KubeAPIServer, zone, loadBalancer)
|
||||
lbBackendHttps.Lifecycle = b.Lifecycle
|
||||
c.AddTask(lbBackendHttps)
|
||||
lbFrontendHttps.Lifecycle = b.Lifecycle
|
||||
c.AddTask(lbFrontendHttps)
|
||||
|
||||
if dns.IsGossipClusterName(b.Cluster.Name) || b.Cluster.UsesPrivateDNS() || b.Cluster.UsesNoneDNS() {
|
||||
// Ensure the LB hostname is included in the TLS certificate,
|
||||
// if we're not going to use an alias for it
|
||||
loadBalancer.ForAPIServer = true
|
||||
|
||||
if b.Cluster.UsesNoneDNS() || b.UseKopsControllerForNodeBootstrap() {
|
||||
lbBackendKopsController, lbFrontendKopsController := createLbBackendAndFrontend("kops-controller", wellknownports.KopsControllerPort, zone, loadBalancer)
|
||||
lbBackendKopsController.Lifecycle = b.Lifecycle
|
||||
c.AddTask(lbBackendKopsController)
|
||||
lbFrontendKopsController.Lifecycle = b.Lifecycle
|
||||
c.AddTask(lbFrontendKopsController)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createLbBackendAndFrontend(name string, port int, zone scw.Zone, loadBalancer *scalewaytasks.LoadBalancer) (*scalewaytasks.LBBackend, *scalewaytasks.LBFrontend) {
|
||||
lbBackendKopsController := &scalewaytasks.LBBackend{
|
||||
Name: fi.PtrTo("lb-backend-" + name),
|
||||
Zone: fi.PtrTo(string(zone)),
|
||||
ForwardProtocol: fi.PtrTo(string(lb.ProtocolTCP)),
|
||||
ForwardPort: fi.PtrTo(int32(443)),
|
||||
ForwardPort: fi.PtrTo(int32(port)),
|
||||
ForwardPortAlgorithm: fi.PtrTo(string(lb.ForwardPortAlgorithmRoundrobin)),
|
||||
StickySessions: fi.PtrTo(string(lb.StickySessionsTypeNone)),
|
||||
ProxyProtocol: fi.PtrTo(string(lb.ProxyProtocolProxyProtocolUnknown)),
|
||||
LoadBalancer: loadBalancer,
|
||||
}
|
||||
|
||||
c.AddTask(lbBackend)
|
||||
|
||||
lbFrontend := &scalewaytasks.LBFrontend{
|
||||
Name: fi.PtrTo("lb-frontend"),
|
||||
Lifecycle: b.Lifecycle,
|
||||
lbFrontendKopsController := &scalewaytasks.LBFrontend{
|
||||
Name: fi.PtrTo("lb-frontend-" + name),
|
||||
Zone: fi.PtrTo(string(zone)),
|
||||
InboundPort: fi.PtrTo(int32(443)),
|
||||
InboundPort: fi.PtrTo(int32(port)),
|
||||
LoadBalancer: loadBalancer,
|
||||
LBBackend: lbBackend,
|
||||
LBBackend: lbBackendKopsController,
|
||||
}
|
||||
|
||||
c.AddTask(lbFrontend)
|
||||
|
||||
if dns.IsGossipClusterName(b.Cluster.Name) || b.Cluster.UsesPrivateDNS() || b.Cluster.UsesNoneDNS() {
|
||||
// Ensure the LB hostname is included in the TLS certificate,
|
||||
// if we're not going to use an alias for it
|
||||
loadBalancer.ForAPIServer = true
|
||||
}
|
||||
|
||||
return nil
|
||||
return lbBackendKopsController, lbFrontendKopsController
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,13 +48,17 @@ type nodeIdentifier struct {
|
|||
|
||||
// New creates and returns a nodeidentity.Identifier for Nodes running on Scaleway
|
||||
func New(CacheNodeidentityInfo bool) (nodeidentity.Identifier, error) {
|
||||
scwClient, err := scw.NewClient(
|
||||
scw.WithUserAgent("kubernetes-kops/"+kopsv.Version),
|
||||
scw.WithEnv(),
|
||||
)
|
||||
profile, err := scaleway.CreateValidScalewayProfile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scwClient, err := scw.NewClient(
|
||||
scw.WithProfile(profile),
|
||||
scw.WithUserAgent(scaleway.KopsUserAgentPrefix+kopsv.Version),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating client for Scaleway NodeIdentifier: %w", err)
|
||||
}
|
||||
|
||||
return &nodeIdentifier{
|
||||
client: scwClient,
|
||||
|
|
|
|||
|
|
@ -66,14 +66,18 @@ func NewScwCloudProvider() (*ScwCloudProvider, error) {
|
|||
privateIP := metadata.PrivateIP
|
||||
klog.V(4).Infof("Found first private net IP of the running server: %q", privateIP)
|
||||
|
||||
profile, err := scaleway.CreateValidScalewayProfile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scwClient, err := scw.NewClient(
|
||||
scw.WithProfile(profile),
|
||||
scw.WithUserAgent(scaleway.KopsUserAgentPrefix+kopsv.Version),
|
||||
scw.WithEnv(),
|
||||
scw.WithDefaultZone(zone),
|
||||
scw.WithDefaultRegion(region),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating client: %w", err)
|
||||
return nil, fmt.Errorf("error creating client for Protokube: %w", err)
|
||||
}
|
||||
|
||||
instanceAPI := instance.NewAPI(scwClient)
|
||||
|
|
|
|||
|
|
@ -15,36 +15,13 @@ Assets:
|
|||
- 54e79e4d48b9e191767e4abc08be1a8476a1c757e9a9f8c45c6ded001226867f@https://github.com/opencontainers/runc/releases/download/v1.1.5/runc.arm64
|
||||
- 2f599c3d54f4c4bdbcc95aaf0c7b513a845d8f9503ec5b34c9f86aa1bc34fc0c@https://artifacts.k8s.io/binaries/kops/1.21.0-alpha.1/linux/arm64/protokube,https://github.com/kubernetes/kops/releases/download/v1.21.0-alpha.1/protokube-linux-arm64
|
||||
- 9d842e3636a95de2315cdea2be7a282355aac0658ef0b86d5dc2449066538f13@https://artifacts.k8s.io/binaries/kops/1.21.0-alpha.1/linux/arm64/channels,https://github.com/kubernetes/kops/releases/download/v1.21.0-alpha.1/channels-linux-arm64
|
||||
CAs:
|
||||
kubernetes-ca: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCARigAwIBAgIMFpANqBD8NSD82AUSMA0GCSqGSIb3DQEBCwUAMBgxFjAU
|
||||
BgNVBAMTDWt1YmVybmV0ZXMtY2EwHhcNMjEwNzA3MDcwODAwWhcNMzEwNzA3MDcw
|
||||
ODAwWjAYMRYwFAYDVQQDEw1rdWJlcm5ldGVzLWNhMFwwDQYJKoZIhvcNAQEBBQAD
|
||||
SwAwSAJBANFI3zr0Tk8krsW8vwjfMpzJOlWQ8616vG3YPa2qAgI7V4oKwfV0yIg1
|
||||
jt+H6f4P/wkPAPTPTfRp9Iy8oHEEFw0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEG
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNG3zVjTcLlJwDsJ4/K9DV7KohUA
|
||||
MA0GCSqGSIb3DQEBCwUAA0EAB8d03fY2w7WKpfO29qI295pu2C4ca9AiVGOpgSc8
|
||||
tmQsq6rcxt3T+rb589PVtz0mw/cKTxOk6gH2CCC+yHfy2w==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCARigAwIBAgIMFpANvmSa0OAlYmXKMA0GCSqGSIb3DQEBCwUAMBgxFjAU
|
||||
BgNVBAMTDWt1YmVybmV0ZXMtY2EwHhcNMjEwNzA3MDcwOTM2WhcNMzEwNzA3MDcw
|
||||
OTM2WjAYMRYwFAYDVQQDEw1rdWJlcm5ldGVzLWNhMFwwDQYJKoZIhvcNAQEBBQAD
|
||||
SwAwSAJBAMF6F4aZdpe0RUpyykaBpWwZCnwbffhYGOw+fs6RdLuUq7QCNmJm/Eq7
|
||||
WWOziMYDiI9SbclpD+6QiJ0N3EqppVUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEG
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLImp6ARjPDAH6nhI+scWVt3Q9bn
|
||||
MA0GCSqGSIb3DQEBCwUAA0EAVQVx5MUtuAIeePuP9o51xtpT2S6Fvfi8J4ICxnlA
|
||||
9B7UD2ushcVFPtaeoL9Gfu8aY4KJBeqqg5ojl4qmRnThjw==
|
||||
-----END CERTIFICATE-----
|
||||
CAs: {}
|
||||
ClusterName: scw-minimal.k8s.local
|
||||
ContainerRuntime: containerd
|
||||
Hooks:
|
||||
- null
|
||||
- null
|
||||
KeypairIDs:
|
||||
kube-proxy: "6986354184403674830529235586"
|
||||
kubelet: "6986354184404014133128804066"
|
||||
kubernetes-ca: "6982820025135291416230495506"
|
||||
KubeProxy: null
|
||||
KubeletConfig:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ spec:
|
|||
addons:
|
||||
- id: k8s-1.16
|
||||
manifest: kops-controller.addons.k8s.io/k8s-1.16.yaml
|
||||
manifestHash: bffd10e2291b38f02725cd04366b8029878272a79e68825e88d98a681068cd6c
|
||||
manifestHash: 0652ed8a25e088a043a9f162f3b73dba1b9b5dcbb8efcb2b6550826d81f32a2b
|
||||
name: kops-controller.addons.k8s.io
|
||||
needsRollingUpdate: control-plane
|
||||
selector:
|
||||
|
|
@ -19,13 +19,6 @@ spec:
|
|||
selector:
|
||||
k8s-addon: coredns.addons.k8s.io
|
||||
version: 9.99.0
|
||||
- id: k8s-1.8
|
||||
manifest: rbac.addons.k8s.io/k8s-1.8.yaml
|
||||
manifestHash: f81bd7c57bc1902ca342635d7ad7d01b82dfeaff01a1192b076e66907d87871e
|
||||
name: rbac.addons.k8s.io
|
||||
selector:
|
||||
k8s-addon: rbac.addons.k8s.io
|
||||
version: 9.99.0
|
||||
- id: k8s-1.9
|
||||
manifest: kubelet-api.rbac.addons.k8s.io/k8s-1.9.yaml
|
||||
manifestHash: 01c120e887bd98d82ef57983ad58a0b22bc85efb48108092a24c4b82e4c9ea81
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
config.yaml: |
|
||||
{"clusterName":"scw-minimal.k8s.local","cloud":"scaleway","configBase":"memfs://tests/scw-minimal.k8s.local","secretStore":"memfs://tests/scw-minimal.k8s.local/secrets","discovery":{"enabled":true}}
|
||||
{"clusterName":"scw-minimal.k8s.local","cloud":"scaleway","configBase":"memfs://tests/scw-minimal.k8s.local","secretStore":"memfs://tests/scw-minimal.k8s.local/secrets","server":{"Listen":":3988","provider":{"scaleway":{}},"serverKeyPath":"/etc/kubernetes/kops-controller/pki/kops-controller.key","serverCertificatePath":"/etc/kubernetes/kops-controller/pki/kops-controller.crt","caBasePath":"/etc/kubernetes/kops-controller/pki","signingCAs":["kubernetes-ca"],"certNames":["kubelet","kubelet-server"]},"discovery":{"enabled":true}}
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
|
|
@ -32,6 +32,8 @@ spec:
|
|||
k8s-app: kops-controller
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
dns.alpha.kubernetes.io/internal: kops-controller.internal.scw-minimal.k8s.local
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
k8s-addon: kops-controller.addons.k8s.io
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
addon.kops.k8s.io/name: rbac.addons.k8s.io
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
app.kubernetes.io/managed-by: kops
|
||||
k8s-addon: rbac.addons.k8s.io
|
||||
kubernetes.io/cluster-service: "true"
|
||||
name: kubelet-cluster-admin
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:node
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: User
|
||||
name: kubelet
|
||||
|
|
@ -150,10 +150,33 @@ __EOF_CLUSTER_SPEC
|
|||
cat > conf/kube_env.yaml << '__EOF_KUBE_ENV'
|
||||
CloudProvider: scaleway
|
||||
ClusterName: scw-minimal.k8s.local
|
||||
ConfigBase: memfs://tests/scw-minimal.k8s.local
|
||||
ConfigServer:
|
||||
CACertificates: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCARigAwIBAgIMFpANqBD8NSD82AUSMA0GCSqGSIb3DQEBCwUAMBgxFjAU
|
||||
BgNVBAMTDWt1YmVybmV0ZXMtY2EwHhcNMjEwNzA3MDcwODAwWhcNMzEwNzA3MDcw
|
||||
ODAwWjAYMRYwFAYDVQQDEw1rdWJlcm5ldGVzLWNhMFwwDQYJKoZIhvcNAQEBBQAD
|
||||
SwAwSAJBANFI3zr0Tk8krsW8vwjfMpzJOlWQ8616vG3YPa2qAgI7V4oKwfV0yIg1
|
||||
jt+H6f4P/wkPAPTPTfRp9Iy8oHEEFw0CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEG
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNG3zVjTcLlJwDsJ4/K9DV7KohUA
|
||||
MA0GCSqGSIb3DQEBCwUAA0EAB8d03fY2w7WKpfO29qI295pu2C4ca9AiVGOpgSc8
|
||||
tmQsq6rcxt3T+rb589PVtz0mw/cKTxOk6gH2CCC+yHfy2w==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbjCCARigAwIBAgIMFpANvmSa0OAlYmXKMA0GCSqGSIb3DQEBCwUAMBgxFjAU
|
||||
BgNVBAMTDWt1YmVybmV0ZXMtY2EwHhcNMjEwNzA3MDcwOTM2WhcNMzEwNzA3MDcw
|
||||
OTM2WjAYMRYwFAYDVQQDEw1rdWJlcm5ldGVzLWNhMFwwDQYJKoZIhvcNAQEBBQAD
|
||||
SwAwSAJBAMF6F4aZdpe0RUpyykaBpWwZCnwbffhYGOw+fs6RdLuUq7QCNmJm/Eq7
|
||||
WWOziMYDiI9SbclpD+6QiJ0N3EqppVUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEG
|
||||
MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLImp6ARjPDAH6nhI+scWVt3Q9bn
|
||||
MA0GCSqGSIb3DQEBCwUAA0EAVQVx5MUtuAIeePuP9o51xtpT2S6Fvfi8J4ICxnlA
|
||||
9B7UD2ushcVFPtaeoL9Gfu8aY4KJBeqqg5ojl4qmRnThjw==
|
||||
-----END CERTIFICATE-----
|
||||
servers:
|
||||
- https://kops-controller.internal.scw-minimal.k8s.local:3988/
|
||||
InstanceGroupName: nodes-fr-par-1
|
||||
InstanceGroupRole: Node
|
||||
NodeupConfigHash: ThbM3OQQUCmecnKq4GQW0fdWp6sjwEiAjfmqga3QcXY=
|
||||
NodeupConfigHash: l6ITXtzPONIgO+uyEAe0rYXGYgBVjPkJ9/Ov2xKxX/U=
|
||||
|
||||
__EOF_KUBE_ENV
|
||||
|
||||
|
|
|
|||
|
|
@ -148,14 +148,6 @@ resource "aws_s3_object" "scw-minimal-k8s-local-addons-networking-cilium-io-k8s-
|
|||
server_side_encryption = "AES256"
|
||||
}
|
||||
|
||||
resource "aws_s3_object" "scw-minimal-k8s-local-addons-rbac-addons-k8s-io-k8s-1-8" {
|
||||
bucket = "testingBucket"
|
||||
content = file("${path.module}/data/aws_s3_object_scw-minimal.k8s.local-addons-rbac.addons.k8s.io-k8s-1.8_content")
|
||||
key = "tests/scw-minimal.k8s.local/addons/rbac.addons.k8s.io/k8s-1.8.yaml"
|
||||
provider = aws.files
|
||||
server_side_encryption = "AES256"
|
||||
}
|
||||
|
||||
resource "aws_s3_object" "scw-minimal-k8s-local-addons-scaleway-cloud-controller-addons-k8s-io-k8s-1-24" {
|
||||
bucket = "testingBucket"
|
||||
content = file("${path.module}/data/aws_s3_object_scw-minimal.k8s.local-addons-scaleway-cloud-controller.addons.k8s.io-k8s-1.24_content")
|
||||
|
|
@ -226,18 +218,32 @@ resource "scaleway_lb" "api-scw-minimal-k8s-local" {
|
|||
type = "LB-S"
|
||||
}
|
||||
|
||||
resource "scaleway_lb_backend" "lb-backend" {
|
||||
resource "scaleway_lb_backend" "lb-backend-https" {
|
||||
forward_port = 443
|
||||
forward_protocol = "tcp"
|
||||
lb_id = scaleway_lb.api-scw-minimal-k8s-local.id
|
||||
name = "lb-backend"
|
||||
name = "lb-backend-https"
|
||||
}
|
||||
|
||||
resource "scaleway_lb_frontend" "lb-frontend" {
|
||||
backend_id = scaleway_lb_backend.lb-backend.id
|
||||
resource "scaleway_lb_backend" "lb-backend-kops-controller" {
|
||||
forward_port = 3988
|
||||
forward_protocol = "tcp"
|
||||
lb_id = scaleway_lb.api-scw-minimal-k8s-local.id
|
||||
name = "lb-backend-kops-controller"
|
||||
}
|
||||
|
||||
resource "scaleway_lb_frontend" "lb-frontend-https" {
|
||||
backend_id = scaleway_lb_backend.lb-backend-https.id
|
||||
inbound_port = 443
|
||||
lb_id = scaleway_lb.api-scw-minimal-k8s-local.id
|
||||
name = "lb-frontend"
|
||||
name = "lb-frontend-https"
|
||||
}
|
||||
|
||||
resource "scaleway_lb_frontend" "lb-frontend-kops-controller" {
|
||||
backend_id = scaleway_lb_backend.lb-backend-kops-controller.id
|
||||
inbound_port = 3988
|
||||
lb_id = scaleway_lb.api-scw-minimal-k8s-local.id
|
||||
name = "lb-frontend-kops-controller"
|
||||
}
|
||||
|
||||
resource "scaleway_lb_ip" "api-scw-minimal-k8s-local" {
|
||||
|
|
|
|||
|
|
@ -1465,7 +1465,7 @@ func (n *nodeUpConfigBuilder) BuildConfig(ig *kops.InstanceGroup, apiserverAddit
|
|||
} else {
|
||||
// If we do have a fixed IP, we use it (on some clouds, initially)
|
||||
switch cluster.Spec.GetCloudProvider() {
|
||||
case kops.CloudProviderHetzner:
|
||||
case kops.CloudProviderHetzner, kops.CloudProviderScaleway:
|
||||
bootConfig.APIServerIPs = controlPlaneIPs
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scaleway
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||
"k8s.io/kops/pkg/bootstrap"
|
||||
)
|
||||
|
||||
const ScalewayAuthenticationTokenPrefix = "x-scaleway-instance-server-id "
|
||||
|
||||
type scalewayAuthenticator struct{}
|
||||
|
||||
var _ bootstrap.Authenticator = &scalewayAuthenticator{}
|
||||
|
||||
func NewScalewayAuthenticator() (bootstrap.Authenticator, error) {
|
||||
return &scalewayAuthenticator{}, nil
|
||||
}
|
||||
|
||||
func (a *scalewayAuthenticator) CreateToken(body []byte) (string, error) {
|
||||
metadataAPI := instance.NewMetadataAPI()
|
||||
metadata, err := metadataAPI.GetMetadata()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve server metadata: %w", err)
|
||||
}
|
||||
return ScalewayAuthenticationTokenPrefix + metadata.ID, nil
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package scaleway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||
kopsv "k8s.io/kops"
|
||||
"k8s.io/kops/pkg/bootstrap"
|
||||
"k8s.io/kops/pkg/wellknownports"
|
||||
)
|
||||
|
||||
type ScalewayVerifierOptions struct{}
|
||||
|
||||
type scalewayVerifier struct {
|
||||
scwClient *scw.Client
|
||||
}
|
||||
|
||||
var _ bootstrap.Verifier = &scalewayVerifier{}
|
||||
|
||||
func NewScalewayVerifier(ctx context.Context, opt *ScalewayVerifierOptions) (bootstrap.Verifier, error) {
|
||||
profile, err := CreateValidScalewayProfile()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating client for Scaleway Verifier: %w", err)
|
||||
}
|
||||
scwClient, err := scw.NewClient(
|
||||
scw.WithProfile(profile),
|
||||
scw.WithUserAgent(KopsUserAgentPrefix+kopsv.Version),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &scalewayVerifier{
|
||||
scwClient: scwClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v scalewayVerifier) VerifyToken(ctx context.Context, rawRequest *http.Request, token string, body []byte, useInstanceIDForNodeName bool) (*bootstrap.VerifyResult, error) {
|
||||
if !strings.HasPrefix(token, ScalewayAuthenticationTokenPrefix) {
|
||||
return nil, fmt.Errorf("incorrect authorization type")
|
||||
}
|
||||
serverID := strings.TrimPrefix(token, ScalewayAuthenticationTokenPrefix)
|
||||
|
||||
metadataAPI := instance.NewMetadataAPI()
|
||||
metadata, err := metadataAPI.GetMetadata()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve server metadata: %w", err)
|
||||
}
|
||||
zone, err := scw.ParseZone(metadata.Location.ZoneID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse Scaleway zone %q: %w", metadata.Location.ZoneID, err)
|
||||
}
|
||||
|
||||
profile, err := CreateValidScalewayProfile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
scwClient, err := scw.NewClient(
|
||||
scw.WithProfile(profile),
|
||||
scw.WithUserAgent(KopsUserAgentPrefix+kopsv.Version),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("creating client for Scaleway Verifier: %w", err)
|
||||
}
|
||||
|
||||
instanceAPI := instance.NewAPI(scwClient)
|
||||
serverResponse, err := instanceAPI.GetServer(&instance.GetServerRequest{
|
||||
ServerID: serverID,
|
||||
Zone: zone,
|
||||
}, scw.WithContext(ctx))
|
||||
if err != nil || serverResponse == nil {
|
||||
return nil, fmt.Errorf("failed to get server %s: %w", serverID, err)
|
||||
}
|
||||
server := serverResponse.Server
|
||||
|
||||
addresses := []string(nil)
|
||||
challengeEndPoints := []string(nil)
|
||||
if server.PrivateIP != nil {
|
||||
addresses = append(addresses, *server.PrivateIP)
|
||||
challengeEndPoints = append(challengeEndPoints, net.JoinHostPort(*server.PrivateIP, strconv.Itoa(wellknownports.NodeupChallenge)))
|
||||
}
|
||||
if server.IPv6 != nil {
|
||||
addresses = append(addresses, server.IPv6.Address.String())
|
||||
challengeEndPoints = append(challengeEndPoints, net.JoinHostPort(server.IPv6.Address.String(), strconv.Itoa(wellknownports.NodeupChallenge)))
|
||||
}
|
||||
|
||||
igName := ""
|
||||
for _, tag := range server.Tags {
|
||||
if strings.HasPrefix(tag, TagInstanceGroup) {
|
||||
igName = strings.TrimPrefix(tag, TagInstanceGroup+"=")
|
||||
}
|
||||
}
|
||||
|
||||
result := &bootstrap.VerifyResult{
|
||||
NodeName: server.Name,
|
||||
InstanceGroupName: igName,
|
||||
CertificateNames: addresses,
|
||||
ChallengeEndpoint: challengeEndPoints[0],
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
@ -278,13 +278,8 @@ func (_ *Instance) RenderScw(t *scaleway.ScwAPITarget, actual, expected, changes
|
|||
if err != nil {
|
||||
return fmt.Errorf("listing load-balancer's back-ends for instance creation: %w", err)
|
||||
}
|
||||
if backEnds.TotalCount > 1 {
|
||||
return fmt.Errorf("cannot have multiple back-ends for load-balancer %s", loadBalancer.Name)
|
||||
} else if backEnds.TotalCount < 1 {
|
||||
return fmt.Errorf("load-balancer %s should have 1 back-end, got 0", loadBalancer.Name)
|
||||
}
|
||||
backEnd := backEnds.Backends[0]
|
||||
|
||||
for _, backEnd := range backEnds.Backends {
|
||||
// If we are adding instances, we also need to add them to the load-balancer's backend
|
||||
if newInstanceCount > 0 {
|
||||
_, err = lbService.AddBackendServers(&lb.ZonedAPIAddBackendServersRequest{
|
||||
|
|
@ -307,7 +302,6 @@ func (_ *Instance) RenderScw(t *scaleway.ScwAPITarget, actual, expected, changes
|
|||
return fmt.Errorf("removing servers' IPs from load-balancer's back-end: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
_, err = lbService.WaitForLb(&lb.ZonedAPIWaitForLBRequest{
|
||||
LBID: loadBalancer.ID,
|
||||
Zone: zone,
|
||||
|
|
@ -317,6 +311,7 @@ func (_ *Instance) RenderScw(t *scaleway.ScwAPITarget, actual, expected, changes
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ func (l *LBBackend) RenderScw(t *scaleway.ScwAPITarget, actual, expected, change
|
|||
|
||||
backendCreated, err := lbService.CreateBackend(&lb.ZonedAPICreateBackendRequest{
|
||||
Zone: scw.Zone(fi.ValueOf(expected.Zone)),
|
||||
LBID: fi.ValueOf(expected.LoadBalancer.LBID), // try expected instead of l
|
||||
LBID: fi.ValueOf(expected.LoadBalancer.LBID),
|
||||
Name: fi.ValueOf(expected.Name),
|
||||
ForwardProtocol: lb.Protocol(fi.ValueOf(expected.ForwardProtocol)),
|
||||
ForwardPort: fi.ValueOf(expected.ForwardPort),
|
||||
|
|
|
|||
|
|
@ -738,6 +738,9 @@ func (tf *TemplateFunctions) KopsControllerConfig() (string, error) {
|
|||
case kops.CloudProviderDO:
|
||||
config.Server.Provider.DigitalOcean = &do.DigitalOceanVerifierOptions{}
|
||||
|
||||
case kops.CloudProviderScaleway:
|
||||
config.Server.Provider.Scaleway = &scaleway.ScalewayVerifierOptions{}
|
||||
|
||||
default:
|
||||
return "", fmt.Errorf("unsupported cloud provider %s", cluster.Spec.GetCloudProvider())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import (
|
|||
"k8s.io/kops/upup/pkg/fi/cloudup/gce/tpm/gcetpmsigner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/hetzner"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/openstack"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/local"
|
||||
"k8s.io/kops/upup/pkg/fi/nodeup/nodetasks"
|
||||
"k8s.io/kops/upup/pkg/fi/secrets"
|
||||
|
|
@ -763,14 +764,18 @@ func getNodeConfigFromServers(ctx context.Context, bootConfig *nodeup.BootConfig
|
|||
return nil, err
|
||||
}
|
||||
authenticator = a
|
||||
|
||||
case api.CloudProviderDO:
|
||||
a, err := do.NewAuthenticator()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authenticator = a
|
||||
|
||||
case api.CloudProviderScaleway:
|
||||
a, err := scaleway.NewScalewayAuthenticator()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authenticator = a
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported cloud provider for node configuration %s", bootConfig.CloudProvider)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue