Last active
November 8, 2019 02:46
-
-
Save drnic/a514fa0842fb88edbee5a285bbca52ca to your computer and use it in GitHub Desktop.
Kubernetes the Hard Way, the Easy Way
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
kubectl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eu | |
MASTERS=${MASTERS:-1} | |
WORKERS=${WORKERS:-2} | |
REGION=$(gcloud config get-value compute/region) | |
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | |
[[ -z ${SKIP_GCLOUD:-} ]] && { | |
( | |
set -x | |
gcloud compute networks create kubernetes-the-hard-way --subnet-mode custom || echo skipping... | |
gcloud compute networks subnets create kubernetes \ | |
--network kubernetes-the-hard-way \ | |
--range 10.240.0.0/24 || echo skipping... | |
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 || echo skipping... | |
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 || echo skipping... | |
gcloud compute addresses create kubernetes-the-hard-way \ | |
--region "$REGION" || echo skipping... | |
) | |
i=0 | |
while [ $i -lt $MASTERS ]; do | |
( | |
set -x | |
gcloud compute instances create controller-${i} \ | |
--async \ | |
--boot-disk-size 200GB \ | |
--can-ip-forward \ | |
--image-family ubuntu-1804-lts \ | |
--image-project ubuntu-os-cloud \ | |
--machine-type n1-standard-1 \ | |
--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 || echo skipping... | |
) | |
((i++)) | |
done | |
i=0 | |
while [ $i -lt $WORKERS ]; do | |
( | |
set -x | |
gcloud compute instances create worker-${i} \ | |
--async \ | |
--boot-disk-size 200GB \ | |
--can-ip-forward \ | |
--image-family ubuntu-1804-lts \ | |
--image-project ubuntu-os-cloud \ | |
--machine-type n1-standard-1 \ | |
--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 || echo skipping... | |
gcloud compute routes create kubernetes-route-10-200-${i}-0-24 \ | |
--network kubernetes-the-hard-way \ | |
--next-hop-address 10.240.0.2${i} \ | |
--destination-range 10.200.${i}.0/24 || echo skipping... | |
) | |
((i++)) | |
done | |
} | |
( | |
set -x | |
gcloud compute instances list | |
) | |
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ | |
--region $(gcloud config get-value compute/region) \ | |
--format 'value(address)') | |
[[ -f ca-key.pem ]] || { | |
cat > ca-config.json <<EOF | |
{ | |
"signing": { | |
"default": { | |
"expiry": "8760h" | |
}, | |
"profiles": { | |
"kubernetes": { | |
"usages": ["signing", "key encipherment", "server auth", "client auth"], | |
"expiry": "8760h" | |
} | |
} | |
} | |
} | |
EOF | |
cat > ca-csr.json <<EOF | |
{ | |
"CN": "Kubernetes", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "Kubernetes", | |
"OU": "CA", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert -initca ca-csr.json | cfssljson -bare ca | |
} | |
[[ -f admin-key.pem ]] || { | |
cat > admin-csr.json <<EOF | |
{ | |
"CN": "admin", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "system:masters", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-profile=kubernetes \ | |
admin-csr.json | cfssljson -bare admin | |
} | |
i=0 | |
while [ $i -lt $WORKERS ]; do | |
instance=worker-$i | |
[[ -f ${instance}.pem ]] || { | |
cat > ${instance}-csr.json <<EOF | |
{ | |
"CN": "system:node:${instance}", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "system:nodes", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
EXTERNAL_IP=$(gcloud compute instances describe ${instance} \ | |
--format 'value(networkInterfaces[0].accessConfigs[0].natIP)') | |
INTERNAL_IP=$(gcloud compute instances describe ${instance} \ | |
--format 'value(networkInterfaces[0].networkIP)') | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-hostname=${instance},${EXTERNAL_IP},${INTERNAL_IP} \ | |
-profile=kubernetes \ | |
${instance}-csr.json | cfssljson -bare ${instance} | |
} | |
((i++)) | |
done | |
[[ -f kube-controller-manager.pem ]] || { | |
cat > kube-controller-manager-csr.json <<EOF | |
{ | |
"CN": "system:kube-controller-manager", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "system:kube-controller-manager", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-profile=kubernetes \ | |
kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager | |
} | |
[[ -f kube-proxy.pem ]] || { | |
cat > kube-proxy-csr.json <<EOF | |
{ | |
"CN": "system:kube-proxy", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "system:node-proxier", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-profile=kubernetes \ | |
kube-proxy-csr.json | cfssljson -bare kube-proxy | |
} | |
[[ -f kube-scheduler.pem ]] || { | |
cat > kube-scheduler-csr.json <<EOF | |
{ | |
"CN": "system:kube-scheduler", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "system:kube-scheduler", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-profile=kubernetes \ | |
kube-scheduler-csr.json | cfssljson -bare kube-scheduler | |
} | |
[[ -f kubernetes.pem ]] || { | |
KUBERNETES_HOSTNAMES=kubernetes,kubernetes.default,kubernetes.default.svc,kubernetes.default.svc.cluster,kubernetes.svc.cluster.local | |
cat > kubernetes-csr.json <<EOF | |
{ | |
"CN": "kubernetes", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "Kubernetes", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-hostname=10.32.0.1,10.240.0.10,10.240.0.11,10.240.0.12,${KUBERNETES_PUBLIC_ADDRESS},127.0.0.1,${KUBERNETES_HOSTNAMES} \ | |
-profile=kubernetes \ | |
kubernetes-csr.json | cfssljson -bare kubernetes | |
} | |
[[ -f service-account.pem ]] || { | |
cat > service-account-csr.json <<EOF | |
{ | |
"CN": "service-accounts", | |
"key": { | |
"algo": "rsa", | |
"size": 2048 | |
}, | |
"names": [ | |
{ | |
"C": "US", | |
"L": "Portland", | |
"O": "Kubernetes", | |
"OU": "Kubernetes The Hard Way", | |
"ST": "Oregon" | |
} | |
] | |
} | |
EOF | |
cfssl gencert \ | |
-ca=ca.pem \ | |
-ca-key=ca-key.pem \ | |
-config=ca-config.json \ | |
-profile=kubernetes \ | |
service-account-csr.json | cfssljson -bare service-account | |
} | |
KUBERNETES_PUBLIC_ADDRESS=$(gcloud compute addresses describe kubernetes-the-hard-way \ | |
--region "$REGION" \ | |
--format 'value(address)') | |
( | |
set -x | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ | |
--kubeconfig=kube-proxy.kubeconfig | |
kubectl config set-credentials system:kube-proxy \ | |
--client-certificate=kube-proxy.pem \ | |
--client-key=kube-proxy-key.pem \ | |
--embed-certs=true \ | |
--kubeconfig=kube-proxy.kubeconfig | |
kubectl config set-context default \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=system:kube-proxy \ | |
--kubeconfig=kube-proxy.kubeconfig | |
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://127.0.0.1:6443 \ | |
--kubeconfig=kube-controller-manager.kubeconfig | |
kubectl config set-credentials system:kube-controller-manager \ | |
--client-certificate=kube-controller-manager.pem \ | |
--client-key=kube-controller-manager-key.pem \ | |
--embed-certs=true \ | |
--kubeconfig=kube-controller-manager.kubeconfig | |
kubectl config set-context default \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=system:kube-controller-manager \ | |
--kubeconfig=kube-controller-manager.kubeconfig | |
kubectl config use-context default --kubeconfig=kube-controller-manager.kubeconfig | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://127.0.0.1:6443 \ | |
--kubeconfig=kube-scheduler.kubeconfig | |
kubectl config set-credentials system:kube-scheduler \ | |
--client-certificate=kube-scheduler.pem \ | |
--client-key=kube-scheduler-key.pem \ | |
--embed-certs=true \ | |
--kubeconfig=kube-scheduler.kubeconfig | |
kubectl config set-context default \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=system:kube-scheduler \ | |
--kubeconfig=kube-scheduler.kubeconfig | |
kubectl config use-context default --kubeconfig=kube-scheduler.kubeconfig | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://127.0.0.1:6443 \ | |
--kubeconfig=admin.kubeconfig | |
kubectl config set-credentials admin \ | |
--client-certificate=admin.pem \ | |
--client-key=admin-key.pem \ | |
--embed-certs=true \ | |
--kubeconfig=admin.kubeconfig | |
kubectl config set-context default \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=admin \ | |
--kubeconfig=admin.kubeconfig | |
kubectl config use-context default --kubeconfig=admin.kubeconfig | |
) | |
[[ -f encryption-config.yaml ]] || { | |
ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64) | |
cat > encryption-config.yaml <<EOF | |
kind: EncryptionConfig | |
apiVersion: v1 | |
resources: | |
- resources: | |
- secrets | |
providers: | |
- aescbc: | |
keys: | |
- name: key1 | |
secret: ${ENCRYPTION_KEY} | |
- identity: {} | |
EOF | |
} | |
i=0 | |
while [ $i -lt $MASTERS ]; do | |
instance=controller-$i | |
( | |
set -x | |
while [[ ! $(gcloud compute ssh ${instance} --command "hostname -s" 2>/dev/null) ]]; do | |
echo "waiting for ssh access to ${instance}" | |
sleep 5 | |
done | |
gcloud compute scp \ | |
ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ | |
service-account-key.pem service-account.pem \ | |
admin.kubeconfig kube-controller-manager.kubeconfig kube-scheduler.kubeconfig \ | |
encryption-config.yaml \ | |
$DIR/setup-etcd.sh \ | |
$DIR/setup-controller.sh \ | |
$DIR/etcdctl.sh \ | |
${instance}:~/ | |
gcloud compute ssh ${instance} -- bash setup-etcd.sh | |
) | |
((i++)) | |
done | |
( | |
set -x | |
sleep 1 | |
gcloud compute ssh controller-0 -- bash etcdctl.sh member list | |
) | |
i=0 | |
while [ $i -lt $MASTERS ]; do | |
instance=controller-$i | |
( | |
set -x | |
gcloud compute ssh ${instance} -- bash setup-controller.sh ${ENABLE_GCE:+--enable-gce} | |
) | |
((i++)) | |
done | |
[[ -z ${SKIP_GCLOUD:-} ]] && { | |
( | |
set -x | |
gcloud compute http-health-checks create kubernetes \ | |
--description "Kubernetes Health Check" \ | |
--host "kubernetes.default.svc.cluster.local" \ | |
--request-path "/healthz" || echo skipping... | |
gcloud compute firewall-rules create kubernetes-the-hard-way-allow-health-check \ | |
--network kubernetes-the-hard-way \ | |
--source-ranges 209.85.152.0/22,209.85.204.0/22,35.191.0.0/16 \ | |
--allow tcp || echo skipping... | |
gcloud compute target-pools create kubernetes-target-pool \ | |
--http-health-check kubernetes || echo skipping... | |
# TODO - support multiple masters | |
gcloud compute target-pools add-instances kubernetes-target-pool \ | |
--instances controller-0 || echo skipping... | |
gcloud compute forwarding-rules create kubernetes-forwarding-rule \ | |
--address "${KUBERNETES_PUBLIC_ADDRESS}" \ | |
--ports 6443 \ | |
--region "${REGION}" \ | |
--target-pool kubernetes-target-pool || echo skipping... | |
) | |
} | |
echo | |
( | |
set -x | |
curl --cacert ca.pem https://${KUBERNETES_PUBLIC_ADDRESS}:6443/version | |
) | |
echo | |
i=0 | |
while [ $i -lt $WORKERS ]; do | |
instance=worker-$i | |
( | |
set -x | |
[[ -z "${DONOT_CONFIGURE_WORKER:-}" ]] && { | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 \ | |
--kubeconfig=${instance}.kubeconfig | |
kubectl config set-credentials system:node:${instance} \ | |
--client-certificate=${instance}.pem \ | |
--client-key=${instance}-key.pem \ | |
--embed-certs=true \ | |
--kubeconfig=${instance}.kubeconfig | |
kubectl config set-context default \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=system:node:${instance} \ | |
--kubeconfig=${instance}.kubeconfig | |
kubectl config use-context default --kubeconfig=${instance}.kubeconfig | |
} | |
touch ${instance}.kubeconfig | |
gcloud compute scp \ | |
ca.pem ${instance}-key.pem ${instance}.pem \ | |
${instance}.kubeconfig kube-proxy.kubeconfig \ | |
$DIR/setup-worker.sh \ | |
${instance}:~/ | |
gcloud compute ssh ${instance} -- bash setup-worker.sh \ | |
${ENABLE_GCE:+--enable-gce} \ | |
${DONOT_CONFIGURE_WORKER:+--do-not-configure} | |
) | |
((i++)) | |
done | |
( | |
set -x | |
gcloud compute ssh controller-0 \ | |
--command "kubectl get nodes --kubeconfig admin.kubeconfig" | |
) | |
( | |
set -x | |
kubectl config set-cluster kubernetes-the-hard-way \ | |
--certificate-authority=ca.pem \ | |
--embed-certs=true \ | |
--server=https://${KUBERNETES_PUBLIC_ADDRESS}:6443 | |
kubectl config set-credentials admin \ | |
--client-certificate=admin.pem \ | |
--client-key=admin-key.pem | |
kubectl config set-context kubernetes-the-hard-way \ | |
--cluster=kubernetes-the-hard-way \ | |
--user=admin | |
kubectl config use-context kubernetes-the-hard-way | |
kubectl get componentstatuses | |
kubectl get nodes | |
kubectl apply -f https://storage.googleapis.com/kubernetes-the-hard-way/coredns.yaml | |
kubectl get pods -l k8s-app=kube-dns -n kube-system | |
) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eux | |
ZONE=$(gcloud config get-value compute/zone) | |
REGION=$(gcloud config get-value compute/region) | |
controllers=$(gcloud compute instances list | grep controller | awk '{print $1}') | |
workers=$(gcloud compute instances list | grep worker | awk '{print $1}') | |
[[ -n $controllers || -n $workers ]] && { | |
gcloud -q compute instances delete --zone $ZONE $controllers $workers | |
} | |
{ | |
gcloud -q compute forwarding-rules delete kubernetes-forwarding-rule \ | |
--region $REGION || echo skipping... | |
gcloud -q compute target-pools delete kubernetes-target-pool || echo skipping... | |
gcloud -q compute http-health-checks delete kubernetes || echo skipping... | |
gcloud -q compute addresses delete kubernetes-the-hard-way || echo skipping... | |
} | |
# Need to regenerate certs for future public IP | |
rm -f *.{pem,csr,json,kubeconfig} | |
gcloud -q compute firewall-rules delete \ | |
kubernetes-the-hard-way-allow-nginx-service \ | |
kubernetes-the-hard-way-allow-internal \ | |
kubernetes-the-hard-way-allow-external \ | |
kubernetes-the-hard-way-allow-health-check || echo skipping... | |
{ | |
gcloud -q compute routes delete \ | |
kubernetes-route-10-200-0-0-24 \ | |
kubernetes-route-10-200-1-0-24 \ | |
kubernetes-route-10-200-2-0-24 || echo skipping... | |
gcloud -q compute networks subnets delete kubernetes || echo skipping... | |
gcloud -q compute networks delete kubernetes-the-hard-way || echo skipping... | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
sudo ETCDCTL_API=3 etcdctl \ | |
--endpoints=https://127.0.0.1:2379 \ | |
--cacert=/etc/etcd/ca.pem \ | |
--cert=/etc/etcd/kubernetes.pem \ | |
--key=/etc/etcd/kubernetes-key.pem \ | |
"$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eux | |
KUBE_VERSION=${KUBE_VERSION:-1.16.2} | |
[[ "${1:-}" == "--enable-gce" ]] && { ENABLE_GCE=1; shift; } | |
sudo mkdir -p /etc/kubernetes/config | |
wget -q --show-progress --https-only --timestamping \ | |
"https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kube-apiserver" \ | |
"https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kube-controller-manager" \ | |
"https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kube-scheduler" \ | |
"https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kubectl" | |
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl | |
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/local/bin/ | |
sudo mkdir -p /var/lib/kubernetes/ | |
sudo mv ca.pem ca-key.pem kubernetes-key.pem kubernetes.pem \ | |
service-account-key.pem service-account.pem \ | |
encryption-config.yaml /var/lib/kubernetes/ | |
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \ | |
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) | |
# TODO for $MASTERS > 1 | |
etcd_servers=https://10.240.0.10:2379 | |
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service | |
[Unit] | |
Description=Kubernetes API Server | |
Documentation=https://github.com/kubernetes/kubernetes | |
[Service] | |
ExecStart=/usr/local/bin/kube-apiserver \\ | |
--advertise-address=${INTERNAL_IP} \\ | |
--allow-privileged=true \\ | |
--apiserver-count=3 \\ | |
--audit-log-maxage=30 \\ | |
--audit-log-maxbackup=3 \\ | |
--audit-log-maxsize=100 \\ | |
--audit-log-path=/var/log/audit.log \\ | |
--authorization-mode=Node,RBAC \\ | |
--bind-address=0.0.0.0 \\ | |
--client-ca-file=/var/lib/kubernetes/ca.pem \\ | |
${ENABLE_GCE:+--cloud-provider=gce} \\ | |
--enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\ | |
--etcd-cafile=/var/lib/kubernetes/ca.pem \\ | |
--etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\ | |
--etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\ | |
--etcd-servers=${etcd_servers} \\ | |
--event-ttl=1h \\ | |
--encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\ | |
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\ | |
--kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\ | |
--kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\ | |
--kubelet-https=true \\ | |
--runtime-config=api/all \\ | |
--service-account-key-file=/var/lib/kubernetes/service-account.pem \\ | |
--service-cluster-ip-range=10.32.0.0/24 \\ | |
--service-node-port-range=30000-32767 \\ | |
--tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\ | |
--tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\ | |
--v=2 | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo mv kube-controller-manager.kubeconfig /var/lib/kubernetes/ | |
cat <<EOF | sudo tee /etc/systemd/system/kube-controller-manager.service | |
[Unit] | |
Description=Kubernetes Controller Manager | |
Documentation=https://github.com/kubernetes/kubernetes | |
[Service] | |
ExecStart=/usr/local/bin/kube-controller-manager \\ | |
--bind-address=0.0.0.0 \\ | |
${ENABLE_GCE:+--cloud-provider=gce} \\ | |
--cluster-cidr=10.200.0.0/16 \\ | |
--cluster-name=kubernetes \\ | |
--cluster-signing-cert-file=/var/lib/kubernetes/ca.pem \\ | |
--cluster-signing-key-file=/var/lib/kubernetes/ca-key.pem \\ | |
--kubeconfig=/var/lib/kubernetes/kube-controller-manager.kubeconfig \\ | |
--leader-elect=true \\ | |
--root-ca-file=/var/lib/kubernetes/ca.pem \\ | |
--service-account-private-key-file=/var/lib/kubernetes/service-account-key.pem \\ | |
--service-cluster-ip-range=10.32.0.0/24 \\ | |
--use-service-account-credentials=true \\ | |
--v=2 | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo mv kube-scheduler.kubeconfig /var/lib/kubernetes/ | |
cat <<EOF | sudo tee /etc/kubernetes/config/kube-scheduler.yaml | |
apiVersion: kubescheduler.config.k8s.io/v1alpha1 | |
kind: KubeSchedulerConfiguration | |
clientConnection: | |
kubeconfig: "/var/lib/kubernetes/kube-scheduler.kubeconfig" | |
leaderElection: | |
leaderElect: true | |
EOF | |
cat <<EOF | sudo tee /etc/systemd/system/kube-scheduler.service | |
[Unit] | |
Description=Kubernetes Scheduler | |
Documentation=https://github.com/kubernetes/kubernetes | |
[Service] | |
ExecStart=/usr/local/bin/kube-scheduler \\ | |
--config=/etc/kubernetes/config/kube-scheduler.yaml \\ | |
--v=2 | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo systemctl daemon-reload | |
sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler | |
sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler | |
sudo apt-get update | |
sudo apt-get install -y nginx | |
cat > kubernetes.default.svc.cluster.local <<EOF | |
server { | |
listen 80; | |
server_name kubernetes.default.svc.cluster.local; | |
location /healthz { | |
proxy_pass https://127.0.0.1:6443/healthz; | |
proxy_ssl_trusted_certificate /var/lib/kubernetes/ca.pem; | |
} | |
} | |
EOF | |
sudo mv kubernetes.default.svc.cluster.local \ | |
/etc/nginx/sites-available/kubernetes.default.svc.cluster.local | |
sudo ln -s /etc/nginx/sites-available/kubernetes.default.svc.cluster.local /etc/nginx/sites-enabled/ || echo skipping... | |
sudo systemctl restart nginx | |
sudo systemctl enable nginx | |
sleep 1 | |
kubectl get componentstatuses --kubeconfig admin.kubeconfig | |
echo | |
curl -H "Host: kubernetes.default.svc.cluster.local" -i http://127.0.0.1/healthz | |
echo | |
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - | |
apiVersion: rbac.authorization.k8s.io/v1 | |
kind: ClusterRole | |
metadata: | |
annotations: | |
rbac.authorization.kubernetes.io/autoupdate: "true" | |
labels: | |
kubernetes.io/bootstrapping: rbac-defaults | |
name: system:kube-apiserver-to-kubelet | |
rules: | |
- apiGroups: | |
- "" | |
resources: | |
- nodes/proxy | |
- nodes/stats | |
- nodes/log | |
- nodes/spec | |
- nodes/metrics | |
verbs: | |
- "*" | |
EOF | |
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f - | |
apiVersion: rbac.authorization.k8s.io/v1 | |
kind: ClusterRoleBinding | |
metadata: | |
name: system:kube-apiserver | |
namespace: "" | |
roleRef: | |
apiGroup: rbac.authorization.k8s.io | |
kind: ClusterRole | |
name: system:kube-apiserver-to-kubelet | |
subjects: | |
- apiGroup: rbac.authorization.k8s.io | |
kind: User | |
name: kubernetes | |
EOF | |
echo $(hostname -s) is setup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eux | |
ETCD_VERSION=${ETCD_VERSION:-3.4.3} | |
rm -rf etcd-*-linux-amd64* | |
wget -q --show-progress --https-only --timestamping \ | |
"https://github.com/etcd-io/etcd/releases/download/v${ETCD_VERSION}/etcd-v${ETCD_VERSION}-linux-amd64.tar.gz" | |
tar -xvf etcd-*-linux-amd64.tar.gz | |
sudo mv etcd-*-linux-amd64/etcd* /usr/local/bin/ | |
sudo mkdir -p /etc/etcd /var/lib/etcd | |
sudo cp ca.pem kubernetes-key.pem kubernetes.pem /etc/etcd/ | |
INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \ | |
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip) | |
ETCD_NAME=$(hostname -s) | |
# TODO for $MASTERS > 1 | |
initial_cluster=controller-0=https://10.240.0.10:2380 | |
cat <<EOF | sudo tee /etc/systemd/system/etcd.service | |
[Unit] | |
Description=etcd | |
Documentation=https://github.com/coreos | |
[Service] | |
Type=notify | |
ExecStart=/usr/local/bin/etcd \\ | |
--name ${ETCD_NAME} \\ | |
--cert-file=/etc/etcd/kubernetes.pem \\ | |
--key-file=/etc/etcd/kubernetes-key.pem \\ | |
--peer-cert-file=/etc/etcd/kubernetes.pem \\ | |
--peer-key-file=/etc/etcd/kubernetes-key.pem \\ | |
--trusted-ca-file=/etc/etcd/ca.pem \\ | |
--peer-trusted-ca-file=/etc/etcd/ca.pem \\ | |
--peer-client-cert-auth \\ | |
--client-cert-auth \\ | |
--initial-advertise-peer-urls https://${INTERNAL_IP}:2380 \\ | |
--listen-peer-urls https://${INTERNAL_IP}:2380 \\ | |
--listen-client-urls https://${INTERNAL_IP}:2379,https://127.0.0.1:2379 \\ | |
--advertise-client-urls https://${INTERNAL_IP}:2379 \\ | |
--initial-cluster-token etcd-cluster-0 \\ | |
--initial-cluster ${initial_cluster} \\ | |
--initial-cluster-state new \\ | |
--data-dir=/var/lib/etcd | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo systemctl daemon-reload | |
sudo systemctl enable etcd | |
sudo systemctl start etcd | |
echo $(hostname -s) is setup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eux | |
KUBE_VERSION=${KUBE_VERSION:-1.16.2} | |
[[ "${1:-}" == "--enable-gce" ]] && { ENABLE_GCE=1; shift; } | |
[[ "${1:-}" == "--do-not-configure" ]] && { DONOT_CONFIGURE_WORKER=1; shift; } | |
sudo apt-get update | |
sudo apt-get -y install socat conntrack ipset | |
sudo swapoff -a | |
rm -rf crictl* runc* cni-plugins* containerd* | |
wget -q --show-progress --https-only --timestamping \ | |
https://github.com/kubernetes-sigs/cri-tools/releases/download/v1.16.1/crictl-v1.16.1-linux-amd64.tar.gz \ | |
https://github.com/opencontainers/runc/releases/download/v1.0.0-rc9/runc.amd64 \ | |
https://github.com/containernetworking/plugins/releases/download/v0.8.2/cni-plugins-linux-amd64-v0.8.2.tgz \ | |
https://github.com/containerd/containerd/releases/download/v1.3.0/containerd-1.3.0.linux-amd64.tar.gz \ | |
https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kubectl \ | |
https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kube-proxy \ | |
https://storage.googleapis.com/kubernetes-release/release/v${KUBE_VERSION}/bin/linux/amd64/kubelet | |
sudo mkdir -p \ | |
/etc/cni/net.d \ | |
/opt/cni/bin \ | |
/var/lib/kubelet \ | |
/var/lib/kube-proxy \ | |
/var/lib/kubernetes \ | |
/var/run/kubernetes | |
mkdir containerd | |
tar -xvf crictl-v1.16.1-linux-amd64.tar.gz | |
tar -xvf containerd-1.3.0.linux-amd64.tar.gz -C containerd | |
sudo tar -xvf cni-plugins-linux-amd64-v0.8.2.tgz -C /opt/cni/bin/ | |
sudo mv runc.amd64 runc | |
chmod +x crictl kubectl kube-proxy kubelet runc | |
sudo mv crictl kubectl kube-proxy kubelet runc /usr/local/bin/ | |
sudo mv containerd/bin/* /bin/ | |
[[ -z "${DONOT_CONFIGURE_WORKER:-}" ]] && { | |
POD_CIDR=$(curl -s -H "Metadata-Flavor: Google" \ | |
http://metadata.google.internal/computeMetadata/v1/instance/attributes/pod-cidr) | |
cat <<EOF | sudo tee /etc/cni/net.d/10-bridge.conf | |
{ | |
"cniVersion": "0.3.1", | |
"name": "bridge", | |
"type": "bridge", | |
"bridge": "cnio0", | |
"isGateway": true, | |
"ipMasq": true, | |
"ipam": { | |
"type": "host-local", | |
"ranges": [ | |
[{"subnet": "${POD_CIDR}"}] | |
], | |
"routes": [{"dst": "0.0.0.0/0"}] | |
} | |
} | |
EOF | |
cat <<EOF | sudo tee /etc/cni/net.d/99-loopback.conf | |
{ | |
"cniVersion": "0.3.1", | |
"name": "lo", | |
"type": "loopback" | |
} | |
EOF | |
sudo mkdir -p /etc/containerd/ | |
cat << EOF | sudo tee /etc/containerd/config.toml | |
[plugins] | |
[plugins.cri.containerd] | |
snapshotter = "overlayfs" | |
[plugins.cri.containerd.default_runtime] | |
runtime_type = "io.containerd.runtime.v1.linux" | |
runtime_engine = "/usr/local/bin/runc" | |
runtime_root = "" | |
EOF | |
cat <<EOF | sudo tee /etc/systemd/system/containerd.service | |
[Unit] | |
Description=containerd container runtime | |
Documentation=https://containerd.io | |
After=network.target | |
[Service] | |
ExecStartPre=/sbin/modprobe overlay | |
ExecStart=/bin/containerd | |
Restart=always | |
RestartSec=5 | |
Delegate=yes | |
KillMode=process | |
OOMScoreAdjust=-999 | |
LimitNOFILE=1048576 | |
LimitNPROC=infinity | |
LimitCORE=infinity | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo mv ${HOSTNAME}-key.pem ${HOSTNAME}.pem /var/lib/kubelet/ | |
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig | |
sudo mv ca.pem /var/lib/kubernetes/ | |
cat <<EOF | sudo tee /var/lib/kubelet/kubelet-config.yaml | |
kind: KubeletConfiguration | |
apiVersion: kubelet.config.k8s.io/v1beta1 | |
authentication: | |
anonymous: | |
enabled: false | |
webhook: | |
enabled: true | |
x509: | |
clientCAFile: "/var/lib/kubernetes/ca.pem" | |
authorization: | |
mode: Webhook | |
clusterDomain: "cluster.local" | |
clusterDNS: | |
- "10.32.0.10" | |
podCIDR: "${POD_CIDR}" | |
resolvConf: "/run/systemd/resolve/resolv.conf" | |
runtimeRequestTimeout: "15m" | |
tlsCertFile: "/var/lib/kubelet/${HOSTNAME}.pem" | |
tlsPrivateKeyFile: "/var/lib/kubelet/${HOSTNAME}-key.pem" | |
EOF | |
HOSTNAME_OVERRIDE=$(curl -sS http://metadata.google.internal/computeMetadata/v1/instance/name -H "Metadata-Flavor: Google") | |
cat <<EOF | sudo tee /etc/systemd/system/kubelet.service | |
[Unit] | |
Description=Kubernetes Kubelet | |
Documentation=https://github.com/kubernetes/kubernetes | |
After=containerd.service | |
Requires=containerd.service | |
[Service] | |
ExecStart=/usr/local/bin/kubelet \\ | |
${ENABLE_GCE:+--cloud-provider=gce} \\ | |
--config=/var/lib/kubelet/kubelet-config.yaml \\ | |
--container-runtime=remote \\ | |
--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock \\ | |
--hostname-override=$HOSTNAME_OVERRIDE \\ | |
--image-pull-progress-deadline=2m \\ | |
--kubeconfig=/var/lib/kubelet/kubeconfig \\ | |
--network-plugin=cni \\ | |
--register-node=true \\ | |
--v=2 | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig | |
cat <<EOF | sudo tee /var/lib/kube-proxy/kube-proxy-config.yaml | |
kind: KubeProxyConfiguration | |
apiVersion: kubeproxy.config.k8s.io/v1alpha1 | |
clientConnection: | |
kubeconfig: "/var/lib/kube-proxy/kubeconfig" | |
mode: "iptables" | |
clusterCIDR: "10.200.0.0/16" | |
EOF | |
cat <<EOF | sudo tee /etc/systemd/system/kube-proxy.service | |
[Unit] | |
Description=Kubernetes Kube Proxy | |
Documentation=https://github.com/kubernetes/kubernetes | |
[Service] | |
ExecStart=/usr/local/bin/kube-proxy \\ | |
--config=/var/lib/kube-proxy/kube-proxy-config.yaml | |
Restart=on-failure | |
RestartSec=5 | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
sudo systemctl daemon-reload | |
sudo systemctl enable containerd kubelet kube-proxy | |
sudo systemctl start containerd kubelet kube-proxy | |
} | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment