2017-08-29 00:19:25 +03:00
# Bootstrapping the Kubernetes Worker Nodes
2019-03-20 07:34:49 +03:00
In this lab you will bootstrap 2 Kubernetes worker nodes. We already have [Docker ](https://www.docker.com ) installed on these nodes.
We will now install the kubernetes components
- [kubelet ](https://kubernetes.io/docs/admin/kubelet )
- [kube-proxy ](https://kubernetes.io/docs/concepts/cluster-administration/proxies ).
2017-08-29 00:19:25 +03:00
## Prerequisites
2019-03-20 07:34:49 +03:00
The commands in this lab must be run on first worker instance: `worker-1` . Login to first worker instance using SSH Terminal.
2017-08-29 00:19:25 +03:00
2019-03-20 07:34:49 +03:00
### Provisioning Kubelet Client Certificates
2017-08-29 00:19:25 +03:00
2019-03-20 07:34:49 +03:00
Kubernetes uses a [special-purpose authorization mode ](https://kubernetes.io/docs/admin/authorization/node/ ) called Node Authorizer, that specifically authorizes API requests made by [Kubelets ](https://kubernetes.io/docs/concepts/overview/components/#kubelet ). In order to be authorized by the Node Authorizer, Kubelets must use a credential that identifies them as being in the `system:nodes` group, with a username of `system:node:<nodeName>` . In this section you will create a certificate for each Kubernetes worker node that meets the Node Authorizer requirements.
2018-05-12 19:54:18 +03:00
2019-03-20 07:34:49 +03:00
Generate a certificate and private key for one worker node:
2018-05-12 19:54:18 +03:00
2019-03-20 07:34:49 +03:00
Worker1:
2017-08-29 00:19:25 +03:00
2019-03-20 07:34:49 +03:00
```
cat > openssl-worker-1.cnf < < EOF
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = worker-1
IP.1 = 192.168.5.11
EOF
2017-08-29 00:19:25 +03:00
2019-03-20 07:34:49 +03:00
openssl genrsa -out worker-1.key 2048
openssl req -new -key worker-1.key -subj "/CN=system:node:worker-1/O=system:nodes" -out worker-1.csr -config openssl-worker-1.cnf
openssl x509 -req -in worker-1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out worker-1.crt -extensions v3_req -extfile openssl-worker-1.cnf
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
Results:
```
worker-1.key
worker-1.crt
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
Copy the appropriate certificates and private keys to the worker node:
```
scp ca.crt worker-1.crt worker-1.key worker-1:~/
```
2017-08-29 00:19:25 +03:00
### Download and Install Worker Binaries
```
wget -q --show-progress --https-only --timestamping \
2019-03-20 07:34:49 +03:00
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl \
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kube-proxy \
https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubelet
2017-08-29 00:19:25 +03:00
```
Create the installation directories:
```
sudo mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
```
Install the worker binaries:
```
2018-05-12 19:54:18 +03:00
{
2019-03-20 07:34:49 +03:00
chmod +x kubectl kube-proxy kubelet
sudo mv kubectl kube-proxy kubelet /usr/local/bin/
2017-08-29 00:19:25 +03:00
}
```
2018-05-12 19:54:18 +03:00
### Configure the Kubelet
2017-08-29 00:19:25 +03:00
```
2018-05-12 19:54:18 +03:00
{
2019-03-20 07:34:49 +03:00
sudo mv ${HOSTNAME}.key ${HOSTNAME}.crt /var/lib/kubelet/
2018-05-12 19:54:18 +03:00
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
2019-03-20 07:34:49 +03:00
sudo mv ca.crt /var/lib/kubernetes/
2018-05-12 19:54:18 +03:00
}
```
Create the `kubelet-config.yaml` configuration file:
```
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:
2019-03-20 07:34:49 +03:00
clientCAFile: "/var/lib/kubernetes/ca.crt"
2018-05-12 19:54:18 +03:00
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
2019-03-20 07:34:49 +03:00
- "10.96.0.10"
2018-09-30 22:35:05 +03:00
resolvConf: "/run/systemd/resolve/resolv.conf"
2018-05-12 19:54:18 +03:00
runtimeRequestTimeout: "15m"
EOF
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
> The `resolvConf` configuration is used to avoid loops when using CoreDNS for service discovery on systems running `systemd-resolved`.
2018-09-30 22:35:05 +03:00
2017-08-29 00:19:25 +03:00
Create the `kubelet.service` systemd unit file:
```
2018-05-12 19:54:18 +03:00
cat < < EOF | sudo tee / etc / systemd / system / kubelet . service
2017-08-29 00:19:25 +03:00
[Unit]
Description=Kubernetes Kubelet
2017-12-18 18:07:54 +03:00
Documentation=https://github.com/kubernetes/kubernetes
2019-03-20 07:34:49 +03:00
After=docker.service
Requires=docker.service
2017-08-29 00:19:25 +03:00
[Service]
ExecStart=/usr/local/bin/kubelet \\
2018-05-12 19:54:18 +03:00
--config=/var/lib/kubelet/kubelet-config.yaml \\
2017-08-29 00:19:25 +03:00
--image-pull-progress-deadline=2m \\
--kubeconfig=/var/lib/kubelet/kubeconfig \\
2019-03-20 07:34:49 +03:00
--tls-cert-file=/var/lib/kubelet/${HOSTNAME}.crt \\
--tls-private-key-file=/var/lib/kubelet/${HOSTNAME}.key \\
2017-08-29 00:19:25 +03:00
--network-plugin=cni \\
--register-node=true \\
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### Configure the Kubernetes Proxy
```
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
```
2018-05-12 19:54:18 +03:00
Create the `kube-proxy-config.yaml` configuration file:
```
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"
2019-03-20 07:34:49 +03:00
clusterCIDR: "192.168.5.0/24"
2018-05-12 19:54:18 +03:00
EOF
```
2017-08-29 00:19:25 +03:00
Create the `kube-proxy.service` systemd unit file:
```
2018-05-12 19:54:18 +03:00
cat < < EOF | sudo tee / etc / systemd / system / kube-proxy . service
2017-08-29 00:19:25 +03:00
[Unit]
Description=Kubernetes Kube Proxy
2017-12-18 18:07:54 +03:00
Documentation=https://github.com/kubernetes/kubernetes
2017-08-29 00:19:25 +03:00
[Service]
ExecStart=/usr/local/bin/kube-proxy \\
2018-05-12 19:54:18 +03:00
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
2017-08-29 00:19:25 +03:00
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### Start the Worker Services
```
2018-05-12 19:54:18 +03:00
{
sudo systemctl daemon-reload
2019-03-20 07:34:49 +03:00
sudo systemctl enable kubelet kube-proxy
sudo systemctl start kubelet kube-proxy
2018-05-12 19:54:18 +03:00
}
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
> Remember to run the above commands on worker node: `worker-1`
2017-08-29 00:19:25 +03:00
## Verification
2019-03-20 07:34:49 +03:00
List the registered Kubernetes nodes from the master node:
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
master-1$ kubectl get nodes --kubeconfig admin.kubeconfig
2017-08-29 00:19:25 +03:00
```
> output
```
2019-03-20 07:34:49 +03:00
NAME STATUS ROLES AGE VERSION
worker-1 NotReady < none > 93s v1.13.0
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
> Note: It is OK for the worker node to be in a NotReady state.
That is because we haven't configured Networking yet.
2017-08-29 00:19:25 +03:00
Next: [Configuring kubectl for Remote Access ](10-configuring-kubectl.md )