From aef85dd6033e576e2c6e6b19c32c9e5fab12cf31 Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Thu, 26 May 2016 11:49:57 -0700 Subject: [PATCH] start a development guide for min-turnup --- min-turnup/Dockerfile | 19 ++ min-turnup/Documentation/devel.md | 59 +++++ min-turnup/Makefile | 2 +- min-turnup/phase1/gce/.gitignore | 1 + min-turnup/phase1/gce/configure-vm.sh | 5 +- min-turnup/phase1/gce/gen | 4 +- min-turnup/phase1/gce/lib/gce.jsonnet | 5 + min-turnup/phase1/gce/out/gce.tf | 243 ------------------ min-turnup/phase3/Kconfig | 12 - min-turnup/phase3/all.jsonnet | 8 + min-turnup/phase3/dashboard/dashboard-rc.json | 59 +++++ .../phase3/dashboard/dashboard-svc.json | 23 ++ min-turnup/phase3/dashboard/dashboard.jsonnet | 5 + min-turnup/phase3/gen | 8 + .../phase3/kube-proxy/kube-proxy-ds.json | 75 ++++++ .../phase3/kube-proxy/kube-proxy.jsonnet | 4 + 16 files changed, 274 insertions(+), 258 deletions(-) create mode 100644 min-turnup/Dockerfile create mode 100644 min-turnup/Documentation/devel.md delete mode 100644 min-turnup/phase1/gce/out/gce.tf create mode 100644 min-turnup/phase3/all.jsonnet create mode 100644 min-turnup/phase3/dashboard/dashboard-rc.json create mode 100644 min-turnup/phase3/dashboard/dashboard-svc.json create mode 100644 min-turnup/phase3/dashboard/dashboard.jsonnet create mode 100755 min-turnup/phase3/gen create mode 100644 min-turnup/phase3/kube-proxy/kube-proxy-ds.json create mode 100644 min-turnup/phase3/kube-proxy/kube-proxy.jsonnet diff --git a/min-turnup/Dockerfile b/min-turnup/Dockerfile new file mode 100644 index 000000000..4134742c2 --- /dev/null +++ b/min-turnup/Dockerfile @@ -0,0 +1,19 @@ +# a big docker file meant for depolying min-turnup +FROM ubuntu + +RUN apt-get update +RUN apt-get install -y curl vim jq libssl-dev openssl zip make sudo + +RUN curl -sSL --fail -o /usr/local/bin/jsonnet \ + "https://storage.googleapis.com/kube-deploy/jsonnet/adf169b1e4a4ba170f58b47111ed88552fae42c8" +RUN chmod +x /usr/local/bin/jsonnet + +RUN curl -sSL --fail \ + "https://releases.hashicorp.com/terraform/0.6.16/terraform_0.6.16_linux_amd64.zip" \ + -o /tmp/tf.zip \ + && unzip -d /usr/local/bin /tmp/tf.zip \ + && rm /tmp/tf.zip + +WORKDIR /root/min-turnup + +CMD bash diff --git a/min-turnup/Documentation/devel.md b/min-turnup/Documentation/devel.md new file mode 100644 index 000000000..027095807 --- /dev/null +++ b/min-turnup/Documentation/devel.md @@ -0,0 +1,59 @@ +# Developing on min-turnup + +### How to deploy a cluster + +Here is a flow for deploying a min-turnup cluster on GCE. +``` +$ # checkout code and enter min-turnup directory +$ cd min-turnup/ + +$ # build .config.json +$ make config +$ # or +$ make menuconfig +$ make .config.json +$ # mine looks like +$ cat .config.json +{ + "phase1": { + "num_nodes": 4, + "instance_prefix": "kuberentes", + "cloud_provider": "gce", + "gce": { + "os_image": "ubuntu-1604-xenial-v20160420c", + "instance_type": "n1-standard-2", + "project": "", + "region": "us-central1", + "zone": "us-central1-b", + "network": "" + } + }, + "phase1b": { + "extra_api_sans": "", + "extra_api_dns_names": "kubernetes-master" + }, + "phase2": { + "docker_registry": "gcr.io/google-containers", + "kubernetes_version": "v1.2.4" + }, + "phase3": { + "run_addons": true, + "kube_proxy": true, + "dashboard": true, + "kube_dns": true, + "elasticsearch": true + } +} + +$ # generate and deploy terraform +$ cd phase1/gce/ +$ ./gen +$ terraform apply out/ +``` + +The current dependencies are: + +* terraform on your path, available [here](https://www.terraform.io/downloads.html). +* jsonnet which needs to be built from source, available [here](https://github.com/google/jsonnet/releases/tag/v0.8.8). +* linux x86_64, other platforms are not yet tested. +* jq diff --git a/min-turnup/Makefile b/min-turnup/Makefile index 26ffa1894..a43e0070a 100644 --- a/min-turnup/Makefile +++ b/min-turnup/Makefile @@ -1,6 +1,6 @@ SHELL=/bin/bash -.SHELLFLAGS="-O extglob -o errexit -o pipefail -o nounset -c" +.SHELLFLAGS="-O" "extglob" "-o" "errexit" "-o" "pipefail" "-o" "nounset" "-c" .PHONY: config echo-config diff --git a/min-turnup/phase1/gce/.gitignore b/min-turnup/phase1/gce/.gitignore index 7cb9a0a86..70dc0b7fd 100644 --- a/min-turnup/phase1/gce/.gitignore +++ b/min-turnup/phase1/gce/.gitignore @@ -1,3 +1,4 @@ terraform.tfstate account.json terraform.tfstate.backup +out/gce.tf diff --git a/min-turnup/phase1/gce/configure-vm.sh b/min-turnup/phase1/gce/configure-vm.sh index 80937170d..fe03ef7f8 100644 --- a/min-turnup/phase1/gce/configure-vm.sh +++ b/min-turnup/phase1/gce/configure-vm.sh @@ -7,6 +7,9 @@ set -o nounset ROLE=$(curl \ -H "Metadata-Flavor: Google" \ "metadata/computeMetadata/v1/instance/attributes/k8s-role") +BUCKET=$(curl \ + -H "Metadata-Flavor: Google" \ + "metadata/computeMetadata/v1/instance/attributes/k8s-deploy-bucket") mkdir -p /etc/systemd/system/docker.service.d/ cat < /etc/systemd/system/docker.service.d/clear_mount_propagtion_flags.conf @@ -22,7 +25,7 @@ curl -H 'Metadata-Flavor:Google' \ #TODO: restrict by role mkdir -p /srv/kubernetes for bundle in root kubelet apiserver; do - gsutil cp "gs://mikedanese-k8s-kube-deploy-k-0/crypto/${bundle}.tar" - \ + gsutil cp "gs://${BUCKET}/crypto/${bundle}.tar" - \ | sudo tar xv -C /srv/kubernetes done; diff --git a/min-turnup/phase1/gce/gen b/min-turnup/phase1/gce/gen index 62280284d..e89e08e41 100755 --- a/min-turnup/phase1/gce/gen +++ b/min-turnup/phase1/gce/gen @@ -4,4 +4,6 @@ set -o errexit set -o pipefail set -o nounset -jsonnet --multi out/ all.jsonnet +cd "${BASH_SOURCE%/*}" + +jsonnet -J ../../ --multi out/ all.jsonnet diff --git a/min-turnup/phase1/gce/lib/gce.jsonnet b/min-turnup/phase1/gce/lib/gce.jsonnet index c78294207..0849417c8 100644 --- a/min-turnup/phase1/gce/lib/gce.jsonnet +++ b/min-turnup/phase1/gce/lib/gce.jsonnet @@ -25,6 +25,9 @@ function(cfg) local config_metadata_template = std.toString(cfg { master_ip: "${google_compute_address.%s.address}", role: "%s", + phase3+: { + addons_config: (import "phase3/all.jsonnet")(cfg), + }, }); { provider: { @@ -119,6 +122,7 @@ function(cfg) metadata_startup_script: std.escapeStringDollars(importstr "../configure-vm.sh"), metadata: { "k8s-role": "master", + "k8s-deploy-bucket": names.release_bucket, "k8s-config": config_metadata_template % [names.master_ip, "master"], }, disk: [{ @@ -136,6 +140,7 @@ function(cfg) metadata: { "startup-script": std.escapeStringDollars(importstr "../configure-vm.sh"), "k8s-role": "node", + "k8s-deploy-bucket": names.release_bucket, "k8s-config": config_metadata_template % [names.master_ip, "node"], }, disk: [{ diff --git a/min-turnup/phase1/gce/out/gce.tf b/min-turnup/phase1/gce/out/gce.tf deleted file mode 100644 index a578ffd76..000000000 --- a/min-turnup/phase1/gce/out/gce.tf +++ /dev/null @@ -1,243 +0,0 @@ -{ - "provider": { - "google": { - "credentials": "${file(\"account.json\")}", - "project": "placeholder", - "region": "us-central1" - } - }, - "resource": { - "google_compute_address": { - "kuberentes-master-ip": { - "name": "kuberentes-master-ip", - "provisioner": [ - { - "local-exec": { - "command": "cat < ../crypto/san-extras\nDNS.1 = kubernetes\nDNS.2 = kubernetes.default\nDNS.3 = kubernetes.default.svc\nDNS.4 = kubernetes.default.svc.cluster.local\nDNS.5 = kuberentes-master\nIP.1 = ${google_compute_address.kuberentes-master-ip.address}\nIP.2 = 10.0.0.1\nEOF\n" - } - } - ], - "region": "us-central1" - } - }, - "google_compute_firewall": { - "kuberentes-master-https": { - "allow": [ - { - "ports": [ - "443" - ], - "protocol": "tcp" - } - ], - "name": "kuberentes-master-https", - "network": "${google_compute_network.network.name}", - "source_ranges": [ - "0.0.0.0/0" - ], - "target_tags": [ - "kuberentes-master" - ] - }, - "kuberentes-minion-all": { - "allow": [ - { - "protocol": "tcp" - }, - { - "protocol": "udp" - }, - { - "protocol": "icmp" - }, - { - "protocol": "ah" - }, - { - "protocol": "sctp" - } - ], - "name": "kuberentes-minion-all", - "network": "${google_compute_network.network.name}", - "source_ranges": [ - "10.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16" - ], - "target_tags": [ - "kuberentes-node" - ] - }, - "ssh_all": { - "allow": [ - { - "ports": [ - "22" - ], - "protocol": "tcp" - } - ], - "name": "ssh-all", - "network": "${google_compute_network.network.name}", - "source_ranges": [ - "0.0.0.0/0" - ] - } - }, - "google_compute_instance": { - "kuberentes-master": { - "can_ip_forward": true, - "disk": [ - { - "image": "ubuntu-1604-xenial-v20160420c" - } - ], - "machine_type": "n1-standard-2", - "metadata": { - "k8s-config": "{\"cloud_provider\": {\"gce\": true}, \"docker_registry\": \"gcr.io/google-containers\", \"gce\": {\"instance_type\": \"n1-standard-2\", \"network\": \"placeholder\", \"os_image\": \"ubuntu-1604-xenial-v20160420c\", \"project\": \"placeholder\", \"region\": \"us-central1\", \"zone\": \"us-central1-b\"}, \"instance_prefix\": \"kuberentes\", \"kubernetes_version\": \"v1.2.4\", \"master_ip\": \"${google_compute_address.kuberentes-master-ip.address}\", \"num_nodes\": 4, \"role\": \"master\"}", - "k8s-role": "master" - }, - "metadata_startup_script": "#! /bin/bash\n\nset -o errexit\nset -o pipefail\nset -o nounset\n\nROLE=$$(curl \\\n -H \"Metadata-Flavor: Google\" \\\n \"metadata/computeMetadata/v1/instance/attributes/k8s-role\")\n\nmkdir -p /etc/systemd/system/docker.service.d/\ncat < /etc/systemd/system/docker.service.d/clear_mount_propagtion_flags.conf\n[Service]\nMountFlags=shared\nEOF\n\nmkdir -p /etc/kubernetes/\ncurl -H 'Metadata-Flavor:Google' \\\n \"metadata/computeMetadata/v1/instance/attributes/k8s-config\" \\\n -o /etc/kubernetes/k8s_config.json\n\ncurl -sSL https://get.docker.com/ | sh\napt-get install bzip2\nsystemctl start docker || true\n\ndocker run \\\n --net=host \\\n -v /:/host_root \\\n -v /etc/kubernetes/k8s_config.json:/opt/playbooks/config.json:ro \\\n gcr.io/mikedanese-k8s/install-k8s:v1 \\\n /opt/do_role.sh \"$${ROLE}\"\n", - "name": "kuberentes-master", - "network_interface": [ - { - "access_config": { - "nat_ip": "${google_compute_address.kuberentes-master-ip.address}" - }, - "network": "${google_compute_network.network.name}" - } - ], - "scheduling": { - "automatic_restart": true, - "on_host_maintenance": "MIGRATE" - }, - "service_account": [ - { - "scopes": [ - "compute-rw", - "storage-ro" - ] - } - ], - "tags": [ - "kuberentes-master", - "kuberentes-node" - ], - "zone": "us-central1-b" - } - }, - "google_compute_instance_group_manager": { - "kuberentes-minion-group": { - "base_instance_name": "kuberentes-minion", - "instance_template": "${google_compute_instance_template.kuberentes-minion-instance-template.self_link}", - "name": "kuberentes-minion-group", - "target_size": 4, - "update_strategy": "NONE", - "zone": "us-central1-b" - } - }, - "google_compute_instance_template": { - "kuberentes-minion-instance-template": { - "can_ip_forward": true, - "disk": [ - { - "auto_delete": true, - "boot": true, - "source_image": "ubuntu-1604-xenial-v20160420c" - } - ], - "machine_type": "n1-standard-2", - "metadata": { - "k8s-config": "{\"cloud_provider\": {\"gce\": true}, \"docker_registry\": \"gcr.io/google-containers\", \"gce\": {\"instance_type\": \"n1-standard-2\", \"network\": \"placeholder\", \"os_image\": \"ubuntu-1604-xenial-v20160420c\", \"project\": \"placeholder\", \"region\": \"us-central1\", \"zone\": \"us-central1-b\"}, \"instance_prefix\": \"kuberentes\", \"kubernetes_version\": \"v1.2.4\", \"master_ip\": \"${google_compute_address.kuberentes-master-ip.address}\", \"num_nodes\": 4, \"role\": \"node\"}", - "k8s-role": "node", - "startup-script": "#! /bin/bash\n\nset -o errexit\nset -o pipefail\nset -o nounset\n\nROLE=$$(curl \\\n -H \"Metadata-Flavor: Google\" \\\n \"metadata/computeMetadata/v1/instance/attributes/k8s-role\")\n\nmkdir -p /etc/systemd/system/docker.service.d/\ncat < /etc/systemd/system/docker.service.d/clear_mount_propagtion_flags.conf\n[Service]\nMountFlags=shared\nEOF\n\nmkdir -p /etc/kubernetes/\ncurl -H 'Metadata-Flavor:Google' \\\n \"metadata/computeMetadata/v1/instance/attributes/k8s-config\" \\\n -o /etc/kubernetes/k8s_config.json\n\ncurl -sSL https://get.docker.com/ | sh\napt-get install bzip2\nsystemctl start docker || true\n\ndocker run \\\n --net=host \\\n -v /:/host_root \\\n -v /etc/kubernetes/k8s_config.json:/opt/playbooks/config.json:ro \\\n gcr.io/mikedanese-k8s/install-k8s:v1 \\\n /opt/do_role.sh \"$${ROLE}\"\n" - }, - "name": "kuberentes-minion-instance-template", - "network_interface": [ - { - "access_config": { }, - "network": "${google_compute_network.network.name}" - } - ], - "scheduling": { - "automatic_restart": true, - "on_host_maintenance": "MIGRATE" - }, - "service_account": [ - { - "scopes": [ - "compute-rw", - "storage-ro" - ] - } - ], - "tags": [ - "kuberentes-node" - ] - } - }, - "google_compute_network": { - "network": { - "auto_create_subnetworks": true, - "name": "placeholder" - } - }, - "google_storage_bucket": { - "placeholder-kube-deploy-kuberentes": { - "name": "placeholder-kube-deploy-kuberentes" - } - }, - "google_storage_bucket_object": { - "crypto_all": { - "bucket": "placeholder-kube-deploy-kuberentes", - "depends_on": [ - "google_storage_bucket.placeholder-kube-deploy-kuberentes", - "null_resource.crypto_assets" - ], - "name": "crypto/all.tar", - "source": "../crypto/all.tar" - }, - "crypto_apiserver": { - "bucket": "placeholder-kube-deploy-kuberentes", - "depends_on": [ - "google_storage_bucket.placeholder-kube-deploy-kuberentes", - "null_resource.crypto_assets" - ], - "name": "crypto/apiserver.tar", - "source": "../crypto/apiserver.tar" - }, - "crypto_kubelet": { - "bucket": "placeholder-kube-deploy-kuberentes", - "depends_on": [ - "google_storage_bucket.placeholder-kube-deploy-kuberentes", - "null_resource.crypto_assets" - ], - "name": "crypto/kubelet.tar", - "source": "../crypto/kubelet.tar" - }, - "crypto_root": { - "bucket": "placeholder-kube-deploy-kuberentes", - "depends_on": [ - "google_storage_bucket.placeholder-kube-deploy-kuberentes", - "null_resource.crypto_assets" - ], - "name": "crypto/root.tar", - "source": "../crypto/root.tar" - } - }, - "null_resource": { - "crypto_assets": { - "depends_on": [ - "google_compute_address.kuberentes-master-ip" - ], - "provisioner": [ - { - "local-exec": { - "command": "make -C ../crypto clean && make -C ../crypto" - } - } - ] - } - } - } -} diff --git a/min-turnup/phase3/Kconfig b/min-turnup/phase3/Kconfig index 19d6fb9d7..8d87117f4 100644 --- a/min-turnup/phase3/Kconfig +++ b/min-turnup/phase3/Kconfig @@ -21,18 +21,6 @@ config phase3.dashboard help Should we deploy the kubernetes dashboard? -config phase3.kube_dns - bool "Run kube-dns?" - default y - help - Should we deploy kube-dns? - -config phase3.elasticsearch - bool "Run elasticsearch?" - default y - help - Should we deploy elasticsearch? - endif endmenu diff --git a/min-turnup/phase3/all.jsonnet b/min-turnup/phase3/all.jsonnet new file mode 100644 index 000000000..9b2adc058 --- /dev/null +++ b/min-turnup/phase3/all.jsonnet @@ -0,0 +1,8 @@ +function(cfg) + local enabled = function(addon) + cfg.phase3[addon]; + if cfg.phase3.run_addons then + (if enabled("kube_proxy") then + (import "kube-proxy/kube-proxy.jsonnet")(cfg)) + + (if enabled("dashboard") then + (import "dashboard/dashboard.jsonnet")(cfg)) diff --git a/min-turnup/phase3/dashboard/dashboard-rc.json b/min-turnup/phase3/dashboard/dashboard-rc.json new file mode 100644 index 000000000..8e7c6ec00 --- /dev/null +++ b/min-turnup/phase3/dashboard/dashboard-rc.json @@ -0,0 +1,59 @@ +{ + "kind": "ReplicationController", + "spec": { + "replicas": 1, + "template": { + "spec": { + "containers": [ + { + "ports": [ + { + "containerPort": 9090 + } + ], + "livenessProbe": { + "initialDelaySeconds": 30, + "httpGet": { + "path": "/", + "port": 9090 + }, + "timeoutSeconds": 30 + }, + "image": "gcr.io/google_containers/kubernetes-dashboard-amd64:v1.1.0-beta2", + "resources": { + "requests": { + "cpu": "100m", + "memory": "50Mi" + }, + "limits": { + "cpu": "100m", + "memory": "50Mi" + } + }, + "name": "kubernetes-dashboard" + } + ] + }, + "metadata": { + "labels": { + "k8s-app": "kubernetes-dashboard", + "version": "v1.1.0-beta2", + "kubernetes.io/cluster-service": "true" + } + } + }, + "selector": { + "k8s-app": "kubernetes-dashboard" + } + }, + "apiVersion": "v1", + "metadata": { + "labels": { + "k8s-app": "kubernetes-dashboard", + "version": "v1.1.0-beta2", + "kubernetes.io/cluster-service": "true" + }, + "namespace": "kube-system", + "name": "kubernetes-dashboard-v1.1.0-beta2" + } +} \ No newline at end of file diff --git a/min-turnup/phase3/dashboard/dashboard-svc.json b/min-turnup/phase3/dashboard/dashboard-svc.json new file mode 100644 index 000000000..a2a0999f5 --- /dev/null +++ b/min-turnup/phase3/dashboard/dashboard-svc.json @@ -0,0 +1,23 @@ +{ + "kind": "Service", + "spec": { + "ports": [ + { + "targetPort": 9090, + "port": 80 + } + ], + "selector": { + "k8s-app": "kubernetes-dashboard" + } + }, + "apiVersion": "v1", + "metadata": { + "labels": { + "k8s-app": "kubernetes-dashboard", + "kubernetes.io/cluster-service": "true" + }, + "namespace": "kube-system", + "name": "kubernetes-dashboard" + } +} \ No newline at end of file diff --git a/min-turnup/phase3/dashboard/dashboard.jsonnet b/min-turnup/phase3/dashboard/dashboard.jsonnet new file mode 100644 index 000000000..1a123a950 --- /dev/null +++ b/min-turnup/phase3/dashboard/dashboard.jsonnet @@ -0,0 +1,5 @@ +function(cfg) + { + "dashboard-svc.json": (import "dashboard-svc.json"), + "dashboard-rc.json": (import "dashboard-rc.json"), + } diff --git a/min-turnup/phase3/gen b/min-turnup/phase3/gen new file mode 100755 index 000000000..021e55d0f --- /dev/null +++ b/min-turnup/phase3/gen @@ -0,0 +1,8 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + +cd "${BASH_SOURCE%/*}" +jsonnet --tla-code-file cfg=../.config.json all.jsonnet diff --git a/min-turnup/phase3/kube-proxy/kube-proxy-ds.json b/min-turnup/phase3/kube-proxy/kube-proxy-ds.json new file mode 100644 index 000000000..708534fca --- /dev/null +++ b/min-turnup/phase3/kube-proxy/kube-proxy-ds.json @@ -0,0 +1,75 @@ +{ + "kind": "DaemonSet", + "spec": { + "hostNetwork": true, + "template": { + "spec": { + "containers": [ + { + "securityContext": { + "privileged": true + }, + "name": "kube-proxy", + "command": [ + "/bin/sh", + "-c", + "kube-proxy --resource-container=\"\"" + ], + "image": "gcr.io/kube-proxy:v1.2.4", + "volumeMounts": [ + { + "readOnly": true, + "mountPath": "/etc/ssl/certs", + "name": "ssl-certs-host" + }, + { + "readOnly": false, + "mountPath": "/var/log", + "name": "varlog" + }, + { + "readOnly": false, + "mountPath": "/var/lib/kube-proxy/kubeconfig", + "name": "kubeconfig" + } + ], + "resources": { + "requests": { + "cpu": "100m" + } + } + } + ], + "volumes": [ + { + "hostPath": { + "path": "/usr/share/ca-certificates" + }, + "name": "ssl-certs-host" + }, + { + "hostPath": { + "path": "/var/lib/kube-proxy/kubeconfig" + }, + "name": "kubeconfig" + }, + { + "hostPath": { + "path": "/var/log" + }, + "name": "varlog" + } + ] + } + } + }, + "apiVersion": "v1", + "metadata": { + "labels": { + "tier": "node", + "component": "kube-proxy" + }, + "namespace": "kube-system", + "name": "kube-proxy" + } +} \ No newline at end of file diff --git a/min-turnup/phase3/kube-proxy/kube-proxy.jsonnet b/min-turnup/phase3/kube-proxy/kube-proxy.jsonnet new file mode 100644 index 000000000..9cf8d5a80 --- /dev/null +++ b/min-turnup/phase3/kube-proxy/kube-proxy.jsonnet @@ -0,0 +1,4 @@ +function(cfg) + { + ["kube-proxy.json"]: (import "kube-proxy-ds.json"), + }