Maryam Tavakkoli Master Thesis TUDelft
Maryam Tavakkoli Master Thesis TUDelft
Maryam Tavakkoli
2
Analyzing the Applicability of Kubernetes for the
Deployment of an IoT Publish/Subscribe System
Maryam Tavakkoli
Title
Analyzing the Applicability of Kubernetes for the Deployment of an IoT Publish/Subscribe System
MSc presentation
31th October, 2019
Graduation Committee
Prof.dr.ir. D.H.J. Epema Delft University of Technology
Dr. Jan S. Rellermeyer Delft University of Technology
Dr. Fernando Kuipers Delft University of Technology
Dr. Kimmo Hätönen Nokia Bell Labs
Abstract
v
vi
Preface
This thesis is made as a completion of the EIT Digital Master program in Cloud
Computing and Services. This work is the result of hard work during the last
semester of my master’s studies. As required by EIT Digital Master School, the
thesis was carried out in a company and resulted in a collaborated work between
academia and industry. More specifically, Nokia Bell Labs, located in Espoo, Fin-
land, provided me this internship opportunity. During this experience, I was able
to apply my academic knowledge to a practical project and it has been a stage of
intense learning for me. Therefore, I hope that it can provide insightful sources to
my colleagues for further research.
I have received a great deal of assistance and support from many people dur-
ing the writing of this thesis. I would therefore firstly like to extend the deepest
of gratitude towards my head supervisor at TU Delft, Prof.dr.ir. D.H.J. Epema,
for supporting me during the whole process. Applying his valuable guidance and
excellent feedback, have improved the quality of my work.
Secondly, I would particularly like to single out my daily supervisor at Nokia
Bell Labs, Dr. Kimmo Hätönen. I would like to thank him for trusting me and
providing me the opportunity to work on this research project and for his con-
structive guidelines and valuable insight into the topic. I am also grateful to all of
those with whom I have had the pleasure to work during this project at Nokia Bell
Labs.
I would also like to express my special gratitude to my best friend, my loving
husband, who has been a constant source of encouragement and support. Last but
not least, I would like to thank my parents and my sister who support me in every
step of my life. Without their love and support, it was not possible for me to excel
in my master studies and complete this thesis project.
Maryam Tavakkoli
vii
viii
Contents
1 Introduction 1
1.1 Motivation and Scenarios . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Research Questions and Goals . . . . . . . . . . . . . . . . . . . 3
1.3 Research Approach . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 Contributions and Thesis Structure . . . . . . . . . . . . . . . . . 4
ix
3 Design And Implementation 29
3.1 Nokia’s IoT Pub/Sub System in Containers . . . . . . . . . . . . 29
3.1.1 The System’s Containerization Procedure . . . . . . . . . 30
3.1.2 Setup a Private Docker Registry . . . . . . . . . . . . . . 31
3.2 System Deployment with Kubernetes . . . . . . . . . . . . . . . . 33
3.2.1 The Use-Case Scenario . . . . . . . . . . . . . . . . . . . 33
3.2.2 System Architecture and Design Decisions . . . . . . . . 34
3.3 Setting Up the Kubernetes Cluster . . . . . . . . . . . . . . . . . 35
3.3.1 Kubernetes Setup . . . . . . . . . . . . . . . . . . . . . . 36
3.3.2 Master Node Installation . . . . . . . . . . . . . . . . . . 36
3.3.3 Worker Node Installation . . . . . . . . . . . . . . . . . . 39
3.4 Deployment and Service Definitions . . . . . . . . . . . . . . . . 39
3.4.1 Common Fields in the Deployment and Service Definition 39
3.4.2 Deployment Definition . . . . . . . . . . . . . . . . . . . 40
3.4.3 Service Definition and Exposing Services . . . . . . . . . 42
3.5 Kubernetes Dashboard . . . . . . . . . . . . . . . . . . . . . . . 46
x
Abbreviations and acronyms
5G 5th Generation of Telecommunication Networks
BTS Base Transceiver Station
CI/CD continuous integration and continuous development
CN Core Network
DF Data Fetcher
DH Data Hub
DNS Domain Name System
DS Data Switch
GB Gigabyte
I/O Input/Output
IoT Internet of Things
KPI Key Performance Indicator
MEC Multi Access Edge Computing
NESC Nokia Engineering and Services Cloud
OS Operating system
PaaS Platform-as-a-Service
RAM Random Access Memory
RAN Radio Access Network
SSH Secure Socket Shell
TCP Transmission Control Protocol
UE User Equipment
VM Virtual Machine
YAML Yet Another Markup Language
xi
xii
Chapter 1
Introduction
We are in the era of the Internet of things (IoT) where billions of devices get con-
nected to the Internet and the generated data is rapidly growing. The number of
IoT devices is projected to surpass 75.4 billion by 2025 [1]. Meanwhile, Fifth-
Generation (5G) telecommunications technologies will bring faster mobile con-
nectivity, which makes the possibility of IoT scenarios even more feasible. Accord-
ing to Ericsson’s mobility report [2], there will be around 1.8 billion IoT devices
with cellular connections in 2023.
The rapid surge in the number of IoT devices has resulted in greater volumes of
data being generated and exchanged between various entities. This highlights the
need for a suitable message delivery solution in an IoT use-case. Among the pos-
sible approaches, publish/subscribe is one of the popular communication patterns
which allows the distribution of data to the interested entities in an efficient way.
A distributed transmission bus based on the Publish/Subscribe paradigm is being
developed in Nokia Bell Labs [3]. The microservice architecture design is used for
the development of this IoT data transfer system. This architecture structures an
application as a collection of small services, where each is running in its process
and is independently deployable. To take the current project one step further to the
real use-case implementation, we need to make it easily deployable.
Deploying a software application traditionally meant to have dedicated physical
servers that would run the entire application. This approach is already outdated
since it is very costly and time-consuming. As an alternative, virtualization tech-
nologies have been developed, where several new machines can be easily launched
to serve various needs. Resources can be consumed more effectively using virtu-
alization techniques compared to the bare-metal setups. However, still, efficiency
could be increased further [4]. Moreover, deploying and running applications dir-
ectly on the infrastructure might cause a problem known as ’Dependency Hell’ and
later will cause troubles for the CI/CD workflow.
The developments in the Linux kernel have led to the evolution of container-
based virtualization [5]. A lightweight virtualization, which has gained its mo-
mentum recently due to its efficiency and mobility [6]. Container virtualization
1
seems to be a viable alternative to the hypervisor for application infrastructure[4].
Using container-based virtualization, we can deploy each component of the
Pub/Sub IoT micro-service system as an independent separate service. Further-
more, containers can be run in any infrastructure without any dependency. How-
ever, the availability of these services becomes a concern when running multiple
different containers in a micro-service architectural style [7], and we need to make
sure that our system is always up and running.
A system is needed to manage the set of these containers, especially when it
comes to applications that might comprise hundreds of containers. This is where
a container management tool such as Kubernetes comes in, and provides mech-
anisms for deploying, maintaining and scaling of the containerized micro-services.
This way Kubernetes manages the availability of containers while it hides the com-
plexity of their orchestration [7].
Due to its micro-service architecture, each of the modules in the current IoT
pub/sub prototype system can be developed and executed separately. However, in
the current state of the system, these services are connected through hard-coded
IP addresses that are defined by the developers. These pre-defined addresses cause
deployment of the system to be dependent on the environment. Hence, the used
approach for the deployment should help for removing this dependency. The ap-
proach also should support the deployment of the system in the larger scales in the
future.
This thesis analyses the suitability of containerizing the current Pub/Sub IoT
microservice-based system and using Kubernetes for its deployment, while the
aforementioned demands of the system are met.
2
development of Nokia’s system is finalized. However, it is still having limitations
to be deployed in a real-world scenario. Moreover, there are specifications that
should be considered towards an efficient deployment.
One of the current limitations is the absence of a service discovery mechanism to
connect the micro-services within the system. Hence, as a temporary solution, they
are connected with hard-coded IP addresses. Furthermore, adapting the features
of edge computing is a specification that must be met for the deployment of the
system. More specifically, one of the micro-services of the system is developed to
perform some data pre-processing. Hence, it would be fully utilized when it resides
at the edge of the network, where is closer to the data sources.
To be more precise on the motivation for this thesis work, we aim to study
whether Kubernetes can be used for the deployment of such a system and if it
removes the limitations and meets the specifications.
• RQ1. How can we ease deployment of the Pub/Sub IoT system and elim-
inate system’s limitations for a large-scale deployment?
Currently, the Pub/Sub IoT system is deployed on different VMs. However,
running an application directly on the infrastructure might cause the depend-
ency hell problem.
Moreover, Nokia’s IoT pub/sub system has a micro-service architectural
design. This architecture is beneficial for the deployment, maintenance, and
further development of the system. However, these independent services are
connected via hard-coded IP addresses in the current state of the system.
This study aims to automate the deployment of the system and to minim-
ize manual configuration and installation work. This is especially import-
ant when we aim to deploy the system on a large-scale. In this thesis, we
study the applicability of Kubernetes and its service discovery mechanism to
achieve this goal.
• RQ2. Which containerization and Kubernetes mechanisms should be
used in the deployment procedure to serve the requirements of the sys-
tem?
3
In this thesis, we study the best approaches for containerizing the current
Pub/Sub IoT system and then, managing containers and deploying the sys-
tem using Kubernetes, as the applied container’s orchestration tool. The de-
ployment architecture is designed according to the requirements of the sys-
tem. An example of such requirements is to consider which micro-services
must be exposed externally and be accessible by whom. A prototype of such
deployment on a small scale is presented in this thesis.
4
In Chapter 3, we present a proof-of-concept prototype solution for the deploy-
ment of the system. To this goal, first, we explain the steps taken for containerizing
the system. Then, we describe a use-case scenario and explain our prototype’s
design decisions according to that. Finally, we discuss the procedures for setting
up a Kubernetes cluster and deploying the Pub/Sub IoT system on top of it.
In Chapter 4, we design some test scenarios to evaluate the proposed proof-of-
concept solution. Furthermore, the results of the test-cases are discussed.
Finally, Chapter 5 is a conclusion on the thesis. Summary of the thesis and the
future possible works are discussed in this chapter.
5
6
Chapter 2
The purpose of this chapter is to provide a description of the main concepts and
technologies relevant to this thesis. The first four sections provide essential back-
ground concepts for the discussed IoT system. The rest of the sections in this
chapter explain the relevant terminologies and technologies that are used in this
work.
The chapter starts with a general introduction of 5G and the evolution of mobile
communication technologies in Section 2.1. The Publish/Subscribe paradigm is
presented in Section 2.2, in which Apache Kafka and Zookeeper are described as
the used Pub/Sub technologies being used in this project. As an approach for de-
veloping distributed applications, Micro-service architecture is used for the current
system. This architectural design is described in Section 2.3. Then, Nokia Bell
Labs’ proof of concept, which this thesis is based on, is discussed in Section 2.4.
Section 2.5 describes the concept of system virtualization, and introduces its two
different methods including hypervisor and container-based virtualization. Section
2.6 described features of docker container engine, a virtualization framework that
is built on top of Linux containers. Section 2.7 explains the concept of container
orchestration and the available orchestration frameworks. Finally, Section 2.8 dis-
cusses the most trending container orchestration framework, Google Kubernetes,
which is the backbone of this thesis.
7
concept of IoT in the Telecom industry are discussed in this section.
8
The first generation (1G) of mobile networks was deployed in the 1980s [15]. 1G
was analog and made only voice calls possible. The second-generation (2G) were
digital systems and supported text messaging. Higher data transmission rate and
more data capacity were results of mobile technology advancement to 3G, which
supported multimedia and allowed real-time video calls [14][15][16].
The fourth-generation (4G) of mobile networks presented an enhanced version
of 3G networks. 4G is an IP-based network system mainly aimed at providing
higher speed, quality of service and security to handle more advanced multimedia
services over IP [16]. LTE, Short for ’Long Term Evolution’, and A-LTE (Ad-
vanced LTE), which are considered as 4G technologies, offered enhanced network
capacity, higher bit rates, and lower delay, to make wireless access possible, any-
time and anywhere [14]. As the result, the data rate has improved from 64 kbps in
2G to 2 Mbps in 3G and 50–100 Mbps in 4G [14].
However, at the time of developing 4G, the efficiency of the traditional point-
to-point link between the user equipment and base station was approaching its the-
oretical limits [17]. Hence, in addition to improvements in the data transmission
capacity, there was a demand for more network coverage offered by the available
infrastructure. To this goal, an increased node density was needed. However, ex-
panding the number of high-power macro-cells was not a viable approach due to the
economical reasons [17]. To meet these requirements, small cell network (SCN)
was introduced as a potential solution to offer a better network coverage and higher
data availability in both fixed and mobile environments, while considering resource
optimization and cost-efficiency. Small cell is served by a low-power cellular base
station and provides a shorter range of network connectivity compared to the tradi-
tional macro-cell [18].
Small cells are categorized as femtocells (coverage up to 30 m range), picocells
(coverage up to 200 m range), and microcells (coverage up to 2 km range) [19].
While traditional macro-cells are usually used in rural areas, a microcell can be
used in a populated urban area. Picocell is suitable for a large office or a mall, and
finally, a femtocell covers the smallest area such as a home or a small office.
9
Popularity and growth of the IoT concept demand higher data rates, lower latency,
and mobility support. To meet IoT application’s demands, mobile operators have
been trying to find new solutions to boost the capacity of services and provide a
higher quality of service in such scenarios. The development of small-cells such as
femtocells is a beneficial deployment in this regard. Using femtocells, considerable
amount of data traffic would be offloaded from macro-cells. This will reduce the
cost significantly from the operator’s side and results in lower power consumption
in user’s devices [20].
Therefore, the 4G has undoubtedly improved the capabilities of cellular net-
works to make IoT scenarios possible, and cellular networks are already being
used in many IoT scenarios. However, 4G is not fully optimized for IoT applic-
ations [22]. We are witnessing an exponential rise in the amount of multi-media
data being generated by new IoT scenarios, and today’s usage is a burden on the
current cellular networks [23]. Hence, there is a demand for higher data rates and
lower latency to transmit such data faster and cheaper. The next mobile generation,
5G, will be able to support the transmission of 1000 times more mobile traffic than
3G and 4G [20]. Hence, it is expected to act as the backbone of IoT applications
in the future.
2.1.4 5G
4G provides the foundation for the next generation of cellular mobile networks,
5G. 5G is initially deployed alongside 4G LTE [24]. The fifth generation of wire-
less mobile technology envisions an extended network coverage, higher data rates,
lower latency, increased bandwidth and considerable improvement in the quality
of service (QoS) which is received by user [25][23].
With a focus on IoT and low latency systems, 5G aims to connect everything.
To meet this goal, data rates up to 20 Gbps, 1000 times increase in the capacity,
latency lower than one millisecond, 10,000 times more data traffic and support for
ultra-low-cost and reliable IoT applications are promised [24]. To achieve all 5G’s
targets, new technologies including new network architecture, antenna technolo-
gies, spectrum, and network slicing are needed [24]. MEC, as an important feature
of 5G, which further enables the possibility of IoT scenarios, is discussed in the
following section.
10
Moreover, being geographically distributed, MEC provides high-quality of service
and broad support for mobility [29]. Considering the benefits MEC introduces,
there is tremendous potential for third-parties to make use of mobile operator’s
services and develop their new and innovative applications utilizing caching capab-
ilities at the edge [28]. IoT use-cases and scenarios are among these new business
opportunities being enabled through emerge of MEC and 5G. Facilitating com-
puting and storage resources at the edge of the network, very close to where data
generates, ensures a fast response to user’s request and supports critical IoT applic-
ations, which require data transmissions with low-latency.
The current project can be considered as an example of where MEC architecture
assists in developing an IoT scenario: A local IoT gateway, which acts as a MEC
platform, receives data from a set of IoT devices, performs some data aggrega-
tion or big data analytics on it, and finally sends the acquired information to the
associated cloud servers for further functionalities.
Therefore, the new decentralized architecture provided by MEC, enables many
IoT applications that need to be served with geo-distribution, location-awareness,
scalability, and low-latency features [29]. A high-level architecture of MEC setting
can be seen in Figure 2.2.
11
and the client or clients that receive the messages is called consumer (subscriber).
There is also a third component, the broker, which routes messages between pub-
lishers and subscribers. Role of the broker is to distribute incoming messages to
the correct subscribers [31]. A more precise architecture overview of the Pub/Sub
messaging model is provided in the next sub-section. Moreover, Kafka and Zoo-
keeper, as the Pub/Sun technologies that have been used in this work, are discussed
in the following sub-sections.
12
Hence, there is no need for senders to wait for acknowledgments from receivers
after they sent a message. Providing decoupling features that support the independ-
ence of the sender and receiver, Pub/Sub model brings more scalability, and hence
makes it a well-suited option for large-scale IoT deployments [33]. Moreover, Sup-
porting asynchronous communications better addresses requirements in distributed
systems, which are asynchronous by nature [32].
Matching between publishers and subscribers can be done based on different
design types of filtering in a Pub/Sub system, mostly topic-based or content-based
[33]. The way that subscribers describe which messages they are interested in
depends on the chosen design. Topic-based or subject-based is the earliest Pub/Sub
design type which has been used in many industrial solutions [32]. Also, most of
current popular Pub/Sub systems such as Apache kafka [34], IBM MQ [35] and
Message Queuing Telemetry Transport (MQTT) [36] work based on this filtering
design scheme. Topics can be considered as individual key-words, and subscribers
are allowed to subscribe for one or more topics. Publishers should assign each
message a topic or topics. So, when the event bus receives a message, it first
checks its assigned topic/topics. If there were subscribers who subscribed to that
topic/topics, the message will be routed to them.
This very basic performance of the topic-based solution introduces some limita-
tions in the implementation. A topic may be too general and a subscriber may not
be interested to receive all data being covered under that topic but is only interested
in a specific part. So, in this way subscriber has to filter the part of the received data
to find its specific part, and also disregard the other additional parts. This is also
not beneficial in network usage since some data is delivered, which is not going to
be used. To solve the described drawback, the topic-based scheme is developed by
various systems.
Content-based is the second design type which allows subscribers to subscribe
for the actual content of a messages. So, consumers can announce their interest
only to a subset of events, and to do that they should define some filters and con-
straints for part of the event’s content that are interested [37]. This filtering is
usually described as a pair of attribute and value. Attributes are defined based on
content and a logical function will be evaluated as the attribute’s value. When a
message is received by the event bus, its content will be evaluated against each
subscription, and if the result was positive message will be sent to the corres-
ponding subscriber. Considering a topic as an attribute in this approach, we can
even conclude that a content-based solution will cover the topic-based design of
Pub/Sub systems. Among current industrial Pub/Sub systems IBM MQ provides
content-based architecture [35].
13
it was initially developed by LinkedIn to provide efficient message delivery to
multiple users [38]. Currently, Kafka is maintained by Apache foundation and
is widely used in Big Data solutions for building real-time data pipelines [38].
The arbitrary number of messages come from different processes called produ-
cers. Then, Kafka groups received data into different topics based on their data
stream category. Each topic, later, will be divided to partitions of equal size. Kafka
runs on top of a server or a cluster of servers, called brokers. Partitions of all
topics are distributed over these cluster nodes. Furthermore, partitions will be rep-
licated to multiple brokers, which will result in a fault-tolerant message delivery
system. Brokers are responsible for maintaining published data and sending it to
the subscribers later. Other processes, called consumers, who wish to receive data
corresponding to a topic, will initiate a subscription request, and it can finally read
messages from partitions.
The overall architecture of Kafka and its components are depicted in Figure 2.4.
14
lightweight independent services. Each of the services runs in its independent
process, and they all communicate with a lightweight mechanism. [40].
An opposite approach for software development, which is the traditional one, is
called monolithic architecture. In a monolithic design, the entire application logic
is written as a single unit. Any changes to a small part of such a system demand for
building and deploying a new version of the entire application [41]. This feature of
the monolithic architecture causes difficulty in the further development of a system,
especially when the application is large.
This is while continuous delivery and deployment are much easier in a micro
service-based architecture [42]. Compiling of the whole application is not needed
upon every small change in the microservice application. As a result, bugs and
security vulnerabilities of the application can be found and fixed easier. Hence,
deploying changes and delivering updated versions of the application to the pro-
duction environment can be performed faster, and this allows the development team
to conduct smaller and more frequent releases. Furthermore, scaling of an applic-
ation developed with monolithic design, requires the whole of the application to
be scaled, while in a micro-service approach, every single component or service is
isolated and is scalable without any dependency to the other parts.
Moreover, different services in a micro-service architecture can be distributed
on multiple physical hosts. To let different micro-services, which are deployed on
different hosts, talk to each other, a service discovery protocol is required [43]. In
contrast, all modules in a monolithic application must be deployed as a single unit
in the same physical environment. Because of this, the same hardware character-
istics, such as RAM and CPU, would be followed for all modules of the mono-
lithic application. However, in a micro-service application, these features could be
defined separately. For example, more CPU can be assigned to a service, while
more RAM is allocated for the other one.
15
Figure 2.5 illustrates the differences between monolithic and micro-service ar-
chitectures. Despite all the benefits of the distributed microservice-based archi-
tecture, it also introduces new challenges. The internal communications among
services, which is accomplished via remote network calls, generate network over-
head. So, the bandwidth and latency requirements should be considered while
developing such an application. Besides, these inter-communications demand for
a reliable and secure network [43].
As the microservice-based application grows and turns into a system with a large
number of services, it becomes more fault-prone [44] and monitoring of the whole
application becomes a difficult task. Hence, an effective automation and monitor-
ing system is required for the deployment of such a system.
16
2.4.2 Introducing Components of Nokia’s System
A general overview of Nokia’s proof of concept system is illustrated in Figure 2.6.
Dashboard, Coordinator, Data Fetcher and Data Hub are the main services, which
are described as follow:
• Data Fetcher
Data Fetcher is responsible for retrieving data from external data sources into
the system. It also performs some pre-processing on data before delivering
it to the corresponding consumer. The current data processing includes KPI
calculation. However, this module could be developed with further function-
alities in the future. Compression and encryption of data are from the other
currently available capabilities of data fetcher. Considering the abovemen-
tioned features, data fetcher will act more appropriate when it is resided at
the edge of the network, where it is closer to the data sources.
• Data Switch
Data switch is not a microservice by itself, instead, it resembles two separate
microservices, namely Kafka broker and Zookeeper, which together provide
one of the main functionalities of the system: the actual Pub/Sub messaging
pattern. Data switch receives the pre-processed data from data fetcher and
then routes it to the right consumer or consumers who have subscribed for it.
• Data Hub
Data hub, which has a corresponding UI, is a gateway for subscribers. End
users who aim to consume data, subscribe for their specific data type, being
17
shown as a list in the data hub. Upon receiving requests, made by sub-
scribers, data hub forwards them to the coordinator. Later, data hub receives
corresponding data for each subscription and forwards it to the end-user.
• Coordinator
Coordinator is considered the main component responsible for managing and
orchestrating all other components and services. The whole process of a sub-
scription, creation, and cancellation of a subscription is handled by coordin-
ator. For example, as mentioned earlier, to receive relevant data from data
switch, data hub first needs to send its requests to the coordinator. Then, co-
ordinator processes this request and asks data fetcher to publish appropriate
data, and finally, data hub will receive the corresponding data.
• Dashboard
Dashboard acts as a user interface for monitoring the state of the system.
Currently, it illustrates the state of main microservices, if they are up and
running and how much traffic they generate.
18
with different operating systems can execute on a single physical host at the same
time.
Two different architectures are shown in Figure 2.7 are differentiated for a hy-
pervisor.
Type 1 hypervisors, called native or bare-metal hypervisors, run directly on hard-
ware to control it and manage operating systems for guests [50]. The most well-
known examples of this architecture include Oracle VM [51], VMWare ESX [52],
Microsoft Hyper-V [53], and Xen [54]. Type 2 hypervisors, called embedded or
hosted hypervisors, on the other hand, require a host operating system to run their
operations on top of it [50]. Hence, these type of hypervisors are dependent on
the host OS for their resource allocation. Some popular hypervisor tools coming
from this architecture are Oracle VM VirtualBox [51], VMWare Workstation [55],
Microsoft Virtual PC [56] and QEMU [57].
Despite differences in types, hypervisors introduce several benefits. Isolation
for guest machines is the main one. Isolation guarantees that consequences of
any operation within one VM will not affect the other VMs or the host. This
prevents any crash, failure or security threat caused by one environment disturb
functionality of the other machines. Moreover, running a hypervisor, enables users
to have multiple machines with different operating systems on top of a single host
machine. Additionally, this introduces various business opportunities for service
providers since they will be able to provide a wide range of customer’s needs with
limited resources.
Despite their benefits, hypervisors have several drawbacks. Firstly, dependency
of guest VMs to booting up of the host machine causes a slow startup time. Each
VM also needs to be booted up like a normal operating system, which makes it
even slower. Upfront costs and possible security vulnerabilities are considered as
the other disadvantages.
19
2.5.2 Container Virtualization
Container-based virtualization, also known as operating system level virtualization,
is a lightweight alternative to the hypervisors. This type of virtualization utilizes
host’s kernel features to creates multiple isolated user-space instances, called con-
tainers [49]. Container architecture is shown in Figure 2.8.
A container, from point of view of processes running inside it, looks like a real
separate machine, while in reality they are running in an isolated space inside the
host OS and share their resources. Hence, despite hypervisors, containers do not
have their own virtualized hardware and OS but they use resources of their host.
This way, each container acts as an independent OS without any intermediate layer
and guest virtualized OS as it is in hypervisors.
Since there is no emulated hardware in containers, they do not need a time for
booting an entire OS. This leads to a fast startup, in milliseconds, which is more
efficient than the conventional hypervisors [50]. A container encapsulates all pack-
ages, which it might need such as libraries, binaries, runtimes and other system-
specific configurations [58]. However, it is still more lightweight than a virtual
machine, which contains a set of toolchains to run an entire OS, including kernel
and drivers. This small resource fingerprint in containers introduces better per-
formance, enhanced security and a good scalability [50].
Container-based virtualization can be implemented on top of any OS, how-
ever the current popular techniques such as Docker rely on Linux kernel features.
In Linux, resource management for containers is accomplished through Control
Groups (Cgroups). Cgroup limits and prioritizes usage of host’s hardware re-
sources, such as memory, CPU and I/O, for containers [59]. Moreover, Linux
namespaces provide isolation for containers so that each process will have its spe-
cific view of the system. An example of this controlled view is to allow a container
to see parts of host’s file system and not all of it. Also, it controls the list of visible
processes in container’s process tree.
Due to the all above-mentioned features of containers, they have gained more
20
popularity during past few years. Realizing advantages of containers compared
to the classical hypervisor-based virtualization, developers have just started to use
them more widely. To benefit these advantages, in this thesis we use Linux con-
tainers for the implementation of our solution.
21
2.6.2 Docker Architecture and Components
Providing a simple tooling, Docker uses a universal packaging approach to wrap
up all application dependencies within a container, which will be run on the Docker
Engine [61]. Docker engine is built based on client-server architecture. The Docker
Daemon, which runs on the host system, manages the images and containers. Addi-
tionally, it is responsible for monitoring state of the system, enforcing policies, ex-
ecuting client’s commands and determining namespace environments for running
containers. The Docker Client is where users interact with Docker. A command-
line tool, which connects to the Docker Daemon, is responsible for managing oper-
ations related to images, containers, networks, the swarm mode and Docker engine
configurations. Using sockets or RESTful APIs, Docker daemon and Docker client
communicate with each other. The Docker architecture is illustrated in Figure 2.9.
The rest of Docker components are described as following.
• Docker Image
A Docker image is the main building block of Docker. It provides the source-
code for creating and running containers. An image contains all the neces-
sary libraries and binaries to build and run an application. There are pre-built
Docker images, which developers can download and use, however they can
build their own images as well. To do so, one should write the required in-
structions in a Docker File. The image template (Docker file) starts with a
base image. An image is a series of data layers built on top of the base im-
age. To combine different layers of an image and treating them as a single
layer, Docker uses a special file system called Union File System (UnionFS)
[63]. Union File System allows combining files and directories of different
file systems into a single consistent file system [63]. Upon applying any
changes to the image, a new layer will be added on top of the existing ones.
22
Hence, despite the traditional approach based on the hypervisors, rebuild-
ing of the whole image is not needed. This process makes the rebuilding of
images quite fast [64].
• Docker File
Docker file is a template, which contains all the required instructions to cre-
ate a Docker image. The Docker engine acquires the required information for
configuring a container or executing the containerized applications from this
file. These instructions will be executed in order by conducting a ’Docker
build’ command issued by a user. In case any of these instructions result in
a change to the current content of the image, changes will be applied to a
new layer based on the layering approach, which described before. The base
image is specified with the ‘FROM’ command written in the very first line
in the Docker file. This is where the entire image will be built upon.
• Docker Container
Docker containers are the running instances created and deployed from docker
images and the allocated system resources, which are manageable through
Docker client tool. While several containers can be launched from the same
or different images on the same host, they are all isolated from each other
and act separately.
23
will remain immutable and several containers could be made out of a single
Docker image.
• Docker Registry
Docker registry is where Docker images can be stored. The main purpose of
a registry is to simplify distribution of images. Hence, developers can make
Docker images and store them in the registries. Then, upon access to the
registry using Docker client, other users can download and use the available
images. We can consider these registries similar to the source-code reposit-
ories [66]. The Docker registry can be either public or private. Docker Hub
[67] is the most popular public Docker registry, where you can freely sign up
and get access to a huge image storage system for uploading and download-
ing images. Docker Registry [68], an open-source project lead by Docker,
provides private Docker repository for organizations with authenticated ac-
cess, which lets them control access to their images.
24
veloped, while Kubernetes is one of the most popular ones that we conducted our
study based on it is and is discussed more in the next section.
2.8 Kubernetes
Kubernetes is an open-source cluster manger, which initially developed and intro-
duced by Google at the June 2014 Google Developer Forum [60]. Kubernetes’s
origin has adopted many ideas from Google’s first internal container management
technology, called Borg [70]. Applications of Google were internally run and man-
aged at scale using Borg. Later, many external developers became interested in
Linux containers and Google developed its public cloud infrastructure. These ad-
vances motivated Google to develop its open-source container management frame-
work, know as Kubernetes.
Kubernetes can be used for effective deployment, updating, managing, resource
sharing, monitoring and scaling of multi-container applications in a highly distrib-
uted environment.
25
• Master and Worker Nodes
Following a master-slave type of architecture [71], Kubernetes consists of
master and worker nodes. A node, in general, refers to the host device,
which is either a virtual or a physical machine. Worker nodes run the pods
and will be managed by the master node. The master node within a cluster
is responsible for managing containers and consists of three processes, kube
APIserver, kube controller manager and kube scheduler [72].
• Pods
The smallest deployable unit of computing in Kubernetes is called pod [73].
Each pod consists of one or more application containers, which are deployed
on the same physical host, and share the same set of resources such as stor-
age and networking. In other words, a pod models an application-specific
’logical host’ and includes different containers which are tightly coupled
[74]. Hence, pod places and operates one level higher than the individual
containers [75].
Kubernetes applies its scheduling and orchestrating mechanisms on top of
pods instead of containers. This allows developers to deploy several con-
tainers out of their closely related micro-services and then package them
into a single pod to act as a single application. A unique IP address would
be assigned to each pod. While containers on the same pod can see each
other on localhost, containers on different pods communicate using pod’s IP
addresses. Additionally, containers on a single pod share the same volume
directories and resources. Hence, a pod resembles a virtual host machine
including all resources needed for its containers.
• Replication Controller
Replication Controller, is often abbreviated as ’rc’, is responsible to make
sure that the specified number of pods are always up and running, and if not,
it will replicate required number of pods [76]. It also terminates some of
the pods if too many of them are running. Each pod’s replication is called
a replica. Replicas will be managed based on the rules defined in the pod’s
template. A pod, which is created manually, can be evicted in case of any
failure, while using a replication controller, we can define pods that will be
replaced if they fail or be deleted for any reason. Hence, it would be a good
practice to define a replication controller instead of manual pod creation.
This will assure health of the application even if it contains only one pod.
• ReplicaSet
ReplicaSet is an API object in Kubernetes, which manages scaling of pods.
It checks state of pods and maintains desired number of them at any given
time. According to the Kubernetes documentation [77], ReplicaSets are the
next generation of Replication Controllers and provide more features.
26
• Deployment
Deployment is a higher-level concept than replicaSet and pod. Defining a de-
ployment, we can declare updates for Pods and ReplicaSets. In other words,
we describe a desired state and deployment controller checks the actual state
against the desired state. Instead of using pods or ReplicaSets directly, it is
recommended to define them by deployments.
• Services
A service is an abstract way to expose applications running on the pods to
the users. As mentioned earlier, a unique IP address is assigned to each pod
within a cluster. However, since pods can be created or removed by replic-
ation controller, their IP addresses are not stable. Each newly created pod
will receive a new IP; hence it would not be a suitable approach for users to
connect to the applications via pod’s IPs. This is where Kubernetes services
solve the issue offering an endpoint API, which lets services being accessible
externally. Moreover, assigning a single DNS name to each service, Kuber-
netes provides an internal service discovery mechanism and developers do
not need to utilize an external approach for that [78].
• API Server
The API Server exposes a REST API, which makes communications of all
cluster components possible. It also allows users to configure and validate
all cluster objects such as pods, replication controllers, services etc. [80].
Furthermore, the API server handles communications between the master
and worker nodes.
• Controller Manager
A controller manager is a control loop, which runs on the master, and using
the API server checks the state of cluster. If any change arises, controller
manger moves the current state of cluster towards the desired state. There
are different controllers in the Kubernetes including replication controller,
27
namespace controller, endpoint controller and service-accounts controller
[81].
• Scheduler
Scheduler acts as a resource controller and handles the workload of a cluster.
More precisely, it is responsible for assigning pods to the different worker
nodes based on several metrics such as nodes computing resources, policy
constraints of pods and quality of service requirements. To this goal, sched-
uler also keeps track of the general overview of resources to see which are
free or occupied.
• etcd
etcd is a lightweight, consistent, highly available and distributed key-value
data store, which is used to store all cluster data including configurations and
state information of cluster. To operate as a data-store, etcd acts based on the
Raft consensus algorithm [82].
• Container Runtime
As the first component, a container runtime is required be installed on each
worker node. Container runtime is the software responsible for running con-
tainers. Several container runtimes are supported by Kubernetes; however,
Docker is the most popular one.
• Kubelet
Being responsible for management of pods and their containers in each node,
makes Kubelet the most important component of worker nodes. Kubelet re-
ceives its instructions from master node and interacting with etcd, it updates
the configurations. Based on acquired information, it makes sure that pods
are healthy and are running properly. Then, it also reports status of nodes to
the cluster.
• Kube-Proxy
Kube-Proxy is a network proxy, which takes care of network rules on each
worker node. These rules allow network communications to the pods from
inside or outside of the Kubernetes cluster. In other words, with mapping
containers to the services and utilizing load-balancing mechanisms, it provides
access to the deployed application from the external world. These network
proxies work based on TCP and UDP streams.
28
Chapter 3
To study the suitability of Docker and Kubernetes for the deployment of the cur-
rent IoT system, a practical proof-of-concept is conducted. This chapter explains
the steps taken towards the implementation of this proof-of-concept. The overall
procedure is divided into five main sections.
First, the containerization of the system and the applied approach using Docker
is described in Section 3.1. Section 3.2 studies the requirements for deploying
the system using Kubernetes. A possible use-case scenario is described and the
relevant architecture details and design decisions are discussed according to this
use-case. General steps for setting up a Kubernetes cluster and detailed instructions
are provided in Section 3.3. This includes guidelines for deploying the cluster, and
follows with detailed explanations for installation phases in the master and worker
nodes separately. The rest of required configurations to accomplish deployment of
the system are discussed in Section 3.4. Deployments and service definitions, and
also the used approaches for exposing the services are explained in this section.
Finally, the required steps for deploying the Kubernetes Dashboard, which is a
useful tool for monitoring the state of the cluster, are explained in Section 3.5.
29
it failed. The reason was the different Java versions on different machines, where
jar files were built and were run. Also, the OS might have an impact in some
cases. These are known as the ’dependency hell’ problem in software development
and CI/CD workflows could be solved using containers. A containerizing tool,
such as Docker, bundles up an application and it’s dependencies together in a self-
contained unit. Hence, a containerized application can be executed in any platform
and has no dependency on the infrastructure.
All the above-mentioned problems motivated us to take a step further in the
deployment and containerize the current system.
Docker, as one of the most popular available technologies, is utilized for our con-
tainerization purpose. Due to the micro-service architecture of the system, making
docker images out of each service is not so complicated. First, we make a Docker
30
file for each service, and from the file, we create the Docker image. For Kafka and
Zookeeper, we use the well-known public Docker images.
As the next step, to check if images are built properly and the system works upon
containers, we run all containers on the same machine using Docker-Compose.
Figure 3.2 illustrates the proposed architectural design of the containerized system.
According to the Figure, Docker-Compose creates a single shared network, where
all containers can join. Different services running on the same Compose network
are reachable by other containers, and they are discoverable at a hostname defined
by the container name [84].
To start Docker-Compose, we create a YAML file to configure our services.
Image name, network name, the ports that should be exposed for the service, and
hostname are among components, which should be defined in this file, for each
service. Since our services are dependent on each other for their run times, we
only include Kafka and Zookeeper services in the compose file.
Starting the Docker-Compose, we bring up Kafka and Zookeeper as is shown on
the left side of the Figure. Then, we run each of other services separately on the
same Docker-Compose’s network. This way, we locate all of the system’s micro-
services under a shared network. Finally, we can access two of our services, which
have a UI, namely ’Dashboard’ and ’DataHub’ on the localhost and their exposed
ports.
31
own images. However, to use the latter, we need to set up it ourselves on top of
Docker’s open-source project, named ’Docker Registry’. Since Nokia’s system
is private, we cannot keep its corresponding Docker images in a public registry.
Hence, in this section, we explain how we set up a private Docker Registry in one
of the Nokia’s servers.
The open-source Docker Registry acts as a storage and distribution system for
Docker images and holds various versions of the same image, which are tagged
differently [85]. The registry stores its data locally by default, hence, users can
pull their images from its local filesystem and push new images to it as well.
It is possible to set up such a registry without any security restrictions. However,
the better approach is to use the available mechanisms to make our registry secure.
To this goal, we apply three main features that are provided by Docker. These
features are explained as follows.
32
3.2 System Deployment with Kubernetes
In this section, firstly, we describe a use-case scenario for deployment of the Pub/Sub
IoT system. Next, the architecture for the deployment using Kubernetes is ex-
plained and the design decisions are discussed.
The micro-service architecture of the current system and containerizing each
service separately, bring several advantages for the deployment, however man-
aging multiple independent containers might cause even more challenges espe-
cially when we aim to scale the system. Ensuring network connectivity of the
containers to each other and to the external world, constant monitoring of their
state, resource optimization for each and finally, scaling the number of containers
are from the challenges.
Making sure to meet all the requirements for managing containers, means to
have an eye on hundreds of containers at the same time. This is fault-prone and
difficult task. Kubernetes is a container orchestration tool, which will take care of
managing containers and their connectivities. Using its self-healing mechanism,
Kubernetes makes sure that all required services are always up and running. Fur-
thermore, Kubernetes gives fine-tuned control over utilizing cloud resources for
each of the containers. Finally, with Kubernetes, we can scale the system with
more similar services with minimum effort.
Apart from the challenges that managing containers bring, deploying the sys-
tem considering its current architectural state is challenging. Currently, the micro-
services in the system are introduced to each other in a manual process. Each
service has one or more configuration files, where the IP address of its related
components are defined. This way each service knows the next destination that
it should get connected. Deployment of such a system in scale, for different cus-
tomers and in different infrastructures, demand for a long manual process, where
we have to go through various files and change the defined IP addresses. Using
containers, this means even more work since we need to rebuild the docker images
after any change being applied to the configuration files of services.
Hence, eliminating this workload in the deployment is one of our biggest mo-
tivations to use Kubernetes in this thesis. Providing an internal service discovery,
Kubernetes allows us to define names for the micro-services instead of IPs.
33
installs different IoT gadgets all around its office and data will be fetched from
these devices using the ’DataFetcher’ module. Other business units (Company Y)
could become its customers and be willing to use this data. They only need to have
access to the ’DataHub’ module of the system.
A general overview of such a use-case is shown in Figure 3.3. Keeping this
business use-case in mind, we deploy the system using Kubernetes.
34
To implement this proof-of-concept, we have used Nokia’s private cloud infra-
structure; Nokia Engineering and Services Cloud (NESC) [87]. NESC, being based
on the OpenStack, provides a fully functional IaaS cloud. A general architectural
overview of the proposed scenario using Kubernetes is demonstrated in Figure 3.4.
35
needed to deploy our micro-services on the different nodes in a Kubernetes Cluster.
• Cluster Networking
36
Based on the networking model in Kubernetes, each pod gets a unique IP.
This way, pods on one node can communicate with all pods on the other
nodes. Since IPs are assigned to pods, all containers within a pod share the
same IP and communicate with each other using localhost. In Kubernetes,
this is called the ’IP-per-pod model’ [91]. Kubernetes does not provide a
default network implementation. Instead, it only defines the model and other
tools must be used for the implementation. There are multiple ways to imple-
ment such a networking model for Kubernetes. These solutions are offered
by external network plugins and interfaces, also known as network add-ons.
The Kubernetes Add-ons are described next.
• Kubernetes Add-ons
In general, add-ons are used to extend the functionality of Kubernetes [92].
Different add-ons are served for different purposes. Network plugins such as
Flannel or Calcio, DNS service managers such as coreDNS, and Kubernetes
Dashboard, which is Kubernetes UI, all are examples of Kubernetes add-ons.
While installing some of these add-ons is a must to run a Kubernetes cluster
properly, there are several optional ones that provide additional services. In-
stalling a network add-on is one of the required steps in the Kubernetes setup.
There is a long list of such add-ons listed in [92] and we choose Flannel for
our work.
• Flannel
Flannel creates a virtual network, which runs over the host network, and is
called an overlay network. This network is responsible to assign unique IPs
to the pods. It does this running a small agent called ’flanned’ on each host
node. This agent allocates a unique IP subnet (by default /24) to each node
from a larger address space. Then, all pods within a node use an IP from this
range. Using these IPs, pods can communicate with each other in a cluster.
To explain this further, we can refer to Figure 3.5, which shows the over-
lay network architecture and IPs assigned. All our VMs are created in the
network subnet 192.168.1.0/24 and they have been assigned IPs within this
range. Flannel overlay network has a default subnet range (10.244.0.0/16),
which must be stated while initiating the control-plane. From this large sub-
net, flannel assigns another smaller subnet to each host node. As it can be
seen in the Figure 3.5, master node is assigned with subnet 10.244.0.0/32,
worker node 1 is assigned with 10.244.1.0/32 and worker node 2 has the
subnet 10.244.2.0/32. Next, each pod within a node will be allocated with
a unique IP from its host node’s IP subnet. The containers within one host
node can communicate with each other using the docker bridge docker0.
Moreover, flannel’s architecture makes the cross-node pod-to-pod commu-
nications possible. This means that pod 1 with IP 10.244.0.1 can see pod 6
with IP 10.244.2.2 through this overlay network.
37
Figure 3.5: The overlay network architecture in Flannel.
To initiate cluster on the master node we issue the ’kubeadm init’ command.
Since we aim to use flannel add-on as the cluster networking, we define the subnet
that flannel must use to create its virtual overlay network, which is 10.244.0.0/16,
while defining ’–pod-network-cidr’ parameter.
This will bring up all components of a master node, described in Section 2.8.2,
including etcd, apiservice, controller-manager, kube-proxy, kube-scheduler and
coreDNS. However, CoreDNS will not start up before we install a network add-
on. Hence, the next step is to install flannel applying its specific configuration
file on our cluster. After this, listing pods in the cluster, we should see all these
38
modules are up and running.
39
Finally, the ’spec’ illustrates the building components of the object. The precise
format of it, is different for various Kubernetes objects. This format is explained
in detail for deployment and a service object separately in the following sections.
• spec.selector Using selector, the deployment finds the Pods that it has to
manage. A label will be assigned to the Pods. Assigning the corresponding
label using ’matchLabels’, we let the deployment to find its related Pods.
40
in the form Service name:Port. This is where we avoide specifying
IPs and instead, we use name of services. Kubernetes CoreDNS
will take care of resolving the corresponding IPs for these names.
For the rest of micro-services, information under this field are spe-
cified with name of corresponding images that we previously have
built and ports that they use. It is worth mentioning that docker im-
ages of Dashboard, Coordinator, DataFetcher and DataHub com-
ponents are re-built and are different from the ones that we used for
running the system locally with Docker. This is because, all IPs
are removed from the corresponding configuration files and are
replaced with name of Kubernetes services. This eliminates the
repetitive phase of changing IPs and re-building images according
to the different deployment infrastructures.
∗ nodeSelector
spec.nodeSelector specifies a map of key-value pairs. By using
it, we constraint running of our Pods to a specific node within
the cluster. If we are not aiming for such a constraining, we do
not need to specify this parameter at all. Then, Kubernetes will
automatically take the responsibility of distributing Pods to the
nodes based on their workload.
Before using this nodeSelector, we should make sure that nodes
are assigned a key-value pair as their labels. In Section 3.2.2, we
defined the required architecture for our Kubernetes cluster and to
follow it, we need to constraint each of our Deployments (Pods) to
its corresponding node. As explained before, Zookeeper, Kafka,
Coordinator and Dashboard must be run on the ’Worker Node 1’.
Data Fetcher on ’Worker Node 2’ and Data Hub on ’Worker Node
3’. Hence, as an example, the field ’spec.nodeSelector’ for the
Dashboard Deployment that has to be run on the ’Worker Node 1’
is defined as: ’dedicated:worker1’. The same procedure is taken
for the other Deployments corresponding to the architecture.
∗ imagePullSecrets
Kubernetes will automatically pull the specified image if it is pub-
lic. This works for Zookeeper and Kafka, but as mentioned in Sec-
tion 3.1.2, for the rest of our components we use private Docker
images.
To let Kubernetes access our private Docker registry, we need
to create a ’secret’ for Kubernetes based on the registry’s login
credentials. Using the ’spec.imagePullSecrets’, we define such a
secret in the Deployment definition for the corresponding image.
41
3.4.3 Service Definition and Exposing Services
Defining deployments, Pods can be created and destroyed dynamically. This causes
Pods to be changed frequently and hence, they will be assigned different IPs every
time. This way, the Pods cannot keep track of each other and provide functionality
to the other Pods. To overcome this issue, we use Services in Kubernetes. A
Service is an abstraction that defines a set of Pods and a policy that they can be
accessed through. As explained in Section 3.3.2, using an add-on, which currently
is CoreDNS, Kubernetes setups a DNS service for the service discovery purpose.
This way, Kubernetes implements an internal service discovery mechanism. The
Kubernetes cluster monitors Kubernetes API for new services and creates a set of
DNS records for each of newly created services. Each service will be assigned a
unique IP address and a DNS host name. Moreover, an internal load balancer on top
of a service will take care of load balancing traffic to the service’s corresponding
Pods.
A service definition starts with ’apiVersion’, ’kind’ and ’metadata’, which are
explained as the common parameters for all object’s definitions before. Hence,
we go straight to the ’spec’ definition. The ’spec’ for a service object includes
categories such as ’selector’, ’ports’, ’type’, and ’externalTrafficPolicy’ and each is
discussed as follows.
• spec.selector Assigning a key-value pair as the label of pods, this field spe-
cifies set of Pods that the service should target. Then, a continuous scan
will be done by the service selector controller to find those Pods, which
their label matches this definition. Upon finding such matches, the control-
ler POSTs the recent updates to them. As an example the ’spec.selector’ for
the Zookeeper Service is defined as ’app:zookeeper’. The same procedure is
followed for all other service objects.
• spec.type Service type specifies how we aim to publish each service. Some
42
of our services only need to communicate with the other services, while
some of the services should be exposed to an external IP and be accessible
from outside of the cluster. According to the publishing approach, we have
to define the service type. Possible types are explained as below:
43
Dashboard UI’s front-end code and for that reason, we need to expose
the Dashbord service on the same port that is used in the code. To solve
the problem, we have changed the Kubernetes’s default port range for
NodePort. After applying this change, we are able to expose the Dash-
board and Data Hub services on their specific ports.
– Ingress We can also use Ingress for exposing services. However, this
is not a service type. Ingress is an API object in Kubernetes that routes
44
HTTP and HTTPS traffic from outside of the cluster to the services
within the cluster. The traffic routing can be managed by defining
traffic rules on the Ingress resource [95]. In other words, Ingress is
a single entry-point to the cluster and acts as a reverse proxy. Figure
3.6 illustrates the relation of an Ingress with a Kubernetes cluster.
An ’Ingress Controller’ is required to satisfy an Ingress in Kubernetes.
One of the possible options is to use NGINX Ingress Controller. The
main function of Ingress is to route requests and provide externally-
reachable URLs for services. However, other functionalities can be
served behind an Ingress, such as load balancing traffic or handling
SSL/TLS termination.
However, this is not exactly what we are aiming for. According to the defin-
itions of micro-services of our system in Section 2.4.2, the Dashboard is a
UI for monitoring state of the system including all micro-services and the
data that is transferring among producers and consumers. Hence, access to
this service should only be given to the company X in the described use-case
(The company that we aim to deploy the system there and owns the data
sources). This is while the UI for the Data Hub service is designed for con-
45
sumers of data, meaning the company Y in the described use-case. There-
fore, we need to expose these services in a way that each is reachable on a
specific IP and port. As a solution, we define the ’spec.externalTrafficPolicy’
field in the service definition of these two services and assign ’Local’ as its
value. Assigning such value, Kubernetes only proxies requests to the local
endpoints and never forwards traffic to the other nodes of the cluster. This
way, Kubernetes preserves the client’s original source IP address.
Finally, the end-user in company X would be able to access the Dashboard
service on the ’Worker Node 1’s IP:Port’. Also, the end-user in company Y
has access to the Data Hub service on the ’Worker Node 3’s IP:Port’ using a
VPN to the company X’s internal network. Figure 3.7 shows an overview of
our approach for exposing Dashboard and Data Hub services externally.
46
netes only supports login to the Dashboard via a Bearer Token. Issuing a specific
command in Kubernetes, we can create such a token for our created admin-user.
47
48
Chapter 4
In this chapter, the proposed solution, to deploy the IoT system using Kubernetes,
is evaluated based on different metrics. The focus for choosing metrics and design-
ing test scenarios is towards the deployment process. Hence, some sections include
measurements, while some are discussion-based and focus on show-casing advant-
ages of the used method for deployment.
The discussed metrics include performance both in the runtime and the cost ef-
ficiency, lifecycle management including system updates and fault-tolerance of the
system, resource management and scalability of the solution. Moreover, a com-
parison with the previous deployment solution (where Kubernetes is not used, and
each micro-service is run in a separate VM) is conducted for some of the discussed
parameters.
Hardware Characteristics IP
VM Name OS HostName
CPU RAM DISK Private Public
Master CentOS 32
2 6 GiB k8s-master 192.168.1.20 10.164.101.20
Node 7.6.1810. x86-64 GiB
Worker CentOS 32
2 6 GiB k8s-worker1 192.168.1.21 10.164.101.21
Node 1 7.6.1810. x86-64 GiB
Worker CentOS 32
2 6 GiB k8s-worker2 192.168.1.22 10.164.101.22
Node 2 7.6.1810. x86-64 GiB
Worker CentOS 32
2 6 GiB k8s-worker3 192.168.1.23 10.164.101.23
Node 3 7.6.1810. x86-64 GiB
49
Table 4.1 illustrates the hardware characteristics of each VM and its public and
private IPs. (To preserve privacy of the company, real IPs are replaced with ex-
ample ones.)
Table 4.2: Runtime Comparison between the previous and current deployment
setup.
Results show an average of 19.2 seconds as the time that takes for completing
a subscription in the previous deployment solution. Using the proposed deploy-
ment solution, this time has reached 9.8 seconds on average. The acquired results
are presented in Table 4.2. We can interpret such a decrease (about 9.4 seconds)
as a result of the designed architecture in the two solutions. In the previous ap-
proach, each micro-service is running in a separate VM. Hence, all traffic and
communications between them are external. This is while, we have three of these
micro-services namely Dashboard, Coordinator, and Data Switch resided on the
50
same VM in the proposed solution. This eliminates part of the external traffic since
communications among these three services are local. Finally, it results in faster
response time for a subscription accomplishment.
Table 4.3: Deployment cost in the proposed solution with Kubernetes [97].
According to Table 4.3, the price difference for the previous and current de-
ployment approaches is 32.85 $ in a month. Comparing the previous approach
51
and possible edition of the current solution as the future work, even shows more
difference, about 65.7 $ in a month. This price difference might seem negligible.
However, if we think of the scalability of the solution, where we would need to
have more Data Hub services, the difference becomes significant.
Table 4.4: Monthly price for a scalable solution using Kubernetes and Ingress [97].
52
Figure 4.1: Price Comparison for Different Deployment Solutions .
53
ponding containers is one of the tasks that should be supported by the deployment
method. Moreover, a fast-enough mechanism for recovery of the failed compon-
ents is required. Kubernetes, as a container orchestration tool, supports monitoring
health of containers. Moreover, it provides mechanisms for their recovery.
Failure recovery in Kubernetes is supported in the Pod level, and each Pod usu-
ally contains one or more containers. However, Pods are not resilient to machine
failures by themselves and we use controllers to make them resilient. Pods, after
creation, do not disappear unless they are destroyed, or an involuntary disruption
happen. An involuntary disruption includes any kind of unavoidable hardware or
software error. For instance, the Pod or the node (that pod is running on) could
be deleted by mistake by the cluster administrator, or there might be a hardware
failure in the machines. Even, the node might disappear from the cluster due to a
cluster network problem.
To observe the effect of such disruptions on our scenario, the following test cases
are designed. Details of the tests and results of the failure recovery, provided by
Kubernetes, are discussed as follows.
• Pod Failure
In Kubernetes, Pods are not resilient to machine failures, but controllers,
such as deployment, are [98]. Deployment provides declarative updates for
Pods. Hence, in case of a pod-failure, deployment kills those pods that do not
respond and instead, it re-creates and restarts another corresponding Pod and
container that is defined by the deployment definition. To benefit from the
self-healing and failure recovery characteristics of Kubernetes, which can be
provided by the controller objects, we have used deployments. So, as men-
tioned in Section 3.4.2, to create corresponding container of each component
in the system, we define ‘Deployments’ instead of defining a Pod directly.
To make sure that such a failure recovery mechanism is present in our im-
54
and results can be seen in Table 4.5. A delay between 2 to 3 seconds was the
usual case for recovering one single pod corresponding to one of the com-
ponents. Also, removing pods, corresponding for all components, together
at the same time, resulted in 50.6 seconds on average for the whole system
to be up and running again. This means that if in the worst case, whole of
the pods fail together, then the time that takes for the whole system to be
recovered is close to one minute.
• Node Failure
In Kubernetes, failure of a worker node to respond to the master node is
defined as the node failure. This would happen due to network failure, often
called a network partition [73]. The Pods that run on a node, will fail due to
node failure.
In Kubernetes, the controller manager is responsible for monitoring the state
of the nodes in the cluster. There are a few default metrics, which are con-
figurable, and have a role in determining the state of the nodes. First, based
on the ‘–node-monitor-period’ parameter, each worker node must respond
to the master node every 5 seconds, which is the default time. Then, if the
worker node fails to respond for a period of 40 seconds (it is defined by the ‘–
node-monitor-grace-period’ parameter as the default value), its state would
be marked as ‘Unknown’. The last effective parameter is ‘–pod-eviction-
timeout’ and is defined as 5 minutes by default. After this time, all Pods that
were running on this node would be deleted. After that, the scheduler will
re-assign them to another available node in the cluster that has the required
resources and is accordance with the specifications of the Pod. To observe
the effect of node failure on our scenario, we simulated failing one of the
worker nodes by shutting down its corresponding instance. To do so, we
chose the ‘Worker Node 2’ that hosts the Data Fetcher Pod.
In Kubernetes, by default, any worker node that has the required resources
can host any running pod. However, as discussed in Section 3.4.2, to serve
the goals of our specific use-case, we have labeled each worker node. Then,
the deployments are constrained to be run on specific nodes using these la-
55
bels. Hence, to let the node recovery happen, we have created another VM,
joined it to our cluster and called it ‘Worker Node 4’. Then, the ‘Worker
Node 2’ and ‘Worker Node 4’ were attached with similar labels. We shut
downed the ‘Worker Node 2’. Initially, we did not notice any changes and
watching the list of running Pods, they all appeared to be running fine. After
about 40 seconds the state of ‘Worker Node 2’ was shown as ’NotReady’.
Finally, it took five minutes until we notice the corresponding Pod failed and
another one was created in 2 seconds on the ‘Worker Node 4’. The observed
life-cycle of node failure are shown in Figure 4.2.
56
CPU (%) Memory (MB)
Node
Stage 1 Stage 2 Stage 3 Stage 1 Stage 2 Stage 3
Master 4 6 4 1689 1693 1714
Worker 1 1 99 7 789 2057 2100
Worker 2 1 91 27 567 1276 1931
Worker 3 1 71 7 594 1224 1629
Table 4.6: Resource usage in three stages of a runtime for different nodes.
Stage 1: Before deploying the system in the cluster; Stage 2: Upon deployment;
Stage 3: After issuing multiple subscriptions on the running system.
of the used CPU is based on the percentage, while memory usage is shown in
Megabytes.
Based on the results, almost all worker nodes use most of their CPU power in
stage 2, when the system is deploying. This is especially the case in the ‘Worker
Node 1’ since it hosts most of the micro-services. Then, in the stage 3, while we
use the system to issue subscriptions, ‘Worker Node 3’ has the most CPU usage,
about 27 percent. This is reasonable since it hosts the main active component upon
issuing a subscription, meaning the Data Fetcher.
The amount of memory consumption upon deploying the system reaches over
to 2 GB in the ‘Worker Node 1’. According to this result, a VM with 2 GB RAM,
which is mentioned as the minimum requirements previously, is not enough for
this use-case and should be considered in a real-world setup. The memory usage
in ‘Worker Node 2’ and ‘Worker Node 3’ reaches to around 1276 at maximum.
Finally, upon using the system and issuing subscriptions, memory usage in the
‘Worker Node 1’ goes even higher and reaches to 2100 MB. In the ‘Worker Node
2’, this number reaches to 1931 MB, which is close to the limitation of 2 GB.
This observation on ‘Worker Node 2’ is important for our use-case. According to
Section 3.2.2, the ultimate aim in this use-case is to deploy the Data Fetcher module
on a gateway, instead of running it on a VM. The gateway that we are planning to
use in the future has capabilities of 2 cores CPU and 2 GB RAM. Hence, studying
the possibility of such a scenario has been one of the goals of this research study.
57
a reasonable value for the memory and CPU requests of the Pod to be running
properly. Defining this value is a help for scheduling of Pods in the nodes with
appropriate available resources. Then, in the ‘limits’ field, we define the upper
bound that the Pod can use. Hence, the containers would not be allowed to use the
whole of available resources on the node.
We have defined such constraints for the Data Fetcher Pod. The constraints are
defined only on memory usage. The motivation behind this is the low capabil-
ities that the real device (for running Data Fetcher) has and is discussed before.
While the memory request is defined by 1000 MB, the memory limit is tested with
different values. Results show that defining the limit with a low value causes the
corresponding Pod to fail. Finally, with a limitation value of 1200 MB, the Data
Fetcher Pod was working properly. To make sure that the system works fine under
such resource constrains, multiple subscriptions were issued, and the runtime was
observed for different periods of time.
Observing the memory usage of Data Fetcher Pod, before defining any con-
straints, shows that the Pod can use up to 1555 MB, while the memory usage of
the ‘Worker Node 2’, which hosts this Pod, reaches to 2023 MB at latest. This
result is recorded under a system runtime pressure, where about 20 different sub-
scriptions are issued with a low free time in between. After defining the memory
limit for 1200 MB, the maximum memory usage in the Data Fetcher Pod reaches
to 1157 MB, while the memory usage in ‘Worker Node 2’ goes up to 1628 MB.
Hence, according to the results, we are able to constrain resources while the system
continues to work properly.
Table 4.7: Memory usage before and after defining resource constraints.
4.5 Scalability
In this section, we have studied and evaluated how the used approach for deploy-
ing the IoT system is scalable. We have categorized the section into two general
sub-sections: ‘Scaling Pods’ and ‘Scaling Services’. In the former, the goal is
to analyze the scalability of individual components of the micro-service system,
while the latter concentrates on the whole solution to be used on a larger scale in
the future.
58
4.5.1 Scaling Pods
In Kubernetes, we can scale the individual Pods corresponding to different micro-
services independently. This would be beneficial in case one of the Pods in the
cluster has more user traffic and requires more resources. Hence, resources would
not be wasted on scaling all the micro-services together, while scaling only one of
them is needed. To test how the system reacts to such scaling we have used two
possible approaches. First, we have tried a manual scaling and results are provided.
Next, the auto-scaling as the other possible option in the Kubernetes is activated
and the requirements are discussed.
• Manual Scaling
The manual scaling is possible through updating number of replicas in a
controller definition, for instance in the Deployment definition in our case.
This way, the number of Pods will be increased to the new desired state.
After deploying the system in the cluster, we scaled out each individual Pod
from 1 replica to 2 replicas and the time that takes for them to be deployed
is recorded as an average of five times repetition of such test scenario. The
test was repeated for scaling from one to 5 replicas. Then, we also calculated
the time for scaling in each Pod from 2 and 5 replicas to one. Finally, we
have repeated these test cases for scaling out and scaling in the whole of the
system’s Pods together at one attempt. Results show that the time, which
takes for scaling in, is always less than the time that takes for scaling out a
Pod and this makes reasonable. However, based on our observations, this is
not the case for the ‘Zookeeper’ Pod. Scaling in of this Pod always take a
longer time than its scaling out. This also affects the scale in time for the
whole system as the ‘Zookeeper’ Pod scales in very slowly. Hence, while it
takes 38.8 seconds for the whole Pods to be scaled out to 5 replicas each, the
time for scaling in is 58 seconds, in contrast of our expectation. However, no
reason has found based on our studies for this but should be studied in the
future.
• Auto-Scaling
59
Scaled Pod Scale Out Time Scale In Time Scale Out Time Scale In Time
For 1 to 2 For 2 to 1 For 1 to 5 For 5 to 1
Replicas (S) Replicas (S) Replicas (S) Replicas (S)
Zookeeper 4.6 30 15 35
Kafka 5.6 2.8 12.8 7.8
Dashboard 2.6 1.8 6.6 4.6
Coordinator 3.8 2.8 9.6 6.2
Data Fetcher 2.8 1.8 4.8 3.2
Data Hub 2.6 1.2 4.6 3.2
All together 26.2 34.2 38.8 58
Table 4.8: Average time for scaling out and scaling in the Pods.
in Section 4.4, to get the resource metrics in Kubernetes, the ‘Metric Server’ must
be deployed on our cluster.
We have set up a horizontal auto-scaler for one of the deployment objects (the
Data Fetcher), in our cluster. The aim is to see how such HPA acts in presence of
a high workload and if it starts to work automatically in practice. In the definition
of the HPA, we have defined the minimum number of Pods as one, and maximum
as three. The condition for starting the HPA is defined by the CPU usage to be
reached to 10 percentage.
Firstly, watching the amount of CPU usage by the corresponding Pod, we have
observed that the CPU usage went above the 10 percent but the HPA did not apply
and the number of Data Fetcher Pods stayed at one. Later, we have noticed for
the HPA to work, it is required that a CPU request be specified in the Deployment
definition. This way, we could observe that the number of Data Fetcher Pods were
scaled from one to three when the target CPU usage is met. The time that it took for
such a scaling was not more than 5 seconds in different repetitions of the test-case.
60
Figure 4.3: General architecture for an scalable scenario.
cess to more than one consumer. Hence, we must be able to expose more than
one Data Hub service instead of only one. Such scalability has evaluated in this
section. Currently, different Data Hub services are distinguished with an ID and
using that, they communicate with the whole system. Hence, to add the second
Data Hub service, first, we have created its corresponding Docker image. Then, a
‘Deployment’ and a ‘Service’ definition is created correspondingly. We have used
another VM for hosting the second Data Hub service. However, trying to expose
it on the same port, which we have used for the first Data Hub service, was not
successful. Later, we have noticed that when we assign a port to a service using
NodePort, Kubernetes opens that specified port on all the worker nodes within the
cluster. Therefore, we can only expose one service per port using NodePort.
Finally, we were able to expose the second Data Hub service on the ‘Worker
node 4’ using a different port. The architecture of such a case is shown in Figure
4.3. Having two Data Hub services, the system was working properly, and the
approach is scalable. However, a downside to the used method is that we must use
one VM per Data Hub and it makes the approach expensive. In future works, we
have discussed a better way of exposing service in Kubernetes that will eliminate
the need for the additional hardware equipment.
61
62
Chapter 5
5.1 Conclusions
We present the conclusions according to the research questions that are presented
in Section 1.2.
• RQ1. How can we ease deployment of the Pub/Sub IoT system and eliminate
system’s limitations for a large-scale deployment?
In this thesis, we studied that containerization bundles an application and
its dependencies together in a self-contained unit. Hence, as an alternative
to running the corresponding Jar file of each micro-service directly on the
infrastructure, we containerized the Pub/Sub IoT system.
Furthermore, we studied whether the deployment of the Pub/Sub IoT system
using Kubernetes will provide a service discovery among the micro-services
of the system to ease its deployment. Kubernetes has an internal built-in
DNS service, named CoreDNS, that is applied on the ’Service’ level. ’Ser-
vice’ is one of the Kubernetes object types that is defined by the Kubernetes
63
API. CoreDNS monitors the Kubernetes API and automatically creates DNS
records for any new services. This enables service discovery across a cluster
and pods are able to perform name resolution automatically for all services.
Hence, defining each of the micro-services in the current IoT system as a
’Service’ object type in Kubernetes, we can utilize Kubernetes’s service dis-
covery for our purpose. This allows us to change the hard-coded IPs to
the name of Kubernetes services. So, changing IPs per deployment is not
required anymore and this is especially beneficial for the large-scale deploy-
ments.
• RQ2. Which containerization and Kubernetes mechanisms should be used
in the deployment procedure to serve requirements of the system?
To containerize the Pub/Sub IoT system, Docker Container Engine is chosen
as the containerization tool, since it works well with Kubernetes. Then, to
preserve the privacy of the project and to keep the created Docker images
within the company, we decided to set up a private Docker Registry. We
have seen that setting up a private registry was a straightforward procedure,
using the Docker’s open-source project, named ’Docker Registry’.
To deploy the Pub/Sub IoT system using Kubernetes, we were required to
consider some specifications. One of such specifications is the location of
Data Fetcher service since it is developed to be performed at the edge of the
network. To serve such capability for DataFetcher, we must make sure that it
is running on a separate node within the cluster. To dedicate a micro-service
to be run in a particular node in the Kubernetes cluster, we labeled each node.
Then, defining ’nodeSelector’ in the Deployment definition of each micro-
service and assigning the right label, we could manage such dedication.
Public exposure of two micro-services, Dashboard and DataHub, is from
the other requirements of the Pub/Sub IoT system. To this goal, we defined
their corresponding Service definition from the NodePort type. However,
NodePort exposes a service on the specified port and IP address of all worker
nodes. This is not fulfilling requirements of the system since we aim to
give unique access of each service to a particular end-user. To solve the
issue, we defined the ’externaltrafficpolicy’ to be set as ’Local’ in the Service
definition of DataHub and Dashboard. As a result, Kubernetes only proxies
requests to the local endpoints and never forwards traffic to the other nodes
of the cluster.
Furthermore, the default port range of NodePort service type in Kubernetes
is between 30000-30767. For a service of type NodePort, if a port is not
specified, Kubernetes will assign a port within this range automatically. A
port is hard-coded in the front-end of the Dashboard micro-service. Hence,
we were required to expose Dashboard service on that particular port. Since
the port was not within the default NodePort range of Kubernetes, we have
configured this default port range in Kubernetes.
64
• RQ3. What are the implications of the system’s deployment based on Kuber-
netes for the efficiency of the system and its scalability?
Upon deployment and running the system, we evaluated the runtime for is-
suing a subscription. Results show a faster response time. This is because
there are less external communications in the Kubernetes-based approach
compared to the previous deployment method. Moreover, we calculated the
corresponding costs for each of the previous and proposed deployment ap-
proaches. We have seen that using Kubernetes for deployment, is cheaper
especially when the solution scales.
Kubernetes provides better life-cycle management for the deployment using
metrics, such as updating of the system and its failure recovery. For system’s
updating, Kubernetes uses concept of ’Rolling Updates’. Results show that
updating any of the system’s micro-services takes under 5 seconds.
Furthermore, using Kubernetes, it is possible to monitor resource consump-
tions and also utilize the resource usages for each of the services. We noticed
that the ’Worker Node 1’ has a higher resource consumption than the basic
requirements for a custom node. This is reasonable since most of the work-
load including four of the micro-services are running on this node. This
allows us to prepare proper hardware requirements for a real-case scenario.
Furthermore, we could manage the resource usage of the Data Fetcher ser-
vice. In the future, we aim to run the Data Fetcher on a gateway. Such
gateway has specific hardware requirements including 2 cores CPU and 2
GB RAM. Hence, we should make sure that we can keep Data Fetcher’s us-
age in this range. We saw that Kubernetes features allow for such resource
management. Finally, regarding scalability of the proposed approach, we
have seen that it is possible to define more than one Data Hub service and
each can be exposed on a separate IP and port.
65
devices and the cloud. Such a gateway has some computation power as well
as network connectivity.
The device that we had accessible at the time of writing this thesis, was
Nokia’s gateway with 1 core CPU and 1 GiB RAM. However, according
to the Kubernetes documents, the minimum requirements for a node to be
run in a Kubernetes cluster is 2 cores CPU and 2 GiB RAM. Hence, despite
using such gateway, in this work we simply used a VM to be the host for
Data Fetcher’s container. As future work, we plan to deploy Data Fetcher’s
service on a real gateway with the proper hardware requirements. During
our research, we learned that a multi-architecture Kubernetes cluster is re-
quired for this purpose. This is because the CPU architecture of the intended
gateway is different from the other nodes (VMs) in the cluster.
2. In the current Pub/Sub IoT system, two of the micro-services have their
corresponding UIs that must be accessible by the end-users. In a scalable
approach, we aim to have more than one DataHub service. Hence, the ad-
dresses of different DataHub URLs must not be the same. In Section 3.4.3,
we discussed the conducted approach for service exposure in Kubernetes
based on NodePort. NodePort exposes a service on a port and to access the
service, we use combination of IP of the VM and the specified port.
One limitation of this approach is that remembering IP and port is not easy
for users. As the solution, we can configure the DNS server to point a do-
main name to the IP of the ports. Moreover, if we expose more than one Data
Hub service on the same VM, we will have the same IPs and only ports will
change. Hence, to provide such scalability, we have used a VM per Data
Hub service in the proposed architecture with NodePort and the ’external-
trafficplocy’ is defined as ’Local’ for these services. in Section 4.2.2, we
discussed that this approach is not cost-efficient for scaling the deployment.
As an alternative approach, we suggest using a loadBalancer for exposing
services. LoadBalancer is another service type that is explained in Section
3.4.3. Using a loadBalancer for exposing services, we can deploy as many
Data Hub services as we like on only one VM, and instead, use different
LoadBalancers for each. This way, we will have different IP addresses to
access each service. However, this approach still has limitations. Firstly,
the DNS server should be configured for each newly added service and new
loadBalancer. Moreover, from the perspective of cost-efficiency, using a
loadBalancer per service still could inversely increase the cloud bill.
Finally, there is still another approach for exposing services in Kubernetes,
namely ’Ingress’ and we suggest it to be used as the best approach in the
future works.
The concept of ’Ingress’ is explained in Section 3.4.3. To satisfy an Ingress
in Kubernetes, an Ingress controller is required. NGINX Ingress controller is
one of the available options. Ingress will act as the single-entry point to the
66
Figure 5.1: Architecture overview of the proposed scenario with Ingress.
cluster. Then, defining different paths for each service, it routes the related
incoming external request to the right service. This way we do not need to
use multiple IP addresses per service as it is with loadBalancer. Hence, it
is very cost-efficient. Furthermore, Ingress will be configured as an internal
Kubernetes object and being the single entry-point to the cluster, it is the
only place that will be affected upon adding a new service.
Using an Ingress we can use a single domain name and assign each service
a separate path. Following this approach in the future works for deploying
the Pub/Sub IoT system still requires an improvement in the system devel-
opment’s level. Since the addresses will be unique only in their paths, an au-
thentication mechanism should be developed for accessing both Dashboard
and Data Hub services.
The architecture overview of the proposed deployment solution using NGINX
Ingress Controller is shown in Figure 5.1. An external loadBalancer can be
used to access the ingress controller, which is resided inside the Kubernetes
cluster. Ingress has the domain name of ’MyDomain.com’ and to access dif-
ferent services, different paths are defined.
67
68
Bibliography
[6] S. Muralidharan, G. Song, and H. Ko, “Monitoring and managing iot ap-
plications in smart cities using kubernetes,” CLOUD COMPUTING 2019,
p. 11, 2019.
69
[11] I. Global, “What is cellular network.” https://www.igi-global.
com/dictionary/cellular-network/3547. [Online; accessed 1-
August-2019].
[20] F. Al-Turjman, Smart Things and Femtocells: From Hype to Reality. CRC
Press, 2018.
[22] S. Li, L. Da Xu, and S. Zhao, “5g internet of things: A survey,” Journal of
Industrial Information Integration, vol. 10, pp. 1–9, 2018.
70
[25] D. Wang, D. Chen, B. Song, N. Guizani, X. Yu, and X. Du, “From iot to
5g i-iot: The next generation iot-based intelligent algorithms and 5g tech-
nologies,” IEEE Communications Magazine, vol. 56, no. 10, pp. 114–120,
2018.
[26] Qwilt, “The mobile edge cloud 5g and mec.” https://qwilt.com/
5g-mec/mec-and-5g/. [Online; accessed 1-August-2019].
[27] Y. C. Hu, M. Patel, D. Sabella, N. Sprecher, and V. Young, “Mobile edge
computing—a key technology towards 5g,” ETSI white paper, vol. 11,
no. 11, pp. 1–16, 2015.
[28] T. Taleb, K. Samdanis, B. Mada, H. Flinck, S. Dutta, and D. Sabella, “On
multi-access edge computing: A survey of the emerging 5g network edge
cloud architecture and orchestration,” IEEE Communications Surveys & Tu-
torials, vol. 19, no. 3, pp. 1657–1681, 2017.
[29] P. Porambage, J. Okwuibe, M. Liyanage, M. Ylianttila, and T. Taleb, “Sur-
vey on multi-access edge computing for internet of things realization,” IEEE
Communications Surveys & Tutorials, vol. 20, no. 4, pp. 2961–2991, 2018.
[30] Q. H. Mahmoud, Middleware for communications, vol. 73. Wiley Online
Library, 2004.
[31] “Mqtt-essentials-part2-publish-subscribe.” https://www.hivemq.
com/blog/mqtt-essentials-part2-publish-subscribe/,
2015. [Online; accessed 23-April-2019].
[32] P. T. Eugster, P. A. Felber, R. Guerraoui, and A.-M. Kermarrec, “The many
faces of publish/subscribe,” ACM computing surveys (CSUR), vol. 35, no. 2,
pp. 114–131, 2003.
[33] D. Happ, N. Karowski, T. Menzel, V. Handziski, and A. Wolisz, “Meeting
iot platform requirements with open pub/sub solutions,” Annals of Telecom-
munications, vol. 72, no. 1-2, pp. 41–52, 2017.
[34] “Apache kafka documentation.” https://kafka.apache.org/
documentation/. [Online; accessed 24-April-2019].
[35] “Ibm official page.” https://www.ibm.com/products/mq. [On-
line; accessed 24-April-2019].
[36] “Mqtt official page.” http://mqtt.org/. [Online; accessed 24-April-
2019].
[37] R. Baldoni, C. Marchetti, A. Virgillito, and R. Vitenberg, “Content-based
publish-subscribe over structured overlay networks,” in 25th IEEE Interna-
tional Conference on Distributed Computing Systems (ICDCS’05), pp. 437–
446, IEEE, 2005.
71
[38] Wikipedia, “Apache kafka.” https://en.wikipedia.org/wiki/
Apache_Kafka. [Online; accessed 1-August-2019].
[43] C. Pahl, “Containerization and the paas cloud,” IEEE Cloud Computing,
vol. 2, no. 3, pp. 24–31, 2015.
[48] S. Sharma and Y. Park, “Virtualization: A review and future directions ex-
ecutive overview,” American Journal of Information Technology.
72
[51] P. Dash, Getting started with oracle vm virtualbox. Packt Publishing Ltd,
2013.
[52] A. Muller and S. Wilson, “Virtualization with vmware esx server,” 2005.
[57] F. Bellard, “Qemu, a fast and portable dynamic translator.,” in USENIX An-
nual Technical Conference, FREENIX Track, vol. 41, p. 46, 2005.
73
[66] D. Jaramillo, D. V. Nguyen, and R. Smart, “Leveraging microservices archi-
tecture by using docker technology,” in SoutheastCon 2016, pp. 1–5, IEEE,
2016.
74
[79] Kubernetes, “Kubernetes control plane.” https://kubernetes.io/
docs/concepts/#kubernetes-control-plane. [Online; ac-
cessed 16-August-2019].
75
[92] Kubernetes, “Installing addons.” https://kubernetes.io/docs/
concepts/cluster-administration/addons/. [Online; ac-
cessed 20-August-2019].
76