Skip to content
This repository has been archived by the owner on Feb 5, 2020. It is now read-only.

Commit

Permalink
digitalocean: Add support for DigitalOcean
Browse files Browse the repository at this point in the history
This extends Tectonic Installer to also support the DigitalOcean cloud
provider.
  • Loading branch information
aknuds1 committed Jan 4, 2018
1 parent 69a0420 commit bf1e2eb
Show file tree
Hide file tree
Showing 32 changed files with 1,339 additions and 1 deletion.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.tpl]
insert_final_newline = false
Expand Down
120 changes: 120 additions & 0 deletions Documentation/dev/digitalocean/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Tectonic Installer for DigitalOcean
This is Tectonic Installer for the [DigitalOcean](http://digitalocean.com/) hosting platform.
Use this guide to bootstrap a Tectonic cluster on with your DigitalOcean account.

## Prerequisites

- **Terraform:** >= v0.10.7
- **Make:** You should install the traditional [Make](https://www.gnu.org/software/make/)
build tool.
- **Docker:** For the time being, you need Docker installed in addition to Terraform, in order
to perform certain tasks.
- **Tectonic Account:** Register for a [Tectonic Account](https://coreos.com/tectonic), which is
free for up to 10 nodes. Download the Tectonic license as tectonic-license.txt and the pull secret
as config.json.
- **DigitalOcean:**
- Obtain an API token by going to DigitalOcean's
[API page](https://cloud.digitalocean.com/settings/api/tokens) and click *Generate New Token*.
Make note of it for later.
- Obtain a Spaces key/secret pair, again by going to DigitalOcean's API page and click
*Generate New Key* in the _Spaces Access Keys_ section. Make note of it for later.
- Ensure that the base domain for the cluster is already created for your DigitalOcean
account and listed among your [domains](https://cloud.digitalocean.com/networking/domains).

## Getting Started

First, clone the Tectonic Installer repository:

```
$ git clone https://github.com/coreos/tectonic-installer.git
$ cd tectonic-installer
```

Then, create the build tree for your cluster:

```
$ CLUSTER=<cluster-name> PLATFORM=digitalocean make localconfig
```

Install the Tectonic license file (tectonic-license.txt) and the pull secret (config.json):

```
$ cp tectonic-license.txt config.json build/<cluster-name>/
```

## Customize the Cluster

You may change the parameters of the cluster bootstrapping via the file
`build/<cluster-name>/terraform.tfvars`, which is
[automatically read](https://www.terraform.io/docs/configuration/variables.html) by Terraform to
populate variables.

Edit the parameters as you need, bearing in mind that some have no defaults and you must
specify values for them. You should substitute the DigitalOcean API token, Spaces key ID and
secret for the variables `tectonic_do_token`, `tectonic_do_spaces_access_key_id` and
`tectonic_do_spaces_secret_access_key` respectively. Additionally, you need to get the ID
of the DigitalOcean SSH key you wish to use, for example like this:
`curl -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $API_TOKEN" https://api.digitalocean.com/v2/account/keys | jq '.ssh_keys[0].id'`.
Substitute the key ID for `tectonic_do_ssh_keys`.

## Deploy the cluster

Test the plan before deploying everything:

```
$ CLUSTER=<cluster-name> PLATFORM=digitalocean make plan
```

Next, bootstrap the cluster:

```
$ CLUSTER=<cluster-name> PLATFORM=digitalocean make apply
```

This should run for a while, and when complete, your Tectonic cluster should be ready.

Tectonic Installer generates a kubeconfig file, which allows you to access your newly created
cluster via kubectl: `build/<cluster-name>/generated/auth/kubeconfig`. For example, you
can inspect the state of your clusters' pods with the following command:
`KUBECONFIG=build/<cluster-name>/generated/auth/kubeconfig kubectl get pods --all-namespaces`.
When every pod is listed as ready, your cluster should be finished bootstrapping.

### Access the cluster

After bootstrapping, you can access the Tectonic Console at `https://<cluster-name>.<base-domain>`.

### Delete the cluster

```
$ CLUSTER=<cluster-name> PLATFORM=digitalocean make destroy
```

## Known Issues

- For technical reasons, only one master is created.

- This is a non stable version currently under heavy development. It is not yet covered by a deprecation policy and may be subject to backward-incompatible changes.

## Developer Notes

### etcd

#### Testing
In order to test the etcd cluster, SSH into one of the etcd nodes and issue the following command
(setting `$CLUSTER_NAME` and `$DOMAIN_NAME` correspondingly):
`sudo ETCDCTL_API=3 etcdctl --cacert=/etc/ssl/etcd/ca.crt --cert=/etc/ssl/etcd/client.crt --key=/etc/ssl/etcd/client.key --endpoints=https://$CLUSTER_NAME-etcd-0.$DOMAIN_NAME:2379 endpoint health`.
This should report that the cluster is healthy.

### Masters
There is currently only one master being created, for reasons of simplicity. It receives the
DNS name `<cluster-name>-api.<domain-name>`, so that it can be contacted as the API server of the
Kubernetes cluster, but also the DNS name `<cluster-name>-master-<index>.<domain-name>`.

### Workers
We create a number of workers corresponding to the variable `tectonic_worker_count`. Each of
these receives a DNS name `<cluster-name>-worker-<index>.<domain-name>`.

### Host Name Resolution
Every master and worker node is configured, via /etc/systemd/resolved.conf, to resolve hostnames
within the base domain. This is because Kubernetes expects to be able to resolve the unqualified
hostnames of its nodes, and will fail otherwise.
2 changes: 1 addition & 1 deletion Documentation/dev/node-bootstrap-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ When a cluster node is being bootstrapped from scratch, it goes through several
1. first-boot OS configuration, via ignition (systemd units, node configuration, etc)
1. provisioning of additional assets (k8s manifests, TLS material), via either of:
* pushing from terraform file/remote-exec (SSH)
* pulling from private cloud stores (S3 buckets)
* pulling from private cloud stores (S3/DigitalOcean Spaces buckets)
1. system-wide updates via `k8s-node-bootstrap.service`, which includes:
* determining current kubernetes cluster version (when joining an existing cluster)
* triggering a ContainerLinux update, via update-engine (optional)
Expand Down
197 changes: 197 additions & 0 deletions examples/terraform.tfvars.digitalocean
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
// Your Tectonic cluster administration email address
tectonic_admin_email = ""

// Your desired Tectonic cluster administration password
tectonic_admin_password = ""

// Your API token for DigitalOcean
tectonic_do_token = ""

// Access key ID and secret access key for DigitalOcean Spaces.
// The Tectonic Installer uses a Spaces bucket to store Tectonic assets and kubeconfig.
tectonic_do_spaces_access_key_id = ""
tectonic_do_spaces_secret_access_key = ""

// Instance size for the etcd node(s). Read the [etcd recommended hardware](https://coreos.com/etcd/docs/latest/op-guide/hardware.html) guide for best performance
tectonic_do_etcd_droplet_size = "2gb"

// (optional) Instance size for the master node(s).
tectonic_do_master_droplet_size = "2gb"

// (optional) Instance size for the worker node(s).
tectonic_do_worker_droplet_size = "2gb"

// A list of DigitalOcean SSH IDs to enable in the created droplets.
tectonic_do_ssh_keys = [1, 2, 3]

// (optional) The region to create your droplets in.
tectonic_do_droplet_region = "nyc1"

// The base DNS domain of the cluster. It must NOT contain a trailing period. Some
// DNS providers will automatically add this if necessary.
//
// Example: `openstack.dev.coreos.systems`.
//
// Note: This field MUST be set manually prior to creating the cluster.
// This applies only to cloud platforms.
//
// [Azure-specific NOTE]
// To use Azure-provided DNS, `tectonic_base_domain` should be set to `""`
// If using DNS records, ensure that `tectonic_base_domain` is set to a properly configured external DNS zone.
// Instructions for configuring delegated domains for Azure DNS can be found here: https://docs.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns
tectonic_base_domain = ""

// (optional) The content of the PEM-encoded CA certificate, used to generate Tectonic Console's server certificate.
// If left blank, a CA certificate will be automatically generated.
// tectonic_ca_cert = ""

// (optional) The content of the PEM-encoded CA key, used to generate Tectonic Console's server certificate.
// This field is mandatory if `tectonic_ca_cert` is set.
// tectonic_ca_key = ""

// (optional) The algorithm used to generate tectonic_ca_key.
// The default value is currently recommended.
// This field is mandatory if `tectonic_ca_cert` is set.
// tectonic_ca_key_alg = "RSA"

// (optional) This declares the IP range to assign Kubernetes pod IPs in CIDR notation.
// tectonic_cluster_cidr = "10.2.0.0/16"

// The name of the cluster.
// If used in a cloud-environment, this will be prepended to `tectonic_base_domain` resulting in the URL to the Tectonic console.
//
// Note: This field MUST be set manually prior to creating the cluster.
// Warning: Special characters in the name like '.' may cause errors on OpenStack platforms due to resource name constraints.
tectonic_cluster_name = ""

// (optional) The Container Linux update channel.
//
// Examples: `stable`, `beta`, `alpha`
// tectonic_container_linux_channel = "stable"

// The Container Linux version to use. Set to `latest` to select the latest available version for the selected update channel.
//
// Examples: `latest`, `1465.6.0`
tectonic_container_linux_version = "latest"

// (optional) A list of PEM encoded CA files that will be installed in /etc/ssl/certs on etcd, master, and worker nodes.
// tectonic_custom_ca_pem_list = ""

// (optional) This only applies if you use the modules/dns/ddns module.
//
// Specifies the RFC2136 Dynamic DNS server key algorithm.
// tectonic_ddns_key_algorithm = ""

// (optional) This only applies if you use the modules/dns/ddns module.
//
// Specifies the RFC2136 Dynamic DNS server key name.
// tectonic_ddns_key_name = ""

// (optional) This only applies if you use the modules/dns/ddns module.
//
// Specifies the RFC2136 Dynamic DNS server key secret.
// tectonic_ddns_key_secret = ""

// (optional) This only applies if you use the modules/dns/ddns module.
//
// Specifies the RFC2136 Dynamic DNS server IP/host to register IP addresses to.
// tectonic_ddns_server = ""

// (optional) DNS prefix used to construct the console and API server endpoints.
// tectonic_dns_name = ""

// (optional) The size in MB of the PersistentVolume used for handling etcd backups.
// tectonic_etcd_backup_size = "512"

// (optional) The name of an existing Kubernetes StorageClass that will be used for handling etcd backups.
// tectonic_etcd_backup_storage_class = ""

// (optional) The path of the file containing the CA certificate for TLS communication with etcd.
//
// Note: This works only when used in conjunction with an external etcd cluster.
// If set, the variable `tectonic_etcd_servers` must also be set.
// tectonic_etcd_ca_cert_path = "/dev/null"

// (optional) The path of the file containing the client certificate for TLS communication with etcd.
//
// Note: This works only when used in conjunction with an external etcd cluster.
// If set, the variables `tectonic_etcd_servers`, `tectonic_etcd_ca_cert_path`, and `tectonic_etcd_client_key_path` must also be set.
// tectonic_etcd_client_cert_path = "/dev/null"

// (optional) The path of the file containing the client key for TLS communication with etcd.
//
// Note: This works only when used in conjunction with an external etcd cluster.
// If set, the variables `tectonic_etcd_servers`, `tectonic_etcd_ca_cert_path`, and `tectonic_etcd_client_cert_path` must also be set.
// tectonic_etcd_client_key_path = "/dev/null"

// The number of etcd nodes to be created.
// If set to zero, the count of etcd nodes will be determined automatically.
//
// Note: This is not supported on bare metal.
tectonic_etcd_count = "0"

// (optional) List of external etcd v3 servers to connect with (hostnames/IPs only).
// Needs to be set if using an external etcd cluster.
// Note: If this variable is defined, the installer will not create self-signed certs.
// To provide a CA certificate to trust the etcd servers, set "tectonic_etcd_ca_cert_path".
//
// Example: `["etcd1", "etcd2", "etcd3"]`
// tectonic_etcd_servers = ""

// (optional) If set to `true`, all etcd endpoints will be configured to use the "https" scheme.
//
// Note: If `tectonic_experimental` is set to `true` this variable has no effect, because the experimental self-hosted etcd always uses TLS.
// tectonic_etcd_tls_enabled = true

// The path to the tectonic licence file.
// You can download the Tectonic license file from your Account overview page at [1].
//
// [1] https://account.coreos.com/overview
//
// Note: This field MUST be set manually prior to creating the cluster unless `tectonic_vanilla_k8s` is set to `true`.
tectonic_license_path = ""

// The number of master nodes to be created.
// This applies only to cloud platforms.
tectonic_master_count = "1"

// (optional) Configures the network to be used in Tectonic. One of the following values can be used:
//
// - "flannel": enables overlay networking only. This is implemented by flannel using VXLAN.
//
// - "canal": [ALPHA] enables overlay networking including network policy. Overlay is implemented by flannel using VXLAN. Network policy is implemented by Calico.
//
// - "calico": [ALPHA] enables BGP based networking. Routing and network policy is implemented by Calico. Note this has been tested on baremetal installations only.
//
// - "none": disables the installation of any Pod level networking layer provided by Tectonic. By setting this value, users are expected to deploy their own solution to enable network connectivity for Pods and Services.
// tectonic_networking = "flannel"

// The path the pull secret file in JSON format.
// This is known to be a "Docker pull secret" as produced by the docker login [1] command.
// A sample JSON content is shown in [2].
// You can download the pull secret from your Account overview page at [3].
//
// [1] https://docs.docker.com/engine/reference/commandline/login/
//
// [2] https://coreos.com/os/docs/latest/registry-authentication.html#manual-registry-auth-setup
//
// [3] https://account.coreos.com/overview
//
// Note: This field MUST be set manually prior to creating the cluster unless `tectonic_vanilla_k8s` is set to `true`.
tectonic_pull_secret_path = ""

// (optional) This declares the IP range to assign Kubernetes service cluster IPs in CIDR notation.
// The maximum size of this IP range is /12
// tectonic_service_cidr = "10.3.0.0/16"

// Validity period of the self-signed certificates (in hours).
// Default is 3 years.
// This setting is ignored if user provided certificates are used.
tectonic_tls_validity_period = "26280"

// If set to true, a vanilla Kubernetes cluster will be deployed, omitting any Tectonic assets.
tectonic_vanilla_k8s = false

// The number of worker nodes to be created.
// This applies only to cloud platforms.
tectonic_worker_count = "3"
7 changes: 7 additions & 0 deletions modules/digitalocean/etcd/dns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
resource "digitalocean_record" "etcd_nodes" {
count = "${var.droplet_count}"
type = "A"
domain = "${var.base_domain}"
name = "${var.cluster_name}-etcd-${count.index}"
value = "${digitalocean_droplet.etcd_node.*.ipv4_address[count.index]}"
}
45 changes: 45 additions & 0 deletions modules/digitalocean/etcd/ignition.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
data "ignition_config" "etcd" {
count = "${var.droplet_count}"

systemd = [
"${data.ignition_systemd_unit.locksmithd.*.id[count.index]}",
"${var.ign_etcd_dropin_id_list[count.index]}",
]

files = [
"${var.ign_etcd_crt_id_list}",
"${data.ignition_file.node_hostname.*.id[count.index]}",
]
}

data "ignition_file" "node_hostname" {
count = "${var.droplet_count}"
path = "/etc/hostname"
mode = 0644
filesystem = "root"

content {
content = "${var.cluster_name}-etcd-${count.index}.${var.base_domain}"
}
}

data "ignition_systemd_unit" "locksmithd" {
count = "${var.droplet_count}"
name = "locksmithd.service"
enabled = true

dropin = [
{
name = "40-etcd-lock.conf"

content = <<EOF
[Service]
Environment=REBOOT_STRATEGY=etcd-lock
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CAFILE=/etc/ssl/etcd/ca.crt\"" : ""}
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_KEYFILE=/etc/ssl/etcd/client.key\"" : ""}
${var.tls_enabled ? "Environment=\"LOCKSMITHD_ETCD_CERTFILE=/etc/ssl/etcd/client.crt\"" : ""}
Environment="LOCKSMITHD_ENDPOINT=${var.tls_enabled ? "https" : "http"}://${var.cluster_name}-etcd-${count.index}.${var.base_domain}:2379"
EOF
},
]
}
Loading

0 comments on commit bf1e2eb

Please sign in to comment.