Single Machine Setup with k0s
K0s is an open-source project offering a lightweight, standalone Kubernetes Operating System (KOS) tailored for single-machine clusters. It simplifies Kubernetes deployment, making it ideal for both development and production environments, providing a minimalist approach to cluster management.
Assuming you already have a clean installation of Ubuntu Server, the following steps will guide you in setting up a single-node Kubernetes cluster using k0s
:
curl -sSLf https://get.k0s.sh | sudo sh
sudo k0s install controller --single
sudo systemctl daemon-reload
sudo k0s start
sudo k0s kubeconfig admin > ~/.kube/config
Confirm successful k0s
installation with the following command: kubectl get node
:
NAME STATUS ROLES AGE VERSION
myk0s Ready control-plane 1d v1.28.2+k0s
As mentioned in the Infrastructure Recommandations table, when working in a development setup based on kind
, you should consider disabling Kafka
. To do so, you need to customize your myvalues.yaml
file as follows:
global:
configuration:
streamTech: "REDIS"
kafka:
enabled: false
As mentionned in the Infrastructure Recommandations table, when working in a single machine setup based on k0s
, it is advised to enable PostgreSQL persistency. To do, you need to customize your myvalues.yaml
file as follows:
postgresql:
enabled: true
## You should define your own strong password for the "postgres" admin user
auth:
postgresPassword: "very_strong_password"
storagePath: "/opt/geocore/pg/data"
postgresql:
primary:
user: "custom_user"
password: "strong_password"
dbname: "db_geocore"
## Update the lines below and define your own strong password for the "postgres" admin user
auth:
postgresPassword: "very_strong_password"
Persistent data are store in a volume using filestorage. You need to create a directory that matches the storagePath
(by default, it’s set to “/opt/geocore/pg/data”). Once connected to the machine where k0s is installed, execute the following commands:
sudo mkdir -p /opt/geocore/pg/data
sudo chown $USER:$USER -R /opt/geocore
sudo chmod 777 -R /opt/geocore
As mentioned earlier in the Identification section, Geocore depends on Keycloak for authentication and authorization. However, the current Geocore OnPremise version does not include Keycloak. Therefore, it is necessary to disable Keycloak. To achieve this, please modify your myvalues.yaml
with the following configuration:
global:
keycloak:
url: ""
The current Geocore OnPremise version does not include Keycloak.
For a single machine setup using k0s
, configure your Geocore deployment to use the MQTT broker service as a NodePort
. Depending on your needs, you can enable TCP plain communication, or restrict communication to TLS. Customize your myvalues.yaml
file as follows:
emqx:
enabled: true
replicaCount: 1
## Update the line below and define your own strong password MQTT broker strong password
allPassword: "very_strong_password"
service:
type: NodePort
nodePorts:
mqttssl: 30883
mqtt: 30881
emqxConfig:
## Allow TLS communication by default
## (substitute "X.X.X.X" with the IP address of the k0s single machine)
EMQX_SSL_CLIENT_OPTS__SERVER_NAME_INDICATION: "X.X.X.X"
## If you want TCP communication, comment the line above
## And uncomment the line below
#EMQX_LISTENERS__TCP__DEFAULT__ENABLE: "true"
If you are using WiFi boards on a network without internet access, you need an NTP server available at the same address as the MQTT broker but on port 123. To do this, deploy the NTP server service as a NodePort
, similar to the MQTT broker. Customize your myvalues.yaml
file as follows:
ntp:
service:
type: NodePort
By default, the NTP server service is accessible on port 30123. However, the WiFi boards require an NTP server on port 123, which falls outside the NodePort range (30000-32767). To address this, we need to redirect incoming UDP traffic from port 123 to port 30123. To achieve this, connect to the machine running your k0s
cluster and install nftables
using the following steps:
sudo apt-get update
sudo apt install nftables
You can now use the following command to retrieve the name of the network interface within the `k0s`` single machine cluster:
ip -o addr | grep 'k0s_single_machine_cluster_IP' | awk '{print $2}'
Take note of the name of this interface (e.g., enp2s0
), and proceed to edit the /etc/nftables.conf
file in order to add a port redirection rule:
sudo vim /etc/nftables.conf
Append the file with the following content (make sure to replace your_interface_name
with the actual name of your interface):
table ip geocore {
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
iifname "your_interface_name" udp dport 123 \
dup to 127.0.0.1 udp dport set 30123 notrack
}
chain input {
type filter hook input priority mangle; policy accept;
iifname lo udp dport 123 ip daddr set 127.0.0.1 notrack
}
}
After editing, apply this configuration using the following command:
sudo nft -f /etc/nftables.conf
Configure the FQDN for Geocore API and Centui, editting myvalues.yaml
file as follow:
front:
apiGeo:
tlsEnabled: true
centui:
tlsEnabled: true
apiURL: "api.local.centiloc.com" # Update this value as you wish
centuiURL: "centui.local.centiloc.com" # Update this value as you wish
Now that your myvalues.yaml
file is appropriately configured for your single machine setup, you can proceed with the Geocore installation using the following command:
helm install geocore centiloc/geocore --namespace geocore --create-namespace -f myvalues.yaml
Please find below the complete content of myvalues.yaml
global:
imageCredentials:
registry: harbor.centiloc.com
email: <your-email>
password: <your-password>
username: <your-usename>
configuration:
streamTech: "REDIS"
keycloak:
url: ""
## connection to the database
postgresql:
primary:
user: "custom_user"
password: "strong_password"
dbname: "db_geocore"
replicas: []
postgresql:
enabled: true
## You should define your own strong password for the "postgres" admin user
auth:
postgresPassword: "very_strong_password"
storagePath: "/opt/geocore/pg/data"
emqx:
enabled: true
replicaCount: 1
## Update the line below and define your own strong password MQTT broker strong password
allPassword: "very_strong_password"
service:
type: NodePort
nodePorts:
mqttssl: 30883
mqtt: 30881
emqxConfig:
## Allow TLS communication by default
## (substitute "X.X.X.X" with the IP address of the k0s single machine)
EMQX_SSL_CLIENT_OPTS__SERVER_NAME_INDICATION: "X.X.X.X"
## If you want TCP communication, comment the line above
## And uncomment the line below
#EMQX_LISTENERS__TCP__DEFAULT__ENABLE: "true"
kafka:
enabled: false
ntp:
service:
type: NodePort
front:
apiGeo:
tlsEnabled: true
centui:
tlsEnabled: true
apiURL: "api.local.centiloc.com" # Update this value as you wish
centuiURL: "centui.local.centiloc.com" # Update this value as you wish
The following section discusses how to install an Ingress Controller as a LoadBalancer using MetalLB and how to set up your own PKI for certificate management, enabling TLS for Geocore within the cluster.
Cert-manager is a Kubernetes tool for automating X.509 certificate management, ensuring secure communication in clusters.
To install cert-manager
with Helm
, start by adding the cert-manager
chart repository using the following command:
helm repo add jetstack https://charts.jetstack.io
Then update your local Helm chart repository cache using the following command:
helm repo update
To complete the installation, use the following command:
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true
Now that cert-manager
is installed, you can set up a basic PKI for Geocore. This minimal PKI consists of a self-signed Root CA that can issue X.509 certificates within the cluster.
To deploy this PKI, create a file named geocore-pki.yaml
with the following content:
## Create a ClusterIssuer for Self-Sign Root CA
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
namespace: cert-manager
spec:
selfSigned: {}
---
# ROOT CA Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: root-ca
namespace: cert-manager
spec:
isCA: true
# At least one of a DNS Name, URI, or IP address is required.
dnsNames:
- X.X.X.X
subject:
organizations:
- YourOrganization
countries:
- FR
commonName: Root CA Issuer
secretName: root-ca-secret
duration: 864000h
renewBefore: 700000h
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
group: cert-manager.io
---
# ROOT CA Cluster Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: root-ca-issuer
namespace: cert-manager
spec:
ca:
secretName: root-ca-secret
---
# Geocore Intermediate Cluster Issuer Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: geocore-cert
namespace: cert-manager
spec:
isCA: true
subject:
organizations:
- "Your Organization Name"
countries:
- "Your Country Name"
commonName: Geocore Intermediate Issuer
secretName: geocore-cert-secret
duration: 438000h
renewBefore: 420000h
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: root-ca-issuer
kind: ClusterIssuer
group: cert-manager.io
---
# Geocore Intermediate Cluster Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: geocore-issuer
namespace: cert-manager
spec:
ca:
secretName: geocore-cert-secret
Make sure to replace the “X.X.X.X” in the provided file content with the IP address of your k0s single-node cluster.
To deploy the PKI use the following command:
kubectl apply -f geocore-pki.yaml
MetalLB is a Kubernetes load balancer ideal for single-node clusters like k0s
. It manages external IP addresses to enable efficient network traffic routing to cluster services.
In order to install metalLB
using Helm, you first need to add metalLB
chart repository using the following command:
helm repo add metallb https://metallb.github.io/metallb
Then update your repository catalog with the following command:
helm repo update
You can now initiate the MetalLB installation using the following command:
helm install -n metallb --create-namespace my-metallb metallb/metallb --version 0.13.11
Now that MetalLB
is installed, configuration is required. To set up the configuration, create a file named metallb-ipaddresspool.yaml
with the following content:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: geocore-pool
namespace: metallb
spec:
addresses:
# The following IP address is given for example
# /!\ Replace it with your k0s single-node cluster IP address
- X.X.X.X/32
Make sure to replace the “X.X.X.X” in the provided file content with the IP address of your k0s single-node cluster.
Apply this resource using the following command:
kubectl apply -f metallb-ipaddresspool.yaml
As mentionned in Managing Incoming Traffic section, it is crucial to ensure that your chosen Ingress Controller supports Geocore’s specific protocols, including HTTP1.1, HTTP2, UDP, TCP, and the gRPC-Web format. We strongly recommend utilizing the Contour Ingress Controller for a smooth Geocore deployment.
To install Contour as a LoadBalancer
, please refer to the comprehensive instructions in Ingress With Contour section.
Now that Geocore and Contour are installed, you still need to add Ingress rules to properly route incoming traffic to containerized applications. For this purpose, the Geocore Ingress Contour chart will help you to quickly create ingress rules using Helm.
To create the ingress rules required, please use the following command:
helm install geocore-ingress-contour centiloc/geocore-ingress-contour -n geocore -f kindValues.yaml
Where kindValues.yaml
content is:
certmanager:
enabled: true
issuer:
name: geocore-issuer
tlsEnabled: true
api:
domain: api.local.centiloc.com
centui:
domain: centui.local.centiloc.com
It is mandatory to ensure FQDN consistency between the values used forapiURL
, andcentuiURL
when deploying Geocore, and the values used forapi.domain
andcentui.domain
when deploying ingress rules.
TBD
To uninstall your k0s cluster, please refer to the official documentation here.