Ubuntuda SaltStacka Başlarken 17.04
SaltStack, yapılandırma dosyalarının, dağıtımların ve diğer herhangi bir şeyin otomasyonu için optimize edilmiş python tabanlı bir yapılandırma yönetim programıdır
Sürekli Entegrasyon, geliştiricilerin değiştirilmiş kodu sık sık paylaşılan depoya günde birçok kez birleştirmelerini sağlayan bir DevOps yazılım geliştirme uygulamasıdır. Her birleştirme işleminden sonra, koddaki sorunları algılamak için otomatik oluşturma ve testler yapılır. Yazılım kalitesini artırmak ve yazılımın sürekli teslimatını sağlamak için geliştiricilerin hataları hızlı bir şekilde bulmalarını ve çözmelerini sağlar. Concourse'a gidip gelmek çok kolaydır, çünkü tüm yapılandırmasını sürüm kontrolüne kontrol edilebilen bildirim dosyalarında tutar. Ayrıca, derleme bilgilerini etkileşimli olarak gösteren bir web kullanıcı arabirimi sağlar.
Tüm tekrarlarını değiştirmek için emin olun 192.0.2.1
ve ci.example.com
gerçek Vultr genel IP adresi ve gerçek alan adınızla değiştirin.
Ubuntu 16.04 Güncelleme kılavuzunu kullanarak temel sisteminizi güncelleyin . Sisteminiz güncellendikten sonra PostgreSQL'i kurmaya devam edin.
PostgreSQL bir nesne ilişkisel veritabanı sistemidir. Concourse, boru hattı verilerini bir PostgreSQL veritabanında saklar. PostgreSQL deposunu ekleyin.
echo "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt update
PostgreSQL veritabanı sunucusunu kurun.
sudo apt -y install postgresql
PostgreSQL sunucusunu başlatın ve önyükleme zamanında otomatik olarak başlamasını sağlayın.
sudo systemctl start postgresql
sudo systemctl enable postgresql
Varsayılan PostgreSQL kullanıcısının parolasını değiştirin.
sudo passwd postgres
PostgreSQL kullanıcısı olarak giriş yapın:
sudo su - postgres
Concourse CI için yeni bir PostgreSQL kullanıcısı oluşturun.
createuser concourse
Not : Varsayılan PostgreSQL kullanıcısı veritabanının kimlik doğrulaması için kullanılabilir, ancak bir üretim kurulumunda Concourse veritabanının kimlik doğrulaması için özel bir kullanıcı kullanılması önerilir.
PostgreSQL, veritabanında sorgu çalıştırmak için bir kabuk sağlar. PostgreSQL kabuğuna geçin.
psql
Yeni oluşturulan Concourse veritabanı kullanıcısı için bir şifre belirleyin.
ALTER USER concourse WITH ENCRYPTED password 'DBPassword';
Önemli : Güçlü bir parola ile değiştirin DBPassword
. Şifreyi not edin ve öğreticinin ilerleyen bölümlerinde gerekli olacaktır.
Concourse için yeni bir veritabanı oluşturun.
CREATE DATABASE concourse OWNER concourse;
Kabuktan çıkın psql
.
\q
Geçerli postgres
kullanıcıdan sudo kullanıcısına geçin .
exit
Concourse yürütülebilir dosyasının en son sürümünü indirin ve /usr/bin
doğrudan çalıştırılabilmesi için saklayın . Concourse ve Fly ikili dosyalarının en son sürümünü Concourse indirme sayfasında bulabilirsiniz . Yeni sürümler çok sık. Aşağıdaki bağlantıyı en son sürüm için yeni bağlantıyla değiştirin.
sudo wget https://github.com/concourse/concourse/releases/download/v3.10.0/concourse_linux_amd64 -O /usr/bin/concourse
Benzer şekilde, fly yürütülebilir dosyasının en son sürümünü indirin ve saklayın /usr/bin
.
sudo wget https://github.com/concourse/concourse/releases/download/v3.10.0/fly_linux_amd64 -O /usr/bin/fly
Fly, Concourse CI'nin ATC API'sine bağlanmak için kullanılan komut satırı arabirimidir. Fly, Linux, Windows ve MacOS gibi birden çok platform için kullanılabilir.
İndirilenlere concourse
ve fly
ikili dosyalara yürütme izni atayın .
sudo chmod +x /usr/bin/concourse /usr/bin/fly
Sürümlerini kontrol ederek Concourse ve Fly'in düzgün çalışıp çalışmadığını kontrol edin.
concourse -version
fly -version
RSA anahtar çiftleri, Concourse bileşenleri arasındaki iletişimi şifrelemek için bir yol sağlar.
Concourse'ın çalışması için en az üç çift anahtar üretilmelidir. Oturum verilerini şifrelemek için bir session_signing_key
. Bu anahtar TSA tarafından ATC'ye yaptığı istekleri imzalamak için de kullanılacaktır. TSA SSH sunucusunu güvenceye almak için a tsa_host_key
. Son olarak, worker_key
her işçi için bir tane oluşturun .
Concourse CI ile ilgili anahtarları ve yapılandırmayı saklamak için yeni bir dizin oluşturun.
sudo mkdir /opt/concourse
Gerekli anahtarları oluşturun.
sudo ssh-keygen -t rsa -q -N '' -f /opt/concourse/session_signing_key
sudo ssh-keygen -t rsa -q -N '' -f /opt/concourse/tsa_host_key
sudo ssh-keygen -t rsa -q -N '' -f /opt/concourse/worker_key
İçeriğini authorized_worker_keys
dosyaya kopyalayarak çalışanların ortak anahtarını yetkilendirin .
sudo cp /opt/concourse/worker_key.pub /opt/concourse/authorized_worker_keys
Concourse, başlatılması gereken iki ayrı bileşen sağlar: web ve çalışan. Concourse web'ini başlatın.
sudo concourse web \
--basic-auth-username admin \
--basic-auth-password StrongPass \
--session-signing-key /opt/concourse/session_signing_key \
--tsa-host-key /opt/concourse/tsa_host_key \
--tsa-authorized-keys /opt/concourse/authorized_worker_keys \
--postgres-user=concourse \
--postgres-password=DBPassword \
--postgres-database=concourse \
--external-url http://192.0.2.1:8080
basic-auth
İsterseniz , kullanıcı adını ve şifresini değiştirin . Anahtar dosyalarına giden yolun doğru olduğundan ve PostgreSQL veritabanı yapılandırmasında kullanıcı adı ve parola için doğru değerin sağlandığından emin olun.
Not : ATC varsayılan bağlantı noktasını 8080
dinler ve TSA bağlantı noktasını dinler 2222
. Kimlik doğrulaması istenmiyorsa, --no-really-i-dont-want-any-auth
temel kimlik doğrulama seçeneklerini kaldırdıktan sonra seçeneği iletin.
Web sunucusu başlatıldığında, aşağıdaki çıktı görüntülenir.
{"timestamp":"1503657859.661247969","source":"tsa","message":"tsa.listening","log_level":1,"data":{}}
{"timestamp":"1503657859.666907549","source":"atc","message":"atc.listening","log_level":1,"data":{"debug":"127.0.0.1:8079","http":"0.0.0.0:8080"}}
Birkaç şey daha ayarlanması gerektiği için sunucuyu şimdilik durdurun.
Concourse CI Çalışanı'nı başlatın.
sudo concourse worker \
--work-dir /opt/concourse/worker \
--tsa-host 127.0.0.1 \
--tsa-public-key /opt/concourse/tsa_host_key.pub \
--tsa-worker-private-key /opt/concourse/worker_key
Yukarıdaki komut, TSA'nın localhost üzerinde çalıştığını ve varsayılan bağlantı noktasını dinlediğini varsayacaktır 2222
.
Concourse web ve çalışanı yukarıdaki komutları kullanarak kolayca başlatılabilse de, sunucuyu yönetmek için Systemd kullanılması önerilir.
Uygulamayı yönetmek için Systemd hizmetini kullanmak, uygulamanın hatalarda ve önyükleme zamanında otomatik olarak başlatılmasını sağlar. Concourse sunucusu herhangi bir yapılandırma dosyasından veri almaz, ancak ortam değişkenlerinden verilere erişebilir. Genel ortam değişkenleri ayarlamak yerine, ortam değişkenlerini saklamak için yeni bir dosya oluşturun ve ardından bu değişkenleri Systemd hizmetini kullanarak Concourse CI'ye iletin.
Concourse web için yeni bir ortam dosyası oluşturun.
sudo nano /opt/concourse/web.env
Dosyayı doldurun.
CONCOURSE_SESSION_SIGNING_KEY=/opt/concourse/session_signing_key
CONCOURSE_TSA_HOST_KEY=/opt/concourse/tsa_host_key
CONCOURSE_TSA_AUTHORIZED_KEYS=/opt/concourse/authorized_worker_keys
CONCOURSE_POSTGRES_USER=concourse
CONCOURSE_POSTGRES_PASSWORD=DBPassword
CONCOURSE_POSTGRES_DATABASE=concourse
CONCOURSE_BASIC_AUTH_USERNAME=admin
CONCOURSE_BASIC_AUTH_PASSWORD=StrongPass
CONCOURSE_EXTERNAL_URL=http://192.0.2.1:8080
BASIC_AUTH
İsterseniz , kullanıcı adını ve şifresini değiştirin . Anahtar dosyalarına giden yolun doğru olduğundan ve PostgreSQL veritabanı yapılandırmasında kullanıcı adı ve parola için doğru değerin sağlandığından emin olun.
Benzer şekilde, çalışan için bir ortam dosyası oluşturun.
sudo nano /opt/concourse/worker.env
Dosyayı doldurun.
CONCOURSE_WORK_DIR=/opt/concourse/worker
CONCOURSE_TSA_WORKER_PRIVATE_KEY=/opt/concourse/worker_key
CONCOURSE_TSA_PUBLIC_KEY=/opt/concourse/tsa_host_key.pub
CONCOURSE_TSA_HOST=127.0.0.1
Ortam dosyaları kullanıcı adları ve parolalar içerdiğinden, izinlerini diğer kullanıcılar tarafından erişilemeyecek şekilde değiştirin.
sudo chmod 600 /opt/concourse/*.env
Şimdi Concourse'ın web ortamını çalıştırması için yeni bir kullanıcı oluşturun. Bu, web sunucusunun yalıtılmış bir ortamda çalışmasını sağlayacaktır.
sudo useradd concourse
Concourse kullanıcısına Concourse CI dosyasının dizini üzerinden sahiplik verin.
sudo chown -R concourse:concourse /opt/concourse
Concourse web hizmeti için yeni bir systemd hizmet dosyası oluşturun.
sudo nano /etc/systemd/system/concourse-web.service
Dosyayı doldurun.
[Unit]
Description=Concourse CI web server
[Service]
Type=simple
User=concourse
Group=concourse
Restart=on-failure
EnvironmentFile=/opt/concourse/web.env
ExecStart=/usr/bin/concourse web
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=concourse_web
[Install]
WantedBy=multi-user.target
Dosyayı kaydedip kapatın. Concourse çalışan hizmeti için yeni bir hizmet dosyası oluşturun.
sudo nano /etc/systemd/system/concourse-worker.service
Dosyayı doldurun.
[Unit]
Description=Concourse CI worker process
[Service]
Type=simple
Restart=on-failure
EnvironmentFile=/opt/concourse/worker.env
ExecStart=/usr/bin/concourse worker
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=concourse_worker
[Install]
WantedBy=multi-user.target
Web ve çalışan hizmeti artık doğrudan başlatılabilir.
sudo systemctl start concourse-web concourse-worker
Çalışan ve web işleminin önyükleme zamanında otomatik olarak başlamasını sağlamak için aşağıdakileri çalıştırın.
sudo systemctl enable concourse-worker concourse-web
Hizmetlerin durumunu kontrol etmek için aşağıdakileri çalıştırın.
sudo systemctl status concourse-worker concourse-web
Hizmet başlatılmamışsa veya FAILED
durumdaysa önbelleği dizinden kaldırın /tmp
.
sudo rm -rf /tmp/*
Hizmetleri yeniden başlatın.
sudo systemctl restart concourse-worker concourse-web
Bu sefer hizmetlerin doğru şekilde başladığına dikkat edin. Hizmetlerin durumunu doğruladıktan sonra çıktı aşağıdakine benzer olacaktır.
[user@vultr ~]$ sudo systemctl status concourse-worker concourse-web
● concourse-worker.service - Concourse CI worker process
Loaded: loaded (/etc/systemd/system/concourse-worker.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2017-08-26 07:27:37 UTC; 55s ago
Main PID: 3037 (concourse)
CGroup: /system.slice/concourse-worker.service
└─3037 /usr/bin/concourse worker
Aug 26 07:27:42 vultr.guest concourse_worker[3037]: {"timestamp":"1503732462.934722900","source":"tsa","message":"t...""}}
Aug 26 07:27:42 vultr.guest concourse_worker[3037]: {"timestamp":"1503732462.941227913","source":"guardian","messag...0"}}
...
● concourse-web.service - Concourse CI web server
Loaded: loaded (/etc/systemd/system/concourse-web.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2017-08-26 07:27:37 UTC; 55s ago
Main PID: 3036 (concourse)
CGroup: /system.slice/concourse-web.service
└─3036 /usr/bin/concourse web
Aug 26 07:27:57 vultr.guest concourse_web[3036]: {"timestamp":"1503732477.925554752","source":"tsa","message":"tsa...ve"}}
Aug 26 07:28:02 vultr.guest concourse_web[3036]: {"timestamp":"1503732482.925430775","source":"tsa","message":"tsa...ve"}}
...
Hint: Some lines were ellipsized, use -l to show in full.
Sunucu başlatıldıktan sonra, Concourse CI'nin web arayüzüne http://192.0.2.1:8080
herhangi bir tarayıcıdan erişilerek erişilebilir . Ortam dosyasında verilen kullanıcı adını ve şifreyi kullanarak oturum açın.
Sunucuya Fly kullanarak bağlanmak için aşağıdakileri çalıştırın.
fly -t my-ci login -c http://192.0.2.1:8080
Yukarıdaki komut, sunucuya ilk giriş için kullanılır. -t
bir hedef adı sağlamak için kullanılır. my-ci
istediğiniz herhangi bir hedef adla değiştirin . Yukarıdaki komut varsayılan ekibe giriş yapacaktır main
. Ortam dosyasında sağlanan kullanıcı adını ve şifreyi soracaktır.
Çıktı aşağıdaki gibi görünecektir.
[user@vultr ~]$ fly -t my-ci login -c http://192.0.2.1:8080
logging in to team 'main'
username: admin
password:
target saved
Hedef girişi bir gün boyunca kaydedilir. Bundan sonra süresi dolacak.
Hemen çıkış yapmak için.
fly -t my-ci logout
Fly, sunucuya ağın dışında oturum açmak için kullanılabilir, ancak yalnızca sunucunun genel bir IP adresi varsa ve ağın dışından erişilebilirse. Windows veya MacOS ikili dosyası indirme sitesinden veya sunucunun web arayüzünden indirilebilir.
Web kullanıcı arayüzü aracılığıyla Concourse sunucusuna gönderilen girişler ve diğer bilgiler güvenli değildir. Bağlantı şifreli değil. Let's Encrypt ücretsiz SSL ile bir Nginx ters proxy kurulabilir.
Nginx'i yükleyin.
sudo apt -y install nginx
Nginx'i başlatın ve önyükleme zamanında otomatik olarak başlamasını sağlayın.
sudo systemctl start nginx
sudo systemctl enable nginx
Certbot deposunu ekleyin.
sudo add-apt-repository --yes ppa:certbot/certbot
sudo apt-get update
Let's Encrypt CA'nın istemci uygulaması olan Certbot'u yükleyin.
sudo apt -y install certbot
Not : Let's Encrypt CA'dan sertifika almak için, sertifikaların oluşturulacağı etki alanı sunucuya yönlendirilmelidir. Değilse, etki alanının DNS kayıtlarında gerekli değişiklikleri yapın ve sertifika isteğini yeniden yapmadan önce DNS'nin yayılmasını bekleyin. Certbot, sertifikaları vermeden önce etki alanı yetkilisini denetler.
SSL sertifikaları oluşturun.
sudo certbot certonly --webroot -w /var/www/html -d ci.example.com
Oluşturulan sertifikaların /etc/letsencrypt/live/ci.example.com/
dizinde depolanması muhtemeldir . SSL sertifikası olarak fullchain.pem
ve özel anahtar olarak depolanacaktır privkey.pem
.
Sertifikaların şifrelenmesini 90 gün içinde sona erdirelim, bu nedenle sertifikaların otomatik yenilenmesinin cronjobs kullanılarak ayarlanması önerilir. Cron, periyodik görevleri yürütmek için kullanılan bir sistem hizmetidir.
Cron iş dosyasını açın.
sudo crontab -e
Dosyanın sonuna aşağıdaki satırı ekleyin.
30 5 * * * /usr/bin/certbot renew --quiet
Yukarıdaki cron işi her gün 05: 30'da çalışacaktır. Sertifikanın geçerlilik süresi dolmuşsa, otomatik olarak yenilenir.
Yeni bir sanal ana bilgisayar oluşturun.
sudo nano /etc/nginx/sites-available/concourse
Dosyayı doldurun.
server {
listen 80;
server_name ci.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443;
server_name ci.example.com;
ssl_certificate /etc/letsencrypt/live/ci.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ci.example.com/privkey.pem;
ssl on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/concourse.access.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
proxy_read_timeout 90;
proxy_redirect http://localhost:8080 https://ci.example.com;
}
}
Not : Gerçek alan adıyla değiştirin ci.example.com
.
Yapılandırma dosyasını etkinleştirin.
sudo ln -s /etc/nginx/sites-available/concourse /etc/nginx/sites-enabled/concourse
Concourse Web için oluşturulan Ortam dosyasını düzenleyin.
sudo nano /opt/concourse/web.env
Değerini değiştirin ve CONCOURSE_EXTERNAL_URL
dosyanın sonuna iki satır daha ekleyin.
CONCOURSE_EXTERNAL_URL=https://ci.example.com
CONCOURSE_BIND_IP=127.0.0.1
CONCOURSE_BIND_PORT=8080
Dosyayı kaydedin ve Concourse Web, Worker ve Nginx'i yeniden başlatın.
sudo systemctl restart concourse-worker concourse-web nginx
Tarayıcıya ve tarayıcıdan gönderilen tüm veriler artık SSL şifrelemeleriyle korunmaktadır.
SaltStack, yapılandırma dosyalarının, dağıtımların ve diğer herhangi bir şeyin otomasyonu için optimize edilmiş python tabanlı bir yapılandırma yönetim programıdır
Jenkins, proje geliştirme, devreye alma ve otomasyon için yaygın olarak kullanılan popüler bir açık kaynaklı CI (Sürekli Entegrasyon) aracıdır. Bu makale
SaltStack veya Salt, uzaktan yürütme, yapılandırma yönetimi, kodek uygulamak için kullanılabilen popüler bir açık kaynak yapılandırma yönetimi çözümüdür
Bir kutuyu kurma ve yapılandırma işlemini otomatikleştirmenin birçok yolu vardır. Herhangi bir nedenden dolayı, bu noktada tüm sistemimiz sadece
Yük Dengeleyici nedir Yük Dengeleyiciler uygulamanızın önünde oturur ve gelen trafiği uygulamanızın birden çok örneğine dağıtır. fo
Giriş Drone, kendi altyapınızda çalışan otomatik, sürekli bir test ve dağıtım platformudur. Drone herhangi bir dili, hizmeti destekler
SaltStack, birçok sunucuda eşzamanlı olarak işlemleri çalıştırmak için harika bir araç olsa da, bir sunucuda depolanan ana bilgisayar başına tanımlanmış yapılandırma ön ayarlarını da destekler.
Farklı Bir Sistem mi Kullanıyorsunuz? Foreman, fiziksel ve sanal sunucuların yapılandırılması ve yönetiminde size yardımcı olan ücretsiz ve açık kaynaklı bir araçtır. FOREMA
Farklı Bir Sistem mi Kullanıyorsunuz? Ansible, görevleri otomatikleştirmek için açık kaynaklı bir araçtır. Linux ve Windows sunucularınızın yapılandırmasını yönetir. İşe yarıyor
Farklı Bir Sistem mi Kullanıyorsunuz? Giriş Sürekli Entegrasyon, geliştiricilerin sık sık bir araya gelmelerini sağlayan bir DevOps yazılım geliştirme uygulamasıdır
Giriş Strider CD, açık kaynaklı bir sürekli dağıtım platformudur. Uygulama Node.js ile yazılmış ve depolama arka uç olarak MongoDB kullanır. Stride
Farklı Bir Sistem mi Kullanıyorsunuz? Ansible, görevleri otomatikleştirmek için açık kaynaklı bir araçtır. Linux ve Windows sunucularınızın yapılandırmasını yönetir. İşe yarıyor
Packer nedir? Packer, HashiCorp tarafından geliştirilen bir sunucu görüntüleme aracıdır. Sunucu görüntüleme; veya alternatif olarak değişmez altyapı; popüler bir alternatif
Giriş Chocolatey, Linux üzerinde yazılım ve bağımlılıkları yönetmeyi kolaylaştıran paket yönetimini Windowsa getiriyor. Hızlı ve kolay bir şekilde yapabilirsiniz
Farklı Bir Sistem mi Kullanıyorsunuz? Foreman, fiziksel ve sanal sunucuların yapılandırılması ve yönetiminde size yardımcı olan ücretsiz ve açık kaynaklı bir araçtır. FOREMA
Farklı Bir Sistem mi Kullanıyorsunuz? GoCD açık kaynaklı bir sürekli dağıtım ve otomasyon sistemidir. Karmaşık iş akışlarını, paralel bir
26 Büyük Veri Analitik Tekniğine Bir Bakış: 1. Bölüm
Birçoğunuz Switch'in Mart 2017'de çıkacağını ve yeni özelliklerini biliyorsunuz. Bilmeyenler için, 'Switch'i 'olmazsa olmaz bir gadget' yapan özelliklerin bir listesini hazırladık.
Teknoloji devlerinin sözlerini yerine getirmesini mi bekliyorsunuz? teslim edilmeyenleri kontrol edin.
Büyük Veri Mimarisindeki farklı katmanları ve işlevlerini en basit şekilde öğrenmek için blogu okuyun.
Yapay Zekanın küçük ölçekli şirketler arasında nasıl popüler hale geldiğini ve onları büyütme ve rakiplerine üstünlük sağlama olasılıklarını nasıl artırdığını öğrenmek için bunu okuyun.
CAPTCHA, son birkaç yılda kullanıcıların çözmesi oldukça zorlaştı. Gelecekte spam ve bot tespitinde etkili kalabilecek mi?
Bilim hızla gelişip birçok çabamızı üstlendikçe, kendimizi açıklanamaz bir Tekilliğe maruz bırakmanın riskleri de artıyor. Okuyun, tekillik bizim için ne anlama gelebilir.
Teletıp, uzaktan sağlık hizmetleri ve gelecek nesiller üzerindeki etkisi nedir? Pandemi durumunda iyi bir yer mi değil mi? Bir görünüm bulmak için blogu okuyun!
Bilgisayar korsanlarının çok para kazandığını duymuş olabilirsiniz, ancak bu kadar parayı nasıl kazandıklarını hiç merak ettiniz mi? Hadi tartışalım.
Son zamanlarda Apple, sorunları gidermek için macOS Catalina 10.15.4'ü ek bir güncelleme yayınladı, ancak güncelleme, mac makinelerinde tuğla oluşmasına neden olan daha fazla soruna neden oluyor gibi görünüyor. Daha fazla bilgi edinmek için bu makaleyi okuyun