Saturday, January 18, 2025

[Asterisk] Hướng dẫn build Asterisk chạy bằng Container

-

Docker làm cho việc cài đặt hệ thống trở nên dễ dàng và nhanh chóng. Vậy docker giúp được gì cho hệ thống VoIP. Bài viết này sẽ hướng dẫn các bạn có thể chạy Asterisk trên docker.

Docker là một dự án mã nguồn mở giúp các Developer và System Admin dễ dàng hơn trong việc tạo, triển khai và chạy ứng dụng trên nhiều nơi khác nhau như trên Windows, laptop, VPS, bằng cách sử dụng  các container. Các hãng công nghệ lớn như Google, Microsoft đã bắt đầu hỗ trợ Docker trên hệ thống và cung cấp nhiều tài liệu đào tạo Docker trên nền tảng của họ.

1. Build image.

Đầu tiên các bạn tạo file Dockerfile với nội dung như dưới

FROM centos:centos7
    RUN yum install -y python3.8 python-setuptools snmp screen vim psmisc tree git tmux cron net-tools python3-pip iputils-ping traceroute initscripts
    RUN pip3 install --upgrade pip
    RUN pip3 install paramiko jsonpath-ng requests

    RUN yum  -y install epel-release
    RUN yum -y install wget vim net-tools
    RUN yum -y groupinstall "Development Tools"
    RUN yum -y install libedit-devel sqlite-devel psmisc gmime-devel ncurses-devel libtermcap-devel sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel uuid-devel libtool libuuid-devel subversion kernel-devel kernel-devel-$(uname -r) git subversion kernel-devel crontabs cronie cronie-anacron

    RUN cd /usr/src/ \
        && wget https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.20.0.tar.gz \
        && tar -xvzf asterisk* \
        && cd asterisk* \
        && ./configure --libdir=/usr/lib64 \
        && contrib/scripts/get_mp3_source.sh \
        && make \
        && make install \
        && make samples \
        && make config \
        && ldconfig

    RUN groupadd asterisk \
        && useradd -r -d /var/lib/asterisk -g asterisk asterisk \
        && usermod -aG audio,dialout asterisk \
        && chown -R asterisk.asterisk /etc/asterisk \
        && chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk \
        && chown -R asterisk.asterisk /usr/lib64/asterisk \
        && chown -R asterisk.asterisk /var/run/asterisk \

    RUN sed -i 's|#AST_USER="asterisk"|AST_USER="asterisk"|' /etc/sysconfig/asterisk \
        && sed -i 's|#AST_GROUP="asterisk"|AST_GROUP="asterisk"|' /etc/sysconfig/asterisk \
        && sed -i 's|;runuser = asterisk|runuser = asterisk|' /etc/asterisk/asterisk.conf \
        && sed -i 's|;rungroup = asterisk|rungroup = asterisk|' /etc/asterisk/asterisk.conf \
        && sed -i 's|(!)||' /etc/asterisk/asterisk.conf \
        && sed -i 's|rtpstart=.*|rtpstart=10000|' /etc/asterisk/rtp.conf \
        && sed -i 's|rtpend=.*|rtpstart=10099|' /etc/asterisk/rtp.conf

    WORKDIR /etc/asterisk/

    RUN echo 'set number' > ~/.vimrc && echo 'syntax on' >> ~/.vimrc && echo 'highlight Comment ctermfg=LightCyan' >> ~/.vimrc && echo 'set relativenumber' >> ~/.vimrc && echo 'set shiftwidth=2' >> ~/.vimrc

    RUN echo '#!/bin/bash' > /usr/local/bin/run_asterisk \
    && echo "/etc/init.d/asterisk start" >> /usr/local/bin/run_asterisk \
    && chmod +x /usr/local/bin/run_asterisk

    ENTRYPOINT run_asterisk && /bin/bash

Sau khi tạo xong Dockerfile các bạn hãy build image từ Dockerfile vừa tạo

docker build -t asterisk:latest --force-rm -f Dockerfile .

Logs đầu ra sẽ có nội dung như dưới

Sending build context to Docker daemon  347.9MB
Step 1/15 : FROM centos:centos7
 ---> eeb6ee3f44bd
Step 2/15 : RUN yum install -y python3.8 python-setuptools snmp screen vim psmisc tree git tmux cron net-tools python3-pip iputils-ping traceroute initscripts
 ---> Using cache
 ---> 5298ad2fbdd8
Step 3/15 : RUN pip3 install --upgrade pip
 ---> Using cache
 ---> 63c7a80da4f9
Step 4/15 : RUN pip3 install paramiko jsonpath-ng requests
 ---> Using cache
 ---> 6c32037428e6
Step 5/15 : RUN yum  -y install epel-release
 ---> Using cache
 ---> ac2d4e170406
Step 6/15 : RUN yum -y install wget vim net-tools
 ---> Using cache
 ---> 037b51b9b69f
Step 7/15 : RUN yum -y groupinstall "Development Tools"
 ---> Using cache
 ---> a9e3358e7f61
Step 8/15 : RUN yum -y install libedit-devel sqlite-devel psmisc gmime-devel ncurses-devel libtermcap-devel sox newt-devel libxml2-devel libtiff-devel audiofile-devel gtk2-devel uuid-devel libtool libuuid-devel subversion kernel-devel kernel-devel-$(uname -r) git subversion kernel-devel crontabs cronie cronie-anacron
 ---> Using cache
 ---> 5b06651bef19
Step 9/15 : RUN cd /usr/src/         && wget https://downloads.asterisk.org/pub/telephony/asterisk/old-releases/asterisk-11.20.0.tar.gz         && tar -xvzf asterisk*         && cd asterisk*         && ./configure --libdir=/usr/lib64         && contrib/scripts/get_mp3_source.sh         && make         && make install         && make samples         && make config         && ldconfig
 ---> Using cache
 ---> 1b4393bc5127
Step 10/15 : RUN groupadd asterisk         && useradd -r -d /var/lib/asterisk -g asterisk asterisk         && usermod -aG audio,dialout asterisk         && chown -R asterisk.asterisk /etc/asterisk         && chown -R asterisk.asterisk /var/{lib,log,spool}/asterisk         && chown -R asterisk.asterisk /usr/lib64/asterisk         && chown -R asterisk.asterisk /var/run/asterisk
 ---> Using cache
 ---> bbfad5016e18
Step 11/15 : RUN sed -i 's|#AST_USER="asterisk"|AST_USER="asterisk"|' /etc/sysconfig/asterisk         && sed -i 's|#AST_GROUP="asterisk"|AST_GROUP="asterisk"|' /etc/sysconfig/asterisk         && sed -i 's|;runuser = asterisk|runuser = asterisk|' /etc/asterisk/asterisk.conf         && sed -i 's|;rungroup = asterisk|rungroup = asterisk|' /etc/asterisk/asterisk.conf         && sed -i 's|(!)||' /etc/asterisk/asterisk.conf         && sed -i 's|rtpstart=.*|rtpstart=10000|' /etc/asterisk/rtp.conf         && sed -i 's|rtpend=.*|rtpstart=10099|' /etc/asterisk/rtp.conf
 ---> Using cache
 ---> f3c276ced4d1
Step 12/15 : WORKDIR /etc/asterisk/
 ---> Using cache
 ---> 9e9ae11bc6f7
Step 13/15 : RUN echo 'set number' > ~/.vimrc && echo 'syntax on' >> ~/.vimrc && echo 'highlight Comment ctermfg=LightCyan' >> ~/.vimrc && echo 'set relativenumber' >> ~/.vimrc && echo 'set shiftwidth=2' >> ~/.vimrc
 ---> Using cache
 ---> 0b8409acda52
Step 14/15 : RUN echo '#!/bin/bash' > /usr/local/bin/run_asterisk     && echo "/etc/init.d/asterisk start" >> /usr/local/bin/run_asterisk     && chmod +x /usr/local/bin/run_asterisk
 ---> Using cache
 ---> bc442065edf5
Step 15/15 : ENTRYPOINT run_asterisk && /bin/bash
 ---> Using cache
 ---> 52fd0031b967
Successfully built 52fd0031b967
Successfully tagged asterisk:latest

Sau khi build xong bạn đã có 1 image asterisk:latest như dưới

$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED              SIZE
asterisk     latest    4a51839d91ee   About a minute ago   2.52GB

2. Push image.

Bây giờ các bạn có thể push image này lên 1 repository nào đó, mình sẽ sử dụng Docker Hub. Đầu tiên hãy login vào Docker Hub bằng command dưới.

docker login -u <ci_registry_user> -p <ci_registry_password>

Nếu login thành công, bạn sẽ nhận được output như vậy.

WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Bây giờ hãy đánh tag cho image bạn chuẩn bị push.

docker tag asterisk:latest <ci_registry>/asterisk:latest

Kết quả sau khi đánh tag cho image xong.

$ docker image ls
REPOSITORY            TAG       IMAGE ID       CREATED              SIZE
hoanghd164/asterisk   latest    ae1b2da89b31   About a minute ago   2.52GB

Giờ hãy dùng command dưới để push image lên Docker Hub nhé

docker push <ci_registry>/asterisk:latest

Đầu ra của bạn sẽ gần giống như vậy sau khi push xong.

The push refers to repository [docker.io/hoanghd164/asterisk]
6f0a3601676b: Pushed 
dbe9dfd85650: Pushed 
6517dc29875a: Pushed 
31a4d0d50e32: Pushed 
63d9ba95077d: Pushed 
96e058c79cd7: Pushed 
a378cc5f1e2e: Pushed 
0c965cd2bd05: Pushed 
1badbade2635: Pushed 
9899c41d36a4: Pushed 
0444cc0e78ed: Pushed 
ecdb53c0081e: Pushed 
0f1bbe31b0f3: Pushed 
174f56854903: Layer already exists 
latest: digest: sha256:905fef0aca40d2c257e63c4698f27b76ff4fe386d18b53b7742eba58c7d58e61 size: 3272

Giờ lên website của Docker Hub bạn đã thấy image của bạn đã sẵn sàng để sử dụng.

3. Sử dụng image vừa tạo xong.

Hãy tạo file docker-compose-asterisk.yaml với nội dung như dưới, bạn có thể thay đổi nội dung file theo cá nhân của bạn.

version: '3'
services:
  asterisk:
    image: <ci_registry>/asterisk:latest
    container_name: asterisk
    restart: always
    privileged: true
    ports:
     - "8080:8080/tcp"
     - "5060:5060/tcp"
     - "5060:5060/udp"
     - "10000-10099:10000-10099/udp"
    network_mode: "host" 
    stdin_open: true 
    tty: true

Bây giờ hãy sử dụng docker-compose để run file docker-compose-asterisk.yaml

$ docker-compose -f docker-compose-asterisk.yaml up -d
[+] Running 1/1
 ⠿ Container asterisk  Started

Sau khi run xong bạn đã có container sẵn sàng sử dụng như dưới.

$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS     NAMES
ebe345ba67ad   asterisk:latest   "/bin/sh -c 'run_ast…"   17 seconds ago   Up 16 seconds             asterisk

4. Kiểm tra.

Mình exec vào container vừa tạo.

docker exec -it asterisk bash

Tạo 2 sip extensions như dưới.

cat >> /etc/asterisk/sip.conf << 'OEF'
[100]
username=100
secret=1234
type=friend
host=dynamic
context=test
qualify=yes
directmedia=no
disallow=all
allow=ulaw,alaw

[101]
username=101
secret=1234
type=friend
host=dynamic
context=test
qualify=yes
directmedia=no
disallow=all
allow=ulaw,alaw
OEF

Tạo 1 asterisk dialplan để test.

cat >> /etc/asterisk/extensions.conf << 'OEF'
[test]
exten => _1XX,1,Dial(SIP/${EXTEN})
OEF

Khởi động lại dịch vụ Asterisk

$ /etc/init.d/asterisk restart
Stopping safe_asterisk:                                    [  OK  ]
Shutting down asterisk:                                    [  OK  ]
Starting asterisk: 

Sử dụng lệnh asterisk -vvvvvr để vào xem logs cuộc gọi.

$ asterisk -vvvvvr
Asterisk 11.20.0, Copyright (C) 1999 - 2013 Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Running as user 'asterisk'
Running under group 'asterisk'
Connected to Asterisk 11.20.0 currently running on kvm-node02 (pid = 165)

Sáu khi đăng ký xong các sip extensions, bạn sẽ thấy trạng thái của chúng đã online.

$ sip show peers
Name/username             Host                                    Dyn Forcerport Comedia    ACL Port     Status      Description                      
100/100                   192.168.12.63                            D  Auto (No)  No             53447    OK (1 ms)                                    
101/101                   192.168.28.54                            D  Auto (No)  No             52026    OK (10 ms)                                   
2 sip peers [Monitored: 2 online, 0 offline Unmonitored: 0 online, 0 offline]

Kết quả khi show dialplan.

$ dialplan show test
[ Context 'test' created by 'pbx_config' ]
  '_1XX' =>         1. Dial(SIP/${EXTEN})                         [pbx_config]

Như vậy là bạn đã có các line sip extensions và contex để test, bây giờ hãy thử thực hiện 1 cuộc gọi và bạn sẽ có kết quả như dưới.

  == Using SIP RTP CoS mark 5
    -- Executing [100@test:1] Dial("SIP/101-00000000", "SIP/100") in new stack
  == Using SIP RTP CoS mark 5
    -- Called SIP/100
    -- SIP/100-00000001 is ringing
       > 0x7f1e1c013e40 -- Probation passed - setting RTP source address to 192.168.12.63:63636
[Jan  5 06:28:31] NOTICE[313][C-00000000]: res_rtp_asterisk.c:4441 ast_rtp_read: Unknown RTP codec 95 received from '(null)'
    -- SIP/100-00000001 answered SIP/101-00000000
    -- Locally bridging SIP/101-00000000 and SIP/100-00000001
       > 0x7f1e9402d970 -- Probation passed - setting RTP source address to 192.168.28.54:62569
[Jan  5 06:28:31] NOTICE[313][C-00000000]: res_rtp_asterisk.c:4441 ast_rtp_read: Unknown RTP codec 95 received from '192.168.28.54:62569'
       > 0x7f1e1c013e40 -- Probation passed - setting RTP source address to 192.168.12.63:63636
  == Spawn extension (test, 100, 1) exited non-zero on 'SIP/101-00000000'

Chúc các bạn thành công.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories