{"id":35990,"date":"2025-12-06T13:40:53","date_gmt":"2025-12-06T10:40:53","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=35990"},"modified":"2025-12-06T13:40:53","modified_gmt":"2025-12-06T10:40:53","slug":"gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/","title":{"rendered":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma"},"content":{"rendered":"<p><body><\/p>\n<h2>GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma<\/h2>\n<h2>Giri\u015f<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda, uygulamalar\u0131 h\u0131zl\u0131, g\u00fcvenilir ve tekrarlanabilir bir \u015fekilde da\u011f\u0131tabilmek kritik bir ba\u015far\u0131 fakt\u00f6r\u00fcd\u00fcr. S\u00fcrekli Entegrasyon (CI) ve S\u00fcrekli Da\u011f\u0131t\u0131m (CD) pratikleri, bu hedefe ula\u015fman\u0131n temelini olu\u015fturur. Bu makalede, a\u00e7\u0131k kaynakl\u0131 ve g\u00fc\u00e7l\u00fc bir DevOps platformu olan GitLab&#8217;\u0131 kullanarak, bulut tabanl\u0131 ve y\u00f6netilen bir Kubernetes hizmeti olan DigitalOcean Managed Kubernetes (DOKS) \u00fczerinde otomatik bir CI\/CD hatt\u0131 nas\u0131l olu\u015fturulaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz. Bu entegrasyon, geli\u015ftiricilere kodlar\u0131n\u0131 h\u0131zl\u0131 bir \u015fekilde test etme, konteynerle\u015ftirme ve \u00fcretim ortam\u0131na da\u011f\u0131tma yetene\u011fi sunarak, geli\u015ftirme s\u00fcre\u00e7lerini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r ve operasyonel y\u00fck\u00fc azalt\u0131r.<\/p>\n<h3>CI\/CD Nedir?<\/h3>\n<p><strong>S\u00fcrekli Entegrasyon (Continuous Integration &#8211; CI)<\/strong>, geli\u015ftiricilerin kod de\u011fi\u015fikliklerini d\u00fczenli olarak merkezi bir depoya entegre etmelerini gerektiren bir yaz\u0131l\u0131m geli\u015ftirme uygulamas\u0131d\u0131r. Her entegrasyon, otomatik bir derleme ve test s\u00fcreci taraf\u0131ndan do\u011frulan\u0131r. Bu, hatalar\u0131n erken tespit edilmesini sa\u011flar, entegrasyon sorunlar\u0131n\u0131 azalt\u0131r ve daha tutarl\u0131 bir kod taban\u0131 olu\u015fturur.<\/p>\n<p><strong>S\u00fcrekli Da\u011f\u0131t\u0131m (Continuous Deployment &#8211; CD)<\/strong>, CI&#8217;n\u0131n bir uzant\u0131s\u0131d\u0131r ve t\u00fcm testleri ba\u015far\u0131yla ge\u00e7en kod de\u011fi\u015fikliklerinin otomatik olarak \u00fcretim ortam\u0131na da\u011f\u0131t\u0131lmas\u0131n\u0131 sa\u011flar. Bu, manuel m\u00fcdahaleyi ortadan kald\u0131r\u0131r ve yaz\u0131l\u0131m\u0131n m\u00fc\u015fterilere \u00e7ok daha h\u0131zl\u0131 ula\u015fmas\u0131n\u0131 sa\u011flar. S\u00fcrekli Teslimat (Continuous Delivery) ise, \u00fcretim ortam\u0131na otomatik da\u011f\u0131t\u0131m yerine, insan onay\u0131na tabi tutularak da\u011f\u0131t\u0131ma haz\u0131r hale getirilmesi anlam\u0131na gelir; CD, S\u00fcrekli Teslimat&#8217;\u0131n tam otomasyonlu halidir.<\/p>\n<h3>GitLab ve DigitalOcean Kubernetes&#8217;in G\u00fcc\u00fc<\/h3>\n<p><strong>GitLab<\/strong>, kod depolama, s\u00fcr\u00fcm kontrol\u00fc, proje y\u00f6netimi, CI\/CD, g\u00fcvenlik taramas\u0131 ve daha fazlas\u0131n\u0131 tek bir platformda sunan kapsaml\u0131 bir DevOps arac\u0131d\u0131r. Entegre CI\/CD motoru sayesinde, <code>.gitlab-ci.yml<\/code> dosyas\u0131 arac\u0131l\u0131\u011f\u0131yla esnek ve g\u00fc\u00e7l\u00fc otomasyon hatlar\u0131 olu\u015fturmak m\u00fcmk\u00fcnd\u00fcr.<\/p>\n<p><strong>DigitalOcean Managed Kubernetes (DOKS)<\/strong>, DigitalOcean&#8217;\u0131n sundu\u011fu, Kubernetes k\u00fcmelerini y\u00f6netmeyi kolayla\u015ft\u0131ran bir hizmettir. DOKS ile altyap\u0131 y\u00f6netimi y\u00fck\u00fcn\u00fc DigitalOcean&#8217;a b\u0131rakarak, uygulamalar\u0131n\u0131z\u0131 \u00f6l\u00e7eklenebilir ve y\u00fcksek eri\u015filebilir bir ortamda \u00e7al\u0131\u015ft\u0131rmaya odaklanabilirsiniz. Otomatik y\u00fckseltmeler, yedeklemeler ve kolay \u00f6l\u00e7ekleme gibi \u00f6zellikler, DOKS&#8217;u geli\u015ftiriciler i\u00e7in cazip bir se\u00e7enek haline getirir.<\/p>\n<p>Bu makalede, bir \u00f6rnek uygulamay\u0131 Docker kullanarak konteynerle\u015ftirecek, GitLab Container Registry&#8217;ye itecek ve ard\u0131ndan Kubernetes manifestleri arac\u0131l\u0131\u011f\u0131yla DOKS k\u00fcmesinde da\u011f\u0131tmak i\u00e7in bir GitLab CI\/CD hatt\u0131 olu\u015fturaca\u011f\u0131z.<\/p>\n<h2>\u00d6n Ko\u015fullar<\/h2>\n<p>Bu makaledeki ad\u0131mlar\u0131 takip edebilmek i\u00e7in a\u015fa\u011f\u0131daki \u00f6n ko\u015fullara sahip olman\u0131z gerekmektedir:<\/p>\n<p>*   <strong>GitLab Hesab\u0131<\/strong>: Bir GitLab hesab\u0131na sahip olman\u0131z ve yeni bir proje olu\u015fturma yetkiniz olmas\u0131.<br \/>\n*   <strong>DigitalOcean Hesab\u0131<\/strong>: Bir DigitalOcean hesab\u0131na sahip olman\u0131z ve Kubernetes k\u00fcmesi olu\u015fturma yetkiniz olmas\u0131.<br \/>\n*   <strong>Temel Docker Bilgisi<\/strong>: Dockerfile olu\u015fturma ve Docker imajlar\u0131 ile \u00e7al\u0131\u015fma konusunda temel bilgi.<br \/>\n*   <strong>Temel Kubernetes Bilgisi<\/strong>: Kubernetes kavramlar\u0131 (Pod, Deployment, Service, Namespace) hakk\u0131nda temel bilgi.<br \/>\n*   <strong><code>kubectl<\/code> Y\u00fckl\u00fc Olmas\u0131<\/strong>: Kubernetes k\u00fcmeleriyle etkile\u015fim kurmak i\u00e7in komut sat\u0131r\u0131 arac\u0131.<br \/>\n*   <strong><code>doctl<\/code> Y\u00fckl\u00fc Olmas\u0131 (\u0130ste\u011fe Ba\u011fl\u0131 ama \u00d6nerilir)<\/strong>: DigitalOcean API ile etkile\u015fim kurmak i\u00e7in komut sat\u0131r\u0131 arac\u0131.<br \/>\n*   <strong>Yerel Geli\u015ftirme Ortam\u0131<\/strong>: Uygulaman\u0131z\u0131 geli\u015ftirmek ve Docker imajlar\u0131n\u0131 yerel olarak test etmek i\u00e7in uygun bir ortam (Node.js, Python, Go vb. kurulu).<\/p>\n<h2>DigitalOcean Kubernetes (DOKS) K\u00fcmesi Olu\u015fturma<\/h2>\n<p>Uygulamam\u0131z\u0131 da\u011f\u0131taca\u011f\u0131m\u0131z temel altyap\u0131, DigitalOcean Kubernetes k\u00fcmesidir. Bu b\u00f6l\u00fcm, bir DOKS k\u00fcmesi olu\u015fturma ve <code>kubectl<\/code> arac\u0131l\u0131\u011f\u0131yla ona ba\u011flanma ad\u0131mlar\u0131n\u0131 kapsar.<\/p>\n<h3>DigitalOcean Hesap Olu\u015fturma ve API Anahtar\u0131<\/h3>\n<p>E\u011fer bir DigitalOcean hesab\u0131n\u0131z yoksa, \u00f6ncelikle bir hesap olu\u015fturman\u0131z gerekmektedir. CI\/CD hatt\u0131m\u0131z\u0131n DigitalOcean kaynaklar\u0131yla etkile\u015fim kurabilmesi i\u00e7in bir API anahtar\u0131 olu\u015fturmam\u0131z gerekecek.<br \/>\n1.  DigitalOcean kontrol paneline giri\u015f yap\u0131n.<br \/>\n2.  Sol men\u00fcden &#8220;API&#8221; b\u00f6l\u00fcm\u00fcne gidin.<br \/>\n3.  &#8220;Tokens\/Keys&#8221; sekmesinde &#8220;Generate New Token&#8221; butonuna t\u0131klay\u0131n.<br \/>\n4.  Token&#8217;a bir isim verin (\u00f6rn. <code>gitlab-ci-token<\/code>) ve &#8220;Read&#8221; ile &#8220;Write&#8221; izinlerini verin.<br \/>\n5.  Olu\u015fturulan token&#8217;\u0131 kopyalay\u0131n. Bu token&#8217;\u0131 daha sonra GitLab CI\/CD ortam de\u011fi\u015fkenlerinde kullanaca\u011f\u0131z. <strong>Bu token&#8217;\u0131 g\u00fcvende tutun ve kimseyle payla\u015fmay\u0131n.<\/strong><\/p>\n<h3>DOKS K\u00fcmesi Kurulumu<\/h3>\n<p>DOKS k\u00fcmenizi DigitalOcean kontrol paneli veya <code>doctl<\/code> komut sat\u0131r\u0131 arac\u0131 arac\u0131l\u0131\u011f\u0131yla olu\u015fturabilirsiniz. Kontrol panelini kullanmak daha g\u00f6rsel ve kolayd\u0131r.<\/p>\n<p><strong>Kontrol Paneli \u00dczerinden:<\/strong><br \/>\n1.  DigitalOcean kontrol paneline giri\u015f yap\u0131n.<br \/>\n2.  Sol men\u00fcden &#8220;Kubernetes&#8221; se\u00e7ene\u011fine t\u0131klay\u0131n.<br \/>\n3.  &#8220;Create Kubernetes Cluster&#8221; butonuna t\u0131klay\u0131n.<br \/>\n4.  K\u00fcmenizin \u00f6zelliklerini yap\u0131land\u0131r\u0131n:<br \/>\n    *   <strong>Kubernetes Version<\/strong>: En son stabil s\u00fcr\u00fcm\u00fc se\u00e7meniz \u00f6nerilir.<br \/>\n    *   <strong>Region<\/strong>: Uygulaman\u0131z\u0131n kullan\u0131c\u0131lar\u0131na en yak\u0131n b\u00f6lgeyi se\u00e7in.<br \/>\n    *   <strong>Node Pool<\/strong>: K\u00fcmenizin d\u00fc\u011f\u00fcmlerinin boyutunu ve say\u0131s\u0131n\u0131 belirleyin. Geli\u015ftirme veya k\u00fc\u00e7\u00fck projeler i\u00e7in daha k\u00fc\u00e7\u00fck ve az say\u0131da d\u00fc\u011f\u00fcmle ba\u015flayabilirsiniz (\u00f6rn. 2 vCPU, 4 GB RAM, 2 d\u00fc\u011f\u00fcm).<br \/>\n    *   <strong>Cluster Name<\/strong>: K\u00fcmenize anlaml\u0131 bir isim verin (\u00f6rn. <code>gitlab-ci-cd-cluster<\/code>).<br \/>\n5.  &#8220;Create Cluster&#8221; butonuna t\u0131klayarak k\u00fcmenizi olu\u015fturun. K\u00fcmenin olu\u015fturulmas\u0131 birka\u00e7 dakika s\u00fcrebilir.<\/p>\n<p><strong><code>doctl<\/code> Komut Sat\u0131r\u0131 \u00dczerinden (API anahtar\u0131n\u0131z\u0131 yap\u0131land\u0131rd\u0131ktan sonra):<\/strong><\/p>\n<pre><code class=\"language-bash\">doctl auth init # Bu komutla API anahtar\u0131n\u0131z\u0131 yap\u0131land\u0131r\u0131n\ndoctl kubernetes cluster create gitlab-ci-cd-cluster \\\n  --region nyc1 \\\n  --version 1.28.2-do.0 \\\n  --node-pool name=worker-pool,size=s-2vcpu-4gb,count=2<\/code><\/pre>\n<p>Bu komut, <code>nyc1<\/code> b\u00f6lgesinde <code>gitlab-ci-cd-cluster<\/code> ad\u0131nda, 1.28.2 Kubernetes s\u00fcr\u00fcm\u00fcne sahip ve <code>s-2vcpu-4gb<\/code> boyutunda iki adet d\u00fc\u011f\u00fcm i\u00e7eren bir k\u00fcme olu\u015fturur.<\/p>\n<h3><code>kubectl<\/code> ile K\u00fcmenize Ba\u011flanma<\/h3>\n<p>K\u00fcmeniz olu\u015fturulduktan sonra, yerel makinenizden <code>kubectl<\/code> arac\u0131n\u0131 kullanarak k\u00fcmenize ba\u011flanman\u0131z gerekir.<br \/>\n1.  DigitalOcean kontrol panelinde, olu\u015fturdu\u011funuz Kubernetes k\u00fcmesinin detay sayfas\u0131na gidin.<br \/>\n2.  &#8220;Actions&#8221; men\u00fcs\u00fcnden &#8220;Download Config File&#8221; se\u00e7ene\u011fine t\u0131klay\u0131n. Bu, <code>kubeconfig.yaml<\/code> dosyas\u0131n\u0131 indirecektir.<br \/>\n3.  \u0130ndirdi\u011finiz dosyay\u0131 <code>~\/.kube\/config<\/code> dosyas\u0131yla birle\u015ftirin veya ayr\u0131 bir dosya olarak kaydedip <code>KUBECONFIG<\/code> ortam de\u011fi\u015fkenini ayarlay\u0131n:<\/p>\n<pre><code class=\"language-bash\">mkdir -p ~\/.kube\n    mv path\/to\/your\/kubeconfig.yaml ~\/.kube\/config-gitlab-ci-cd\n    export KUBECONFIG=~\/.kube\/config-gitlab-ci-cd:$KUBECONFIG # Mevcut config'lerinizle birle\u015ftirin<\/code><\/pre>\n<p>4.  Ba\u011flant\u0131y\u0131 test etmek i\u00e7in a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">kubectl get nodes<\/code><\/pre>\n<p>    Bu komut, k\u00fcmenizdeki d\u00fc\u011f\u00fcmleri listelemelidir. E\u011fer d\u00fc\u011f\u00fcmleri g\u00f6r\u00fcyorsan\u0131z, <code>kubectl<\/code> ba\u015far\u0131yla yap\u0131land\u0131r\u0131lm\u0131\u015ft\u0131r.<\/p>\n<p><strong>\u00d6NEML\u0130:<\/strong> Bu <code>kubeconfig<\/code> dosyas\u0131, k\u00fcmenize tam eri\u015fim sa\u011flar. Bu dosyay\u0131 g\u00fcvende tutman\u0131z ve daha sonra GitLab CI\/CD ortam de\u011fi\u015fkenlerinde kullanmak \u00fczere base64 ile kodlanm\u0131\u015f halini alman\u0131z gerekecektir.<\/p>\n<h2>Uygulamay\u0131 Konteynerle\u015ftirme (Docker)<\/h2>\n<p>CI\/CD hatt\u0131m\u0131z\u0131n ilk ad\u0131m\u0131, uygulamam\u0131z\u0131 bir Docker imaj\u0131 haline getirmektir. Bu, uygulaman\u0131n t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131yla birlikte ta\u015f\u0131nabilir ve izole bir ortamda \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. \u00d6rnek olarak, basit bir Node.js uygulamas\u0131n\u0131 konteynerle\u015ftirelim.<\/p>\n<h3>Dockerfile Olu\u015fturma<\/h3>\n<p>Uygulama dizininizin k\u00f6k dizininde <code>Dockerfile<\/code> ad\u0131nda bir dosya olu\u015fturun:<\/p>\n<pre><code class=\"language-dockerfile\"># Node.js i\u00e7in resmi bir temel imaj kullan\nFROM node:18-alpine\n\n<h2>\u00c7al\u0131\u015fma dizinini ayarla<\/h2>\nWORKDIR \/app\n\n<h2>package.json ve package-lock.json dosyalar\u0131n\u0131 kopyala<\/h2>\n<h2>Ba\u011f\u0131ml\u0131l\u0131klar\u0131 \u00f6nbelle\u011fe almak i\u00e7in bu ad\u0131m\u0131 ayr\u0131 yap\u0131n<\/h2>\nCOPY package*.json .\/\n\n<h2>Ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckle<\/h2>\nRUN npm install\n\n<h2>Uygulama kaynak kodunu kopyala<\/h2>\nCOPY . .\n\n<h2>Uygulaman\u0131n dinleyece\u011fi portu a\u00e7\u0131\u011fa \u00e7\u0131kar<\/h2>\nEXPOSE 3000\n\n<h2>Uygulamay\u0131 ba\u015flatma komutu<\/h2>\nCMD [ \"node\", \"server.js\" ]<\/code><\/pre>\n<p>\u00d6rnek <code>server.js<\/code> dosyas\u0131:<\/p>\n<pre><code class=\"language-javascript\">const http = require('http');\n\nconst hostname = '0.0.0.0';\nconst port = 3000;\n\nconst server = http.createServer((req, res) => {\n  res.statusCode = 200;\n  res.setHeader('Content-Type', 'text\/plain');\n  res.end('Merhaba Dunya! Bu benim GitLab CI\/CD uygulamam.\\n');\n});\n\nserver.listen(port, hostname, () => {\n  console.log(<code>Sunucu http:\/\/${hostname}:${port}\/ adresinde calisiyor<\/code>);\n});<\/code><\/pre>\n<p>\u00d6rnek <code>package.json<\/code> dosyas\u0131:<\/p>\n<pre><code class=\"language-json\">{\n  \"name\": \"my-node-app\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A simple Node.js app for GitLab CI\/CD\",\n  \"main\": \"server.js\",\n  \"scripts\": {\n    \"start\": \"node server.js\"\n  },\n  \"dependencies\": {\n    \"express\": \"^4.18.2\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}<\/code><\/pre>\n<h3>Yerel Olarak Docker \u0130maj\u0131n\u0131 Test Etme<\/h3>\n<p>Dockerfile&#8217;\u0131n\u0131z\u0131 olu\u015fturduktan sonra, yerel makinenizde imaj\u0131 derleyip \u00e7al\u0131\u015ft\u0131rarak uygulaman\u0131z\u0131n konteyner i\u00e7inde do\u011fru \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olun.<\/p>\n<p>1.  Uygulama dizininizde terminali a\u00e7\u0131n.<br \/>\n2.  Docker imaj\u0131n\u0131 derleyin:<\/p>\n<pre><code class=\"language-bash\">docker build -t my-node-app:latest .<\/code><\/pre>\n<p>3.  Derlenen imaj\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre><code class=\"language-bash\">docker run -p 8080:3000 my-node-app:latest<\/code><\/pre>\n<p>4.  Taray\u0131c\u0131n\u0131zda <code>http:\/\/localhost:8080<\/code> adresine giderek uygulaman\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 do\u011frulay\u0131n.<\/p>\n<h2>GitLab Projesi Kurulumu<\/h2>\n<p>Uygulama kodumuzu ve CI\/CD yap\u0131land\u0131rmam\u0131z\u0131 GitLab&#8217;da bar\u0131nd\u0131raca\u011f\u0131z.<\/p>\n<h3>Yeni Bir GitLab Projesi Olu\u015fturma<\/h3>\n<p>1.  GitLab hesab\u0131n\u0131za giri\u015f yap\u0131n.<br \/>\n2.  Sol men\u00fcden &#8220;Projects&#8221; > &#8220;Your projects&#8221; yolunu izleyin veya do\u011frudan sa\u011f \u00fcstteki &#8220;New project&#8221; butonuna t\u0131klay\u0131n.<br \/>\n3.  &#8220;Create blank project&#8221; se\u00e7ene\u011fini se\u00e7in.<br \/>\n4.  Projenize bir isim verin (\u00f6rn. <code>gitlab-doks-ci-cd<\/code>).<br \/>\n5.  G\u00f6r\u00fcn\u00fcrl\u00fck seviyesini (Public, Internal, Private) se\u00e7in.<br \/>\n6.  &#8220;Create project&#8221; butonuna t\u0131klay\u0131n.<\/p>\n<h3>Uygulama Kodunu GitLab&#8217;a Y\u00fckleme<\/h3>\n<p>Yerel uygulama kodunuzu yeni olu\u015fturdu\u011funuz GitLab projesine push edin.<\/p>\n<pre><code class=\"language-bash\"># Yerel Git deposu ba\u015flatma (e\u011fer hen\u00fcz yapmad\u0131ysan\u0131z)\ngit init\n\n<h2>Dosyalar\u0131 ekle<\/h2>\ngit add .\n\n<h2>\u0130lk commit'i yap<\/h2>\ngit commit -m \"Initial commit of Node.js app\"\n\n<h2>GitLab projenizin URL'sini uzak depo olarak ekle<\/h2>\ngit remote add origin https:\/\/gitlab.com\/your-username\/gitlab-doks-ci-cd.git # Kendi URL'nizle de\u011fi\u015ftirin\n\n<h2>Kodu GitLab'a push et<\/h2>\ngit push -u origin master<\/code><\/pre>\n<p>Art\u0131k uygulama kodunuz GitLab&#8217;da bar\u0131nd\u0131r\u0131l\u0131yor.<\/p>\n<h2>GitLab Container Registry Kullan\u0131m\u0131<\/h2>\n<p>GitLab, her projeye entegre bir Container Registry (Docker Registry) sunar. Bu, Docker imajlar\u0131n\u0131z\u0131 depolamak ve y\u00f6netmek i\u00e7in harici bir hizmete ihtiya\u00e7 duymadan GitLab i\u00e7inde kalman\u0131z\u0131 sa\u011flar.<\/p>\n<h3>Container Registry&#8217;nin \u00d6nemi<\/h3>\n<p>CI\/CD hatt\u0131m\u0131zda Docker imajlar\u0131 olu\u015fturduktan sonra, bu imajlar\u0131 Kubernetes k\u00fcmemizin eri\u015febilece\u011fi bir yere depolamam\u0131z gerekir. GitLab Container Registry, bu ama\u00e7 i\u00e7in idealdir. \u0130majlar\u0131 burada depolayarak, Kubernetes Deployment manifestlerimizde do\u011frudan GitLab Registry&#8217;den \u00e7ekebiliriz. Bu, g\u00fcvenlik ve entegrasyon a\u00e7\u0131s\u0131ndan b\u00fcy\u00fck avantaj sa\u011flar.<\/p>\n<h3>Kimlik Do\u011frulama ve \u0130maj Y\u00fckleme<\/h3>\n<p>GitLab CI\/CD hatt\u0131m\u0131z, GitLab Container Registry&#8217;ye kimlik do\u011frulamas\u0131 yaparak imajlar\u0131 y\u00fckleyecektir. CI\/CD i\u015fleri, varsay\u0131lan olarak <code>CI_REGISTRY_USER<\/code> (genellikle <code>gitlab-ci-token<\/code>) ve <code>CI_REGISTRY_PASSWORD<\/code> (i\u015fe \u00f6zel token) ortam de\u011fi\u015fkenleri arac\u0131l\u0131\u011f\u0131yla Registry&#8217;ye eri\u015fim sa\u011flar.<\/p>\n<p>Bir imaj\u0131 GitLab Container Registry&#8217;ye y\u00fcklemek i\u00e7in, \u00f6nce <code>docker login<\/code> komutuyla kimlik do\u011frulamas\u0131 yapman\u0131z ve ard\u0131ndan <code>docker push<\/code> komutunu kullanman\u0131z gerekir. CI\/CD hatt\u0131m\u0131zda bu ad\u0131mlar otomatik olarak ger\u00e7ekle\u015ftirilecektir.<\/p>\n<p>GitLab Container Registry adresi genellikle <code>registry.gitlab.com\/your-username\/your-project-name<\/code> \u015feklindedir. GitLab CI\/CD i\u00e7inde bu adres <code>CI_REGISTRY<\/code> ve <code>CI_REGISTRY_IMAGE<\/code> de\u011fi\u015fkenleriyle otomatik olarak sa\u011flan\u0131r.<\/p>\n<h2>Kubernetes Da\u011f\u0131t\u0131m Manifestleri Olu\u015fturma<\/h2>\n<p>Uygulamam\u0131z\u0131 Kubernetes k\u00fcmesinde da\u011f\u0131tmak i\u00e7in Kubernetes manifest dosyalar\u0131 (YAML) olu\u015fturmam\u0131z gerekir. Bu dosyalar, uygulaman\u0131z\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131r\u0131laca\u011f\u0131n\u0131, nas\u0131l eri\u015filece\u011fini ve nas\u0131l \u00f6l\u00e7eklenece\u011fini tan\u0131mlar. Uygulama kodunuzun k\u00f6k dizininde <code>.k8s<\/code> ad\u0131nda bir dizin olu\u015fturup manifest dosyalar\u0131n\u0131 buraya yerle\u015ftirebilirsiniz.<\/p>\n<h3>Namespace Tan\u0131mlama (\u0130ste\u011fe Ba\u011fl\u0131 ama \u00d6nerilir)<\/h3>\n<p>Uygulamalar\u0131n\u0131z\u0131 izole etmek ve kaynaklar\u0131 daha iyi y\u00f6netmek i\u00e7in bir Namespace olu\u015fturmak iyi bir pratiktir.<br \/>\n<strong><code>.k8s\/namespace.yaml<\/code>:<\/strong><\/p>\n<pre><code class=\"language-yaml\">apiVersion: v1\nkind: Namespace\nmetadata:\n  name: my-app-namespace<\/code><\/pre>\n<h3>Deployment Manifesti<\/h3>\n<p>Deployment, uygulaman\u0131z\u0131n Pod&#8217;lar\u0131n\u0131 y\u00f6netir ve bunlar\u0131n k\u00fcmenizde istenen durumda \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar.<br \/>\n<strong><code>.k8s\/deployment.yaml<\/code>:<\/strong><\/p>\n<pre><code class=\"language-yaml\">apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: my-node-app-deployment\n  namespace: my-app-namespace # Namespace belirtin\n  labels:\n    app: my-node-app\nspec:\n  replicas: 2 # Uygulaman\u0131z\u0131n 2 kopyas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n\n  selector:\n    matchLabels:\n      app: my-node-app\n  template:\n    metadata:\n      labels:\n        app: my-node-app\n    spec:\n      containers:\n      - name: my-node-app\n        image: registry.gitlab.com\/your-username\/gitlab-doks-ci-cd:latest # CI\/CD ile g\u00fcncellenecek\n        ports:\n        - containerPort: 3000\n        resources: # Kaynak limitleri ve istekleri tan\u0131mlay\u0131n (iyi bir pratik)\n          requests:\n            memory: \"64Mi\"\n            cpu: \"100m\"\n          limits:\n            memory: \"128Mi\"\n            cpu: \"200m\"<\/code><\/pre>\n<p><strong>\u00d6NEML\u0130:<\/strong> <code>image<\/code> alan\u0131n\u0131 kendi GitLab Container Registry adresinizle g\u00fcncelleyin. CI\/CD hatt\u0131 bu <code>latest<\/code> etiketi yerine commit SHA veya dinamik bir etiket kullanacakt\u0131r.<\/p>\n<h3>Service Manifesti<\/h3>\n<p>Service, Pod&#8217;lar\u0131n\u0131za a\u011f eri\u015fimi sa\u011flar. D\u0131\u015far\u0131dan eri\u015fim i\u00e7in <code>NodePort<\/code> veya <code>LoadBalancer<\/code> tipi bir Service kullanabiliriz. DOKS \u00fczerinde <code>LoadBalancer<\/code> tipi kullanmak, DigitalOcean&#8217;\u0131n otomatik olarak bir Load Balancer sa\u011flamas\u0131n\u0131 ve uygulaman\u0131za d\u0131\u015far\u0131dan bir IP adresi atamas\u0131n\u0131 sa\u011flar.<br \/>\n<strong><code>.k8s\/service.yaml<\/code>:<\/strong><\/p>\n<pre><code class=\"language-yaml\">apiVersion: v1\nkind: Service\nmetadata:\n  name: my-node-app-service\n  namespace: my-app-namespace\n  labels:\n    app: my-node-app\nspec:\n  selector:\n    app: my-node-app\n  type: LoadBalancer # D\u0131\u015far\u0131dan eri\u015fim i\u00e7in DigitalOcean Load Balancer sa\u011flar\n  ports:\n    - protocol: TCP\n      port: 80 # Servisin dinleyece\u011fi port\n      targetPort: 3000 # Pod'un dinledi\u011fi port<\/code><\/pre>\n<h3>Ingress Manifesti (\u0130ste\u011fe Ba\u011fl\u0131)<\/h3>\n<p>Daha geli\u015fmi\u015f y\u00f6nlendirme, SSL sonland\u0131rma ve birden fazla servisi tek bir alan ad\u0131 alt\u0131nda y\u00f6netmek i\u00e7in Ingress kullanabilirsiniz. Ingress kullanabilmek i\u00e7in k\u00fcmenizde bir Ingress Controller (\u00f6rn. Nginx Ingress Controller) kurulu olmas\u0131 gerekir. Bu kurulum DigitalOcean&#8217;da genellikle tek t\u0131kla yap\u0131labilir veya manuel olarak eklenebilir. Bu makalede <code>LoadBalancer<\/code> Service kullanaca\u011f\u0131m\u0131z i\u00e7in Ingress&#8217;i atlayabiliriz, ancak \u00fcretim ortamlar\u0131 i\u00e7in Ingress daha esnek bir \u00e7\u00f6z\u00fcmd\u00fcr.<\/p>\n<h2>GitLab CI\/CD Pipeline (.gitlab-ci.yml) Yap\u0131land\u0131rmas\u0131<\/h2>\n<p>Bu b\u00f6l\u00fcm, projemizin k\u00f6k dizininde <code>.gitlab-ci.yml<\/code> dosyas\u0131n\u0131 olu\u015fturarak CI\/CD hatt\u0131m\u0131z\u0131 tan\u0131mlayaca\u011f\u0131m\u0131z en kritik k\u0131s\u0131md\u0131r. Bu dosya, GitLab Runner&#8217;lar\u0131n hangi ad\u0131mlar\u0131 hangi s\u0131rada ger\u00e7ekle\u015ftirece\u011fini belirler.<\/p>\n<h3>Pipeline A\u015famalar\u0131 (Stages)<\/h3>\n<p>CI\/CD hatt\u0131m\u0131z\u0131 mant\u0131ksal a\u015famalara ay\u0131rmak, s\u00fcreci daha anla\u015f\u0131l\u0131r ve y\u00f6netilebilir k\u0131lar. Genellikle <code>build<\/code>, <code>test<\/code> ve <code>deploy<\/code> a\u015famalar\u0131 kullan\u0131l\u0131r.<\/p>\n<pre><code class=\"language-yaml\">stages:\n  - build\n  - deploy<\/code><\/pre>\n<h3>Build A\u015famas\u0131: Docker \u0130maj\u0131 Olu\u015fturma ve Y\u00fckleme<\/h3>\n<p>Bu a\u015famada, uygulama kodumuzdan bir Docker imaj\u0131 olu\u015fturacak ve bunu GitLab Container Registry&#8217;ye y\u00fckleyece\u011fiz. <code>docker:dind<\/code> (Docker-in-Docker) hizmetini kullanarak bir Docker ortam\u0131 sa\u011flar\u0131z.<\/p>\n<pre><code class=\"language-yaml\">build-image:\n  stage: build\n  image: docker:latest # Bu i\u015f i\u00e7in Docker CLI i\u00e7eren bir imaj kullan\n  services:\n    - docker:dind # Docker-in-Docker hizmetini etkinle\u015ftir\n  variables:\n    DOCKER_HOST: tcp:\/\/docker:2375 # DIND servisine ba\u011flanmak i\u00e7in\n    DOCKER_TLS_CERTDIR: \"\" # TLS'i devre d\u0131\u015f\u0131 b\u0131rak (g\u00fcvenli de\u011fil, sadece \u00f6rnek i\u00e7in)\n    # Production ortam\u0131nda TLS kullanmal\u0131 ve DOCKER_TLS_CERTDIR'i yap\u0131land\u0131rmal\u0131s\u0131n\u0131z\n  before_script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n  script:\n    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .\n    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA\n    - docker tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA $CI_REGISTRY_IMAGE:latest # latest etiketini de g\u00fcncelleyin\n    - docker push $CI_REGISTRY_IMAGE:latest\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"master\" # Sadece master branch'ine yap\u0131lan push'larda \u00e7al\u0131\u015ft\u0131r<\/code><\/pre>\n<p><strong>A\u00e7\u0131klama:<\/strong><br \/>\n*   <code>image: docker:latest<\/code>: Bu i\u015fin \u00e7al\u0131\u015faca\u011f\u0131 Docker imaj\u0131n\u0131 belirtir.<br \/>\n*   <code>services: - docker:dind<\/code>: \u0130\u015f i\u00e7inde Docker komutlar\u0131n\u0131 \u00e7al\u0131\u015ft\u0131rabilmek i\u00e7in bir Docker daemon&#8217;\u0131 sa\u011flar.<br \/>\n*   <code>variables<\/code>: <code>DOCKER_HOST<\/code> ve <code>DOCKER_TLS_CERTDIR<\/code> DIND servisiyle ileti\u015fim kurmak i\u00e7in ayarlan\u0131r.<br \/>\n*   <code>before_script<\/code>: GitLab Container Registry&#8217;ye kimlik do\u011frulamas\u0131 yapar. <code>$CI_REGISTRY_USER<\/code> ve <code>$CI_REGISTRY_PASSWORD<\/code> GitLab taraf\u0131ndan otomatik olarak sa\u011flanan gizli de\u011fi\u015fkenlerdir.<br \/>\n*   <code>script<\/code>:<br \/>\n    *   <code>docker build<\/code>: Uygulamam\u0131z\u0131n Dockerfile&#8217;\u0131ndan bir imaj derler. <code>$CI_REGISTRY_IMAGE<\/code> de\u011fi\u015fkeni GitLab Registry&#8217;deki projemizin imaj yolunu i\u00e7erir (\u00f6rn. <code>registry.gitlab.com\/your-username\/your-project<\/code>). <code>$CI_COMMIT_SHORT_SHA<\/code> ise mevcut commit&#8217;in k\u0131sa SHA de\u011feridir ve imaj\u0131 benzersiz bir \u015fekilde etiketlemek i\u00e7in kullan\u0131l\u0131r.<br \/>\n    *   <code>docker push<\/code>: Derlenen imaj\u0131 GitLab Container Registry&#8217;ye y\u00fckler.<br \/>\n    *   <code>docker tag<\/code>: <code>latest<\/code> etiketini de mevcut imaja i\u015faret edecek \u015fekilde g\u00fcnceller.<br \/>\n    *   <code>docker push<\/code>: <code>latest<\/code> etiketli imaj\u0131 da y\u00fckler.<br \/>\n*   <code>rules<\/code>: Bu i\u015fin ne zaman \u00e7al\u0131\u015faca\u011f\u0131n\u0131 belirler. Burada sadece <code>master<\/code> (veya <code>main<\/code>) dal\u0131na yap\u0131lan commit&#8217;lerde \u00e7al\u0131\u015fmas\u0131 sa\u011flanm\u0131\u015ft\u0131r.<\/p>\n<h3>Deploy A\u015famas\u0131: Kubernetes&#8217;e Da\u011f\u0131t\u0131m<\/h3>\n<p>Bu a\u015famada, olu\u015fturdu\u011fumuz Docker imaj\u0131n\u0131 Kubernetes k\u00fcmemize da\u011f\u0131taca\u011f\u0131z. Bunun i\u00e7in <code>kubectl<\/code> komutlar\u0131n\u0131 kullanaca\u011f\u0131z.<\/p>\n<pre><code class=\"language-yaml\">deploy-to-kubernetes:\n  stage: deploy\n  image: bitnami\/kubectl:latest # kubectl arac\u0131 i\u00e7eren bir imaj kullan\n  before_script:\n    # Kubeconfig dosyas\u0131n\u0131 base64'ten \u00e7\u00f6zerek ge\u00e7ici bir dosyaya yaz\n    - echo $KUBECONFIG_BASE64 | base64 -d > kubeconfig.yaml\n    - export KUBECONFIG=$(pwd)\/kubeconfig.yaml # kubectl'in bu dosyay\u0131 kullanmas\u0131n\u0131 sa\u011fla\n    - kubectl config use-context $(kubectl config get-contexts -o name | grep -E 'gitlab-ci-cd-cluster|do-nyc1-gitlab-ci-cd-cluster' | head -n 1) # K\u00fcmenizin context ad\u0131n\u0131 dinamik olarak bulmaya \u00e7al\u0131\u015f\u0131r\n    - kubectl get nodes # Ba\u011flant\u0131y\u0131 test etmek i\u00e7in\n  script:\n    # Namespace olu\u015ftur (e\u011fer yoksa)\n    - kubectl apply -f .k8s\/namespace.yaml || true # Hata verirse devam et\n    # Deployment manifestindeki imaj etiketini g\u00fcncelle\n    - sed -i \"s|image: registry.gitlab.com\/your-username\/gitlab-doks-ci-cd:latest|image: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA|g\" .k8s\/deployment.yaml\n    # Kubernetes manifestlerini uygula\n    - kubectl apply -f .k8s\/\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"master\"\n  environment:\n    name: production\n    url: http:\/\/my-node-app-service.my-app-namespace.svc.cluster.local # Bu URL k\u00fcme i\u00e7i eri\u015fim i\u00e7in, d\u0131\u015far\u0131dan eri\u015fim i\u00e7in LoadBalancer IP'sini kullan\u0131n<\/code><\/pre>\n<p><strong>A\u00e7\u0131klama:<\/strong><br \/>\n*   <code>image: bitnami\/kubectl:latest<\/code>: <code>kubectl<\/code> arac\u0131n\u0131 i\u00e7eren bir Docker imaj\u0131 kullan\u0131r.<br \/>\n*   <code>before_script<\/code>:<br \/>\n    *   <code>KUBECONFIG_BASE64<\/code> ad\u0131nda bir GitLab CI\/CD ortam de\u011fi\u015fkeni tan\u0131mlayaca\u011f\u0131z. Bu de\u011fi\u015fken, base64 ile kodlanm\u0131\u015f Kubernetes <code>kubeconfig<\/code> dosyam\u0131z\u0131 i\u00e7erecek. Burada bu de\u011fi\u015fkeni \u00e7\u00f6z\u00fcp ge\u00e7ici bir dosyaya yazar\u0131z.<br \/>\n    *   <code>export KUBECONFIG<\/code>: <code>kubectl<\/code>&#8216;in bu ge\u00e7ici dosyay\u0131 kullanmas\u0131n\u0131 sa\u011flar.<br \/>\n    *   <code>kubectl config use-context<\/code>: K\u00fcmenizin do\u011fru context&#8217;ini se\u00e7er. DigitalOcean&#8217;da context ad\u0131 genellikle <code>do-b\u00f6lge-k\u00fcmead\u0131<\/code> format\u0131ndad\u0131r.<br \/>\n    *   <code>kubectl get nodes<\/code>: K\u00fcme ba\u011flant\u0131s\u0131n\u0131n ba\u015far\u0131l\u0131 olup olmad\u0131\u011f\u0131n\u0131 kontrol eder.<br \/>\n*   <code>script<\/code>:<br \/>\n    *   <code>kubectl apply -f .k8s\/namespace.yaml || true<\/code>: Namespace&#8217;i olu\u015fturur. E\u011fer zaten varsa hata vermesini engellemek i\u00e7in <code>|| true<\/code> eklenmi\u015ftir.<br \/>\n    *   <code>sed -i \"s|...|...|g\" .k8s\/deployment.yaml<\/code>: Bu komut, <code>deployment.yaml<\/code> dosyas\u0131ndaki Docker imaj etiketini dinamik olarak, <code>build<\/code> a\u015famas\u0131nda olu\u015fturdu\u011fumuz ve <code>$CI_COMMIT_SHORT_SHA<\/code> ile etiketledi\u011fimiz imajla g\u00fcnceller. <strong><code>your-username\/gitlab-doks-ci-cd<\/code> k\u0131sm\u0131n\u0131 kendi projenizin yoluyla g\u00fcncellemeyi unutmay\u0131n!<\/strong><br \/>\n    *   <code>kubectl apply -f .k8s\/<\/code>: <code>.k8s<\/code> dizinindeki t\u00fcm manifest dosyalar\u0131n\u0131 Kubernetes k\u00fcmesine uygular. Bu, Deployment ve Service&#8217;i olu\u015fturur veya g\u00fcnceller.<br \/>\n*   <code>rules<\/code>: Sadece <code>master<\/code> dal\u0131na yap\u0131lan push&#8217;larda \u00e7al\u0131\u015f\u0131r.<br \/>\n*   <code>environment<\/code>: GitLab UI&#8217;da da\u011f\u0131t\u0131m\u0131n hangi ortama yap\u0131ld\u0131\u011f\u0131n\u0131 ve ilgili URL&#8217;yi g\u00f6sterir.<\/p>\n<h3>GitLab CI\/CD Ortam De\u011fi\u015fkenleri ve Gizlilik Y\u00f6netimi<\/h3>\n<p>CI\/CD hatt\u0131m\u0131z\u0131n g\u00fcvenli bir \u015fekilde \u00e7al\u0131\u015fabilmesi i\u00e7in hassas bilgileri (kubeconfig, Docker kimlik bilgileri vb.) ortam de\u011fi\u015fkenleri olarak saklamam\u0131z gerekir. GitLab, bunu &#8220;Settings&#8221; > &#8220;CI\/CD&#8221; > &#8220;Variables&#8221; alt\u0131nda y\u00f6netmenize olanak tan\u0131r.<\/p>\n<p><strong>Gerekli De\u011fi\u015fkenler:<\/strong><\/p>\n<p>1.  <strong><code>KUBECONFIG_BASE64<\/code><\/strong>:<br \/>\n    *   <strong>De\u011fer<\/strong>: DigitalOcean k\u00fcmenizden indirdi\u011finiz <code>kubeconfig.yaml<\/code> dosyas\u0131n\u0131n base64 ile kodlanm\u0131\u015f hali.<\/p>\n<pre><code class=\"language-bash\">base64 -w 0 ~\/.kube\/config-gitlab-ci-cd # macOS\/Linux i\u00e7in\n        # veya PowerShell'de: [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes(\"C:\\path\\to\\kubeconfig.yaml\"))<\/code><\/pre>\n<p>    *   <strong>Tip<\/strong>: File (\u00f6nerilir) veya Variable<br \/>\n    *   <strong>Masked<\/strong>: Evet (gizli tutmak i\u00e7in)<br \/>\n    *   <strong>Protected<\/strong>: Evet (sadece korumal\u0131 dallar ve etiketler i\u00e7in)<\/p>\n<p>2.  <strong><code>DOCKER_USERNAME<\/code><\/strong> ve <strong><code>DOCKER_PASSWORD<\/code><\/strong>: GitLab Container Registry&#8217;ye manuel olarak login olman\u0131z gerekirse kullanabilirsiniz, ancak <code>$CI_REGISTRY_USER<\/code> ve <code>$CI_REGISTRY_PASSWORD<\/code> genellikle yeterlidir. E\u011fer harici bir registry kullan\u0131yorsan\u0131z bu de\u011fi\u015fkenleri tan\u0131mlaman\u0131z gerekir.<\/p>\n<p>Bu de\u011fi\u015fkenleri GitLab projenizin &#8220;Settings&#8221; > &#8220;CI\/CD&#8221; > &#8220;Variables&#8221; b\u00f6l\u00fcm\u00fcne eklemeyi unutmay\u0131n. <code>KUBECONFIG_BASE64<\/code> de\u011fi\u015fkenini kesinlikle <code>Masked<\/code> olarak i\u015faretleyin.<\/p>\n<h2>CI\/CD Pipeline&#8217;\u0131 Test Etme<\/h2>\n<p>T\u00fcm yap\u0131land\u0131rmalar\u0131 tamamlad\u0131ktan sonra, CI\/CD hatt\u0131m\u0131z\u0131n beklendi\u011fi gibi \u00e7al\u0131\u015f\u0131p \u00e7al\u0131\u015fmad\u0131\u011f\u0131n\u0131 test etme zaman\u0131.<\/p>\n<h3>De\u011fi\u015fiklikleri Push Etme<\/h3>\n<p><code>.gitlab-ci.yml<\/code> ve <code>.k8s<\/code> dizinindeki manifest dosyalar\u0131n\u0131 GitLab projenize push edin:<\/p>\n<pre><code class=\"language-bash\">git add .gitlab-ci.yml .k8s\/\ngit commit -m \"Add GitLab CI\/CD pipeline and Kubernetes manifests\"\ngit push origin master # Veya hangi dal\u0131 kullan\u0131yorsan\u0131z<\/code><\/pre>\n<p>Bu push i\u015flemi, GitLab&#8217;da otomatik olarak bir pipeline tetikleyecektir.<\/p>\n<h3>Pipeline \u00c7al\u0131\u015fmas\u0131n\u0131 \u0130zleme<\/h3>\n<p>1.  GitLab projenize gidin.<br \/>\n2.  Sol men\u00fcden &#8220;CI\/CD&#8221; > &#8220;Pipelines&#8221; se\u00e7ene\u011fine t\u0131klay\u0131n.<br \/>\n3.  Yeni tetiklenen pipeline&#8217;\u0131 g\u00f6receksiniz. \u00dczerine t\u0131klayarak detaylar\u0131na gidin.<br \/>\n4.  Pipeline&#8217;daki her bir i\u015fin (build-image, deploy-to-kubernetes) durumunu ve g\u00fcnl\u00fcklerini (logs) izleyebilirsiniz. Herhangi bir hata durumunda, g\u00fcnl\u00fckler sorunu tespit etmenize yard\u0131mc\u0131 olacakt\u0131r.<\/p>\n<h3>Uygulaman\u0131n Do\u011frulanmas\u0131<\/h3>\n<p>Pipeline ba\u015far\u0131yla tamamland\u0131\u011f\u0131nda, uygulaman\u0131z DigitalOcean Kubernetes k\u00fcmenize da\u011f\u0131t\u0131lm\u0131\u015f olmal\u0131d\u0131r.<\/p>\n<p>1.  <strong>Kubernetes Pod&#8217;lar\u0131n\u0131 kontrol edin:<\/strong><\/p>\n<pre><code class=\"language-bash\">kubectl get pods -n my-app-namespace<\/code><\/pre>\n<p>    \u0130ki adet <code>my-node-app-deployment<\/code> Pod&#8217;unun <code>Running<\/code> durumda oldu\u011funu g\u00f6rmelisiniz.<\/p>\n<p>2.  <strong>Kubernetes Service&#8217;i kontrol edin:<\/strong><\/p>\n<pre><code class=\"language-bash\">kubectl get svc -n my-app-namespace<\/code><\/pre>\n<p>    <code>my-node-app-service<\/code> ad\u0131nda bir Service g\u00f6receksiniz. <code>EXTERNAL-IP<\/code> s\u00fctununda bir IP adresi atanm\u0131\u015f olmal\u0131d\u0131r. Bu IP adresi, DigitalOcean Load Balancer taraf\u0131ndan sa\u011flanan genel IP&#8217;dir. IP&#8217;nin atanmas\u0131 birka\u00e7 dakika s\u00fcrebilir.<\/p>\n<p>3.  <strong>Uygulamaya Taray\u0131c\u0131dan Eri\u015fin:<\/strong><br \/>\n    <code>kubectl get svc<\/code> komutundan ald\u0131\u011f\u0131n\u0131z <code>EXTERNAL-IP<\/code> adresini taray\u0131c\u0131n\u0131zda a\u00e7\u0131n. Uygulaman\u0131z\u0131n &#8220;Merhaba Dunya! Bu benim GitLab CI\/CD uygulamam.&#8221; mesaj\u0131n\u0131 g\u00f6stermesi gerekir.<\/p>\n<p>Tebrikler! GitLab ve DigitalOcean Kubernetes kullanarak tam otomatik bir CI\/CD hatt\u0131 olu\u015fturdunuz. Art\u0131k <code>master<\/code> dal\u0131na yapt\u0131\u011f\u0131n\u0131z her kod de\u011fi\u015fikli\u011fi otomatik olarak derlenecek, konteynerle\u015ftirilecek ve Kubernetes k\u00fcmenize da\u011f\u0131t\u0131lacakt\u0131r.<\/p>\n<h2>\u0130leri Seviye Konular ve En \u0130yi Uygulamalar<\/h2>\n<p>Kurdu\u011fumuz temel CI\/CD hatt\u0131 harika bir ba\u015flang\u0131\u00e7 noktas\u0131d\u0131r, ancak ger\u00e7ek d\u00fcnya uygulamalar\u0131 i\u00e7in dikkate al\u0131nmas\u0131 gereken bir\u00e7ok ileri seviye konu ve en iyi uygulama bulunmaktad\u0131r.<\/p>\n<h3>Ortam Bazl\u0131 Da\u011f\u0131t\u0131mlar (Staging, Production)<\/h3>\n<p>Genellikle uygulamalar\u0131 do\u011frudan \u00fcretim ortam\u0131na da\u011f\u0131tmadan \u00f6nce bir haz\u0131rl\u0131k (staging) ortam\u0131nda test etmek istenir. GitLab CI\/CD, farkl\u0131 dallara (\u00f6rn. <code>develop<\/code> i\u00e7in staging, <code>master<\/code> i\u00e7in production) veya manuel tetiklemelere dayal\u0131 olarak farkl\u0131 da\u011f\u0131t\u0131m i\u015fleri tan\u0131mlaman\u0131za olanak tan\u0131r.<\/p>\n<p>*   <strong><code>rules<\/code> veya <code>only\/except<\/code> anahtar kelimeleri<\/strong>: Farkl\u0131 dallar i\u00e7in farkl\u0131 da\u011f\u0131t\u0131m i\u015fleri tan\u0131mlay\u0131n.<br \/>\n*   <strong>GitLab Environments<\/strong>: GitLab, da\u011f\u0131t\u0131mlar\u0131n\u0131z\u0131 ortamlara g\u00f6re d\u00fczenlemenizi sa\u011flar. Bu, hangi s\u00fcr\u00fcm\u00fcn hangi ortamda \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 takip etmeyi kolayla\u015ft\u0131r\u0131r.<br \/>\n*   <strong>Kubernetes Namespaces<\/strong>: Her ortam i\u00e7in ayr\u0131 Kubernetes Namespace&#8217;leri kullanmak, kaynak izolasyonu ve y\u00f6netimi sa\u011flar.<\/p>\n<h3>Geri Alma (Rollback) Stratejileri<\/h3>\n<p>Yeni bir da\u011f\u0131t\u0131m\u0131n sorunlara yol a\u00e7mas\u0131 durumunda, h\u0131zl\u0131 bir \u015fekilde \u00f6nceki stabil s\u00fcr\u00fcme geri d\u00f6nebilmek kritik \u00f6neme sahiptir. Kubernetes Deployment&#8217;lar\u0131, yerle\u015fik geri alma yeteneklerine sahiptir:<\/p>\n<pre><code class=\"language-bash\">kubectl rollout undo deployment\/my-node-app-deployment -n my-app-namespace<\/code><\/pre>\n<p>CI\/CD hatt\u0131n\u0131za manuel veya otomatik bir geri alma ad\u0131m\u0131 ekleyebilirsiniz.<\/p>\n<h3>Helm Charts ile Da\u011f\u0131t\u0131m\u0131 Y\u00f6netme<\/h3>\n<p>Uygulamalar\u0131n\u0131z b\u00fcy\u00fcd\u00fck\u00e7e ve Kubernetes manifestleriniz karma\u015f\u0131kla\u015ft\u0131k\u00e7a, Helm Charts kullanmak da\u011f\u0131t\u0131m\u0131 basitle\u015ftirir. Helm, Kubernetes uygulamalar\u0131 i\u00e7in bir paket y\u00f6neticisidir.<\/p>\n<p>*   <strong>\u015eablonlama<\/strong>: Helm, manifest dosyalar\u0131n\u0131z\u0131 \u015fablonlaman\u0131za olanak tan\u0131r, b\u00f6ylece farkl\u0131 ortamlar i\u00e7in de\u011ferleri kolayca de\u011fi\u015ftirebilirsiniz.<br \/>\n*   <strong>S\u00fcr\u00fcmleme<\/strong>: Uygulaman\u0131z\u0131n da\u011f\u0131t\u0131mlar\u0131n\u0131 s\u00fcr\u00fcmleyebilir ve kolayca geri alabilirsiniz.<br \/>\n*   <strong>Ba\u011f\u0131ml\u0131l\u0131k Y\u00f6netimi<\/strong>: Birden fazla Kubernetes kayna\u011f\u0131n\u0131 tek bir paket olarak y\u00f6netmenizi sa\u011flar.<\/p>\n<p>Helm kullanmak i\u00e7in CI\/CD hatt\u0131n\u0131zdaki <code>kubectl apply<\/code> ad\u0131mlar\u0131n\u0131 <code>helm upgrade --install<\/code> komutlar\u0131yla de\u011fi\u015ftirmeniz gerekir.<\/p>\n<h3>\u0130zleme ve G\u00fcnl\u00fckleme (Monitoring &#038; Logging)<\/h3>\n<p>Da\u011f\u0131t\u0131lan uygulamalar\u0131n\u0131z\u0131n sa\u011fl\u0131\u011f\u0131n\u0131 ve performans\u0131n\u0131 s\u00fcrekli izlemek \u00f6nemlidir.<\/p>\n<p>*   <strong>DigitalOcean Monitoring<\/strong>: DOKS, d\u00fc\u011f\u00fcm metrikleri ve baz\u0131 temel Pod metrikleri i\u00e7in DigitalOcean izlemesiyle entegredir.<br \/>\n*   <strong>Prometheus ve Grafana<\/strong>: Kubernetes i\u00e7in end\u00fcstri standard\u0131 izleme ara\u00e7lar\u0131d\u0131r. K\u00fcmenize kurularak detayl\u0131 metrikler toplayabilir ve g\u00f6rselle\u015ftirebilirsiniz.<br \/>\n*   <strong>Elastic Stack (ELK) veya Loki<\/strong>: Uygulama g\u00fcnl\u00fcklerini toplamak, depolamak ve analiz etmek i\u00e7in kullan\u0131labilir.<\/p>\n<h3>Otomatik \u00d6l\u00e7ekleme (Autoscaling)<\/h3>\n<p>Uygulaman\u0131z\u0131n trafi\u011fi de\u011fi\u015ftik\u00e7e, kaynaklar\u0131 otomatik olarak ayarlamak maliyetleri optimize eder ve performans\u0131 art\u0131r\u0131r.<\/p>\n<p>*   <strong>Horizontal Pod Autoscaler (HPA)<\/strong>: Pod&#8217;lar\u0131n\u0131z\u0131n CPU veya bellek kullan\u0131m\u0131na g\u00f6re otomatik olarak \u00f6l\u00e7eklenmesini sa\u011flar.<br \/>\n*   <strong>Cluster Autoscaler<\/strong>: D\u00fc\u011f\u00fcm kaynaklar\u0131 yetersiz kald\u0131\u011f\u0131nda k\u00fcmenize otomatik olarak yeni d\u00fc\u011f\u00fcmler ekler (DOKS bunu otomatik olarak y\u00f6netir, ancak yap\u0131land\u0131rma gerekebilir).<\/p>\n<h2>Sonu\u00e7<\/h2>\n<p>Bu makalede, GitLab ve DigitalOcean Managed Kubernetes&#8217;i bir araya getirerek g\u00fc\u00e7l\u00fc ve otomatik bir CI\/CD hatt\u0131 olu\u015fturmay\u0131 ad\u0131m ad\u0131m \u00f6\u011frendik. Uygulamam\u0131z\u0131 konteynerle\u015ftirdik, GitLab Container Registry&#8217;ye ittik ve Kubernetes manifestleri arac\u0131l\u0131\u011f\u0131yla DOKS k\u00fcmemize da\u011f\u0131tt\u0131k. Bu s\u00fcre\u00e7, geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131r, insan hatas\u0131n\u0131 azalt\u0131r ve uygulamalar\u0131n daha h\u0131zl\u0131 ve g\u00fcvenilir bir \u015fekilde m\u00fc\u015fterilere ula\u015fmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>Kurdu\u011fumuz bu temel hatt\u0131, ileri seviye konular\u0131 ve en iyi uygulamalar\u0131 (ortam bazl\u0131 da\u011f\u0131t\u0131mlar, Helm, izleme, otomatik \u00f6l\u00e7ekleme) entegre ederek daha da geli\u015ftirebilirsiniz. DevOps yolculu\u011funuzda bu entegrasyon, modern bulut tabanl\u0131 uygulama da\u011f\u0131t\u0131m\u0131n\u0131n temel ta\u015flar\u0131ndan birini olu\u015fturacakt\u0131r. Bu altyap\u0131 ile, kodunuzu yazmaya ve yenilik yapmaya odaklan\u0131rken, da\u011f\u0131t\u0131m s\u00fcre\u00e7lerinizin sorunsuz ve otomatik bir \u015fekilde ilerledi\u011finden emin olabilirsiniz.<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma\nGiri\u015f\nG\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda, uy","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1328],"tags":[],"class_list":{"0":"post-35990","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-bash","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma\" \/>\n<meta property=\"og:description\" content=\"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma Giri\u015f G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda, uy\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-06T10:40:53+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"22 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma\",\"datePublished\":\"2025-12-06T10:40:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\"},\"wordCount\":3349,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Bash\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\",\"name\":\"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-06T10:40:53+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/","og_locale":"tr_TR","og_type":"article","og_title":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma","og_description":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma Giri\u015f G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen yaz\u0131l\u0131m geli\u015ftirme d\u00fcnyas\u0131nda, uy","og_url":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-06T10:40:53+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"22 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma","datePublished":"2025-12-06T10:40:53+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/"},"wordCount":3349,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Bash"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/","url":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/","name":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-06T10:40:53+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/gitlab-ve-digitalocean-yonetilen-kubernetes-ile-ci-cd-hatti-olusturma\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"GitLab ve DigitalOcean Y\u00f6netilen Kubernetes ile CI\/CD Hatt\u0131 Olu\u015fturma"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35990","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=35990"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35990\/revisions"}],"predecessor-version":[{"id":35991,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35990\/revisions\/35991"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=35990"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=35990"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=35990"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}