2016-07-07 18:25:27 +03:00
# Bootstrapping an H/A Kubernetes Control Plane
2016-07-07 17:15:59 +03:00
2016-07-07 18:25:27 +03:00
In this lab you will bootstrap a 3 node Kubernetes controller cluster. The following virtual machines will be used:
```
2016-07-09 03:22:02 +03:00
gcloud compute instances list
```
```
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
controller0 us-central1-f n1-standard-1 10.240.0.20 XXX.XXX.XXX.XXX RUNNING
controller1 us-central1-f n1-standard-1 10.240.0.21 XXX.XXX.XXX.XXX RUNNING
controller2 us-central1-f n1-standard-1 10.240.0.22 XXX.XXX.XXX.XXX RUNNING
etcd0 us-central1-f n1-standard-1 10.240.0.10 XXX.XXX.XXX.XXX RUNNING
2016-07-07 18:25:27 +03:00
```
2016-07-07 17:15:59 +03:00
2016-07-08 00:37:13 +03:00
In this lab you will also create a frontend load balancer with a public IP address for remote access to the API servers and H/A.
2016-07-08 00:36:48 +03:00
2016-07-07 18:30:15 +03:00
## Why
The Kubernetes components that make up the control plane include the following components:
* Kubernetes API Server
* Kubernetes Scheduler
* Kubernetes Controller Manager
Each component is being run on the same machines for the following reasons:
* The Scheduler and Controller Manager are tightly coupled with the API Server
* Only one Scheduler and Controller Manager can be active at a given time, but it's ok to run multiple at the same time. Each component will elect a leader via the API Server.
* Running multiple copies of each component is required for H/A
* Running each component next to the API Server eases configuration.
2016-07-07 18:25:27 +03:00
## Provision the Kubernetes Controller Cluster
2016-07-07 17:15:59 +03:00
2016-07-08 20:26:32 +03:00
Run the following commands on `controller0` , `controller1` , `controller2` :
> SSH into each machine using the `gcloud compute ssh` command
2016-07-07 17:15:59 +03:00
2016-07-07 18:25:27 +03:00
Move the TLS certificates in place:
```
2016-07-09 10:15:26 +03:00
sudo mkdir -p /var/lib/kubernetes
2016-07-07 18:25:27 +03:00
```
```
2016-07-09 10:15:26 +03:00
sudo mv ca.pem kubernetes-key.pem kubernetes.pem /var/lib/kubernetes/
2016-07-07 18:25:27 +03:00
```
Download and install the Kubernetes controller binaries:
2016-07-07 17:15:59 +03:00
```
2016-07-08 14:37:03 +03:00
wget https://storage.googleapis.com/kubernetes-release/release/v1.3.0/bin/linux/amd64/kube-apiserver
wget https://storage.googleapis.com/kubernetes-release/release/v1.3.0/bin/linux/amd64/kube-controller-manager
wget https://storage.googleapis.com/kubernetes-release/release/v1.3.0/bin/linux/amd64/kube-scheduler
wget https://storage.googleapis.com/kubernetes-release/release/v1.3.0/bin/linux/amd64/kubectl
2016-07-07 17:15:59 +03:00
```
```
2016-07-08 14:37:03 +03:00
chmod +x kube-apiserver kube-controller-manager kube-scheduler kubectl
2016-07-07 17:15:59 +03:00
```
```
2016-07-08 14:37:03 +03:00
sudo mv kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/bin/
2016-07-07 17:15:59 +03:00
```
2016-07-09 19:28:12 +03:00
### Kubernetes API Server
#### Setup Authentication and Authorization
##### Authentication
[Token based authentication ](http://kubernetes.io/docs/admin/authentication ) will be used to limit access to Kubernetes API.
2016-07-07 17:15:59 +03:00
```
2016-07-09 19:28:12 +03:00
wget https://raw.githubusercontent.com/kelseyhightower/kubernetes-the-hard-way/master/token.csv
2016-07-07 17:15:59 +03:00
```
```
2016-07-09 19:28:12 +03:00
cat token.csv
2016-07-07 17:15:59 +03:00
```
```
2016-07-09 19:28:12 +03:00
sudo mv token.csv /var/lib/kubernetes/
2016-07-07 17:15:59 +03:00
```
2016-07-09 19:28:12 +03:00
##### Authorization
Attribute-Based Access Control (ABAC) will be used to authorize access to the Kubernetes API. In this lab ABAC will be setup using the Kuberentes policy file backend as documented in the [Kubernetes authorization guide ](http://kubernetes.io/docs/admin/authorization ).
2016-07-07 17:15:59 +03:00
```
2016-07-09 19:28:12 +03:00
wget https://raw.githubusercontent.com/kelseyhightower/kubernetes-the-hard-way/master/authorization-policy.jsonl
2016-07-07 17:15:59 +03:00
```
```
2016-07-09 19:28:12 +03:00
cat authorization-policy.jsonl
2016-07-07 17:15:59 +03:00
```
```
2016-07-09 19:28:12 +03:00
sudo mv authorization-policy.jsonl /var/lib/kubernetes/
2016-07-07 17:15:59 +03:00
```
2016-07-09 19:28:12 +03:00
### Create the systemd unit file
2016-07-08 20:26:32 +03:00
Capture the internal IP address:
```
export INTERNAL_IP=$(curl -s -H "Metadata-Flavor: Google" \
http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip)
2016-07-07 17:15:59 +03:00
```
2016-07-08 20:26:32 +03:00
Create the systemd unit file:
```
2016-07-16 21:39:36 +03:00
sudo sh -c "echo '[Unit]
2016-07-07 17:15:59 +03:00
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
2016-07-16 21:39:36 +03:00
ExecStart=/usr/bin/kube-apiserver \\
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota \\
--advertise-address=$INTERNAL_IP \\
--allow-privileged=true \\
--apiserver-count=3 \\
--authorization-mode=ABAC \\
--authorization-policy-file=/var/lib/kubernetes/authorization-policy.jsonl \\
--bind-address=0.0.0.0 \\
--enable-swagger-ui=true \\
--etcd-cafile=/var/lib/kubernetes/ca.pem \\
--insecure-bind-address=0.0.0.0 \\
--kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
--etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
--service-account-key-file=/var/lib/kubernetes/kubernetes-key.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 \\
--token-auth-file=/var/lib/kubernetes/token.csv \\
2016-07-07 17:15:59 +03:00
--v=2
Restart=on-failure
RestartSec=5
[Install]
2016-07-16 21:39:36 +03:00
WantedBy=multi-user.target' > /etc/systemd/system/kube-apiserver.service"
2016-07-07 17:15:59 +03:00
```
```
2016-07-08 20:26:32 +03:00
sudo mv kube-apiserver.service /etc/systemd/system/
2016-07-07 17:15:59 +03:00
```
2016-07-07 18:37:41 +03:00
```
sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver
sudo systemctl start kube-apiserver
```
```
2016-07-08 20:26:32 +03:00
sudo systemctl status kube-apiserver --no-pager
2016-07-07 18:37:41 +03:00
```
2016-07-09 19:28:12 +03:00
### Kubernetes Controller Manager
2016-07-07 18:37:41 +03:00
```
2016-07-16 21:39:36 +03:00
sudo su -c "echo '[Unit]
2016-07-07 18:37:41 +03:00
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
2016-07-16 21:39:36 +03:00
ExecStart=/usr/bin/kube-controller-manager \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.200.0.0/16 \\
--cluster-name=kubernetes \\
--leader-elect=true \\
--master=http://$INTERNAL_IP:8080 \\
--root-ca-file=/var/lib/kubernetes/ca.pem \\
--service-account-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
--service-cluster-ip-range=10.32.0.0/24 \\
2016-07-07 18:37:41 +03:00
--v=2
Restart=on-failure
RestartSec=5
[Install]
2016-07-16 21:39:36 +03:00
WantedBy=multi-user.target' > /etc/systemd/system/kube-controller-manager.service"
2016-07-07 18:37:41 +03:00
```
```
sudo systemctl daemon-reload
2016-07-08 20:26:32 +03:00
sudo systemctl enable kube-controller-manager
sudo systemctl start kube-controller-manager
2016-07-07 18:37:41 +03:00
```
```
2016-07-08 20:26:32 +03:00
sudo systemctl status kube-controller-manager --no-pager
2016-07-07 18:37:41 +03:00
```
2016-07-09 19:28:12 +03:00
### Kubernetes Scheduler
2016-07-07 18:37:41 +03:00
```
2016-07-16 21:39:36 +03:00
sudo sh -c "echo '[Unit]
2016-07-08 20:26:32 +03:00
Description=Kubernetes Scheduler
2016-07-07 18:37:41 +03:00
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
2016-07-16 21:39:36 +03:00
ExecStart=/usr/bin/kube-scheduler \\
--leader-elect=true \\
--master=http://$INTERNAL_IP:8080 \\
2016-07-07 18:37:41 +03:00
--v=2
Restart=on-failure
RestartSec=5
[Install]
2016-07-16 21:39:36 +03:00
WantedBy=multi-user.target' > /etc/systemd/system/kube-scheduler.service"
2016-07-07 18:37:41 +03:00
```
```
sudo systemctl daemon-reload
sudo systemctl enable kube-scheduler
sudo systemctl start kube-scheduler
```
```
2016-07-08 20:26:32 +03:00
sudo systemctl status kube-scheduler --no-pager
2016-07-07 18:37:41 +03:00
```
2016-07-09 19:28:12 +03:00
### Verification
2016-07-07 18:37:41 +03:00
```
kubectl get componentstatuses
```
```
NAME STATUS MESSAGE ERROR
controller-manager Healthy ok
scheduler Healthy ok
etcd-1 Healthy {"health": "true"}
etcd-0 Healthy {"health": "true"}
etcd-2 Healthy {"health": "true"}
2016-07-07 23:26:27 +03:00
```
2016-07-09 03:26:43 +03:00
> Remember to run these steps on `controller0`, `controller1`, and `controller2`
2016-07-07 23:39:33 +03:00
## Setup Kubernetes API Server Frontend Load Balancer
2016-07-07 23:26:27 +03:00
2016-07-08 00:39:37 +03:00
The virtual machines created in this tutorial will not have permission to complete this section. Run the following commands from the same place used to create the virtual machines for this tutorial.
2016-07-07 23:26:27 +03:00
```
gcloud compute http-health-checks create kube-apiserver-check \
--description "Kubernetes API Server Health Check" \
--port 8080 \
--request-path /healthz
```
```
gcloud compute target-pools create kubernetes-pool \
2016-07-09 03:32:42 +03:00
--health-check kube-apiserver-check \
--region us-central1
2016-07-07 23:26:27 +03:00
```
```
gcloud compute target-pools add-instances kubernetes-pool \
2016-07-08 20:26:32 +03:00
--instances controller0,controller1,controller2
2016-07-07 23:26:27 +03:00
```
2016-07-08 20:28:27 +03:00
```
2016-07-09 03:33:39 +03:00
export KUBERNETES_PUBLIC_IP_ADDRESS=$(gcloud compute addresses describe kubernetes \
--format 'value(address)')
2016-07-08 20:28:27 +03:00
```
2016-07-07 23:26:27 +03:00
```
2016-07-07 23:53:39 +03:00
gcloud compute forwarding-rules create kubernetes-rule \
2016-07-09 03:34:25 +03:00
--address ${KUBERNETES_PUBLIC_IP_ADDRESS} \
2016-07-07 23:26:27 +03:00
--ports 6443 \
--target-pool kubernetes-pool
```