mirror of https://github.com/kubernetes/kops.git
Merge pull request #3248 from andrewsykim/do
Automatic merge from submit-queue Create cluster requirements for DigitalOcean Initial changes required to create a cluster state. Running `kops update cluster --yes` does not work yet. Note that DO has already adopted cloud controller managers (https://github.com/digitalocean/digitalocean-cloud-controller-manager) so we set `--cloud-provider=external`. This will end up being the case for aws, gce and vsphere over the next couple of releases. https://github.com/kubernetes/kops/issues/2150 ```bash $ kops create cluster --cloud=digitalocean --name=dev.asykim.com --zones=tor1 I0821 18:47:06.302218 28623 create_cluster.go:845] Using SSH public key: /Users/AndrewSyKim/.ssh/id_rsa.pub I0821 18:47:06.302293 28623 subnets.go:183] Assigned CIDR 172.20.32.0/19 to subnet tor1 Previewing changes that will be made: I0821 18:47:11.457696 28623 executor.go:91] Tasks: 0 done / 27 total; 27 can run I0821 18:47:12.113133 28623 executor.go:91] Tasks: 27 done / 27 total; 0 can run Will create resources: Keypair/kops Subject o=system:masters,cn=kops Type client Keypair/kube-controller-manager Subject cn=system:kube-controller-manager Type client Keypair/kube-proxy Subject cn=system:kube-proxy Type client Keypair/kube-scheduler Subject cn=system:kube-scheduler Type client Keypair/kubecfg Subject o=system:masters,cn=kubecfg Type client Keypair/kubelet Subject o=system:nodes,cn=kubelet Type client Keypair/kubelet-api Subject cn=kubelet-api Type client Keypair/master Subject cn=kubernetes-master Type server AlternateNames [100.64.0.1, 127.0.0.1, api.dev.asykim.com, api.internal.dev.asykim.com, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster.local] ManagedFile/dev.asykim.com-addons-bootstrap Location addons/bootstrap-channel.yaml ManagedFile/dev.asykim.com-addons-core.addons.k8s.io Location addons/core.addons.k8s.io/v1.4.0.yaml ManagedFile/dev.asykim.com-addons-dns-controller.addons.k8s.io-k8s-1.6 Location addons/dns-controller.addons.k8s.io/k8s-1.6.yaml ManagedFile/dev.asykim.com-addons-dns-controller.addons.k8s.io-pre-k8s-1.6 Location addons/dns-controller.addons.k8s.io/pre-k8s-1.6.yaml ManagedFile/dev.asykim.com-addons-kube-dns.addons.k8s.io-k8s-1.6 Location addons/kube-dns.addons.k8s.io/k8s-1.6.yaml ManagedFile/dev.asykim.com-addons-kube-dns.addons.k8s.io-pre-k8s-1.6 Location addons/kube-dns.addons.k8s.io/pre-k8s-1.6.yaml ManagedFile/dev.asykim.com-addons-limit-range.addons.k8s.io Location addons/limit-range.addons.k8s.io/v1.5.0.yaml ManagedFile/dev.asykim.com-addons-storage-aws.addons.k8s.io Location addons/storage-aws.addons.k8s.io/v1.6.0.yaml Secret/admin Secret/kube Secret/kube-proxy Secret/kubelet Secret/system:controller_manager Secret/system:dns Secret/system:logging Secret/system:monitoring Secret/system:scheduler Must specify --yes to apply changes Cluster configuration has been created. Suggestions: * list clusters with: kops get cluster * edit this cluster with: kops edit cluster dev.asykim.com * edit your node instance group: kops edit ig --name=dev.asykim.com nodes * edit your master instance group: kops edit ig --name=dev.asykim.com master-tor1 Finally configure your cluster with: kops update cluster dev.asykim.com --yes ```
This commit is contained in:
commit
7a2ff89d77
2
Makefile
2
Makefile
|
@ -136,8 +136,8 @@ codegen: kops-gobindata
|
|||
go install k8s.io/kops/upup/tools/generators/...
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/cloudup/awstasks
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/cloudup/gcetasks
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/assettasks
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/cloudup/dotasks
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/assettasks
|
||||
PATH=${GOPATH_1ST}/bin:${PATH} go generate k8s.io/kops/upup/pkg/fi/fitasks
|
||||
|
||||
.PHONY: protobuf
|
||||
|
|
|
@ -215,22 +215,22 @@ func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
|
|||
return field.Required(fieldSpec.Child("CloudProvider"), "")
|
||||
}
|
||||
if c.Spec.Kubelet != nil && (strict || c.Spec.Kubelet.CloudProvider != "") {
|
||||
if cloudProvider != c.Spec.Kubelet.CloudProvider {
|
||||
if cloudProvider != c.Spec.Kubelet.CloudProvider && c.Spec.Kubelet.CloudProvider != "external" {
|
||||
return field.Invalid(fieldSpec.Child("Kubelet", "CloudProvider"), c.Spec.Kubelet.CloudProvider, "Did not match cluster CloudProvider")
|
||||
}
|
||||
}
|
||||
if c.Spec.MasterKubelet != nil && (strict || c.Spec.MasterKubelet.CloudProvider != "") {
|
||||
if cloudProvider != c.Spec.MasterKubelet.CloudProvider {
|
||||
if cloudProvider != c.Spec.MasterKubelet.CloudProvider && c.Spec.MasterKubelet.CloudProvider != "external" {
|
||||
return field.Invalid(fieldSpec.Child("MasterKubelet", "CloudProvider"), c.Spec.MasterKubelet.CloudProvider, "Did not match cluster CloudProvider")
|
||||
}
|
||||
}
|
||||
if c.Spec.KubeAPIServer != nil && (strict || c.Spec.KubeAPIServer.CloudProvider != "") {
|
||||
if cloudProvider != c.Spec.KubeAPIServer.CloudProvider {
|
||||
if cloudProvider != c.Spec.KubeAPIServer.CloudProvider && c.Spec.KubeAPIServer.CloudProvider != "external" {
|
||||
return field.Invalid(fieldSpec.Child("KubeAPIServer", "CloudProvider"), c.Spec.KubeAPIServer.CloudProvider, "Did not match cluster CloudProvider")
|
||||
}
|
||||
}
|
||||
if c.Spec.KubeControllerManager != nil && (strict || c.Spec.KubeControllerManager.CloudProvider != "") {
|
||||
if cloudProvider != c.Spec.KubeControllerManager.CloudProvider {
|
||||
if cloudProvider != c.Spec.KubeControllerManager.CloudProvider && c.Spec.KubeControllerManager.CloudProvider != "external" {
|
||||
return field.Invalid(fieldSpec.Child("KubeControllerManager", "CloudProvider"), c.Spec.KubeControllerManager.CloudProvider, "Did not match cluster CloudProvider")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,6 +104,9 @@ func (b *KubeControllerManagerOptionsBuilder) BuildOptions(o interface{}) error
|
|||
kcm.CloudProvider = "gce"
|
||||
kcm.ClusterName = gce.SafeClusterName(b.Context.ClusterName)
|
||||
|
||||
case kops.CloudProviderDO:
|
||||
kcm.CloudProvider = "external"
|
||||
|
||||
case kops.CloudProviderVSphere:
|
||||
kcm.CloudProvider = "vsphere"
|
||||
|
||||
|
|
|
@ -151,6 +151,10 @@ func (b *KubeletOptionsBuilder) BuildOptions(o interface{}) error {
|
|||
clusterSpec.Kubelet.HostnameOverride = "@aws"
|
||||
}
|
||||
|
||||
if cloudProvider == kops.CloudProviderDO {
|
||||
clusterSpec.Kubelet.CloudProvider = "external"
|
||||
}
|
||||
|
||||
if cloudProvider == kops.CloudProviderGCE {
|
||||
clusterSpec.Kubelet.CloudProvider = "gce"
|
||||
clusterSpec.Kubelet.HairpinMode = "promiscuous-bridge"
|
||||
|
|
|
@ -141,6 +141,14 @@ func (b *MasterVolumeBuilder) addAWSVolume(c *fi.ModelBuilderContext, name strin
|
|||
}
|
||||
|
||||
func (b *MasterVolumeBuilder) addDOVolume(c *fi.ModelBuilderContext, name string, volumeSize int32, subnet *kops.ClusterSubnetSpec, etcd *kops.EtcdClusterSpec, m *kops.EtcdMemberSpec, allMembers []string) {
|
||||
// required that names start with a lower case and only contains letters, numbers and hyphens
|
||||
name = "kops-" + strings.Replace(name, ".", "-", -1)
|
||||
|
||||
// DO has a 64 character limit for volume names
|
||||
if len(name) >= 64 {
|
||||
name = name[:64]
|
||||
}
|
||||
|
||||
t := &dotasks.Volume{
|
||||
Name: s(name),
|
||||
Lifecycle: b.Lifecycle,
|
||||
|
|
|
@ -69,6 +69,8 @@ func (c *ClusterResources) ListResources() (map[string]*ResourceTracker, error)
|
|||
switch c.Cloud.ProviderID() {
|
||||
case kops.CloudProviderAWS:
|
||||
return c.listResourcesAWS()
|
||||
case kops.CloudProviderDO:
|
||||
return c.listResourcesDO()
|
||||
case kops.CloudProviderGCE:
|
||||
return c.listResourcesGCE()
|
||||
case kops.CloudProviderVSphere:
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Copyright 2016 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 resources
|
||||
|
||||
func (c *ClusterResources) listResourcesDO() (map[string]*ResourceTracker, error) {
|
||||
return nil, nil
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
KubeAPIServer:
|
||||
CloudProvider: external
|
|
@ -335,7 +335,6 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
return fmt.Errorf("DigitalOcean support is currently (very) alpha and is feature-gated. export KOPS_FEATURE_FLAGS=AlphaAllowDO to enable it")
|
||||
}
|
||||
|
||||
// this is a no-op for now, add tasks to this list as more DO support is added
|
||||
l.AddTypes(map[string]interface{}{
|
||||
"volume": &dotasks.Volume{},
|
||||
})
|
||||
|
@ -649,7 +648,8 @@ func (c *ApplyClusterCmd) Run() error {
|
|||
BootstrapScript: bootstrapScriptBuilder,
|
||||
Lifecycle: clusterLifecycle,
|
||||
})
|
||||
|
||||
case kops.CloudProviderDO:
|
||||
// DigitalOcean tasks will go here
|
||||
case kops.CloudProviderGCE:
|
||||
{
|
||||
gceModelContext := &gcemodel.GCEModelContext{
|
||||
|
|
|
@ -33,14 +33,17 @@ import (
|
|||
const (
|
||||
defaultNodeMachineTypeGCE = "n1-standard-2"
|
||||
defaultNodeMachineTypeVSphere = "vsphere_node"
|
||||
defaultNodeMachineTypeDO = "2gb"
|
||||
|
||||
defaultBastionMachineTypeGCE = "f1-micro"
|
||||
defaultBastionMachineTypeVSphere = "vsphere_bastion"
|
||||
|
||||
defaultMasterMachineTypeGCE = "n1-standard-1"
|
||||
defaultMasterMachineTypeVSphere = "vsphere_master"
|
||||
defaultMasterMachineTypeDO = "2gb"
|
||||
|
||||
defaultVSphereNodeImage = "kops_ubuntu_16_04.ova"
|
||||
defaultDONodeImage = "coreos-stable"
|
||||
)
|
||||
|
||||
var awsDedicatedInstanceExceptions = map[string]bool{
|
||||
|
@ -177,6 +180,16 @@ func defaultMachineType(cluster *kops.Cluster, ig *kops.InstanceGroup) (string,
|
|||
return defaultBastionMachineTypeGCE, nil
|
||||
}
|
||||
|
||||
case kops.CloudProviderDO:
|
||||
switch ig.Spec.Role {
|
||||
case kops.InstanceGroupRoleMaster:
|
||||
return defaultMasterMachineTypeDO, nil
|
||||
|
||||
case kops.InstanceGroupRoleNode:
|
||||
return defaultNodeMachineTypeDO, nil
|
||||
|
||||
}
|
||||
|
||||
case kops.CloudProviderVSphere:
|
||||
switch ig.Spec.Role {
|
||||
case kops.InstanceGroupRoleMaster:
|
||||
|
@ -211,9 +224,15 @@ func defaultImage(cluster *kops.Cluster, channel *kops.Channel) string {
|
|||
return image.Name
|
||||
}
|
||||
}
|
||||
} else if kops.CloudProviderID(cluster.Spec.CloudProvider) == kops.CloudProviderVSphere {
|
||||
}
|
||||
|
||||
switch kops.CloudProviderID(cluster.Spec.CloudProvider) {
|
||||
case kops.CloudProviderDO:
|
||||
return defaultDONodeImage
|
||||
case kops.CloudProviderVSphere:
|
||||
return defaultVSphereNodeImage
|
||||
}
|
||||
|
||||
glog.Infof("Cannot set default Image for CloudProvider=%q", cluster.Spec.CloudProvider)
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -66,6 +66,10 @@ func buildCloudupTags(cluster *api.Cluster) (sets.String, error) {
|
|||
{
|
||||
tags.Insert("_aws")
|
||||
}
|
||||
case "digitalocean":
|
||||
{
|
||||
tags.Insert("_do")
|
||||
}
|
||||
case "vsphere":
|
||||
{
|
||||
tags.Insert("_vsphere")
|
||||
|
@ -147,6 +151,9 @@ func buildNodeupTags(role api.InstanceGroupRole, cluster *api.Cluster, clusterTa
|
|||
if clusterTags.Has("_aws") {
|
||||
tags.Insert("_aws")
|
||||
}
|
||||
if clusterTags.Has("_do") {
|
||||
tags.Insert("_do")
|
||||
}
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
|
|
@ -149,6 +149,10 @@ func (tf *TemplateFunctions) DnsControllerArgv() ([]string, error) {
|
|||
}
|
||||
case kops.CloudProviderGCE:
|
||||
argv = append(argv, "--dns=google-clouddns")
|
||||
case kops.CloudProviderDO:
|
||||
// this is not supported yet, here so we can successfully create clusters
|
||||
// this will be supported for digitalocean in the future
|
||||
argv = append(argv, "--dns=digitalocean")
|
||||
case kops.CloudProviderVSphere:
|
||||
argv = append(argv, "--dns=coredns")
|
||||
argv = append(argv, "--dns-server="+*tf.cluster.Spec.CloudConfig.VSphereCoreDNSServer)
|
||||
|
|
Loading…
Reference in New Issue