You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Created VM instances for what will be Control Plane nodes and Worker Nodes.
Created a slew of certificates (all signed by a self-signed CA) to secure communications between components.
Created kubeconfig for all of the API Service clients.
Established a shared secret for encryption of data at rest.
Installed etcd (a clustered key-value DB) on the controller nodes (required configuration).
Attempted to install the control plane software (apiserver, controller-manager, scheduler,...) but all three control plane VMs jammed-up processing etcd traffic. I chose undersized instances and they could not, in fact, handle even idle loads.
... so I started over from "Create VM instances" ...
...
1.
Details
Prep
installed gcloud (via brew cask install google-cloud-sdk) so that we can do IaaS work from the command-line
(and likely so that other tooling has programmatic access to the infrastructure?)
installed cfssl (via brew install cfssl in order to generate certificates (why not use openssl?)
(see also https://github.com/cloudflare/cfssl)
Side trips
(stuff I did that wasn't in the tutorial)
fix the kubectl install
$ brew reinstall kubectl
==> Reinstalling kubernetes-cli
==> Downloading https://homebrew.bintray.com/bottles/kubernetes-cli-1.16.1.mojave.bottle.tar.gz
Already downloaded: /Users/jryan/Library/Caches/Homebrew/downloads/65c8ffb92651c32e96cc7eb2e36e58ea97b3a1148a579c3fb9a287df498ea59e--kubernetes-cli-1.16.1.mojave.bottle.tar.gz
==> Pouring kubernetes-cli-1.16.1.mojave.bottle.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/kubectl
Target /usr/local/bin/kubectl
already exists. You may want to remove it:
rm '/usr/local/bin/kubectl'
...
Possible conflicting files are:
/usr/local/bin/kubectl -> /Applications/Docker.app/Contents/Resources/bin/kubectl
...
So, I:
$ $ brew link --overwrite kubernetes-cli
Linking /usr/local/Cellar/kubernetes-cli/1.16.1... 227 symlinks created
Paving (manual)
Create VPC
$ gcloud compute networks create k8s-the-hard-way --subnet-mode custom
Created [https://www.googleapis.com/compute/v1/projects/cf-sandbox-release-engineering/global/networks/k8s-the-hard-way].
NAME SUBNET_MODE BGP_ROUTING_MODE IPV4_RANGE GATEWAY_IPV4
k8s-the-hard-way CUSTOM REGIONAL
Instances on this network will not be reachable until firewall rules
are created. As an example, you can allow all internal traffic between
instances as well as SSH, RDP, and ICMP by running:
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network k8s-the-hard-way --allow tcp,udp,icmp --source-ranges <IP_RANGE>
$ gcloud compute firewall-rules create <FIREWALL_NAME> --network k8s-the-hard-way --allow tcp:22,tcp:3389,icmp
Create Subnet within the VPC
$ gcloud compute networks subnets create k8s-cluster-subnet --network k8s-the-hard-way --range 10.240.0.0/24
Created [https://www.googleapis.com/compute/v1/projects/cf-sandbox-release-engineering/regions/us-central1/subnetworks/k8s-cluster-subnet].
NAME REGION NETWORK RANGE
k8s-cluster-subnet us-central1 k8s-the-hard-way 10.240.0.0/24
$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca
2019/10/13 06:55:43 [INFO] generating a new CA key and certificate from CSR
2019/10/13 06:55:43 [INFO] generate received request
2019/10/13 06:55:43 [INFO] received CSR
2019/10/13 06:55:43 [INFO] generating key: rsa-2048
2019/10/13 06:55:43 [INFO] encoded CSR
2019/10/13 06:55:43 [INFO] signed certificate with serial number 318904427095986789448913517096609908161556343159
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=k8s_profile admin-csr.json | cfssljson -bare admin
2019/10/13 07:18:53 [INFO] generate received request
2019/10/13 07:18:53 [INFO] received CSR
2019/10/13 07:18:53 [INFO] generating key: rsa-2048
2019/10/13 07:18:53 [INFO] encoded CSR
2019/10/13 07:18:53 [INFO] signed certificate with serial number 152182081464568438529354720500210576012060174994
2019/10/13 07:18:53 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
On each Node, it's the kubelet process that communicates with the API server. The API provides for what is called
"Node Authentication": where if the process provides a CA-signed certificate in which the "CN" is in the format: system:node:<NODE-HOSTNAME> (where NODE-HOSTNAME matches perfectly the hostname of the node) and is in the system:nodes group (i.e. has the name "O": "system:nodes")... the API will consider calls from that node as authenticated.
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=k8s_profile kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
2019/10/13 10:57:33 [INFO] generate received request
2019/10/13 10:57:33 [INFO] received CSR
2019/10/13 10:57:33 [INFO] generating key: rsa-2048
2019/10/13 10:57:33 [INFO] encoded CSR
2019/10/13 10:57:33 [INFO] signed certificate with serial number 519343206361199162178115795663679563707198112632
2019/10/13 10:57:33 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=k8s_profile kube-proxy-csr.json | cfssljson -bare kube-proxy
2019/10/13 15:54:22 [INFO] generate received request
2019/10/13 15:54:22 [INFO] received CSR
2019/10/13 15:54:22 [INFO] generating key: rsa-2048
2019/10/13 15:54:22 [INFO] encoded CSR
2019/10/13 15:54:22 [INFO] signed certificate with serial number 85244603884961202522822863434789970908800025971
2019/10/13 15:54:22 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=k8s_profile kube-scheduler-csr.json | cfssljson -bare kube-scheduler
2019/10/13 16:00:01 [INFO] generate received request
2019/10/13 16:00:01 [INFO] received CSR
2019/10/13 16:00:01 [INFO] generating key: rsa-2048
2019/10/13 16:00:01 [INFO] encoded CSR
2019/10/13 16:00:01 [INFO] signed certificate with serial number 306089489826831215456760835511263900668702419959
2019/10/13 16:00:01 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
$ cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=k8s_profile service-account-csr.json | cfssljson -bare service-account
2019/10/13 16:43:48 [INFO] generate received request
2019/10/13 16:43:48 [INFO] received CSR
2019/10/13 16:43:48 [INFO] generating key: rsa-2048
2019/10/13 16:43:48 [INFO] encoded CSR
2019/10/13 16:43:48 [INFO] signed certificate with serial number 140630582793387107716676495732507467442102422418
2019/10/13 16:43:48 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
Distribute PKI Bits
distribute-certificates.sh
#!/usr/bin/env bash
WORKERS=$(gcloud compute instances list --filter="tags.items=(worker)" --format=json | jq -r .[].name)
echo "Distributing with CA cert, node cert, node private key to worker nodes:"
for worker in ${WORKERS}; do
echo "- ${worker}"
gcloud compute scp ca.pem ${worker}-key.pem ${worker}.pem ${worker}:~/
done
echo "done."
CONTROLLERS=$(gcloud compute instances list --filter="tags.items=(controller)" --format=json | jq -r .[].name)
echo "Distributing CA cert & private key, 'kubernetes' service cert & private key, 'service-account' cert & private key:"
for controller in ${CONTROLLERS}; do
echo "- ${controller}"
gcloud compute scp ca.pem ca-key.pem kubernetes.pem kubernetes-key.pem service-account.pem service-account-key.pem ${controller}:~/
done