Merhabalar,
Bu makalemde, “Shell Script kullanarak, Systemd’de Yeni Hizmet Birimleri Nasıl Oluşturulur ve Çalıştırılır” konusunu sizlerle paylaşacağım. Sizler, sunucunuz her açıldığında, kendi oluşturduğunuz servisin çalıştırılmasını isteyebilirsiniz. Bu amaçla kendi servislerinizi nasıl oluşturacağınız konusunun ilgi çekici olacağını düşünüyorum.
Ayrıca bu makalede, systemd’deki bir “service unit”in (hizmet birimi) ne olduğu, nasıl oluşturulacağı ve çalıştırılmasıyla ilgili bilgiler de aktaracağım. Bunun yanında, “target”’ların ne olduğunu, neden onlara “collection of units” (hizmet birimleri seti) dediğimizi ve “wants” (isteklerin) ne olduğunu da basitleştirerek aktarmaya çalışacağım.
Sonrasında, önyükleme prosedüründen sonra kendi scriptimizi çalıştırmak için, yeni bir hizmet birimi oluşturup, bu hizmetten yararlanacağız.
Buradaki işlemleri, RedHat, CentOS, Ubuntu, Debian gibi birçok linux sunucu üzerinde uygulayabilirsiniz. Dağıtımlar arasında değişebilen komut karşılıklarını kullanmak koşuluyla tabi ki J Ben burada anlatacağım işlemleri, CentOS 8 sunucu üzerinde uygulayacağım.
Sunucularımızın, sunduğu hizmetleri yerine getirilebilmesi için, bu hizmetlerin sunucu önyükleme işlemi sırasında çağırılması ve farklı seviyelere ulaşması gerekir. Bazı hizmetler, bilgisayar örneğin kurtarma düzeyine (run level 0) ulaştığında ve bazıları da multi-user (çok kullanıcı) düzeyine (run level 3) ulaştığında çalıştırılmak üzere çağırılır. Bu seviyeleri, targets (hedefler) olarak düşünebilirsiniz.
Basit bir şekilde target, hizmet birimlerinden oluşan bir hizmet birimleri koleksiyondur. Örneğin, şu an bulunduğunuz target seviyenizde çalışan hizmet birimlerine göz atmak isterseniz, aşağıdaki komutu yazabilirsiniz:
systemctl –type=service
Gördüğünüz gibi, bazı servisler her zaman aktif ve “çalışıyor”, bazıları ise tek seferlik çalışıyor ve sonlanıyor (çıkılıyor-exited).
Bir hizmetin durumunu kontrol etmek istiyorsanız, şu komutu kullanabilirsiniz:
systemctl status firewalld
Enabled veya disabled durumu, bir sonraki önyükleme sırasında hizmetin kalıcı olarak yüklenip yüklenmeyeceği anlamına gelir. Öte yandan, bir hizmeti başlatmak ve durdurmak, mevcut oturumun sınırlamasına tabidir ve kalıcı değildir.
Örneğin, aşağıdaki komutlarla bunu inceleyelim.
systemctl stop firewalld
systemctl status firewalld
Firewalld.service’in çalışmadığını, ancak yine de etkin olduğunu (enabled) görebilirsiniz, bu da bir sonraki önyükleme sırasında yükleneceği anlamına gelir.
Öyleyse, gelecekte önyükleme sırasında bir hizmetin yüklenmesini istiyorsak, onu etkinleştirmeliyiz.
Aşağıdaki klasöre geçiş yapalım ve içeriğini listeleyelim.
cd /etc/systemd/system
ls -l
Birim hizmetlerinin (unit services) bazı link dosyalarını ve bir target’ın “wants” dizinlerini görebilirsiniz. Örneğin:
Önyükleme prosedürü, multi-user-target’ın (çok kullanıcılı hedefin), yüklenmesini istediği işin seviyesine ulaştığında, /etc/systemd/system/multi-user.target.wants/ adıyla dizinde listelenir.
ls -l multi-user.target.wants/
Gördüğünüz gibi yalnızca hizmetleri değil, aynı zamanda hizmet koleksiyonları olan diğer target’ları da içerir.
Şimdi çok basit bir örnekle, kendi servisimizi oluşturacağız.
isleyen.service adında yeni bir servis oluşturalım. 🙂 Ne de olsa isleyen servis ışıldar 🙂 Aşağıdaki komutla, şu an bulunduğumuz dizinde isleyen.service adında bir dosya oluşturuyoruz ve aşağıdaki satırları bu dosya içine ekliyoruz. Bu servis, örneğin bir network kartını up ya da down duruma getiren bir servis olsun çok basit anlamda.
nano isleyen.service
[Unit]
Description = Network baglantisini up duruma getirir
After = network.target
[Service]
ExecStart = /root/scripts/isleyen.sh
[Install]
WantedBy = multi-user.target
Dosyayı kaydedip, düzenleme arayüzünden çıkabiliriz. Peki bu tanımlar, ne anlama geliyor?
Yukarıdaki yapılandırma, systemd’ye bunun bir unit (hizmet tipi birimi) olduğunu, network.target‘ten sonra yüklenmesi gerektiğini söyler.
Ve sistem network.target’a girdiğinde, systemd bir hizmet olarak “/root/scripts/isleyen.sh” komutunu çağıracaktır.
[Install] bölümü, systemd’ye bu hizmetin “multi-user.target” tarafından istendiğini bildirir. Dolayısıyla, hizmetimizi etkinleştirirsek, multi-user.target.wants klasöründe, bu hizmete sembolik bir bağlantı oluşturulacaktır. Yani aşağıdaki gibi olur.
/etc/systemd/system/multi-user.target.wants/isleyen.service‘den /usr/lib/systemd/system/isleyen.service‘e sembolik bir bağlantı oluşturulur.
Devre dışı bırakıldığında bu sembolik bağlantı silinir.
Servisimizi hemen enable duruma getirelim.
systemctl enable isleyen.service
multi-user.target.wants klasöründeki sembolik bağlantının oluşturulduğunu görebiliriz. Hemen kontrol edelim.
ls -l multi-user.target.wants/
Gördüğünüz gibi “isleyen.service” bir sonraki önyükleme için hazır, ancak önce komut dosyasını da oluşturmamız gerekiyor. Ben, aşağıdaki gibi bir lokasyonda isleyen.sh adında bir script oluşturacağım. Bu script, örneğin birden fazla ethernet kartı olan sistemde, benim tanımladığım ethernet kartını, başlangıçta up ya da down edecek bir script olsun… Elbette bu örneği gerçekleştirmek için, servis oluşturmaya gerek yok. Fakat mantığı anlamanız açısından çok basit bir örnek olarak bunu gerçekleştireceğim…
cd /root
mkdir scripts
cd scripts
nano isleyen.sh
Aşağıdaki satırı bu dosya içine ekleyin ve kaydedin:
#!/bin/bash
nmcli connection up ens33
Normalde şu anda scriptimiz de hazır, fakat test etmemiz iyi olacak. Ben bu amaçla isleyen.sh dosyasına, geçici olarak aşağıdaki satırları yazacağım.
İkinci satır yerine, çalışıp çalışmadığını test etmek üzere /tmp dizini altında ServisTestDosyasi adında bir dosya oluşturacak bir komut yazıyorum.
#!/bin/bash
touch /tmp/ServisTestDosyasi
Dosyayı kaydedip kapatıyoruz ve scripti, çalıştırılabilir (executable) hale getiriyoruz.
chmod +x isleyen.sh
Artık hazırız. Bir sonraki önyüklemeye kadar beklemek istemiyorsanız (zaten etkinleştirilmişse), mevcut oturum yazarak hizmeti başlatabiliriz:
systemctl start isleyen.service
Komut dosyasının içine, “touch /tmp/ServisTestDosyasi” komutunu yazmayı seçtiyseniz, sadece işlevselliğini kontrol etmek için, bu dosyanın /tmp klasöründe oluşturulduğunu göreceksiniz.
Fakat bazı arkadaşlarmız, /tmp altında bu dosyanın oluşmadığını görecekler ve servis durumunu kontrol ettiğinde, aşağıdaki gibi bir hatayla karşılacaklar.
systemctl status isleyen.service
Hemen logları kontrol edelim.
tail -f /var/log/audit/audit.log
Permissive=0 ibaresini görebildiniz mi? Bu bize SELinux’un aktif olduğunu ve permission denied olduğu için böyle bir hata aldığını gösteriyor. SELinux durumunu kontrol edersek göreceğiz. Ben bu yüzden, birçok makalemde SELinux’u kapatmayı uygun görüyorum. 🙂
sestatus
SELinux enable durumda ve enforcing modda çalışıyor. İlerleyen makalelerimde SELinux ile ilgili detaylı bilgiler de aktaracağım.
SELinux’u disable edelim.
nano /etc/selinux/config
SELINUX=enforcing olan satırı,
SELINUX=disabled olarak değiştiriyoruz ve dosyayı kaydedip çıkıyoruz.
SELinux disable etme işlemi, sunucu restart gerektirmektedir. Bazı makalelerde, getenforce ve setenforce komutlarıyla SELinux’u kapattıklarını düşünen arkadaşlarıma rastlıyorum. Sunucu açıldığında bu ayarlar eski haline gelmekte ve yeniden yüklenmektedir. Dolayısıyla, SELinux’u tamamen kapatmanın yolu, konfigürasyon dosyasından disabled duruma getirmek ve sunucuyu restart etmektir.
Sunucumu restart ediyorum ve script içine yazmış olduğum komut ile açılış sonrası /tmp altında, isim verdiğim dosyanın oluştuğunu ve servisin zaten çalışmış olduğunu göreceğim.
reboot
Sunucum açıldı, hemen servisin durumunu kontrol ediyorum.
systemctl status isleyen.service
Başarılı bir şekilde servisimiz çalışmış.
/tmp dizinini de kontrol edelim.
ls -l /tmp
Oluşturduğum bu servisin çalıştığını gördük. isleyen.sh Script içinde, ikinci satıra yazdığım komutu ben değiştirmiyorum. Fakat siz test ettiğinizi gördükten sonra kendi istediğiniz komutları yazarak, bu dosyayı değiştirmeyi unutmayın.
Linux üzerinde, kendi servislerimizi oluşturma işlemlerimiz bu adımlardan ibaret. Çok daha ileri seviye işler için, artık kendi servislerinizi yapılandırabilirsiniz.
Yararlı olması dileğiyle.
Yusuf İşleyen