Adding a static node to the cluster
You can add a static node manually or using Cluster API Provider Static.
Adding a static node manually
To add a bare-metal server to the cluster as a static node, follow these steps:
Use an existing NodeGroup custom resource or create a new one (NodeGroup). The
nodeTypeparameter of the NodeGroup custom resource for static nodes must beStaticorCloudStatic.Get the Base64-encoded script code for adding and configuring the node.
Example of getting the Base64-encoded script code for adding a node to the
workerNodeGroup:NODE_GROUP=worker d8 k -n d8-cloud-instance-manager get secret manual-bootstrap-for-${NODE_GROUP} -o json | jq '.data."bootstrap.sh"' -rPre-configure the new node according to the specifics of your environment:
- add the required mount points to the
/etc/fstabfile (NFS, Ceph, etc.); - install the required packages (for example,
ceph-common); - configure network connectivity between the new node and the other cluster nodes.
Connect to the new node via SSH and run the following command, inserting the Base64 string obtained in step 2:
echo <BASE64_SCRIPT> | base64 -d | bashAdding a static node using Cluster API Provider Static
Example of adding a static node to the cluster using Cluster API Provider Static (CAPS):
Allocate a server with an installed OS, configure network connectivity, etc., and, if necessary, install OS-specific packages and add the mount points that the node will need.
Create a user (
capsin the example) that can runsudoby running the following commands on the server:useradd -m -s /bin/bash caps usermod -aG sudo capsAllow the user to run commands via
sudowithout a password. To do this, add the following line to thesudoconfiguration on the server (by editing the/etc/sudoersfile, runningsudo visudo, or in another way):caps ALL=(ALL) NOPASSWD: ALLGenerate an SSH key pair with an empty passphrase on the server:
ssh-keygen -t rsa -f caps-id -C "" -N ""The public and private keys of the
capsuser will be saved to thecaps-id.pubandcaps-idfiles in the current directory on the server.Add the generated public key to the
/home/caps/.ssh/authorized_keysfile of thecapsuser by running the following commands in the key directory on the server:mkdir -p /home/caps/.ssh cat caps-id.pub >> /home/caps/.ssh/authorized_keys chmod 700 /home/caps/.ssh chmod 600 /home/caps/.ssh/authorized_keys chown -R caps:caps /home/caps/- In Astra Linux operating systems, when using the Parsec mandatory integrity control module, configure the maximum integrity level for the
capsuser:
- In Astra Linux operating systems, when using the Parsec mandatory integrity control module, configure the maximum integrity level for the
pdpl-user -i 63 capsCreate an SSHCredentials resource in the cluster.
- To access the server being added, the CAPS component needs the private key of the
capsservice user. The key in Base64 format is added to the SSHCredentials resource.
In the user key directory on the server, run the following command to get the private key in Base64 format:
base64 -w0 caps-id- On any computer configured to manage the cluster, create an environment variable with the Base64-encoded private key obtained in the previous step (add a space at the beginning of the command so that the key is not saved in the command history):
CAPS_PRIVATE_KEY_BASE64=<PRIVATE_KEY_IN_BASE64>- Create an SSHCredentials resource with the service user name and its private key:
d8 k create -f - <<EOF
apiVersion: deckhouse.io/v1alpha2
kind: SSHCredentials
metadata:
name: static-0-access
spec:
user: caps
privateSSHKey: "${CAPS_PRIVATE_KEY_BASE64}"
EOFCreate a StaticInstance resource in the cluster:
The StaticInstance resource defines the IP address of the static node server and the credentials for accessing the server:
d8 k create -f - <<EOF
apiVersion: deckhouse.io/v1alpha2
kind: StaticInstance
metadata:
name: static-0
spec:
# Specify the IP address of the static node server.
address: "<SERVER-IP>"
credentialsRef:
kind: SSHCredentials
name: static-0-access
EOFCreate a NodeGroup resource in the cluster:
d8 k create -f - <<EOF
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
name: worker
spec:
nodeType: Static
staticInstances:
count: 1
EOFWait for the Ready state:
The NodeGroup status should show 1 node in the Ready column:
d8 k get ng worker
NAME TYPE READY NODES UPTODATE INSTANCES DESIRED MIN MAX STANDBY STATUS AGE SYNCED
worker Static 1 1 1 15m TrueAdding a static node using Cluster API Provider Static and label selector filters
To connect different StaticInstances to different NodeGroups, you can use a label selector specified in the NodeGroup and in the StaticInstance metadata.
As an example, consider distributing 3 static nodes across 2 NodeGroups: 1 node is added to the worker group and 2 nodes to the front group.
Prepare the required resources (3 servers) and create SSHCredentials resources for them, similarly to steps 1 and 2 of the previous example.
Create two NodeGroup resources in the cluster:
Specify a labelSelector so that only servers matching it are connected to the NodeGroup.
d8 k create -f - <<EOF apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: front spec: nodeType: Static staticInstances: count: 2 labelSelector: matchLabels: role: front --- apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static staticInstances: count: 1 labelSelector: matchLabels: role: worker EOFCreate StaticInstance resources in the cluster.
Specify the actual IP addresses of the servers and set the role label in the metadata:
d8 k create -f - <<EOF apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-front-1 labels: role: front spec: address: "<SERVER-FRONT-IP1>" credentialsRef: kind: SSHCredentials name: front-1-credentials --- apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-front-2 labels: role: front spec: address: "<SERVER-FRONT-IP2>" credentialsRef: kind: SSHCredentials name: front-2-credentials --- apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-worker-1 labels: role: worker spec: address: "<SERVER-WORKER-IP>" credentialsRef: kind: SSHCredentials name: worker-1-credentials EOF
Result:
d8 k get ng
NAME TYPE READY NODES UPTODATE INSTANCES DESIRED MIN MAX STANDBY STATUS AGE SYNCED
master Static 1 1 1 1h True
front Static 2 2 2 1h TrueHow to tell if something went wrong?
If a node in a NodeGroup is not updated (the UPTODATE value in the output of d8 k get nodegroup is less than the NODES value), or you suspect other problems that may be related to the node-manager module, check the logs of the bashible service. The bashible service runs on every node managed by the node-manager module.
To view the bashible service logs, run the following command on the node:
journalctl -fu bashibleExample output when all required actions have been completed:
May 25 04:39:16 kube-master-0 systemd[1]: Started Bashible service.
May 25 04:39:16 kube-master-0 bashible.sh[1976339]: Configuration is in sync, nothing to do.
May 25 04:39:16 kube-master-0 systemd[1]: bashible.service: Succeeded.
Removing a node from the cluster
These instructions apply both to a node configured manually (using the bootstrap script) and to a node configured using CAPS.
To remove a node from the cluster and clean up the server (VM), run the following command on the node:
bash /var/lib/bashible/cleanup_static_node.sh --yes-i-am-sane-and-i-understand-what-i-am-doingHow to clean up a node for adding it to a cluster later?
This is only needed if you need to move a static node from one cluster to another. Keep in mind that these operations delete local storage data. If you only need to change the NodeGroup, follow the instructions for changing the NodeGroup of a static node.
If the node being cleaned up has LINSTOR/DRBD storage pools, follow the sds-replicated-volume module instructions to evict resources from the node and delete the LINSTOR/DRBD node.
Delete the node from the Kubernetes cluster:
d8 k drain <NODE_NAME> --ignore-daemonsets --delete-emptydir-data d8 k delete node <NODE_NAME>Run the cleanup script on the node:
bash /var/lib/bashible/cleanup_static_node.sh --yes-i-am-sane-and-i-understand-what-i-am-doingAfter the reboot, the node can be added to another cluster.
FAQ
Can a StaticInstance be deleted?
A StaticInstance in the Pending state can be deleted without any issues.
To delete a StaticInstance in any state other than Pending (Running, Cleaning, Bootstraping):
Add the
"node.deckhouse.io/allow-bootstrap": "false"label to the StaticInstance.Example command for adding the label:
d8 k label staticinstance d8cluster-worker node.deckhouse.io/allow-bootstrap=falseWait until the StaticInstance switches to the
Pendingstatus.To check the StaticInstance status, use the command:
d8 k get staticinstancesDelete the StaticInstance.
Example command for deleting a StaticInstance:
d8 k delete staticinstance d8cluster-workerDecrease the
NodeGroup.spec.staticInstances.countparameter value by 1.Wait for the NodeGroup to reach the
Readystate.
How to change the IP address of a StaticInstance?
You cannot change the IP address in a StaticInstance resource. If a StaticInstance has an incorrect address, delete the StaticInstance and create a new one.
How to migrate a manually configured static node to CAPS management?
Clean up the node, then add the node under CAPS management.
How to change the NodeGroup of a static node?
If the node is managed by CAPS, you cannot change its NodeGroup membership. The only option is to delete the StaticInstance and create a new one.
If the static node was added to the cluster manually, to move it to another NodeGroup, change the label with the group name and remove the label with the role:
d8 k label node --overwrite <NODE_NAME> node.deckhouse.io/group=<NEW_NODEGROUP_NAME>
d8 k label node <NODE_NAME> node-role.kubernetes.io/<OLD_NODEGROUP_NAME>-Applying the changes will take some time.
How to see what is currently running on a node while it is being created?
If you need to find out what is happening on a node (for example, it takes a long time to create or is stuck in Pending), you can check the cloud-init logs. To do this, follow these steps:
Find the node that is currently bootstrapping:
d8 k get instances | grep Pending # dev-worker-2a6158ff-6764d-nrtbj Pending 46sGet the connection parameters for viewing the logs:
d8 k get instances dev-worker-2a6158ff-6764d-nrtbj -o yaml | grep 'bootstrapStatus' -B0 -A2 # bootstrapStatus: # description: Use 'curl -N http://192.168.199.158:8000' to get bootstrap logs. # logsEndpoint: 192.168.199.178:8000Run the obtained command (
curl -N http://192.168.199.158:8000in the example above) to get thecloud-initlogs for further diagnostics.
The logs of the initial node configuration are located in /var/log/cloud-init-output.log.
When is a node reboot required?
During node configuration, some configuration changes may require a reboot.
For example, a node reboot is required in Astra Linux when changing the kernel.yama.ptrace_scope sysctl parameter (the result of the astra-ptrace-lock enable/disable command).
The reboot mode is defined in the disruptions parameter section of the NodeGroup resource.