Edge devices deployed in the field, whether its manufacturing, transportation, communication or space, pose very different operational business challenge from those of the data center and cloud computing. These motivate different engineering trade-offs for Kubernetes at the far edge than for cloud or near-edge scenarios. Enter Microshift whose goals are to address the following use cases:
- Parsimonious use of system resources (CPU, memory, network, storage)
- Toleration of bandwidth and latency networking constraints
- Non-disruptive upgrades with rollback capabilities
- Build and integrate with edge OSes like Fedora IoT and RHEL for Edge
- Implement a consistent development and management experience on par with OpenShift
Let's explore this potential edge use case savior as we dive into a real world example of deploying Microshift and a functional workload in this blog.
Lab Environment
Before we start let't quickly review the lab environment we will be using for this demonstration. The lab device itself is a virtual machine with the following properties:
- KVM Virtual Machine
- RHEL 8.6 Installed
- 4 vCpu
- 8GB of Memory
- 2 x 120GB disk
- Zigbee 3.0 USB Dongle Plus E
When completed with the deployment of Microshift and our Zigbee2MQTT workload we will end up with an environment that looks like the following diagram:
Dependencies, Build Microshift & Installation
Now that we have had a review of the lab environment and a diagram of what the finished demonstration will look like let's go ahead and start building the environment out. To begin we need to install some dependency packages onto the Red Hat Enterprise Linux 8.6 host.
$ sudo dnf install -y git cockpit make golang selinux-policy-devel rpm-build bash-completion
Once the dependencies have been installed we can then clone down the Microshift repository from git.
$ git clone https://github.com/openshift/microshift.git ~/microshift
Cloning into '/home/bschmaus/microshift'...
remote: Enumerating objects: 47728, done.
remote: Counting objects: 100% (766/766), done.
remote: Compressing objects: 100% (264/264), done.
remote: Total 47728 (delta 595), reused 538 (delta 502), pack-reused 46962
Receiving objects: 100% (47728/47728), 46.05 MiB | 10.85 MiB/s, done.
Resolving deltas: 100% (24411/24411), done.
Updating files: 100% (13866/13866), done.
Next let's change into the microshift directory. From here we can issue a make rpm
command to build the necessary Microshift rpms.
$ cd microshift/
$ make rpm
fatal: No names found, cannot describe anything.
BUILD=rpm \
SOURCE_GIT_COMMIT=60b605d2 \
SOURCE_GIT_TREE_STATE=clean RELEASE_BASE=4.12.0 \
RELEASE_PRE=4.12.0-0.microshift ./packaging/rpm/make-rpm.sh local
# Creating local tarball
tar: Removing leading `/home/bschmaus/microshift/packaging/rpm/../..' from member names
tar: Removing leading `/home/bschmaus/microshift/packaging/rpm/../../' from member names
# Building RPM packages
fatal: No names found, cannot describe anything.
fatal: No names found, cannot describe anything.
warning: Missing build-id in /home/bschmaus/microshift/_output/rpmbuild/BUILDROOT/microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64/usr/bin/microshift
Once the packages finish building we can move onto adding the rhocp-4.11 & fast-datapath
repositories using subscription-manager
. We need them because when we go to install Microshift it will pull in some additional dependencies from those repositories.
$ sudo subscription-manager repos --enable rhocp-4.11-for-rhel-8-$(uname -i)-rpms --enable fast-datapath-for-rhel-8-$(uname -i)-rpms
Repository 'rhocp-4.11-for-rhel-8-x86_64-rpms' is enabled for this system.
Repository 'fast-datapath-for-rhel-8-x86_64-rpms' is enabled for this system.
Now we can initiate a local install pointing to the directory where the Microshift rpms were built.
$ sudo dnf localinstall -y ~/microshift/_output/rpmbuild/RPMS/*/*.rpm
Updating Subscription Management repositories.
Red Hat OpenShift Container Platform 4.11 for RHEL 8 x86_64 (RPMs) 183 kB/s | 122 kB 00:00
Fast Datapath for RHEL 8 x86_64 (RPMs) 938 kB/s | 486 kB 00:00
Dependencies resolved.
===================================================================================================================================================================================================================
Package Architecture Version Repository Size
===================================================================================================================================================================================================================
Installing:
microshift x86_64 4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8 @commandline 25 M
microshift-networking x86_64 4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8 @commandline 20 k
microshift-selinux noarch 4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8 @commandline 20 k
Installing dependencies:
NetworkManager-ovs x86_64 1:1.36.0-7.el8_6 rhel-8-for-x86_64-baseos-rpms 171 k
conntrack-tools x86_64 1.4.4-10.el8 rhel-8-for-x86_64-baseos-rpms 204 k
cri-o x86_64 1.24.2-9.rhaos4.11.gitac6f687.el8 rhocp-4.11-for-rhel-8-x86_64-rpms 24 M
cri-tools x86_64 1.24.2-6.el8 rhocp-4.11-for-rhel-8-x86_64-rpms 6.3 M
libnetfilter_cthelper x86_64 1.0.0-15.el8 rhel-8-for-x86_64-baseos-rpms 24 k
libnetfilter_cttimeout x86_64 1.0.0-11.el8 rhel-8-for-x86_64-baseos-rpms 24 k
libnetfilter_queue x86_64 1.0.4-3.el8 rhel-8-for-x86_64-baseos-rpms 31 k
openvswitch-selinux-extra-policy noarch 1.0-29.el8fdp fast-datapath-for-rhel-8-x86_64-rpms 16 k
openvswitch2.17 x86_64 2.17.0-50.el8fdp fast-datapath-for-rhel-8-x86_64-rpms 17 M
Transaction Summary
===================================================================================================================================================================================================================
Install 12 Packages
Total size: 72 M
Total download size: 47 M
Installed size: 300 M
Downloading Packages:
(1/9): openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch.rpm 59 kB/s | 16 kB 00:00
(2/9): openvswitch2.17-2.17.0-50.el8fdp.x86_64.rpm 6.4 MB/s | 17 MB 00:02
(3/9): cri-tools-1.24.2-6.el8.x86_64.rpm 2.2 MB/s | 6.3 MB 00:02
(4/9): libnetfilter_cttimeout-1.0.0-11.el8.x86_64.rpm 155 kB/s | 24 kB 00:00
(5/9): conntrack-tools-1.4.4-10.el8.x86_64.rpm 1.3 MB/s | 204 kB 00:00
(6/9): libnetfilter_cthelper-1.0.0-15.el8.x86_64.rpm 238 kB/s | 24 kB 00:00
(7/9): libnetfilter_queue-1.0.4-3.el8.x86_64.rpm 197 kB/s | 31 kB 00:00
(8/9): NetworkManager-ovs-1.36.0-7.el8_6.x86_64.rpm 1.3 MB/s | 171 kB 00:00
(9/9): cri-o-1.24.2-9.rhaos4.11.gitac6f687.el8.x86_64.rpm 4.5 MB/s | 24 MB 00:05
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 8.9 MB/s | 47 MB 00:05
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : microshift-selinux-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.noarch 1/12
Running scriptlet: microshift-selinux-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.noarch 1/12
Installing : NetworkManager-ovs-1:1.36.0-7.el8_6.x86_64 2/12
Installing : libnetfilter_queue-1.0.4-3.el8.x86_64 3/12
Running scriptlet: libnetfilter_queue-1.0.4-3.el8.x86_64 3/12
Installing : libnetfilter_cthelper-1.0.0-15.el8.x86_64 4/12
Running scriptlet: libnetfilter_cthelper-1.0.0-15.el8.x86_64 4/12
Installing : libnetfilter_cttimeout-1.0.0-11.el8.x86_64 5/12
Running scriptlet: libnetfilter_cttimeout-1.0.0-11.el8.x86_64 5/12
Installing : conntrack-tools-1.4.4-10.el8.x86_64 6/12
Running scriptlet: conntrack-tools-1.4.4-10.el8.x86_64 6/12
Running scriptlet: openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch 7/12
Installing : openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch 7/12
Running scriptlet: openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch 7/12
Running scriptlet: openvswitch2.17-2.17.0-50.el8fdp.x86_64 8/12
Installing : openvswitch2.17-2.17.0-50.el8fdp.x86_64 8/12
Running scriptlet: openvswitch2.17-2.17.0-50.el8fdp.x86_64 8/12
Installing : microshift-networking-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 9/12
Running scriptlet: microshift-networking-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 9/12
Warning: The unit file, source configuration file or drop-ins of NetworkManager.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Installing : cri-o-1.24.2-9.rhaos4.11.gitac6f687.el8.x86_64 10/12
Running scriptlet: cri-o-1.24.2-9.rhaos4.11.gitac6f687.el8.x86_64 10/12
Installing : cri-tools-1.24.2-6.el8.x86_64 11/12
Installing : microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 12/12
Running scriptlet: microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 12/12
Running scriptlet: microshift-selinux-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.noarch 12/12
Running scriptlet: openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch 12/12
Running scriptlet: microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 12/12
Verifying : cri-tools-1.24.2-6.el8.x86_64 1/12
Verifying : cri-o-1.24.2-9.rhaos4.11.gitac6f687.el8.x86_64 2/12
Verifying : openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch 3/12
Verifying : openvswitch2.17-2.17.0-50.el8fdp.x86_64 4/12
Verifying : libnetfilter_cttimeout-1.0.0-11.el8.x86_64 5/12
Verifying : conntrack-tools-1.4.4-10.el8.x86_64 6/12
Verifying : libnetfilter_cthelper-1.0.0-15.el8.x86_64 7/12
Verifying : libnetfilter_queue-1.0.4-3.el8.x86_64 8/12
Verifying : NetworkManager-ovs-1:1.36.0-7.el8_6.x86_64 9/12
Verifying : microshift-selinux-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.noarch 10/12
Verifying : microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 11/12
Verifying : microshift-networking-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 12/12
Installed products updated.
Installed:
NetworkManager-ovs-1:1.36.0-7.el8_6.x86_64 conntrack-tools-1.4.4-10.el8.x86_64
cri-o-1.24.2-9.rhaos4.11.gitac6f687.el8.x86_64 cri-tools-1.24.2-6.el8.x86_64
libnetfilter_cthelper-1.0.0-15.el8.x86_64 libnetfilter_cttimeout-1.0.0-11.el8.x86_64
libnetfilter_queue-1.0.4-3.el8.x86_64 microshift-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64
microshift-networking-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.x86_64 microshift-selinux-4.12.0-4.10.0_0.microshift_2022_09_08_132255_196_g60b605d2.el8.noarch
openvswitch-selinux-extra-policy-1.0-29.el8fdp.noarch openvswitch2.17-2.17.0-50.el8fdp.x86_64
Complete!
Before we can start Microshift we need to configure a few more items. One of those are the firewall rules.
$ sudo firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
success
$ sudo firewall-cmd --permanent --zone=trusted --add-source=169.254.169.1
success
$ sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
success
$ sudo firewall-cmd --permanent --zone=public --add-port=443/tcp
success
$ sudo firewall-cmd --permanent --zone=public --add-port=5353/udp
success
$ sudo firewall-cmd --permanent --zone=public --add-port=30000-32767/tcp
success
$ sudo firewall-cmd --permanent --zone=public --add-port=30000-32767/udp
success
$ sudo firewall-cmd --permanent --zone=public --add-port=6443/tcp
success
$ sudo firewall-cmd --reload
success
After the firewall rules we need to ensure we have a rhel volume group created because TopoLVM which comes as part of Microshift will be, by default, using a volume group called rhel. On our system I actually have a second disk sdb
that I will be using to create that volume group.
$ sudo lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 120G 0 disk
├─sda1 8:1 0 600M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 118.4G 0 part
├─rhel_sno3-root 253:0 0 70G 0 lvm /
├─rhel_sno3-swap 253:1 0 9.6G 0 lvm [SWAP]
└─rhel_sno3-home 253:2 0 38.8G 0 lvm /home
sdb 8:16 0 120G 0 disk
sr0 11:0 1 10.7G 0 rom
We can generate the volume group by using the vgcreate
command.
$ sudo vgcreate rhel /dev/sdb
Physical volume "/dev/sdb" successfully created.
Volume group "rhel" successfully created
We can then validate the volume group was created with the vgs
command.
$ sudo vgs
VG #PV #LV #SN Attr VSize VFree
rhel 1 0 0 wz--n- <120.00g <120.00g
rhel_sno3 1 3 0 wz--n- <118.43g 0
Another configuration item we need is to set our pull-secret
keys in the file openshift-pull-secret
under the /etc/crio
directory.
$ sudo vi /etc/crio/openshift-pull-secret
And finally since we will be running oc & kubectl
commands against Microshift we need to install the openshift-clients.
$ sudo dnf install -y openshift-clients
We have now reached the point where we can enable and start both crio and Microshift.
$ sudo systemctl enable crio --now
Created symlink /etc/systemd/system/cri-o.service → /usr/lib/systemd/system/crio.service.
Created symlink /etc/systemd/system/multi-user.target.wants/crio.service → /usr/lib/systemd/system/crio.service.
$ sudo systemctl enable microshift --now
Created symlink /etc/systemd/system/multi-user.target.wants/microshift.service → /usr/lib/systemd/system/microshift.service.
Once the services have been started let's go ahead and create a hidden directory called .kube
and copy the kubeconfig in there.
$ mkdir ~/.kube
$ sudo cat /var/lib/microshift/resources/kubeadmin/kubeconfig > ~/.kube/config
In a few minutes we can then issue a oc get pods -A
and hopefully we see the following pods running.
$ oc get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
openshift-dns dns-default-h58l2 2/2 Running 0 34m
openshift-dns node-resolver-nj296 1/1 Running 0 34m
openshift-ingress router-default-559ff9d676-vvzjs 1/1 Running 0 34m
openshift-ovn-kubernetes ovnkube-master-s74f5 4/4 Running 0 34m
openshift-ovn-kubernetes ovnkube-node-dtbbv 1/1 Running 0 34m
openshift-service-ca service-ca-5f9bc879d8-dnxcj 1/1 Running 0 34m
openshift-storage topolvm-controller-5cbd9d9684-zs7v6 4/4 Running 0 34m
openshift-storage topolvm-node-779zz 4/4 Running 0 34m
If everything looks correct in the last step we can proceed to deploying our workloads.
Deployment Workloads
For my workload I am choosing to run Zigbee2MQTT which allows one to control home smart devices via the Zigbee protocol. The Zigbee protocol is use in such applications as:
- Home automation
- Wireless sensor networks
- Industrial control systems
- Embedded sensing
- Medical data collection
- Smoke and intruder warning
- Building automation
- Remote wireless microphone configuration
Zigbee2MQTT also has a few dependencies we need to install as well: Ser2sock and Mosquitto. Let's go ahead and get started by creating a namespace called zigbee.
$ oc create namespace zigbee
namespace/zigbee created
Once the namespace is created we can go ahead and create a service and deployment file for the Ser2sock application. Ser2sock allows a serial device to communicate over TCP/IP and will enable us to communicate with the Sonoff Zigbee dongle.
$ cat << EOF > ser2sock-service.yaml
apiVersion: v1
kind: Service
metadata:
name: ser2sock
namespace: zigbee
spec:
ports:
- name: server
port: 10000
protocol: TCP
targetPort: server
selector:
app.kubernetes.io/instance: ser2sock
app.kubernetes.io/name: ser2sock
sessionAffinity: None
type: ClusterIP
EOF
$ cat << EOF > ser2sock-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ser2sock
namespace: zigbee
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/instance: ser2sock
app.kubernetes.io/name: ser2sock
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/instance: ser2sock
app.kubernetes.io/name: ser2sock
spec:
automountServiceAccountToken: true
containers:
- env:
- name: BAUD_RATE
value: "115200"
- name: LISTENER_PORT
value: "10000"
- name: SERIAL_DEVICE
value: /dev/ttyACM0
- name: TZ
value: UTC
image: tenstartups/ser2sock:latest
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 10000
timeoutSeconds: 1
name: ser2sock
ports:
- containerPort: 10000
name: server
protocol: TCP
readinessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 10000
timeoutSeconds: 1
resources: {}
securityContext:
privileged: true
startupProbe:
failureThreshold: 30
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 10000
timeoutSeconds: 1
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
enableServiceLinks: true
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
EOF
With the custom resource files generated let's create them against the Microshift environment.
$ oc create -f ser2sock-service.yaml
service/ser2sock created
$ oc create -f ser2sock-deployment.yaml
deployment.apps/ser2sock created
We can validate the service was created and also validate the pod is running correctly by checking the initial logs of the pod.
$ oc get pods -n zigbee
NAME READY STATUS RESTARTS AGE
ser2sock-79db88f44c-lfg74 1/1 Running 0 21s
$ oc get svc -n zigbee
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ser2sock ClusterIP 10.43.226.155 <none> 10000/TCP 41s
$ oc logs ser2sock-79db88f44c-lfg74 -n zigbee
[✔] Serial 2 Socket Relay version V1.5.5 starting
[✔] Listening socket created on port 10000
[✔] Start wait loop using ser2sock communication mode
[✔] Opened com port at /dev/ttyACM0
[✔] Setting speed 115200
[✔] Set speed successful
With Ser2sock up and running we can proceed to configure and install Mosquitto. Mosquitto is a message broker that implements the MQTT protocol and enables a lightweight method of carrying out messaging using a publish/subscribe model. We need to create three custom resource files here: a configmap, a service and a deployment.
$ cat << EOF > mosquitto-configmap.yaml
apiVersion: v1
data:
mosquitto.conf: |
per_listener_settings false
listener 1883
allow_anonymous true
kind: ConfigMap
metadata:
name: mosquitto-config
namespace: zigbee
EOF
$ cat << EOF > mosquitto-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mosquitto
namespace: zigbee
spec:
ports:
- name: mqtt
port: 1883
protocol: TCP
targetPort: mqtt
selector:
app.kubernetes.io/instance: mosquitto
app.kubernetes.io/name: mosquitto
sessionAffinity: None
type: ClusterIP
EOF
$ cat << EOF > mosquitto-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mosquitto
namespace: zigbee
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/instance: mosquitto
app.kubernetes.io/name: mosquitto
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/instance: mosquitto
app.kubernetes.io/name: mosquitto
spec:
automountServiceAccountToken: true
containers:
- image: eclipse-mosquitto:2.0.14
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 1883
timeoutSeconds: 1
name: mosquitto
ports:
- containerPort: 1883
name: mqtt
protocol: TCP
readinessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 1883
timeoutSeconds: 1
resources: {}
securityContext:
privileged: true
startupProbe:
failureThreshold: 30
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 1883
timeoutSeconds: 1
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /mosquitto/config/mosquitto.conf
name: mosquitto-config
subPath: mosquitto.conf
dnsPolicy: ClusterFirst
enableServiceLinks: true
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
volumes:
- configMap:
defaultMode: 420
name: mosquitto-config
name: mosquitto-config
EOF
With our Mosquitto customer resource files created we can now apply them to the Microshift environment.
$ oc create -f mosquitto-configmap.yaml
configmap/mosquitto-config created
$ oc create -f mosquitto-service.yaml
service/mosquitto created
$ oc create -f mosquitto-deployment.yaml
deployment.apps/mosquitto created
Again we can validate that everything is running correctly by confirming the pod is running, the service was created and by examaning the logs files of the pod.
$ oc get pods -n zigbee
NAME READY STATUS RESTARTS AGE
mosquitto-84c6bfcd44-6qb74 1/1 Running 0 32s
ser2sock-79db88f44c-lfg74 1/1 Running 0 1m50s
$ oc create -f mosquitto-deployment.yaml
deployment.apps/mosquitto created
[bschmaus@sno3 ~]$ oc get svc -n zigbee
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mosquitto ClusterIP 10.43.72.122 <none> 1883/TCP 52s
ser2sock ClusterIP 10.43.226.155 <none> 10000/TCP 2m3s
$ oc logs mosquitto-84c6bfcd44-6qb74 -n zigbee
chown: /mosquitto/config/mosquitto.conf: Read-only file system
1666223617: mosquitto version 2.0.14 starting
1666223617: Config loaded from /mosquitto/config/mosquitto.conf.
1666223617: Opening ipv4 listen socket on port 1883.
1666223617: Opening ipv6 listen socket on port 1883.
1666223617: mosquitto version 2.0.14 running
At this point we are now ready to install Zigbee2MQTT. The deployment will require four custom resource files: a configmap, a pvc, a service and a deployment file.
cat << EOF > zigbee2mqtt-configmap.yaml
apiVersion: v1
data:
configuration.yaml: |
advanced:
homeassistant_discovery_topic: homeassistant
homeassistant_status_topic: homeassistant/status
last_seen: ISO_8601
log_level: info
log_output:
- console
network_key: GENERATE
experimental:
new_api: true
frontend:
port: 8080
homeassistant: true
mqtt:
base_topic: zigbee2mqtt
include_device_information: true
server: mqtt://mosquitto
permit_join: true
serial:
adapter: ezsp
port: tcp://ser2sock:10000
kind: ConfigMap
metadata:
name: zigbee2mqtt-settings
namespace: zigbee
EOF
cat << EOF > zigbee2mqtt-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: zigbee2mqtt-data
namespace: zigbee
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: topolvm-provisioner
volumeMode: Filesystem
EOF
cat << EOF > zigbee2mqtt-service.yaml
apiVersion: v1
kind: Service
metadata:
name: zigbee2mqtt
namespace: zigbee
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/instance: zigbee2mqtt
app.kubernetes.io/name: zigbee2mqtt
sessionAffinity: None
type: ClusterIP
EOF
cat << EOF > zigbee2mqtt-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zigbee2mqtt
namespace: zigbee
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app.kubernetes.io/instance: zigbee2mqtt
app.kubernetes.io/name: zigbee2mqtt
strategy:
type: Recreate
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/instance: zigbee2mqtt
app.kubernetes.io/name: zigbee2mqtt
spec:
automountServiceAccountToken: true
containers:
- env:
- name: ZIGBEE2MQTT_DATA
value: /data
image: koenkk/zigbee2mqtt:1.19.1
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 8080
timeoutSeconds: 1
name: zigbee2mqtt
ports:
- containerPort: 8080
name: http
protocol: TCP
readinessProbe:
failureThreshold: 3
periodSeconds: 10
successThreshold: 1
tcpSocket:
port: 8080
timeoutSeconds: 1
resources: {}
securityContext:
privileged: true
startupProbe:
failureThreshold: 30
periodSeconds: 5
successThreshold: 1
tcpSocket:
port: 8080
timeoutSeconds: 1
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /data
name: data
- mountPath: /app/configuration.yaml
name: zigbee2mqtt-settings
subPath: configuration.yaml
dnsPolicy: ClusterFirst
enableServiceLinks: true
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
volumes:
- name: data
persistentVolumeClaim:
claimName: zigbee2mqtt-data
- configMap:
defaultMode: 420
name: zigbee2mqtt-settings
name: zigbee2mqtt-settings
EOF
Once the custom resource files have been generated we can go ahead and create them on the Microshift environment.
$ oc create -f zigbee2mqtt-configmap.yaml
configmap/zigbee2mqtt-settings created
$ oc create -f zigbee2mqtt-pvc.yaml
persistentvolumeclaim/zigbee2mqtt-data created
$ oc create -f zigbee2mqtt-service.yaml
service/zigbee2mqtt created
$ oc create -f zigbee2mqtt-deployment.yaml
deployment.apps/zigbee2mqtt created
We can also validate Zigbee2MQTT is working by validating the pvc, service, pod state and log files of the pod.
$ oc get pvc -n zigbee
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
zigbee2mqtt-data Bound pvc-0171efa4-49c2-42ce-9c6e-a3a730f61020 1Gi RWO topolvm-provisioner 22s
$ oc get svc -n zigbee
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mosquitto ClusterIP 10.43.72.122 <none> 1883/TCP 3m17s
ser2sock ClusterIP 10.43.226.155 <none> 10000/TCP 4m28s
zigbee2mqtt ClusterIP 10.43.164.117 <none> 8080/TCP 14s
$ oc get pods -n zigbee
NAME READY STATUS RESTARTS AGE
mosquitto-84c6bfcd44-4lc88 1/1 Running 0 3m33s
ser2sock-79db88f44c-9rvc2 1/1 Running 0 4m41s
zigbee2mqtt-5c6bdcc6ff-flk54 1/1 Running 0 27s
$ oc logs zigbee2mqtt-5c6bdcc6ff-flk54 -n zigbee
Using '/data' as data directory
Creating configuration file...
Zigbee2MQTT:info 2022-10-20 19:46:54: Logging to console only'
Zigbee2MQTT:info 2022-10-20 19:46:54: Starting Zigbee2MQTT version 1.19.1 (commit #9bd4693)
Zigbee2MQTT:info 2022-10-20 19:46:54: Starting zigbee-herdsman (0.13.111)
Assertion failed
Assertion failed
Assertion failed
Zigbee2MQTT:info 2022-10-20 19:46:57: zigbee-herdsman started
Zigbee2MQTT:info 2022-10-20 19:46:57: Coordinator firmware version: '{"meta":{"maintrel":"3 ","majorrel":"6","minorrel":"10","product":8,"revision":"6.10.3.0 build 297"},"type":"EZSP v8"}'
Zigbee2MQTT:info 2022-10-20 19:46:57: Currently 0 devices are joined:
Zigbee2MQTT:warn 2022-10-20 19:46:57: `permit_join` set to `true` in configuration.yaml.
Zigbee2MQTT:warn 2022-10-20 19:46:57: Allowing new devices to join.
Zigbee2MQTT:warn 2022-10-20 19:46:57: Set `permit_join` to `false` once you joined all devices.
Zigbee2MQTT:info 2022-10-20 19:46:57: Zigbee: allowing new devices to join.
Zigbee2MQTT:info 2022-10-20 19:46:57: Started frontend on port 0.0.0.0:8080
Zigbee2MQTT:info 2022-10-20 19:46:57: Connecting to MQTT server at mqtt://mosquitto
Zigbee2MQTT:info 2022-10-20 19:46:57: Connected to MQTT server
Zigbee2MQTT:info 2022-10-20 19:46:57: MQTT publish: topic 'zigbee2mqtt/bridge/state', payload 'online'
Zigbee2MQTT:info 2022-10-20 19:46:57: MQTT publish: topic 'zigbee2mqtt/bridge/config', payload '{"commit":"9bd4693","coordinator":{"meta":{"maintrel":"3 ","majorrel":"6","minorrel":"10","product":8,"revision":"6.10.3.0 build 297"},"type":"EZSP v8"},"log_level":"info","network":{"channel":11,"extendedPanID":221,"panID":6754},"permit_join":true,"version":"1.19.1"}'
And if everything validated appropriately above we should be able to hit the web interface of Zigbee2MQTT.
Hopefully this gives anyone interested in running Microshift an idea of how it can be used. Considering if one is familar OpenShift, the API compatability of Microshift makes it rather easy to roll out applications on this light weight platform!