SlideShare ist ein Scribd-Unternehmen logo
1 von 40
Downloaden Sie, um offline zu lesen
KWC 2018 - Berlin
Kamailio with Docker and
Kubernetes
Scale in the right way
about me...
My name is Paolo Visintin
I’m passionate about telecommunications and technology, I design, develop and maintain
VoIP platforms based on Kamailio and Asterisk
I’m the CTO of an Italian telco operator providing internet and voice services in the Country
I decided to start a new project named evosip, a cloud PaaS VoIP infrastructure built on
kubernetes
You can follow me:
https://www.linkedin.com/in/paolo-visintin-cloudvoip/
http://evosip.cloud/
Agenda
In this speech I’d like to tell you how we created a platform that:
…a platform we named evosip!
● scales with no limits
● scales fast and automatically
● is distributed
● is QoE oriented
● has no vendor lock-in
● achieve business continuity
evosip diagram
● Kamailio proxy and “routing” layer
● Asterisk as TPS
● RTPEngine
● Custom API SIP orchestration
evosip … from the beginning
We were looking for a platform able to :
● create instances in a very fast way (couple of seconds)
● orchestrate instances between layers
● orchestrate network and policies
● works in a distributed environment
Using Docker for instance deployment and Kubernetes for orchestration (container,
network and policies) we found an optimal stack to start this adventure and create a really
fast and mutational SIP ecosystem based on Kamailio, Asterisk and RTPEngine
So we started to use containerisation and saw it was really fast and useful
Containers … avoid network pain!
If you have used containers in a classical way probably you have noticed something terrible
about dealing with networking and SIP
This diagram shows the classical use of networking with docker
Containers … avoid network pain!
So how could you use SIP in containers without doing NAT / bridging and avoid network
issues and lack of performance ?
Differences between bridge networking and [mac/ip]vlan networking
…with macvlan !
Thanks to macvlan every instance can have a direct public IP address with its own mac
address
It uses less CPU and provides better throughput (almost like the physical interface)
Containers … avoid network pain (with macvlan)!
macvlan associate to Linux Ethernet interface or sub-interface
We also decided to separate
● data network (DB / API / etc)
● core service network (SIP / RTP)
But … if you know kubernetes, you also know that a POD (a group of one or more containers
with shared storage/network) by default provides a single network interface
Containers with multiple networks
with multus (https://github.com/Intel-Corp/multus-cni - a CNI plugin) you are able to do it!
Containers with multiple network
Containers with multiple network
Containerized services work and scale better
with stateless applications
Then, how to make kamailio ASAP ?
Kamailio ASAP (As Stateless As Possible)
We will now focus on :
● dispatcher
● authentication
● user location
● dialogs
We use the dispatcher module to route request from proxy layer to router layer (both are
kamailio auto-scalable instances)
As of the possibility of reloading the dispatcher module (e.g. autoscaling of routers) once used
ds_select_dst we store the $du and callerid ($ci) in a hash table in order to re-use $du on
the next request and maintain the path to the same endpoint for the call
We disabled the keepalive option in dispatcher to avoid pinging endpoints
We set instead short timers to handle failure_route in case of tear-down on unreachability of
endpoints
Kamailio ASAP - cached dispatchers
Kamailio ASAP - cached dispatchers
if ($sht(hDispatcherTps=>$ci)==$null) {
# select tps from dispacher
ds_select_dst("1","0");
$sht(hDispatcherTps=>$ci) = $du;
} else {
$du = $sht(hDispatcherTps=>$ci);
}
Kamailio ASAP - cached dispatchers
if ($sht(hDispatcherTps=>$ci)==$null) {
# select tps from dispacher
ds_select_dst("1","0");
$sht(hDispatcherTps=>$ci) = $du;
} else {
$du = $sht(hDispatcherTps=>$ci);
}
How we implemented authentication in kamailio ?
Kamailio ASAP - Auth module
● we call API to retrieve user profile and store it in htable
● we use pv_auth_check method to deal with authentication
● Orchestrator calls via RPC kamailio if profile changes and need to be reloaded / updated
Caching authentication in this way improves performance and optimize API calls
How we implemented authentication in kamailio ?
Kamailio ASAP - Auth module
route[AUTHCACHE] {
if($au && $sht(auth=>$au::passwd)==$null) {
# get password from API
...
$var(graphql_query) = "{"query": "{ kamailio
{ subscriber { auth(username:"" + $au + "") {
usernamen secret } } } } "}";
$http_req(body) = $var(graphql_query);
http_async_query(API_QUERY_URL, "SET_PASSWD");
...
}
How we implemented authentication in kamailio ?
Kamailio ASAP - Auth module
route[SET_PASSWD] {
if ($http_ok && $http_rs == 200) {
xlog("L_INFO", "route[SET_PASSWD]: response
$http_rb)n");
jansson_get("data.kamailio.subscriber.auth.username",
$http_rb, "$var(username)");
jansson_get("data.kamailio.subscriber.auth.secret",
$http_rb, "$var(secret)");
xlog("L_INFO", "route[SET_PASSWD]: setting
password >>>$var(secret)<<< for user
>>>$var(username)<<< in shared tablen");
$sht(auth=>$var(username)::passwd) =
$var(secret);
} else {
xlog("L_INFO", "route[HTTP_REPLY]: error
$http_err)n");
}
}
How we implemented authentication in kamailio ?
Kamailio ASAP - Auth module
$var(user_passwd) = $sht(auth=>$au::passwd);
if(!pv_auth_check("$fd", "$var(user_passwd)",
"0", "1")) {
auth_challenge("$fd", "1");
exit;
}#end if
} # end route[AUTH_ACCOUNT]
We save in memory and share user locations using DMQ
Kamailio ASAP - Usrloc module
Router instance
…
loadmodule "dmq.so"
loadmodule "usrloc.so"
loadmodule "dmq_usrloc.so"
#!define DMQ_SERVER_ADDRESS "sip:<pod-macvlan-ip>:5060"
#!define DMQ_NOTIFICATION_ADDRESS "sip:dmq-service:5060"
modparam("dmq_usrloc", "enable", 1)
modparam("dmq", "multi_notify", 1)
modparam("dmq", "num_workers", 4)
DMQ server
...
request_route {
if(is_method("KDMQ")){
dmq_handle_message();
}
...
As of the stateless and mutational architecture we decided to use a containerized DMQ
server based on kamailio
We thought that having tons of dialogs replicated among router instances was not the
best way to achieve an unlimited scalable architecture
Kamailio ASAP - Dialogs
The best way to deal with dialogs in a distributed form for us is:
● every router instance deals with its own dialogs
● foreign dialogs are managed in case of tear-down or failover
● foreign dialogs have to be manager “on demand”
proxy
router 1
router 2
router 3
user call
user call
shared
dialog DB
dialog is saved in write-back mode from kamailio to DB
user call
a single dialog for specific callerid is
recovererd from DB
router 3
We needed to implement an intelligent and distributed sharing of dialogs in order to
work with a fast architecture mutation and failover-proof
Kamailio ASAP - Dialogs
...
if(has_totag()) {
if(!is_known_dlg()) {
# not a MINE dialog, let’s recover from DB
dlg_db_load_callid("$ci");
....
dlg_manage();
}
}
...
Now kamailio has a new amazing method implemented in dialog module
dlg_db_load_callid(“$ci”)
(ref. https://github.com/kamailio/kamailio/issues/1512)
HA and balancing
edge
Possible solutions in a distributed architecture?
DNS
● Round-robin
● GeoIP
● short TTL
HA and balancing
edge
Possible solutions in a distributed architecture?
DNS
● Round-robin
● GeoIP
● short TTL
application / service caching !
Anycast IP
● using dynamic routing (OSPF)
○ proxy instances
○ border routers
HA and balancing (again in containers)
We use OSPF equal cost multipath and balance hashing per source / destination
packets (a session with specific client will maintain the path to the same proxy)
Reducing OSPF timeouts in “area 1” gave us the possibility to converge more quickly in
case of tear-down or failover
call
HA and balancing (again in containers)
We use OSPF equal cost multipath and balance hashing per source / destination
packets (a session with specific client will maintain the path to the same proxy)
Reducing OSPF timeouts in “area 1” gave us the possibility to converge more quickly in
case of tear-down or failover
call
HA and balancing (again in containers)
We decided to use FRRouting (https://frrouting.org/ a fork of the famous Quagga
project) both for core ospf router and for proxy instances that announce the anycast ip
HA and balancing (again in containers)
FRR configuration example
FRR CORE
...
interface net0
description *** OSPF MacVLAN ***
ip ospf dead-interval minimal hello-multiplier 5
router ospf
default-information originate always
passive-interface default
no passive-interface net0
no passive-interface eth0
network <MACVLAN_NET>/<MACVLAN_SUB> area 1
network <BACKBONE_NET>/<BACKBONE_SUB> area 0
ip route 0.0.0.0/0 <DEFAULT_GW>
we set a short dead-interval to reach a fast
convergence in “area 1”
we define areas
- eth0 as backbone area 0
- net0 as proxy area 1
this router is the default gateway for proxy layer
HA and balancing (again in containers)
FRR configuration example
FRR PROXY
...
interface eth0
description *** OSPF interface ***
ip ospf area 1
ip ospf dead-interval minimal hello-multiplier 5
router ospf
redistribute static
passive-interface default
no passive-interface eth0
ip route <proxy.ip>/32 Null0
ip route 0.0.0.0/0 <FRR_COREIP>
we set a short dead-interval to reach a fast
convergence in “area 1”
we create the static route to Null0 to annunce the
anycast ip
Orchestrate !
And what about population of dispatchers and RTP nodes ?
We wrote a kubernetes controller to notify
events (create, update, delete) among the
pods
These notifications are sent to a "sidecar"
container which in turn updates the
dispatcher lists or dbtexts and call kamailio
through RPC to trigger a reload
Orchestrate !
event_route[xhttp:request] {
...
if ($hu =~ "^/rpc") {
xlog("L_NOTICE", "[XHTTP:REQUEST] $si ACCEPTED ***n");
jansson_get("method", "$rb", "$var(rpcMethod)");
xlog("L_NOTICE", "[XHTTP:REQUEST] RPC METHOD: $var(rpcMethod) ***n");
if($var(rpcMethod) == "dispatcher.reload") {
xlog("L_NOTICE", "Reloading dispatcher listn");
python_exec("updateDispatchers");
CHECK_XHTTP_EXIT
} else if($var(rpcMethod) == "rtpengine.reload") {
xlog("L_NOTICE", "Reloading RTP listn");
python_exec("updateRTPs");
CHECK_XHTTP_EXIT
} else if($var(rpcMethod) == "permissions.addressReload") {
xlog("L_NOTICE", "Reloading address listn");
} else if($var(rpcMethod) == "remove.dispatcher") {
if($hdr(dispatcherIP) != "") {
xlog("L_NOTICE","RPC Call: remove dispatcher: $hdr(dispatcherIP)n");
Module reload in kamailio using xhttp
Application layer - stateless
We are using Asterisk as a stateless application
we use SIP headers to instruct asterisk what is the application with parameters to
execute
this makes evosip able to use multiple application services (asterisk, freeswitch, sems,
etc) without changing anything on kamailio side
router TPS
INVITE …
...
X-evosip-Action: Playback
X-evosip-Sound: mysoundfile
...
asterisk extensions.conf
[default]
exten => _X.,1,NoOP(:: dispatching requests ::)
exten => _X.,n, GotoIf($["${SIP_HEADER(X-evosip-Action)}" =
"Playback"]? playback)
exten => _X.,n,GotoIf($["${SIP_HEADER(X-evosip-Action)}" =
"Voicemail"]?voicemail)
Kamailio injects custom sip headers to
pilot the application layer and uses
dispatcher to balance requests among
TPS instances
Asterisk uses extensions modules and default context to dispatch requests
using GotoIf statement depending on the x-evosip-Action header
Application layer - stateless
We are using Asterisk as a stateless application
playback, transcoding, voicemail and other applications have its own portion of context
router TPS
INVITE …
...
X-evosip-Action: Playback
X-evosip-Sound: mysoundfile
...
asterisk extensions.conf
[default]
…
exten => _X.,n(playback),NoOp(*** Doing playback - ***)
;PATH of sound file
;${SIP_HEADER(X-evosip-SoundCustom)}${SIP_HEADER(X-evosip-SoundLocale)}
${SIP_HEADER(X-evosip-Sound)}
exten => _X.,n,SipRemoveHeader(X-evosip)
exten => _X.,n,Progress()
exten => _X.,n,Wait(1)
exten =>
_X.,n,Set(exists=${STAT(e,${ASTDATADIR}/sounds/${SIP_HEADER(X-evosip-So
undCustom)}/${SIP_HEADER(X-evosip-SoundLocale)}/${SIP_HEADER(X-evosip-S
ound)}.wav)})
exten => _X.,n,Playback(${IF($[ ${exists} = 1 ] ?
${SIP_HEADER(X-evosip-SoundCustom)}/${SIP_HEADER(X-evosip-SoundLocale)}
/${SIP_HEADER(X-evosip-Sound)},noanswer :
default/${SIP_HEADER(X-evosip-SoundLocale)}/${SIP_HEADER(X-evosip-Sound
)},noanswer)})
; exten => _X.,n,Playback(${SIP_HEADER(X-evosip-Option)},noanswer)
exten => _X.,n,Hangup()
Kamailio injects custom sip headers to
pilot the application layer and uses
dispatcher to balance requests among
TPS instances
Application layer - stateless
there is no sip trunk or peer, everything is profile-less (and uses the default context)
Connected to Asterisk 13.1.0~dfsg-1.1ubuntu4.1 currently running on tps-d768ccb6b-bnnlk (pid = 73)
tps-d768ccb6b-bnnlk*CLI> sip show peers
Name/username Host Dyn Forcerport Comedia ACL Port
Status Description
0 sip peers [Monitored: 0 online, 0 offline Unmonitored: 0 online, 0 offline]
SDP manipulations are made using context command “Set(SIP_CODEC)“
Media can be in cloud or on premise
We use RTPEngine to bridge RTP traffic
To enhance the QoE of voice / video services you are able to move closer to you this layer; less
latency, less network hops and full control of your media in your network!
In evosip rtpengine works in kubernetes using kernel module xt_RTPENGINE and scaling
automatically new instances (also on the same host)
Every node (that shares the same kernel in every container) loads at startup the xt_RTPENGINE
module and every instance, in bootstrap mode, uses the first free “table” on that node (and uses
IPTABLES inside the container to mark packets)
Media can be in cloud or on premise
example of rtp instance bootstrap bash script:
# configure iptables fw
iptables -N rtpengine 2> /dev/null
iptables -D INPUT -j rtpengine 2> /dev/null
iptables -I INPUT -j rtpengine
iptables -D rtpengine -p udp -j RTPENGINE --id " $TABLE" 2>/dev/null
iptables -I rtpengine -p udp -j RTPENGINE --id " $TABLE"
Media can be in cloud or on premise
example of rtp instance bootstrap bash script:
cat << EOF > /etc/rtpengine/rtpengine.conf
[rtpengine]
table = $TABLE
interface = $POD_PUBLIC_IP
#interface=internal/$POD_PUBLIC_IP;external/$POD_PUBLIC_IP
... snip ...
EOF
# run rtpengine
/usr/sbin/rtpengine --table=$TABLE --config-file=/etc/rtpengine/rtpengine.conf
--pidfile=/var/run/rtpengine.pid -E -f -F
/pod_scripts/disablePod.sh 99 "rtpengine crashed"
Recap
evosip is a startup project
ideas, contributions, partnership and knowledge sharing are really welcome !
What we focused on:
● scalability (auto)
● distribution
● QoE
● being ASAP (as stateless as possible)
Recap
evosip is a startup project
ideas, contributions, partnership and knowledge sharing are really welcome !
What will be in the next months:
● datacollect with ELK stack and Homer
● preemptive autoscaling with machine learning
● chaos engineering
● IPV6 protocol
Stay tuned !
Do you like concepts and examples in this speech ?
subscribe and join evosip community @ http://evosip.cloud
Articles, news, interviews, podcast and videos of the project
for free implementing the knowledge sharing!

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Scaling Asterisk with Kamailio
Scaling Asterisk with KamailioScaling Asterisk with Kamailio
Scaling Asterisk with Kamailio
 
Kamailio - Load Balancing Load Balancers
Kamailio - Load Balancing Load BalancersKamailio - Load Balancing Load Balancers
Kamailio - Load Balancing Load Balancers
 
Kamailio - Secure Communication
Kamailio - Secure CommunicationKamailio - Secure Communication
Kamailio - Secure Communication
 
Kamailio - API Based SIP Routing
Kamailio - API Based SIP RoutingKamailio - API Based SIP Routing
Kamailio - API Based SIP Routing
 
Why is Kamailio so different? An introduction.
Why is Kamailio so different? An introduction.Why is Kamailio so different? An introduction.
Why is Kamailio so different? An introduction.
 
Kamailio, FreeSWITCH, and You
Kamailio, FreeSWITCH, and YouKamailio, FreeSWITCH, and You
Kamailio, FreeSWITCH, and You
 
Using Kamailio for Scalability and Security
Using Kamailio for Scalability and SecurityUsing Kamailio for Scalability and Security
Using Kamailio for Scalability and Security
 
SIP Testing with FreeSWITCH
SIP Testing with FreeSWITCHSIP Testing with FreeSWITCH
SIP Testing with FreeSWITCH
 
Sipwise rtpengine
Sipwise rtpengineSipwise rtpengine
Sipwise rtpengine
 
Three Ways Kamailio Can Help Your FreeSWITCH Deployment
Three Ways Kamailio Can Help Your FreeSWITCH DeploymentThree Ways Kamailio Can Help Your FreeSWITCH Deployment
Three Ways Kamailio Can Help Your FreeSWITCH Deployment
 
SIPREC RTPEngine Media Forking
SIPREC RTPEngine Media ForkingSIPREC RTPEngine Media Forking
SIPREC RTPEngine Media Forking
 
Introduction to FreeSWITCH
Introduction to FreeSWITCHIntroduction to FreeSWITCH
Introduction to FreeSWITCH
 
Astricon 10 (October 2013) - SIP over WebSocket on Kamailio
Astricon 10 (October 2013) - SIP over WebSocket on KamailioAstricon 10 (October 2013) - SIP over WebSocket on Kamailio
Astricon 10 (October 2013) - SIP over WebSocket on Kamailio
 
Kamailio, FreeSWITCH, and the Half-Blood Prince
Kamailio, FreeSWITCH, and the Half-Blood PrinceKamailio, FreeSWITCH, and the Half-Blood Prince
Kamailio, FreeSWITCH, and the Half-Blood Prince
 
Media Handling in FreeSWITCH
Media Handling in FreeSWITCHMedia Handling in FreeSWITCH
Media Handling in FreeSWITCH
 
SIP Attack Handling (Kamailio World 2021)
SIP Attack Handling (Kamailio World 2021)SIP Attack Handling (Kamailio World 2021)
SIP Attack Handling (Kamailio World 2021)
 
The TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux KernelThe TCP/IP Stack in the Linux Kernel
The TCP/IP Stack in the Linux Kernel
 
Getting started with SIP Express Media Server SIP app server and SBC - workshop
Getting started with SIP Express Media Server SIP app server and SBC - workshopGetting started with SIP Express Media Server SIP app server and SBC - workshop
Getting started with SIP Express Media Server SIP app server and SBC - workshop
 
Scaling FreeSWITCH Performance
Scaling FreeSWITCH PerformanceScaling FreeSWITCH Performance
Scaling FreeSWITCH Performance
 
FreeSWITCH on Docker
FreeSWITCH on DockerFreeSWITCH on Docker
FreeSWITCH on Docker
 

Ähnlich wie Kamailio with Docker and Kubernetes

PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
grim_radical
 

Ähnlich wie Kamailio with Docker and Kubernetes (20)

Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...Anton Moldovan "Building an efficient replication system for thousands of ter...
Anton Moldovan "Building an efficient replication system for thousands of ter...
 
Import golang; struct microservice
Import golang; struct microserviceImport golang; struct microservice
Import golang; struct microservice
 
Docker Swarm secrets for creating great FIWARE platforms
Docker Swarm secrets for creating great FIWARE platformsDocker Swarm secrets for creating great FIWARE platforms
Docker Swarm secrets for creating great FIWARE platforms
 
Containers, Docker, and Microservices: the Terrific Trio
Containers, Docker, and Microservices: the Terrific TrioContainers, Docker, and Microservices: the Terrific Trio
Containers, Docker, and Microservices: the Terrific Trio
 
Docker Internet Money Gateway
Docker Internet Money GatewayDocker Internet Money Gateway
Docker Internet Money Gateway
 
Docker img-no-disclosure
Docker img-no-disclosureDocker img-no-disclosure
Docker img-no-disclosure
 
Build HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/HeartbeatBuild HA Asterisk on Microsoft Azure using DRBD/Heartbeat
Build HA Asterisk on Microsoft Azure using DRBD/Heartbeat
 
One-Man Ops
One-Man OpsOne-Man Ops
One-Man Ops
 
FIWARE Tech Summit - Docker Swarm Secrets for Creating Great FIWARE Platforms
FIWARE Tech Summit - Docker Swarm Secrets for Creating Great FIWARE PlatformsFIWARE Tech Summit - Docker Swarm Secrets for Creating Great FIWARE Platforms
FIWARE Tech Summit - Docker Swarm Secrets for Creating Great FIWARE Platforms
 
PuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into OperationsPuppetDB: Sneaking Clojure into Operations
PuppetDB: Sneaking Clojure into Operations
 
A DevOps guide to Kubernetes
A DevOps guide to KubernetesA DevOps guide to Kubernetes
A DevOps guide to Kubernetes
 
Automating the Network
Automating the NetworkAutomating the Network
Automating the Network
 
Apache Kafka - Scalable Message-Processing and more !
Apache Kafka - Scalable Message-Processing and more !Apache Kafka - Scalable Message-Processing and more !
Apache Kafka - Scalable Message-Processing and more !
 
The advantages of Arista/OVH configurations, and the technologies behind buil...
The advantages of Arista/OVH configurations, and the technologies behind buil...The advantages of Arista/OVH configurations, and the technologies behind buil...
The advantages of Arista/OVH configurations, and the technologies behind buil...
 
OpenNebulaConf 2016 - Networking, NFVs and SDNs Hands-on Workshop by Rubén S....
OpenNebulaConf 2016 - Networking, NFVs and SDNs Hands-on Workshop by Rubén S....OpenNebulaConf 2016 - Networking, NFVs and SDNs Hands-on Workshop by Rubén S....
OpenNebulaConf 2016 - Networking, NFVs and SDNs Hands-on Workshop by Rubén S....
 
ABC Present-Service-Mesh.pptx
ABC Present-Service-Mesh.pptxABC Present-Service-Mesh.pptx
ABC Present-Service-Mesh.pptx
 
End-to-end IoT solutions with Java and Eclipse IoT
End-to-end IoT solutions with Java and Eclipse IoTEnd-to-end IoT solutions with Java and Eclipse IoT
End-to-end IoT solutions with Java and Eclipse IoT
 
Containerization is more than the new Virtualization: enabling separation of ...
Containerization is more than the new Virtualization: enabling separation of ...Containerization is more than the new Virtualization: enabling separation of ...
Containerization is more than the new Virtualization: enabling separation of ...
 
Cloud Native Applications on OpenShift
Cloud Native Applications on OpenShiftCloud Native Applications on OpenShift
Cloud Native Applications on OpenShift
 
Building Hopsworks, a cloud-native managed feature store for machine learning
Building Hopsworks, a cloud-native managed feature store for machine learning Building Hopsworks, a cloud-native managed feature store for machine learning
Building Hopsworks, a cloud-native managed feature store for machine learning
 

Kürzlich hochgeladen

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Kamailio with Docker and Kubernetes

  • 1. KWC 2018 - Berlin Kamailio with Docker and Kubernetes Scale in the right way
  • 2. about me... My name is Paolo Visintin I’m passionate about telecommunications and technology, I design, develop and maintain VoIP platforms based on Kamailio and Asterisk I’m the CTO of an Italian telco operator providing internet and voice services in the Country I decided to start a new project named evosip, a cloud PaaS VoIP infrastructure built on kubernetes You can follow me: https://www.linkedin.com/in/paolo-visintin-cloudvoip/ http://evosip.cloud/
  • 3. Agenda In this speech I’d like to tell you how we created a platform that: …a platform we named evosip! ● scales with no limits ● scales fast and automatically ● is distributed ● is QoE oriented ● has no vendor lock-in ● achieve business continuity
  • 4. evosip diagram ● Kamailio proxy and “routing” layer ● Asterisk as TPS ● RTPEngine ● Custom API SIP orchestration
  • 5. evosip … from the beginning We were looking for a platform able to : ● create instances in a very fast way (couple of seconds) ● orchestrate instances between layers ● orchestrate network and policies ● works in a distributed environment Using Docker for instance deployment and Kubernetes for orchestration (container, network and policies) we found an optimal stack to start this adventure and create a really fast and mutational SIP ecosystem based on Kamailio, Asterisk and RTPEngine So we started to use containerisation and saw it was really fast and useful
  • 6. Containers … avoid network pain! If you have used containers in a classical way probably you have noticed something terrible about dealing with networking and SIP This diagram shows the classical use of networking with docker
  • 7. Containers … avoid network pain! So how could you use SIP in containers without doing NAT / bridging and avoid network issues and lack of performance ? Differences between bridge networking and [mac/ip]vlan networking …with macvlan !
  • 8. Thanks to macvlan every instance can have a direct public IP address with its own mac address It uses less CPU and provides better throughput (almost like the physical interface) Containers … avoid network pain (with macvlan)! macvlan associate to Linux Ethernet interface or sub-interface
  • 9. We also decided to separate ● data network (DB / API / etc) ● core service network (SIP / RTP) But … if you know kubernetes, you also know that a POD (a group of one or more containers with shared storage/network) by default provides a single network interface Containers with multiple networks
  • 10. with multus (https://github.com/Intel-Corp/multus-cni - a CNI plugin) you are able to do it! Containers with multiple network
  • 12. Containerized services work and scale better with stateless applications Then, how to make kamailio ASAP ? Kamailio ASAP (As Stateless As Possible) We will now focus on : ● dispatcher ● authentication ● user location ● dialogs
  • 13. We use the dispatcher module to route request from proxy layer to router layer (both are kamailio auto-scalable instances) As of the possibility of reloading the dispatcher module (e.g. autoscaling of routers) once used ds_select_dst we store the $du and callerid ($ci) in a hash table in order to re-use $du on the next request and maintain the path to the same endpoint for the call We disabled the keepalive option in dispatcher to avoid pinging endpoints We set instead short timers to handle failure_route in case of tear-down on unreachability of endpoints Kamailio ASAP - cached dispatchers
  • 14. Kamailio ASAP - cached dispatchers if ($sht(hDispatcherTps=>$ci)==$null) { # select tps from dispacher ds_select_dst("1","0"); $sht(hDispatcherTps=>$ci) = $du; } else { $du = $sht(hDispatcherTps=>$ci); }
  • 15. Kamailio ASAP - cached dispatchers if ($sht(hDispatcherTps=>$ci)==$null) { # select tps from dispacher ds_select_dst("1","0"); $sht(hDispatcherTps=>$ci) = $du; } else { $du = $sht(hDispatcherTps=>$ci); }
  • 16. How we implemented authentication in kamailio ? Kamailio ASAP - Auth module ● we call API to retrieve user profile and store it in htable ● we use pv_auth_check method to deal with authentication ● Orchestrator calls via RPC kamailio if profile changes and need to be reloaded / updated Caching authentication in this way improves performance and optimize API calls
  • 17. How we implemented authentication in kamailio ? Kamailio ASAP - Auth module route[AUTHCACHE] { if($au && $sht(auth=>$au::passwd)==$null) { # get password from API ... $var(graphql_query) = "{"query": "{ kamailio { subscriber { auth(username:"" + $au + "") { usernamen secret } } } } "}"; $http_req(body) = $var(graphql_query); http_async_query(API_QUERY_URL, "SET_PASSWD"); ... }
  • 18. How we implemented authentication in kamailio ? Kamailio ASAP - Auth module route[SET_PASSWD] { if ($http_ok && $http_rs == 200) { xlog("L_INFO", "route[SET_PASSWD]: response $http_rb)n"); jansson_get("data.kamailio.subscriber.auth.username", $http_rb, "$var(username)"); jansson_get("data.kamailio.subscriber.auth.secret", $http_rb, "$var(secret)"); xlog("L_INFO", "route[SET_PASSWD]: setting password >>>$var(secret)<<< for user >>>$var(username)<<< in shared tablen"); $sht(auth=>$var(username)::passwd) = $var(secret); } else { xlog("L_INFO", "route[HTTP_REPLY]: error $http_err)n"); } }
  • 19. How we implemented authentication in kamailio ? Kamailio ASAP - Auth module $var(user_passwd) = $sht(auth=>$au::passwd); if(!pv_auth_check("$fd", "$var(user_passwd)", "0", "1")) { auth_challenge("$fd", "1"); exit; }#end if } # end route[AUTH_ACCOUNT]
  • 20. We save in memory and share user locations using DMQ Kamailio ASAP - Usrloc module Router instance … loadmodule "dmq.so" loadmodule "usrloc.so" loadmodule "dmq_usrloc.so" #!define DMQ_SERVER_ADDRESS "sip:<pod-macvlan-ip>:5060" #!define DMQ_NOTIFICATION_ADDRESS "sip:dmq-service:5060" modparam("dmq_usrloc", "enable", 1) modparam("dmq", "multi_notify", 1) modparam("dmq", "num_workers", 4) DMQ server ... request_route { if(is_method("KDMQ")){ dmq_handle_message(); } ... As of the stateless and mutational architecture we decided to use a containerized DMQ server based on kamailio
  • 21. We thought that having tons of dialogs replicated among router instances was not the best way to achieve an unlimited scalable architecture Kamailio ASAP - Dialogs The best way to deal with dialogs in a distributed form for us is: ● every router instance deals with its own dialogs ● foreign dialogs are managed in case of tear-down or failover ● foreign dialogs have to be manager “on demand” proxy router 1 router 2 router 3 user call user call shared dialog DB dialog is saved in write-back mode from kamailio to DB user call a single dialog for specific callerid is recovererd from DB router 3
  • 22. We needed to implement an intelligent and distributed sharing of dialogs in order to work with a fast architecture mutation and failover-proof Kamailio ASAP - Dialogs ... if(has_totag()) { if(!is_known_dlg()) { # not a MINE dialog, let’s recover from DB dlg_db_load_callid("$ci"); .... dlg_manage(); } } ... Now kamailio has a new amazing method implemented in dialog module dlg_db_load_callid(“$ci”) (ref. https://github.com/kamailio/kamailio/issues/1512)
  • 23. HA and balancing edge Possible solutions in a distributed architecture? DNS ● Round-robin ● GeoIP ● short TTL
  • 24. HA and balancing edge Possible solutions in a distributed architecture? DNS ● Round-robin ● GeoIP ● short TTL application / service caching ! Anycast IP ● using dynamic routing (OSPF) ○ proxy instances ○ border routers
  • 25. HA and balancing (again in containers) We use OSPF equal cost multipath and balance hashing per source / destination packets (a session with specific client will maintain the path to the same proxy) Reducing OSPF timeouts in “area 1” gave us the possibility to converge more quickly in case of tear-down or failover call
  • 26. HA and balancing (again in containers) We use OSPF equal cost multipath and balance hashing per source / destination packets (a session with specific client will maintain the path to the same proxy) Reducing OSPF timeouts in “area 1” gave us the possibility to converge more quickly in case of tear-down or failover call
  • 27. HA and balancing (again in containers) We decided to use FRRouting (https://frrouting.org/ a fork of the famous Quagga project) both for core ospf router and for proxy instances that announce the anycast ip
  • 28. HA and balancing (again in containers) FRR configuration example FRR CORE ... interface net0 description *** OSPF MacVLAN *** ip ospf dead-interval minimal hello-multiplier 5 router ospf default-information originate always passive-interface default no passive-interface net0 no passive-interface eth0 network <MACVLAN_NET>/<MACVLAN_SUB> area 1 network <BACKBONE_NET>/<BACKBONE_SUB> area 0 ip route 0.0.0.0/0 <DEFAULT_GW> we set a short dead-interval to reach a fast convergence in “area 1” we define areas - eth0 as backbone area 0 - net0 as proxy area 1 this router is the default gateway for proxy layer
  • 29. HA and balancing (again in containers) FRR configuration example FRR PROXY ... interface eth0 description *** OSPF interface *** ip ospf area 1 ip ospf dead-interval minimal hello-multiplier 5 router ospf redistribute static passive-interface default no passive-interface eth0 ip route <proxy.ip>/32 Null0 ip route 0.0.0.0/0 <FRR_COREIP> we set a short dead-interval to reach a fast convergence in “area 1” we create the static route to Null0 to annunce the anycast ip
  • 30. Orchestrate ! And what about population of dispatchers and RTP nodes ? We wrote a kubernetes controller to notify events (create, update, delete) among the pods These notifications are sent to a "sidecar" container which in turn updates the dispatcher lists or dbtexts and call kamailio through RPC to trigger a reload
  • 31. Orchestrate ! event_route[xhttp:request] { ... if ($hu =~ "^/rpc") { xlog("L_NOTICE", "[XHTTP:REQUEST] $si ACCEPTED ***n"); jansson_get("method", "$rb", "$var(rpcMethod)"); xlog("L_NOTICE", "[XHTTP:REQUEST] RPC METHOD: $var(rpcMethod) ***n"); if($var(rpcMethod) == "dispatcher.reload") { xlog("L_NOTICE", "Reloading dispatcher listn"); python_exec("updateDispatchers"); CHECK_XHTTP_EXIT } else if($var(rpcMethod) == "rtpengine.reload") { xlog("L_NOTICE", "Reloading RTP listn"); python_exec("updateRTPs"); CHECK_XHTTP_EXIT } else if($var(rpcMethod) == "permissions.addressReload") { xlog("L_NOTICE", "Reloading address listn"); } else if($var(rpcMethod) == "remove.dispatcher") { if($hdr(dispatcherIP) != "") { xlog("L_NOTICE","RPC Call: remove dispatcher: $hdr(dispatcherIP)n"); Module reload in kamailio using xhttp
  • 32. Application layer - stateless We are using Asterisk as a stateless application we use SIP headers to instruct asterisk what is the application with parameters to execute this makes evosip able to use multiple application services (asterisk, freeswitch, sems, etc) without changing anything on kamailio side router TPS INVITE … ... X-evosip-Action: Playback X-evosip-Sound: mysoundfile ... asterisk extensions.conf [default] exten => _X.,1,NoOP(:: dispatching requests ::) exten => _X.,n, GotoIf($["${SIP_HEADER(X-evosip-Action)}" = "Playback"]? playback) exten => _X.,n,GotoIf($["${SIP_HEADER(X-evosip-Action)}" = "Voicemail"]?voicemail) Kamailio injects custom sip headers to pilot the application layer and uses dispatcher to balance requests among TPS instances Asterisk uses extensions modules and default context to dispatch requests using GotoIf statement depending on the x-evosip-Action header
  • 33. Application layer - stateless We are using Asterisk as a stateless application playback, transcoding, voicemail and other applications have its own portion of context router TPS INVITE … ... X-evosip-Action: Playback X-evosip-Sound: mysoundfile ... asterisk extensions.conf [default] … exten => _X.,n(playback),NoOp(*** Doing playback - ***) ;PATH of sound file ;${SIP_HEADER(X-evosip-SoundCustom)}${SIP_HEADER(X-evosip-SoundLocale)} ${SIP_HEADER(X-evosip-Sound)} exten => _X.,n,SipRemoveHeader(X-evosip) exten => _X.,n,Progress() exten => _X.,n,Wait(1) exten => _X.,n,Set(exists=${STAT(e,${ASTDATADIR}/sounds/${SIP_HEADER(X-evosip-So undCustom)}/${SIP_HEADER(X-evosip-SoundLocale)}/${SIP_HEADER(X-evosip-S ound)}.wav)}) exten => _X.,n,Playback(${IF($[ ${exists} = 1 ] ? ${SIP_HEADER(X-evosip-SoundCustom)}/${SIP_HEADER(X-evosip-SoundLocale)} /${SIP_HEADER(X-evosip-Sound)},noanswer : default/${SIP_HEADER(X-evosip-SoundLocale)}/${SIP_HEADER(X-evosip-Sound )},noanswer)}) ; exten => _X.,n,Playback(${SIP_HEADER(X-evosip-Option)},noanswer) exten => _X.,n,Hangup() Kamailio injects custom sip headers to pilot the application layer and uses dispatcher to balance requests among TPS instances
  • 34. Application layer - stateless there is no sip trunk or peer, everything is profile-less (and uses the default context) Connected to Asterisk 13.1.0~dfsg-1.1ubuntu4.1 currently running on tps-d768ccb6b-bnnlk (pid = 73) tps-d768ccb6b-bnnlk*CLI> sip show peers Name/username Host Dyn Forcerport Comedia ACL Port Status Description 0 sip peers [Monitored: 0 online, 0 offline Unmonitored: 0 online, 0 offline] SDP manipulations are made using context command “Set(SIP_CODEC)“
  • 35. Media can be in cloud or on premise We use RTPEngine to bridge RTP traffic To enhance the QoE of voice / video services you are able to move closer to you this layer; less latency, less network hops and full control of your media in your network! In evosip rtpengine works in kubernetes using kernel module xt_RTPENGINE and scaling automatically new instances (also on the same host) Every node (that shares the same kernel in every container) loads at startup the xt_RTPENGINE module and every instance, in bootstrap mode, uses the first free “table” on that node (and uses IPTABLES inside the container to mark packets)
  • 36. Media can be in cloud or on premise example of rtp instance bootstrap bash script: # configure iptables fw iptables -N rtpengine 2> /dev/null iptables -D INPUT -j rtpengine 2> /dev/null iptables -I INPUT -j rtpengine iptables -D rtpengine -p udp -j RTPENGINE --id " $TABLE" 2>/dev/null iptables -I rtpengine -p udp -j RTPENGINE --id " $TABLE"
  • 37. Media can be in cloud or on premise example of rtp instance bootstrap bash script: cat << EOF > /etc/rtpengine/rtpengine.conf [rtpengine] table = $TABLE interface = $POD_PUBLIC_IP #interface=internal/$POD_PUBLIC_IP;external/$POD_PUBLIC_IP ... snip ... EOF # run rtpengine /usr/sbin/rtpengine --table=$TABLE --config-file=/etc/rtpengine/rtpengine.conf --pidfile=/var/run/rtpengine.pid -E -f -F /pod_scripts/disablePod.sh 99 "rtpengine crashed"
  • 38. Recap evosip is a startup project ideas, contributions, partnership and knowledge sharing are really welcome ! What we focused on: ● scalability (auto) ● distribution ● QoE ● being ASAP (as stateless as possible)
  • 39. Recap evosip is a startup project ideas, contributions, partnership and knowledge sharing are really welcome ! What will be in the next months: ● datacollect with ELK stack and Homer ● preemptive autoscaling with machine learning ● chaos engineering ● IPV6 protocol
  • 40. Stay tuned ! Do you like concepts and examples in this speech ? subscribe and join evosip community @ http://evosip.cloud Articles, news, interviews, podcast and videos of the project for free implementing the knowledge sharing!