Below are some examples of NodeGroup
description, as well as installing the cert-manager plugin for kubectl and setting the sysctl parameter.
Examples of the NodeGroup
configuration
Cloud nodes
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
name: test
spec:
nodeType: CloudEphemeral
cloudInstances:
zones:
- eu-west-1a
- eu-west-1b
minPerZone: 1
maxPerZone: 2
classReference:
kind: AWSInstanceClass
name: test
nodeTemplate:
labels:
tier: test
Static nodes
Use nodeType: Static
for physical servers and VMs on Hypervisors.
An example:
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
name: worker
spec:
nodeType: Static
Adding nodes to such a group is done manually using the pre-made scripts.
You can also use a method that adds static nodes using the Cluster API Provider Static.
System nodes
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
name: system
spec:
nodeTemplate:
labels:
node-role.deckhouse.io/system: ""
taints:
- effect: NoExecute
key: dedicated.deckhouse.io
value: system
nodeType: Static
Adding a static node to a cluster
Adding a static node can be done manually or using the Cluster API Provider Static.
Manually
Follow the steps below to add a new static node (e.g., VM or bare metal server) to the cluster:
- For CloudStatic nodes in the following cloud providers, refer to the steps outlined in the documentation:
- Use the existing one or create a new NodeGroup custom resource (see the example for the
NodeGroup
calledworker
). The nodeType parameter for static nodes in the NodeGroup must beStatic
orCloudStatic
. -
Get the Base64-encoded script code to add and configure the node.
Here is how you can get Base64-encoded script code to add a node to the
worker
NodeGroup:NODE_GROUP=worker kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-${NODE_GROUP} -o json | jq '.data."bootstrap.sh"' -r
- Pre-configure the new node according to the specifics of your environment. For example:
- Add all the necessary mount points to the
/etc/fstab
file (NFS, Ceph, etc.); - Install the necessary packages (e.g.,
ceph-common
); - Configure network connectivity between the new node and the other nodes of the cluster.
- Add all the necessary mount points to the
-
Connect to the new node over SSH and run the following command, inserting the Base64 string you got in step 2:
echo <Base64-CODE> | base64 -d | bash
Using the Cluster API Provider Static
A brief example of adding a static node to a cluster using Cluster API Provider Static (CAPS):
-
Prepare the necessary resources.
-
Allocate a server (or a virtual machine), configure networking, etc. If required, install specific OS packages and add the mount points on the node.
-
Create a user (
caps
in the example below) and add it to sudoers by running the following command on the server:useradd -m -s /bin/bash caps usermod -aG sudo caps
-
Allow the user to run sudo commands without having to enter a password. For this, add the following line to the sudo configuration on the server (you can either edit the
/etc/sudoers
file, or run thesudo visudo
command, or use some other method):caps ALL=(ALL) NOPASSWD: ALL
-
Generate a pair of SSH keys with an empty passphrase on the server:
ssh-keygen -t rsa -f caps-id -C "" -N ""
The public and private keys of the
caps
user will be stored in thecaps-id.pub
andcaps-id
files in the current directory on the server. -
Add the generated public key to the
/home/caps/.ssh/authorized_keys
file of thecaps
user by executing the following commands in the keys 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/
-
-
Create a SSHCredentials resource in the cluster:
Run the following command in the user key directory on the server to encode the private key to Base64:
base64 -w0 caps-id
On any computer with
kubectl
configured to manage the cluster, create an environment variable with the value of the Base64-encoded private key you generated in the previous step:CAPS_PRIVATE_KEY_BASE64=<BASE64-ENCODED PRIVATE KEY>
Create a
SSHCredentials
resource in the cluster (note that from this point on, you have to usekubectl
configured to manage the cluster):kubectl create -f - <<EOF apiVersion: deckhouse.io/v1alpha1 kind: SSHCredentials metadata: name: credentials spec: user: caps privateSSHKey: "${CAPS_PRIVATE_KEY_BASE64}" EOF
-
Create a StaticInstance resource in the cluster; specify the IP address of the static node server:
kubectl create -f - <<EOF apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-0 spec: # Specify the IP address of the static node server. address: "<SERVER-IP>" credentialsRef: kind: SSHCredentials name: credentials EOF
-
Create a NodeGroup resource in the cluster:
kubectl create -f - <<EOF apiVersion: deckhouse.io/v1 kind: NodeGroup metadata: name: worker spec: nodeType: Static staticInstances: count: 1 EOF
Using the Cluster API Provider Static and label selector filters
This example shows how you can use filters in the StaticInstance label selector to group static nodes and use them in different NodeGroups. Here, two node groups (front
and worker
) are used for different tasks. Each group includes nodes with different characteristics — the front
group has two servers and the worker
group has one.
-
Prepare the required resources (3 servers or virtual machines) and create the
SSHCredentials
resource in the same way as step 1 and step 2 of the example. -
Create two NodeGroup in the cluster (from this point on, use
kubectl
configured to manage the cluster):kubectl 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 EOF
-
Create StaticInstance resources in the cluster and specify the valid IP addresses of the servers:
kubectl 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: credentials --- apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-front-2 labels: role: front spec: address: "<SERVER-FRONT-IP2>" credentialsRef: kind: SSHCredentials name: credentials --- apiVersion: deckhouse.io/v1alpha1 kind: StaticInstance metadata: name: static-worker-1 labels: role: worker spec: address: "<SERVER-WORKER-IP>" credentialsRef: kind: SSHCredentials name: credentials EOF
An example of the NodeUser
configuration
apiVersion: deckhouse.io/v1
kind: NodeUser
metadata:
name: testuser
spec:
uid: 1100
sshPublicKeys:
- "<SSH_PUBLIC_KEY>"
passwordHash: <PASSWORD_HASH>
isSudoer: true
An example of the NodeGroupConfiguration
configuration
Installing the cert-manager plugin for kubectl on master nodes
apiVersion: deckhouse.io/v1alpha1
kind: NodeGroupConfiguration
metadata:
name: add-cert-manager-plugin.sh
spec:
weight: 100
bundles:
- "*"
nodeGroups:
- "master"
content: |
if [ -x /usr/local/bin/kubectl-cert_manager ]; then
exit 0
fi
curl -L https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/kubectl-cert_manager-linux-amd64.tar.gz -o - | tar -zxvf - kubectl-cert_manager
mv kubectl-cert_manager /usr/local/bin
Tuning sysctl parameters
apiVersion: deckhouse.io/v1alpha1
kind: NodeGroupConfiguration
metadata:
name: sysctl-tune.sh
spec:
weight: 100
bundles:
- "*"
nodeGroups:
- "*"
content: |
sysctl -w vm.max_map_count=262144
Adding a root certificate to the host
Example is given for Ubuntu OS.
The method of adding certificates to the store may differ depending on the OS.
Change the bundles parameter to adapt the script to a different OS.
To use the certificate in containerd
(including pulling containers from a private repository), a restart of the service is required after adding the certificate.
apiVersion: deckhouse.io/v1alpha1
kind: NodeGroupConfiguration
metadata:
name: add-custom-ca.sh
spec:
weight: 31
nodeGroups:
- '*'
bundles:
- 'ubuntu-lts'
content: |-
CERT_FILE_NAME=example_ca
CERTS_FOLDER="/usr/local/share/ca-certificates"
CERT_CONTENT=$(cat <<EOF
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw
JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx
MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu
NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p
WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl
WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN
G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H
fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP
G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg
Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB
/wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu
NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG
SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL
dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36
D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU
by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K
aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn
iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP
-----END CERTIFICATE-----
EOF
)
# bb-event - Creating subscription for event function. More information: http://www.bashbooster.net/#event
## ca-file-updated - Event name
## update-certs - The function name that the event will call
bb-event-on "ca-file-updated" "update-certs"
update-certs() { # Function with commands for adding a certificate to the store
update-ca-certificates
}
# bb-tmp-file - Creating temp file function. More information: http://www.bashbooster.net/#tmp
CERT_TMP_FILE="$( bb-tmp-file )"
echo -e "${CERT_CONTENT}" > "${CERT_TMP_FILE}"
# bb-sync-file - File synchronization function. More information: http://www.bashbooster.net/#sync
## "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" - Destination file
## ${CERT_TMP_FILE} - Source file
## ca-file-updated - Name of event that will be called if the file changes.
bb-sync-file \
"${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" \
${CERT_TMP_FILE} \
ca-file-updated
Adding a certificate to the OS and containerd
Example is given for Ubuntu OS.
The method of adding certificates to the store may differ depending on the OS.
Change the bundles parameter to adapt the script to a different OS.
The example of NodeGroupConfiguration
uses functions of the script 032_configure_containerd.sh.
apiVersion: deckhouse.io/v1alpha1
kind: NodeGroupConfiguration
metadata:
name: add-custom-ca-containerd..sh
spec:
weight: 31
nodeGroups:
- '*'
bundles:
- 'ubuntu-lts'
content: |-
REGISTRY_URL=private.registry.example
CERT_FILE_NAME=${REGISTRY_URL}
CERTS_FOLDER="/usr/local/share/ca-certificates"
CERT_CONTENT=$(cat <<EOF
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw
JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx
MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu
NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p
WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl
WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN
G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H
fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP
G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg
Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB
/wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu
NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG
SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL
dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36
D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU
by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K
aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn
iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP
-----END CERTIFICATE-----
EOF
)
CONFIG_CONTENT=$(cat <<EOF
[plugins]
[plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_URL}".tls]
ca_file = "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt"
EOF
)
mkdir -p /etc/containerd/conf.d
# bb-tmp-file - Create temp file function. More information: http://www.bashbooster.net/#tmp
CERT_TMP_FILE="$( bb-tmp-file )"
echo -e "${CERT_CONTENT}" > "${CERT_TMP_FILE}"
CONFIG_TMP_FILE="$( bb-tmp-file )"
echo -e "${CONFIG_CONTENT}" > "${CONFIG_TMP_FILE}"
# bb-event - Creating subscription for event function. More information: http://www.bashbooster.net/#event
## ca-file-updated - Event name
## update-certs - The function name that the event will call
bb-event-on "ca-file-updated" "update-certs"
update-certs() { # Function with commands for adding a certificate to the store
update-ca-certificates # Restarting the containerd service is not required as this is done automatically in the script 032_configure_containerd.sh
}
# bb-sync-file - File synchronization function. More information: http://www.bashbooster.net/#sync
## "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" - Destination file
## ${CERT_TMP_FILE} - Source file
## ca-file-updated - Name of event that will be called if the file changes.
bb-sync-file \
"${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" \
${CERT_TMP_FILE} \
ca-file-updated
bb-sync-file \
"/etc/containerd/conf.d/${REGISTRY_URL}.toml" \
${CONFIG_TMP_FILE}