2017-08-29 00:19:25 +03:00
# Bootstrapping the Kubernetes Worker Nodes
2022-09-20 09:17:00 +03:00
In this lab you will bootstrap 2 Kubernetes worker nodes. We already installed `containerd` and its dependencies on these nodes in the previous lab.
2019-03-20 07:34:49 +03:00
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
2024-03-18 08:16:56 +03:00
The Certificates and Configuration are created on `controlplane01` node and then copied over to workers using `scp` .
Once this is done, the commands are to be run on first worker instance: `node01` . Login to first worker instance using SSH Terminal.
2017-08-29 00:19:25 +03:00
2021-05-18 11:42:07 +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
2024-03-18 08:16:56 +03:00
On `controlplane01` :
2017-08-29 00:19:25 +03:00
2024-03-18 08:16:56 +03:00
[//]: # (host:controlplane01)
2022-09-20 09:17:00 +03:00
```bash
2024-03-18 08:16:56 +03:00
NODE01=$(dig +short node01)
2019-03-20 07:34:49 +03:00
```
2022-09-20 09:17:00 +03:00
```bash
2024-03-18 08:16:56 +03:00
cat > openssl-node01.cnf < < EOF
2019-03-20 07:34:49 +03:00
[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]
2024-03-18 08:16:56 +03:00
DNS.1 = node01
IP.1 = ${NODE01}
2019-03-20 07:34:49 +03:00
EOF
2017-08-29 00:19:25 +03:00
2024-03-18 08:16:56 +03:00
openssl genrsa -out node01.key 2048
openssl req -new -key node01.key -subj "/CN=system:node:node01/O=system:nodes" -out node01.csr -config openssl-node01.cnf
openssl x509 -req -in node01.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out node01.crt -extensions v3_req -extfile openssl-node01.cnf -days 1000
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
Results:
```
2024-03-18 08:16:56 +03:00
node01.key
node01.crt
2017-08-29 00:19:25 +03:00
```
2019-03-20 10:25:38 +03:00
### The kubelet Kubernetes Configuration File
When generating kubeconfig files for Kubelets the client certificate matching the Kubelet's node name must be used. This will ensure Kubelets are properly authorized by the Kubernetes [Node Authorizer ](https://kubernetes.io/docs/admin/authorization/node/ ).
2024-03-18 08:16:56 +03:00
Get the kube-api server load-balancer IP.
2022-09-20 09:17:00 +03:00
```bash
LOADBALANCER=$(dig +short loadbalancer)
2019-03-20 10:25:38 +03:00
```
2020-04-12 01:58:59 +03:00
Generate a kubeconfig file for the first worker node.
2019-03-20 10:25:38 +03:00
2024-03-18 08:16:56 +03:00
On `controlplane01` :
2022-09-20 09:17:00 +03:00
```bash
2019-03-20 11:04:22 +03:00
{
2019-03-20 10:25:38 +03:00
kubectl config set-cluster kubernetes-the-hard-way \
2022-09-20 09:17:00 +03:00
--certificate-authority=/var/lib/kubernetes/pki/ca.crt \
--server=https://${LOADBALANCER}:6443 \
2024-03-18 08:16:56 +03:00
--kubeconfig=node01.kubeconfig
2019-03-20 10:25:38 +03:00
2024-03-18 08:16:56 +03:00
kubectl config set-credentials system:node:node01 \
--client-certificate=/var/lib/kubernetes/pki/node01.crt \
--client-key=/var/lib/kubernetes/pki/node01.key \
--kubeconfig=node01.kubeconfig
2019-03-20 10:25:38 +03:00
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
2024-03-18 08:16:56 +03:00
--user=system:node:node01 \
--kubeconfig=node01.kubeconfig
2019-03-20 10:25:38 +03:00
2024-03-18 08:16:56 +03:00
kubectl config use-context default --kubeconfig=node01.kubeconfig
2019-03-20 11:04:22 +03:00
}
2019-03-20 10:25:38 +03:00
```
Results:
```
2024-03-18 08:16:56 +03:00
node01.kubeconfig
2019-03-20 10:25:38 +03:00
```
2019-03-20 10:35:02 +03:00
### Copy certificates, private keys and kubeconfig files to the worker node:
2024-03-18 08:16:56 +03:00
On `controlplane01` :
2022-09-20 09:17:00 +03:00
```bash
2024-03-18 08:16:56 +03:00
scp ca.crt node01.crt node01.key node01.kubeconfig node01:~/
2019-03-20 10:35:02 +03:00
```
2022-09-20 09:17:00 +03:00
2017-08-29 00:19:25 +03:00
### Download and Install Worker Binaries
2024-03-18 08:16:56 +03:00
All the following commands from here until the [verification ](#verification ) step must be run on `node01`
2019-03-20 11:04:22 +03:00
2024-03-18 08:16:56 +03:00
[//]: # (host:node01)
2022-09-20 09:17:00 +03:00
```bash
2023-11-23 22:52:14 +03:00
KUBE_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt)
2022-09-20 09:17:00 +03:00
wget -q --show-progress --https-only --timestamping \
2024-03-18 08:16:56 +03:00
https://dl.k8s.io/release/${KUBE_VERSION}/bin/linux/${ARCH}/kube-proxy \
https://dl.k8s.io/release/${KUBE_VERSION}/bin/linux/${ARCH}/kubelet
2017-08-29 00:19:25 +03:00
```
2022-09-20 09:17:00 +03:00
Reference: https://kubernetes.io/releases/download/#binaries
2019-11-19 07:08:01 +03:00
2017-08-29 00:19:25 +03:00
Create the installation directories:
2022-09-20 09:17:00 +03:00
```bash
sudo mkdir -p \
2017-08-29 00:19:25 +03:00
/var/lib/kubelet \
/var/lib/kube-proxy \
2022-09-20 09:17:00 +03:00
/var/lib/kubernetes/pki \
2017-08-29 00:19:25 +03:00
/var/run/kubernetes
```
Install the worker binaries:
2022-09-20 09:17:00 +03:00
```bash
2018-05-12 19:54:18 +03:00
{
2023-11-23 22:52:14 +03:00
chmod +x kube-proxy kubelet
sudo mv 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
Adjust markdown formatting (#328)
* Adjust markdown formatting:
* Remove extra capitalization.
* Remove extra curly braces {} inside Bash code blocks.
* Use in-line code block `` for IP-addresses, file names and commands.
* Add a dot at the end of sentences.
* Use list formatting in `differences-to-original.md`. Also add escaping for angle brackets <>.
* No logic changes were made, only formatting improvements.
* 01-prerequisites.md: remove extra capitalization, remove extra space in "Virtual Box"
* 01-prerequisites.md: split text into different lines (before, it was rendered into one line)
* Remove extra capitalization, use inline code blocks, add a dot at the end of sentences.
* 02-compute-resources.md: add escaping for angle brackets <>.
* 03-client-tools.md: remove extra capitalization, use inline code blocks
* 04-certificate-authority.md: remove extra capitalization, use inline code blocks, remove extra curly braces {} inside Bash code blocks
* 04-certificate-authority.md: remove extra curly braces {} inside Bash code blocks
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
As per @fireflycons https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1926329908 :
> They are there for a reason. If you paste a block of code within braces, then it is not executed immediately by the shell - you have to press ENTER. Quite often when making changes to this repo and I have multiple terminals open, it gives me a chance to check that I have pasted the block into the correct terminal before it executes in the wrong terminal and borks everything.
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
* Revert back all "Remove extra capitalization", as per request @fireflycons
https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1944388993
2024-02-21 23:50:31 +03:00
2024-03-18 08:16:56 +03:00
On `node01` :
2022-09-20 09:17:00 +03:00
Copy keys and config to correct directories and secure
```bash
2018-05-12 19:54:18 +03:00
{
2022-09-20 09:17:00 +03:00
sudo mv ${HOSTNAME}.key ${HOSTNAME}.crt /var/lib/kubernetes/pki/
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubelet.kubeconfig
sudo mv ca.crt /var/lib/kubernetes/pki/
sudo mv kube-proxy.crt kube-proxy.key /var/lib/kubernetes/pki/
sudo chown root:root /var/lib/kubernetes/pki/*
sudo chmod 600 /var/lib/kubernetes/pki/*
sudo chown root:root /var/lib/kubelet/*
sudo chmod 600 /var/lib/kubelet/*
2018-05-12 19:54:18 +03:00
}
```
2022-09-20 09:17:00 +03:00
CIDR ranges used *within* the cluster
2018-05-12 19:54:18 +03:00
2022-09-20 09:17:00 +03:00
```bash
POD_CIDR=10.244.0.0/16
SERVICE_CIDR=10.96.0.0/16
2018-05-12 19:54:18 +03:00
```
2022-09-20 09:17:00 +03:00
Compute cluster DNS addess, which is conventionally .10 in the service CIDR range
```bash
CLUSTER_DNS=$(echo $SERVICE_CIDR | awk 'BEGIN {FS="."} ; { printf("%s.%s.%s.10", $1, $2, $3) }')
```
Create the `kubelet-config.yaml` configuration file:
2023-11-23 22:52:14 +03:00
Reference: https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/
2022-09-20 09:17:00 +03:00
```bash
cat < < EOF | sudo tee / var / lib / kubelet / kubelet-config . yaml
2018-05-12 19:54:18 +03:00
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
2022-09-20 09:17:00 +03:00
clientCAFile: /var/lib/kubernetes/pki/ca.crt
2018-05-12 19:54:18 +03:00
authorization:
mode: Webhook
2023-11-23 22:52:14 +03:00
containerRuntimeEndpoint: unix:///var/run/containerd/containerd.sock
2022-09-20 09:17:00 +03:00
clusterDomain: cluster.local
2018-05-12 19:54:18 +03:00
clusterDNS:
2022-09-20 09:17:00 +03:00
- ${CLUSTER_DNS}
2023-11-23 22:52:14 +03:00
cgroupDriver: systemd
2022-09-20 09:17:00 +03:00
resolvConf: /run/systemd/resolve/resolv.conf
2018-05-12 19:54:18 +03:00
runtimeRequestTimeout: "15m"
2022-09-20 09:17:00 +03:00
tlsCertFile: /var/lib/kubernetes/pki/${HOSTNAME}.crt
tlsPrivateKeyFile: /var/lib/kubernetes/pki/${HOSTNAME}.key
registerNode: true
2018-05-12 19:54:18 +03:00
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:
2022-09-20 09:17:00 +03:00
```bash
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
2022-09-20 09:17:00 +03:00
After=containerd.service
Requires=containerd.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 \\
2022-09-20 09:17:00 +03:00
--kubeconfig=/var/lib/kubelet/kubelet.kubeconfig \\
2024-03-18 08:16:56 +03:00
--node-ip=${PRIMARY_IP} \\
2017-08-29 00:19:25 +03:00
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
```
### Configure the Kubernetes Proxy
Adjust markdown formatting (#328)
* Adjust markdown formatting:
* Remove extra capitalization.
* Remove extra curly braces {} inside Bash code blocks.
* Use in-line code block `` for IP-addresses, file names and commands.
* Add a dot at the end of sentences.
* Use list formatting in `differences-to-original.md`. Also add escaping for angle brackets <>.
* No logic changes were made, only formatting improvements.
* 01-prerequisites.md: remove extra capitalization, remove extra space in "Virtual Box"
* 01-prerequisites.md: split text into different lines (before, it was rendered into one line)
* Remove extra capitalization, use inline code blocks, add a dot at the end of sentences.
* 02-compute-resources.md: add escaping for angle brackets <>.
* 03-client-tools.md: remove extra capitalization, use inline code blocks
* 04-certificate-authority.md: remove extra capitalization, use inline code blocks, remove extra curly braces {} inside Bash code blocks
* 04-certificate-authority.md: remove extra curly braces {} inside Bash code blocks
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
As per @fireflycons https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1926329908 :
> They are there for a reason. If you paste a block of code within braces, then it is not executed immediately by the shell - you have to press ENTER. Quite often when making changes to this repo and I have multiple terminals open, it gives me a chance to check that I have pasted the block into the correct terminal before it executes in the wrong terminal and borks everything.
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
* Revert back all "Remove extra capitalization", as per request @fireflycons
https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1944388993
2024-02-21 23:50:31 +03:00
2024-03-18 08:16:56 +03:00
On `node01` :
2022-09-20 09:17:00 +03:00
```bash
sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/
2017-08-29 00:19:25 +03:00
```
2018-05-12 19:54:18 +03:00
Create the `kube-proxy-config.yaml` configuration file:
2023-11-23 22:52:14 +03:00
Reference: https://kubernetes.io/docs/reference/config-api/kube-proxy-config.v1alpha1/
2022-09-20 09:17:00 +03:00
```bash
cat < < EOF | sudo tee / var / lib / kube-proxy / kube-proxy-config . yaml
2018-05-12 19:54:18 +03:00
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
2023-11-23 22:52:14 +03:00
kubeconfig: /var/lib/kube-proxy/kube-proxy.kubeconfig
2024-03-18 08:16:56 +03:00
mode: iptables
2022-09-20 09:17:00 +03:00
clusterCIDR: ${POD_CIDR}
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:
2022-09-20 09:17:00 +03:00
```bash
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
```
2022-09-20 09:17:00 +03:00
## Optional - Check Certificates and kubeconfigs
2024-03-18 08:16:56 +03:00
At `node01` node, run the following, selecting option 4
2022-09-20 09:17:00 +03:00
2023-11-23 22:52:14 +03:00
[//]: # (command:./cert_verify.sh 4)
```
2022-09-20 09:17:00 +03:00
./cert_verify.sh
```
2017-08-29 00:19:25 +03:00
### Start the Worker Services
Adjust markdown formatting (#328)
* Adjust markdown formatting:
* Remove extra capitalization.
* Remove extra curly braces {} inside Bash code blocks.
* Use in-line code block `` for IP-addresses, file names and commands.
* Add a dot at the end of sentences.
* Use list formatting in `differences-to-original.md`. Also add escaping for angle brackets <>.
* No logic changes were made, only formatting improvements.
* 01-prerequisites.md: remove extra capitalization, remove extra space in "Virtual Box"
* 01-prerequisites.md: split text into different lines (before, it was rendered into one line)
* Remove extra capitalization, use inline code blocks, add a dot at the end of sentences.
* 02-compute-resources.md: add escaping for angle brackets <>.
* 03-client-tools.md: remove extra capitalization, use inline code blocks
* 04-certificate-authority.md: remove extra capitalization, use inline code blocks, remove extra curly braces {} inside Bash code blocks
* 04-certificate-authority.md: remove extra curly braces {} inside Bash code blocks
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
As per @fireflycons https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1926329908 :
> They are there for a reason. If you paste a block of code within braces, then it is not executed immediately by the shell - you have to press ENTER. Quite often when making changes to this repo and I have multiple terminals open, it gives me a chance to check that I have pasted the block into the correct terminal before it executes in the wrong terminal and borks everything.
* Revert back: all "remove extra curly braces {} inside Bash code blocks"
* Revert back all "Remove extra capitalization", as per request @fireflycons
https://github.com/mmumshad/kubernetes-the-hard-way/pull/328#issuecomment-1944388993
2024-02-21 23:50:31 +03:00
2024-03-18 08:16:56 +03:00
On `node01` :
2022-09-20 09:17:00 +03:00
```bash
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
```
2024-03-18 08:16:56 +03:00
> Remember to run the above commands on worker node: `node01`
2017-08-29 00:19:25 +03:00
## Verification
2022-09-20 09:17:00 +03:00
2024-03-18 08:16:56 +03:00
[//]: # (host:controlplane01)
2022-09-20 09:17:00 +03:00
2024-03-18 08:16:56 +03:00
Now return to the `controlplane01` node.
2017-08-29 00:19:25 +03:00
2024-03-18 08:16:56 +03:00
List the registered Kubernetes nodes from the controlplane node:
2017-08-29 00:19:25 +03:00
2022-09-20 09:17:00 +03:00
```bash
kubectl get nodes --kubeconfig admin.kubeconfig
2017-08-29 00:19:25 +03:00
```
2024-03-18 08:16:56 +03:00
Output will be similar to
2017-08-29 00:19:25 +03:00
```
2019-03-20 07:34:49 +03:00
NAME STATUS ROLES AGE VERSION
2024-03-18 08:16:56 +03:00
node01 NotReady < none > 93s v1.28.4
2017-08-29 00:19:25 +03:00
```
2022-09-20 09:17:00 +03:00
The node is not ready as we have not yet installed pod networking. This comes later.
2020-05-18 23:16:20 +03:00
2024-03-18 08:16:56 +03:00
Next: [TLS Bootstrapping Kubernetes Workers ](./11-tls-bootstrapping-kubernetes-workers.md )< br >
Prev: [Installing CRI on the Kubernetes Worker Nodes ](./09-install-cri-workers.md )