Skip to content

Instantly share code, notes, and snippets.

@ttwd80
Last active April 18, 2021 19:55
Show Gist options
  • Save ttwd80/72b2cb574a0f007cdea5a494b0c2396e to your computer and use it in GitHub Desktop.
Save ttwd80/72b2cb574a0f007cdea5a494b0c2396e to your computer and use it in GitHub Desktop.

Kubernetes the hard way

docker pull gcr.io/google.com/cloudsdktool/cloud-sdk:latest && \
    docker run --rm -it -v ${HOME}/.config/gcloud:/root/.config/gcloud \
        gcr.io/google.com/cloudsdktool/cloud-sdk /bin/bash

Based on commit ca96371e4d2d2176e8b2c3f5b656b5d92973479e

Chapter 1 - Prerequisites

Prerequisites

Original code #1

Purpose: To check the current version. It should be version 301.0.0 or higher. My version was Google Cloud SDK 336.0.0.

gcloud version

Original code #2

Purpose: Initialize or reinitialize gcloud.

gcloud init

Original code #3

Purpose: To authenticate.

gcloud auth login

Original code #4

Purpose: To set the compute region.

gcloud config set compute/region us-west1

Changed to:

gcloud config set compute/region australia-southeast1

Note: If you enter an invalid region:

# gcloud config set compute/region invalid
Updated property [compute/region].
WARNING: invalid is not a valid region. Run `gcloud compute regions list`to get all regions.

Original code #5

Purpose: To set the compute zone.

gcloud config set compute/zone us-west1-c

Changed to:

gcloud config set compute/zone australia-southeast1-a

Chapter 2 - Installing the Client Tools

Installing the Client Tools

Original code #6

Purpose: To get cfssl and cfssljson.

wget -q --show-progress --https-only --timestamping \
  https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssl \
  https://storage.googleapis.com/kubernetes-the-hard-way/cfssl/1.4.1/linux/cfssljson

Changed to:

apt-get update
apt-get install -y wget jq sudo
CFSSL_VERSION=$(curl https://github.com/cloudflare/cfssl/releases/latest | grep -o "[0-9]*\.[0-9]*\.[0-9]*")
echo ${CFSSL_VERSION}
wget -q --show-progress --https-only --timestamping \
  "https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssl_${CFSSL_VERSION}_linux_amd64" \
  "https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssljson_${CFSSL_VERSION}_linux_amd64"
mv cfssl_${CFSSL_VERSION}_linux_amd64 cfssl
mv cfssljson_${CFSSL_VERSION}_linux_amd64 cfssljson

Original code #7

Purpose: To make the downloaded files to be executable.

chmod +x cfssl cfssljson

Original code #8

Purpose: To move the executable files to a directory in the PATH.

sudo mv cfssl cfssljson /usr/local/bin/

Original code #9

Purpose: To verify we have cfssl version >= 1.4.1.

cfssl version

Original code #10

Purpose: To verify we have cfssljson version >= 1.4.1.

cfssljson --version

Original code #11

Purpose: To get kubectl version >= 1.18.6.

wget https://storage.googleapis.com/kubernetes-release/release/v1.18.6/bin/linux/amd64/kubectl
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

Changed to:

wget "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl /usr/local/bin/

Original code #12

Purpose: To verify kubectl version >= 1.18.6.

kubectl version --client

Chapter 3 - Provisioning Compute Resources

Provisioning Compute Resources

Original code #13

Purpose: To create a network named kubernetes-the-hard-way. The --subnet-mode custom is for manual settings.

gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom

Original code #14

Purpose: To create a subnet 10.240.0.0/24 in the kubernetes-the-hard-way network.

gcloud compute networks subnets create kubernetes \
  --network kubernetes-the-hard-way \
  --range 10.240.0.0/24

Original code #15

Purpose: To allow all instances in the same network to talk to each other.

gcloud compute firewall-rules create kubernetes-the-hard-way-allow-internal \
  --allow tcp,udp,icmp \
  --network kubernetes-the-hard-way \
  --source-ranges 10.240.0.0/24,10.200.0.0/16

Removed.

This will be added later on. I want to know the port numbers and I don't know where we got 10.200.0.0/16.

Original code #16

Purpose: To allow external connections to the instances.

gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \
  --allow tcp:22,tcp:6443,icmp \
  --network kubernetes-the-hard-way \
  --source-ranges 0.0.0.0/0

Removed.

I don't want public ssh access. There is no mention why we need port 6443.

Original code #17

Purpose: To see the firewall rules.

gcloud compute firewall-rules list --filter="network:kubernetes-the-hard-way"

We should see no rules.

Original code #18

Purpose: To allocate a static public IP.

gcloud compute addresses create kubernetes-the-hard-way \
  --region $(gcloud config get-value compute/region)

Original code #19

Purpose: To list the newly created static public IP.

gcloud compute addresses list --filter="name=('kubernetes-the-hard-way')"

Original code #20

Purpose: To create 3 controllers

for i in 0 1 2; do
  gcloud compute instances create controller-${i} \
    --async \
    --boot-disk-size 200GB \
    --can-ip-forward \
    --image-family ubuntu-2004-lts \
    --image-project ubuntu-os-cloud \
    --machine-type e2-standard-2 \
    --private-network-ip 10.240.0.1${i} \
    --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,controller
done

Changes:

  • I don't want --async.

Update #1

If there is no --image-family and --image-project, we get a Debian box. With --image-project only, we get: ERROR: (gcloud.compute.instances.create) Must specify either [--image] or [--image-family] when specifying [--image-project] flag. With --image-family only, we get: ERROR: (gcloud.compute.instances.create) Could not fetch resource:. The --image-family specifies the group and --image-project specifies the item in the group.

Changing it to:

for i in 0 1 2; do
    gcloud compute instances create controller-${i} \
    --machine-type e2-standard-2 \
    --private-network-ip 10.101.0.1${i} \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,controller
done

gcloud compute firewall-rules create kubernetes-the-hard-way-allow-external \
  --allow tcp:22 \
  --network kubernetes-the-hard-way \
  --source-ranges 0.0.0.0/0

gcloud compute firewall-rules list --filter="network:kubernetes-the-hard-way" --format=json | jq ".[0].sourceRanges"

EXTERNAL_IP=$(gcloud compute ssh controller-0 --command="tail -20 /var/log/auth.log" | grep "Accepted" | grep -o "[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*" | tail -1)

echo "External IP is ${EXTERNAL_IP}"

gcloud compute firewall-rules update kubernetes-the-hard-way-allow-external \
  --allow tcp:22  \
  --source-ranges ${EXTERNAL_IP}/32

gcloud compute firewall-rules list --filter="network:kubernetes-the-hard-way" --format=json | jq ".[0].sourceRanges"

gcloud compute ssh controller-0 --command="cat /etc/os-release"

Original code #21

Purpose: To create 3 workers

for i in 0 1 2; do
  gcloud compute instances create worker-${i} \
    --async \
    --boot-disk-size 200GB \
    --can-ip-forward \
    --image-family ubuntu-2004-lts \
    --image-project ubuntu-os-cloud \
    --machine-type e2-standard-2 \
    --metadata pod-cidr=10.200.${i}.0/24 \
    --private-network-ip 10.240.0.2${i} \
    --scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,worker
done

Changed to:

for i in 0 1 2; do
  gcloud compute instances create worker-${i} \
    --can-ip-forward \
    --machine-type e2-standard-2 \
    --metadata pod-cidr=10.200.${i}.0/24 \
    --private-network-ip 10.101.0.20${i} \
    --subnet kubernetes \
    --tags kubernetes-the-hard-way,worker
done

Original code #22

Purpose: To list all 6 compute nodes

gcloud compute instances list --filter="tags.items=kubernetes-the-hard-way"

Clean up

gcloud compute firewall-rules delete kubernetes-the-hard-way-allow-external
gcloud compute instances delete worker-0 worker-1 worker-2
gcloud compute instances delete controller-0 controller-1 controller-2
gcloud compute addresses delete kubernetes-the-hard-way
gcloud compute networks subnets delete kubernetes
gcloud compute networks delete kubernetes-the-hard-way

Start again at: Original code #13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment