kubernetes-the-hard-way/docs/09-bootstrapping-kubernetes...

259 lines
6.9 KiB
Markdown
Raw Normal View History

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.
2019-03-20 07:34:49 +03:00
Generate a certificate and private key for one worker node:
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
```
2019-03-20 10:35:02 +03:00
master-1$ cat > openssl-worker-1.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]
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 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/).
Get the kub-api server load-balancer IP.
```
LOADBALANCER_ADDRESS=192.168.5.30
```
Generate a kubeconfig file for the first worker node:
```
2019-03-20 11:04:22 +03:00
{
2019-03-20 10:25:38 +03:00
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca.crt \
--embed-certs=true \
--server=https://${LOADBALANCER_ADDRESS}:6443 \
2019-03-20 11:04:22 +03:00
--kubeconfig=worker-1.kubeconfig
2019-03-20 10:25:38 +03:00
kubectl config set-credentials system:node:worker-1 \
--client-certificate=worker-1.crt \
--client-key=worker-1.key \
--embed-certs=true \
--kubeconfig=worker-1.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:worker-1 \
--kubeconfig=worker-1.kubeconfig
kubectl config use-context default --kubeconfig=worker-1.kubeconfig
2019-03-20 11:04:22 +03:00
}
2019-03-20 10:25:38 +03:00
```
Results:
```
worker-1.kubeconfig
```
2019-03-20 10:35:02 +03:00
### Copy certificates, private keys and kubeconfig files to the worker node:
```
master-1$ scp ca.crt worker-1.crt worker-1.key worker-1.kubeconfig worker-1:~/
```
2017-08-29 00:19:25 +03:00
### Download and Install Worker Binaries
2019-03-20 11:04:22 +03:00
Going forward all activities are to be done on the `worker-1` node.
2017-08-29 00:19:25 +03:00
```
2019-03-20 10:35:02 +03:00
worker-1$ 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:
```
2019-03-20 10:35:02 +03:00
worker-1$ sudo mkdir -p \
2017-08-29 00:19:25 +03:00
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
```
Install the worker binaries:
```
{
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
}
```
### Configure the Kubelet
2017-08-29 00:19:25 +03:00
```
{
2019-03-20 07:34:49 +03:00
sudo mv ${HOSTNAME}.key ${HOSTNAME}.crt /var/lib/kubelet/
sudo mv ${HOSTNAME}.kubeconfig /var/lib/kubelet/kubeconfig
2019-03-20 07:34:49 +03:00
sudo mv ca.crt /var/lib/kubernetes/
}
```
Create the `kubelet-config.yaml` configuration file:
```
2019-03-20 10:35:02 +03:00
worker-1$ 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"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
2019-03-20 07:34:49 +03:00
- "10.96.0.10"
resolvConf: "/run/systemd/resolve/resolv.conf"
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`.
2017-08-29 00:19:25 +03:00
Create the `kubelet.service` systemd unit file:
```
2019-03-20 10:35:02 +03:00
worker-1$ 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 \\
--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
```
2019-03-20 10:35:02 +03:00
worker-1$ sudo mv kube-proxy.kubeconfig /var/lib/kube-proxy/kubeconfig
2017-08-29 00:19:25 +03:00
```
Create the `kube-proxy-config.yaml` configuration file:
```
2019-03-20 10:35:02 +03:00
worker-1$ 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"
EOF
```
2017-08-29 00:19:25 +03:00
Create the `kube-proxy.service` systemd unit file:
```
2019-03-20 10:35:02 +03:00
worker-1$ 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 \\
--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
```
{
sudo systemctl daemon-reload
2019-03-20 07:34:49 +03:00
sudo systemctl enable kubelet kube-proxy
sudo systemctl start kubelet kube-proxy
}
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)