Kapsayıcılarınız ile dış dünya arasında iletişimi etkinleştirmek için Docker’da bağlantı noktalarını etkili şekilde dışa açıp yayınlamayı öğrenin. Bu kılavuz, Dockerfile yapılandırmasından çalışma zamanı bayraklarına, Docker Compose orkestrasyonundan sorun giderme tekniklerine kadar her şeyi kapsar.
Docker kapsayıcılarıyla çalışırken karşılaştığım en kritik konulardan biri, kapsayıcılar ile dış dünya arasında ağ iletişimini etkinleştirmektir. Doğru bağlantı noktası yapılandırması olmadan, kapsayıcılı uygulamalar yalıtılmış ve erişilemez kalır. Bu yazıda, kapsayıcı tabanlı uygulamalarla çalışan herkes için temel bir beceri olan Docker bağlantı noktalarını dışa açma sürecini adım adım anlatacağım.
Bu kılavuz, kapsayıcılı uygulamalarını kullanıcıların, diğer hizmetlerin veya harici sistemlerin erişimine açması gereken yazılım geliştiricileri, DevOps mühendisleri ve BT profesyonelleri için özel olarak hazırlanmıştır. Bir kapsayıcı içinde bir web sunucusu, API veya veritabanı dağıtıyor olun, bağlantı noktalarını dışa açmayı anlamak, işlevsel Docker tabanlı sistemler kurmak için şarttır.
Yazının sonunda, Docker ağ yapısının nasıl çalıştığını, bağlantı noktalarını dışa açmanın farklı yöntemlerini ve bu kavramları kendi projelerinizde uygulamak için pratik teknikleri net bir şekilde kavramış olacaksınız.
Docker’da Bir Bağlantı Noktasını Dışa Açmak Nedir?
Teknik ayrıntılara girmeden önce, Docker ekosisteminde bağlantı noktası dışa açmanın ne anlama geldiğini anlamak önemlidir.
Kapsayıcı ağ yalıtımı ilkeleri
Docker kapsayıcıları, çekirdek bir ilke olarak yalıtım gözetilerek tasarlanmıştır. Bu yalıtım, ad alanları (namespaces) ve cgroups gibi Linux çekirdek özellikleri sayesinde sağlanır. Ad alanları, süreç yalıtımı sunarak bir kapsayıcı içindeki süreçlerin diğer kapsayıcılardaki veya ana sistemdeki süreçleri görmesini ya da onlarla etkileşime girmesini engeller. Cgroups ise kaynak tahsisini kontrol eder; bir kapsayıcının ne kadar CPU, bellek ve diğer kaynakları kullanabileceğini sınırlar.
Ağ açısından bakıldığında, her kapsayıcı varsayılan olarak bir sanal Ethernet arayüzü (veth çifti) ile birlikte kendi ağ ad alanını alır. Bu arayüz, varsayılan olarak bir Docker köprü ağına bağlanır; bu da kapsayıcılar arası iletişime olanak tanırken ana makine ağından yalıtımı sürdürür. Bunu, her kapsayıcının dış dünyaya görünmeyen kendine ait özel bir ağ adresi olması gibi düşünebilirsiniz.
Varsayılan yapılandırmada bir Docker kapsayıcısı tamamen kum havuzu (sandbox) içindedir. İçeride çalışan hizmetler birbirleriyle iletişim kurabilir, ancak kapsayıcının dışından, hatta ana makineden bile erişilemezler. İşte bu noktada bağlantı noktalarını dışa açma gerekliliği ortaya çıkar.
Expose ve publish: anlamsal ayrım
Docker bağlantı noktası yapılandırmasıyla çalışırken, birbiriyle ilişkili ancak farklı iki kavramla karşılaşırsınız: bağlantı noktalarını dışa açma (expose) ve yayınlama (publish).
Bağlantı noktalarını dışa açma (expose) esasen bir dokümantasyon özelliğidir. Docker’da bir bağlantı noktasını dışa açtığınızda, kapsayıcı imgenize, kapsayıcılı uygulamanın belirli bağlantı noktalarını dinlediğini belirten meta veriler eklersiniz.
Ancak bir bağlantı noktasını dışa açmak, onu kapsayıcının dışından erişilebilir kılmaz. Bu, imgenizi kullananlar için bir dokümantasyon işlevi görür.
Bağlantı noktalarını yayınlama (publish) ise hizmetlerinizi gerçekten dış dünyaya açar. Yayınlama, ana makinedeki bir bağlantı noktası ile kapsayıcı içindeki bir bağlantı noktası arasında eşleme (mapping) oluşturur. Bir bağlantı noktasını yayınladığınızda Docker, belirtilen ana makine bağlantı noktasından gelen trafiği karşılık gelen kapsayıcı bağlantı noktasına yönlendirmek üzere ana makine ağını yapılandırır.
Hangi yaklaşımı ne zaman kullanmalısınız?
Uygulamanızın hangi bağlantı noktalarını kullandığını belgelemek için, başka Docker kullanıcılarının kullanacağı imgeler oluştururken expose kullanın.
Kapsayıcınız içinde çalışan hizmetlere ana makine dahil harici sistemlerin erişmesi gerektiğinde publish kullanın.
Özellikle üretim ortamlarında, tam dokümantasyon ve işlevsellik için her ikisini birlikte kullanın.
Docker Bağlantı Noktaları Nasıl Dışa Açılır
Artık kavramları anladığımıza göre, farklı bağlamlarda Docker bağlantı noktalarını dışa açmanın pratik yönlerine bakalım.
Dockerfile bildirim stratejileri
Bir bağlantı noktasını dışa açmanın en temel yolu, Dockerfile içinde EXPOSE yönergesini kullanmaktır. Bu, kapsayıcının kullanmak üzere tasarlandığı bağlantı noktalarını bildirir.
Bu örnekte, kapsayıcının HTTP (Hypertext Transfer Protocol) ve HTTPS (Hypertext Transfer Protocol Secure) trafiği için standart olan 80 ve 443 bağlantı noktalarını kullanacağını belirttim. Bunları tek bir yönergede birleştirebilirsiniz:
Bağlantı noktalarını belirtirken, uygulamanız belirli bir protokol kullanıyorsa protokolü de (TCP - Transmission Control Protocol veya UDP - User Datagram Protocol) eklemek iyi bir uygulamadır:
Herhangi bir protokol belirtilmezse varsayılan olarak TCP kabul edilir. Bu, çoğu web uygulaması için uygundur ancak DNS (Domain Name System) veya oyun sunucuları gibi hizmetler sıklıkla UDP gerektirir.
Güvenlik açısından, yalnızca uygulamanızın gerçekten ihtiyaç duyduğu bağlantı noktalarını dışa açmanızı öneririm. Dışa açılan her bağlantı noktası potansiyel bir saldırı yüzeyi oluşturur; bu nedenle dışa açılan bağlantı noktalarının sayısını en aza indirmek, asgari ayrıcalık ilkesine uygun olacaktır.
Çalışma zamanında bağlantı noktası yönetimi
EXPOSE yönergesi kapsayıcının kullandığı bağlantı noktalarını belgelese de, bu bağlantı noktalarını ana makineden veya diğer makinelerden erişilebilir kılmak için kapsayıcıyı çalıştırırken bunları yayınlamanız gerekir.
Bir kapsayıcı bağlantı noktasını belirli bir ana makine bağlantı noktasına açıkça bağlama şekli şöyledir:
-p (veya --publish) bayrağı, kapsayıcıdaki tek bir bağlantı noktasını veya bağlantı noktası aralığını ana makineye bağlamanıza olanak tanır.
Bu komut, kapsayıcı içindeki 80 numaralı bağlantı noktasını ana makinedeki 8081’e eşler. Bu komutu çalıştırdıktan sonra tarayıcınızda http://localhost:8081 adresine giderek web sunucusuna erişebilirsiniz.
Geliştirme sırasında kolaylık olması için Docker, dışa açılmış tüm bağlantı noktalarını ana makinede rastgele yüksek numaralı bağlantı noktalarına otomatik olarak yayınlayan -P (büyük P) veya --publish-all bayrağını sağlar:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7c53d9413bf image "/docker-.…"10 s ago Up 9 s 0.0.0.0:49153->80/tcp, :::49153->80/tcp wizardlAltyapı:
Burada, kapsayıcı içindeki 80 numaralı bağlantı noktası ana makinede 49153’e eşlenmiştir.
Hem TCP hem de UDP’yi aynı bağlantı noktasında kullanan hizmetlerle (DNS sunucuları gibi) çalışırken, yayınlarken protokolü belirtmeniz gerekir:
docker run -p53:53/tcp -p53:53/udp dns-serverAltyapı:
Docker Compose orkestrasyonu
Birden çok kapsayıcıdan oluşan uygulamalar için Docker Compose, ağ ve bağlantı noktası yapılandırmalarını yönetmek için daha kolay bir yol sunar.
Bir Docker Compose YAML dosyasında, her hizmet için ports anahtarı altında bağlantı noktası eşlemelerini belirtebilirsiniz:
Docker Compose, ports ve expose arasında önemli bir ayrım yapar. ports bölümü dışarıdan erişilebilen yayınlanmış bağlantı noktası eşlemeleri oluştururken, expose yalnızca aynı Compose ağı içindeki bağlı hizmetlere bağlantı noktalarını sunar:
Bu örnekte, web hizmetine ana makineden 8081 portundan erişilebilirken, PostgreSQL veritabanına yalnızca Compose dosyasındaki diğer hizmetler erişebilir; ana makineden doğrudan erişilemez.
Özellikle farklı ortamlar arasında esneklik için, bağlantı noktası eşlemelerinde ortam değişkenleri kullanabilirim:
Bu söz dizimi, ortam değişkeni (WEB_PORT) ile ana makine bağlantı noktasını belirtmeme olanak tanır; ayarlanmamışsa varsayılan olarak 8081 kullanılır.
Docker Bağlantı Noktalarını Dışa Açma - Uygulamalı Örnek
Bir veritabanı arka ucu olan bir web uygulaması için Docker bağlantı noktalarını dışa açmanın tam bir örneğini birlikte inceleyelim.
Python Flask API hizmeti ve bir PostgreSQL veritabanından oluşan basit bir web uygulaması geliştirdiğimizi hayal edin. API hizmeti 5000 portunda dinler ve PostgreSQL varsayılan 5432 portunu kullanır.
Basit Flask uygulamamızın (app.py) şu şekilde göründüğünü varsayalım. Bu uygulama bir myapp veritabanı oluşturur ve veritabanında bu tablo oluşturulduktan sonra items tablosundan verileri çeker.
from flask import Flask, jsonify
import os
import psycopg2
app = Flask(__name__)# Database connection parameters from environment variables
DB_HOST = os.environ.get('DB_HOST','db')
DB_NAME = os.environ.get('DB_NAME','myapp')
DB_USER = os.environ.get('DB_USER','postgres')
DB_PASS = os.environ.get('DB_PASSWORD','postgres')@app.route('/')defindex():return jsonify({'message':'API is running'})@app.route('/items')defget_items():# Connect to the PostgreSQL database
conn = psycopg2.connect(
host=DB_HOST,
database=DB_NAME,
user=DB_USER,
password=DB_PASS
)# Create a cursor and execute a query
cur = conn.cursor()
cur.execute('SELECT id, name FROM items')# Fetch results and format as list of dictionaries
items =[{'id': row[0],'name': row[1]}for row in cur.fetchall()]# Close connections
cur.close()
conn.close()return jsonify(items)if __name__ =='__main__':# Run the Flask app, binding to all interfaces (important for Docker)
app.run(host='0.0.0.0', port=5000)Altyapı:
Ardından, requirements.txt dosyamızı oluşturacağım:
Artık API’ye http://localhost:5000 adresinden erişebilirim; ancak PostgreSQL örneğine Docker ağı dışından doğrudan erişilemez; bu da veritabanı hizmetleri için iyi bir güvenlik uygulamasıdır. Ancak çalışan kapsayıcıdan PostgreSQL’e erişebilirsiniz:
docker compose exec db psql -U postgres -d myappAltyapı:
Bu komut PostgreSQL CLI’a erişir; burada veritabanını görüntüleyebilir ve bir items tablosu oluşturabilirsiniz. Oluşturulduktan sonra verileri http://localhost:5000/items adresinde görebilirim.
Birden fazla Docker bağlantı noktasını nasıl dışa açarım
Python uygulamamın birden fazla bağlantı noktasını dışa açması gerekiyorsa, bunların hepsini Dockerfile’da belirtebilirim:
Ana Flask uygulaması için 5000 portu (şu anda aktif)
Olası bir izleme panosu için 8081 portu
Gelecekteki bir hata ayıklama arayüzü için 9090 portu
Dockerfile’da 8081 ve 9090 bağlantı noktalarını dokümantasyon amaçlı olarak dışa açmış olsam da, mevcut Flask uygulamam yalnızca 5000 portunu dinlemek üzere yapılandırılmıştır. Ek dışa açılan bağlantı noktaları gelecekte hangi işlevlerin uygulanabileceğini işaret eder.
Dışa açılmış bağlantı noktaları nasıl yayınlanır
Bir Dockerfile’da dışa açılan bağlantı noktalarını yayınlamak için, kapsayıcıyı çalıştırırken -p veya -P bayrağını kullanırım:
Bu, kapsayıcıdaki (Dockerfile’da dışa açılan ve Flask’ın dinlediği) 5000 portunu ana makinede 8081 portuna eşler. Bu komutu çalıştırdıktan sonra tarayıcımda http://localhost:8081 adresine giderek Flask uygulamama erişebilirim.
Ayrıca -P bayrağını kullanarak dışa açılmış tüm bağlantı noktalarını ana makinede rastgele bağlantı noktalarına otomatik olarak yayınlayabilirim:
Bu komut, belirli bir kapsayıcı için tüm bağlantı noktası eşlemelerini gösterir. Örneğin, Flask uygulamam yalnızca 5000 portunu dinliyor olsa da Dockerfile’da birden fazla bağlantı noktasını dışa açmışsam, Docker port bana hangi ana makine bağlantı noktalarının hangi kapsayıcı bağlantı noktalarına eşlendiğini tam olarak gösterecektir. Dolayısıyla, 5000 portu 32768’e eşlenmişse Flask uygulamama http://localhost:32768 adresinden erişebilirim.
Teşhis ve Sorun Giderme Teknikleri
Dikkatli yapılandırmaya rağmen Docker bağlantı noktası eşlemelerinde sorunlar ortaya çıkabilir. Yaygın problemleri teşhis etmek ve çözmek için kullandığım bazı teknikler aşağıdadır.
Bağlantı noktası eşlemesini inceleme
Bağlantı noktasıyla ilgili sorunları teşhis etmenin ilk adımı, eşlemelerin doğru kurulduğunu doğrulamaktır. Şu komutları kullanırım:
Bağlantı noktası eşlemeleriyle çalışan tüm kapsayıcıları listeleyin:
Daha derin trafik analizi yapmanız gerekirse, tcpdump ve netstat gibi araçlar çok yararlı olabilir. Öncelikle bunların kapsayıcı içinde kurulu olduğundan emin olun. Kapsayıcı bu araçları içermiyorsa, aşağıdaki komutu çalıştırarak kurabilirsiniz:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 000.0.0.0:5000 0.0.0.0:* LISTEN
tcp 00127.0.0.11:42265 0.0.0.0:* LISTEN
udp 00127.0.0.11:34267 0.0.0.0:*Altyapı:
Bu çıktı örneğin Flask uygulamasının tüm arayüzlerde 5000 portunu dinlediğini gösterir.
Kapsayıcının ana ağ arayüzündeki (genellikle eth0) gelen ve giden trafiği izlemek için:
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytesAltyapı:
Bu komut, trafiği izleyip isteklerin kapsayıcıya ulaşıp ulaşmadığını veya paketlerin düşürülüp düşürülmediğini ya da yanlış yönlendirilip yönlendirilmediğini tespit etmenizi sağlar.
Iptables kural analizi
Docker, Ağ Adresi Çevirisi’ni (NAT) yönetmek ve ana makine ile kapsayıcılar arasındaki trafik akışını kontrol etmek için iptables’ı kullanır. Ana makine bağlantı noktalarını uygun kapsayıcı IP’lerine ve bağlantı noktalarına yönlendirmek için kuralları otomatik olarak ekler; böylece kapsayıcılı hizmetlere kesintisiz erişim sağlanır.
Yerel Linux ana makinelerinde, bu kuralları şu gibi komutlarla inceleyebilirsiniz:
Bu komut, belirli ana makine bağlantı noktalarındaki gelen trafiğin Docker tarafından kapsayıcı uç noktalarına nasıl yönlendirildiğini gösterir. Daha önceki Docker Compose dosyasına göre iletilen bağlantı noktalarını göreceksiniz:
DNAT kuralları, trafiği ana makineden kapsayıcıya yeniden yönlendirir.
RETURN kuralları, dahili Docker ağı trafiğinin doğru yönlendirilmesini sağlar.
Ancak ortamınıza bağlı olarak (örneğin Windows üzerinde Docker Desktop veya WSL2), Docker bağlantı noktası yönlendirmesini farklı şekilde ele alabilir ve iptables kuralları sistem içinde görünmez veya değiştirilemez olabilir. Bu durumda, bağlantı noktası yönlendirmesini aşağıdaki komutla kontrol edebilirsiniz:
docker ps ve docker port [container] ile bağlantı noktası eşlemelerini doğrulayın.
Ana makine güvenlik duvarının veya güvenlik yazılımının bağlantı noktalarını engelleyip engellemediğini kontrol edin.
Uygulamanızın ağ davranışını doğrulamak için kapsayıcı günlüklerini ve netstat, tcpdump gibi ağ araçlarını kullanın.
Sonuç
Docker bağlantı noktalarını dışa açmak, kapsayıcı yalıtımı ile pratik kullanılabilirlik arasındaki boşluğu kapatan temel bir beceridir. Bu yazı boyunca Docker’ın ağ modeli nasıl çalışır, bağlantı noktalarını dışa açma ve yayınlama arasındaki fark nedir açıkladım ve çeşitli senaryolar için pratik örnekler sundum.
Şu önemli noktaları aklınızda tutun:
EXPOSE’u Dockerfile’larda uygulamanızın hangi bağlantı noktalarını kullandığını belgelemek için kullanın
Bu bağlantı noktalarını dışarıdan erişilebilir kılmak için kapsayıcıları çalıştırırken -p veya -P kullanın
Karmaşık çoklu kapsayıcı uygulamaları yönetmek için Docker Compose’tan yararlanın
Sorunlar ortaya çıktığında teşhis araçlarını kullanarak sorun giderin
Bu kavram ve tekniklerde ustalaşmak, hem dahili olarak hem de dış dünya ile etkili şekilde iletişim kuran daha sağlam kapsayıcılı uygulamalar tasarlamanızı sağlar. İster basit bir web uygulaması ister karmaşık bir mikro hizmet mimarisi geliştiriyor olun, doğru bağlantı noktası yönetimi başarının kritik unsurudur.
Kapsayıcılar modern uygulama dağıtım stratejilerine hükmetmeye devam ettikçe, Docker ağ yapılandırmasını ve bağlantı noktalarını güvenle yönetebilme yeteneği her geliştiricinin araç setinde vazgeçilmez bir beceri olarak kalacaktır.
Öğrenmeye devam etmek için şu kaynaklara göz atmayı unutmayın:
Docker’da bir bağlantı noktasını dışa açmak ne anlama gelir?⌄
Docker’da bir bağlantı noktasını dışa açmak, kapsayıcılı uygulamanızın hangi bağlantı noktalarını dinlediğini belgeleme yoludur; ancak bu, bağlantı noktasını kapsayıcı dışından erişilebilir kılmaz.
Bir Docker kapsayıcısının bağlantı noktasını ana makinemden nasıl erişilebilir yaparım?⌄
Bir bağlantı noktasını, docker run ile -p bayrağını veya Docker Compose içindeki ports bölümünü kullanarak yayınlayabilirsiniz; bu işlem ana makinedeki bir bağlantı noktasını kapsayıcı bağlantı noktasına eşler.
Docker’da `EXPOSE` ile `-p` arasındaki fark nedir?⌄
EXPOSE, belgelendirme amacıyla bağlantı noktalarını bildirmek için Dockerfile’da kullanılır; -p ise bu bağlantı noktalarını harici erişim için yayınlar ve eşler.
Tek bir Docker kapsayıcısı için birden fazla bağlantı noktası dışa açabilir miyim?⌄
Evet, bir Docker kapsayıcısı için birden fazla bağlantı noktasını Dockerfile’da birden çok EXPOSE yönergesiyle veya Docker Compose’un ports bölümünde birden çok bağlantı noktası belirterek dışa açabilirsiniz.
Docker bağlantı noktası eşleme sorunlarını nasıl gideririm?⌄
Bağlantı noktası eşlemelerini ve trafik akışını doğrulamak için docker ps, docker port, docker inspect gibi komutları ve kapsayıcı içinde netstat, tcpdump gibi ağ araçlarını kullanın.
Martin Data Solutions’ın Kurucusu ve Serbest Çalışan Veri Bilimci, ML ve AI Mühendisi olarak Regresyon, Sınıflandırma, NLP, LLM, RAG, Sinir Ağları, Topluluk Yöntemleri ve Bilgisayarlı Görü alanlarında geniş bir portföy sunuyorum.
Veri temizleme, analitik, modelleme ve AWS ile GCP’de dağıtımı kapsayan uçtan uca birçok ML projesini başarıyla geliştirerek etkili ve ölçeklenebilir çözümler sundum.
Çeşitli sektör kullanım senaryoları için Streamlit ve Gradio ile etkileşimli ve ölçeklenebilir web uygulamaları geliştirdim.
Veri bilimi ve analitik alanlarında öğrencilere eğitim verdim ve mentorluk yaparak kişiselleştirilmiş öğrenme yaklaşımlarıyla mesleki gelişimlerini destekledim.
Kurumsal gereksinimlere uyarlanmış geri getirme destekli üretim (RAG) uygulamaları için kurs içerikleri tasarladım.
MLOps, vektör veritabanları ve LLM’ler gibi konuları ele alan, yüksek etki yaratan yapay zeka ve ML teknik blogları yazdım ve önemli etkileşim sağladım.
Üstlendiğim her projede CI/CD, kod linting’i, biçimlendirme, model izleme, deney takibi ve sağlam hata yönetimi gibi yazılım mühendisliği ve DevOps’taki güncel uygulamaları hayata geçiririm. Tam kapsamlı çözümler sunmaya; veri içgörülerini, işletmelerin büyümesine yardımcı olan ve veri bilimi, makine öğrenimi ile yapay zekâdan en iyi şekilde yararlanan pratik stratejilere dönüştürmeye kararlıyım.
Algoritmalar, sistem tasarımı ve davranışsal senaryoları kapsayan bu temel sorularla teknik mülakat sürecine hakim olun. Uzman cevapları, kod örnekleri ve kanıtlanmış hazırlık stratejileri edinin.
Git deponuzu temiz tutmak için .gitignore’u nasıl kullanacağınızı öğrenin. Bu eğitim; temelleri, yaygın kullanım durumlarını ve başlamanıza yardımcı olacak pratik örnekleri kapsar!
Profesyonel Veri Mühendisi programımızla, günümüzde veri mühendisliği rollerinde devrim yaratan gelişmiş becerilere ve son teknoloji araçlara derinlemesine dalın.
Docker kapsayıcılarıyla çalışırken karşılaştığım en kritik konulardan biri, kapsayıcılar ile dış dünya arasında ağ iletişimini etkinleştirmektir. Doğru bağlantı noktası yapılandırması olmadan, kapsayıcılı uygulamalar yalıtılmış ve erişilemez kalır. Bu yazıda, kapsayıcı tabanlı uygulamalarla çalışan herkes için temel bir beceri olan Docker bağlantı noktalarını dışa açma sürecini adım adım anlatacağım.
Bu kılavuz, kapsayıcılı uygulamalarını kullanıcıların, diğer hizmetlerin veya harici sistemlerin erişimine açması gereken yazılım geliştiricileri, DevOps mühendisleri ve BT profesyonelleri için özel olarak hazırlanmıştır. Bir kapsayıcı içinde bir web sunucusu, API veya veritabanı dağıtıyor olun, bağlantı noktalarını dışa açmayı anlamak, işlevsel Docker tabanlı sistemler kurmak için şarttır.
Yazının sonunda, Docker ağ yapısının nasıl çalıştığını, bağlantı noktalarını dışa açmanın farklı yöntemlerini ve bu kavramları kendi projelerinizde uygulamak için pratik teknikleri net bir şekilde kavramış olacaksınız.
Docker’a yeniyseniz, Introduction to Docker, Containerization and Virtualization with Docker and Kubernetes, Intermediate Docker veya Containerization and Virtualization Concepts gibi kurslarımızdan birini almayı düşünebilirsiniz.
Docker’da Bir Bağlantı Noktasını Dışa Açmak Nedir?
Teknik ayrıntılara girmeden önce, Docker ekosisteminde bağlantı noktası dışa açmanın ne anlama geldiğini anlamak önemlidir.
Kapsayıcı ağ yalıtımı ilkeleri
Docker kapsayıcıları, çekirdek bir ilke olarak yalıtım gözetilerek tasarlanmıştır. Bu yalıtım, ad alanları (namespaces) ve cgroups gibi Linux çekirdek özellikleri sayesinde sağlanır. Ad alanları, süreç yalıtımı sunarak bir kapsayıcı içindeki süreçlerin diğer kapsayıcılardaki veya ana sistemdeki süreçleri görmesini ya da onlarla etkileşime girmesini engeller. Cgroups ise kaynak tahsisini kontrol eder; bir kapsayıcının ne kadar CPU, bellek ve diğer kaynakları kullanabileceğini sınırlar.
Ağ açısından bakıldığında, her kapsayıcı varsayılan olarak bir sanal Ethernet arayüzü (veth çifti) ile birlikte kendi ağ ad alanını alır. Bu arayüz, varsayılan olarak bir Docker köprü ağına bağlanır; bu da kapsayıcılar arası iletişime olanak tanırken ana makine ağından yalıtımı sürdürür. Bunu, her kapsayıcının dış dünyaya görünmeyen kendine ait özel bir ağ adresi olması gibi düşünebilirsiniz.
Varsayılan yapılandırmada bir Docker kapsayıcısı tamamen kum havuzu (sandbox) içindedir. İçeride çalışan hizmetler birbirleriyle iletişim kurabilir, ancak kapsayıcının dışından, hatta ana makineden bile erişilemezler. İşte bu noktada bağlantı noktalarını dışa açma gerekliliği ortaya çıkar.
Expose ve publish: anlamsal ayrım
Docker bağlantı noktası yapılandırmasıyla çalışırken, birbiriyle ilişkili ancak farklı iki kavramla karşılaşırsınız: bağlantı noktalarını dışa açma (expose) ve yayınlama (publish).
Bağlantı noktalarını dışa açma (expose) esasen bir dokümantasyon özelliğidir. Docker’da bir bağlantı noktasını dışa açtığınızda, kapsayıcı imgenize, kapsayıcılı uygulamanın belirli bağlantı noktalarını dinlediğini belirten meta veriler eklersiniz.
Ancak bir bağlantı noktasını dışa açmak, onu kapsayıcının dışından erişilebilir kılmaz. Bu, imgenizi kullananlar için bir dokümantasyon işlevi görür.
Bağlantı noktalarını yayınlama (publish) ise hizmetlerinizi gerçekten dış dünyaya açar. Yayınlama, ana makinedeki bir bağlantı noktası ile kapsayıcı içindeki bir bağlantı noktası arasında eşleme (mapping) oluşturur. Bir bağlantı noktasını yayınladığınızda Docker, belirtilen ana makine bağlantı noktasından gelen trafiği karşılık gelen kapsayıcı bağlantı noktasına yönlendirmek üzere ana makine ağını yapılandırır.
Hangi yaklaşımı ne zaman kullanmalısınız?
Docker Bağlantı Noktaları Nasıl Dışa Açılır
Artık kavramları anladığımıza göre, farklı bağlamlarda Docker bağlantı noktalarını dışa açmanın pratik yönlerine bakalım.
Dockerfile bildirim stratejileri
Bir bağlantı noktasını dışa açmanın en temel yolu, Dockerfile içinde
EXPOSEyönergesini kullanmaktır. Bu, kapsayıcının kullanmak üzere tasarlandığı bağlantı noktalarını bildirir.Bu örnekte, kapsayıcının HTTP (Hypertext Transfer Protocol) ve HTTPS (Hypertext Transfer Protocol Secure) trafiği için standart olan
80ve443bağlantı noktalarını kullanacağını belirttim. Bunları tek bir yönergede birleştirebilirsiniz:Bağlantı noktalarını belirtirken, uygulamanız belirli bir protokol kullanıyorsa protokolü de (TCP - Transmission Control Protocol veya UDP - User Datagram Protocol) eklemek iyi bir uygulamadır:
Herhangi bir protokol belirtilmezse varsayılan olarak TCP kabul edilir. Bu, çoğu web uygulaması için uygundur ancak DNS (Domain Name System) veya oyun sunucuları gibi hizmetler sıklıkla UDP gerektirir.
Güvenlik açısından, yalnızca uygulamanızın gerçekten ihtiyaç duyduğu bağlantı noktalarını dışa açmanızı öneririm. Dışa açılan her bağlantı noktası potansiyel bir saldırı yüzeyi oluşturur; bu nedenle dışa açılan bağlantı noktalarının sayısını en aza indirmek, asgari ayrıcalık ilkesine uygun olacaktır.
Çalışma zamanında bağlantı noktası yönetimi
EXPOSEyönergesi kapsayıcının kullandığı bağlantı noktalarını belgelese de, bu bağlantı noktalarını ana makineden veya diğer makinelerden erişilebilir kılmak için kapsayıcıyı çalıştırırken bunları yayınlamanız gerekir.Bir kapsayıcı bağlantı noktasını belirli bir ana makine bağlantı noktasına açıkça bağlama şekli şöyledir:
-p(veya--publish) bayrağı, kapsayıcıdaki tek bir bağlantı noktasını veya bağlantı noktası aralığını ana makineye bağlamanıza olanak tanır.Bu komut, kapsayıcı içindeki 80 numaralı bağlantı noktasını ana makinedeki 8081’e eşler. Bu komutu çalıştırdıktan sonra tarayıcınızda
http://localhost:8081adresine giderek web sunucusuna erişebilirsiniz.Geliştirme sırasında kolaylık olması için Docker, dışa açılmış tüm bağlantı noktalarını ana makinede rastgele yüksek numaralı bağlantı noktalarına otomatik olarak yayınlayan
-P(büyük P) veya--publish-allbayrağını sağlar:Hangi ana makine bağlantı noktalarının atandığını bulmak için
docker pskomutunu kullanabilirim:Çıktı şöyle görünecektir:
Burada, kapsayıcı içindeki 80 numaralı bağlantı noktası ana makinede 49153’e eşlenmiştir.
Hem TCP hem de UDP’yi aynı bağlantı noktasında kullanan hizmetlerle (DNS sunucuları gibi) çalışırken, yayınlarken protokolü belirtmeniz gerekir:
Docker Compose orkestrasyonu
Birden çok kapsayıcıdan oluşan uygulamalar için Docker Compose, ağ ve bağlantı noktası yapılandırmalarını yönetmek için daha kolay bir yol sunar.
Bir Docker Compose YAML dosyasında, her hizmet için
portsanahtarı altında bağlantı noktası eşlemelerini belirtebilirsiniz:Docker Compose,
portsveexposearasında önemli bir ayrım yapar.portsbölümü dışarıdan erişilebilen yayınlanmış bağlantı noktası eşlemeleri oluştururken,exposeyalnızca aynı Compose ağı içindeki bağlı hizmetlere bağlantı noktalarını sunar:Bu örnekte,
webhizmetine ana makineden 8081 portundan erişilebilirken, PostgreSQL veritabanına yalnızca Compose dosyasındaki diğer hizmetler erişebilir; ana makineden doğrudan erişilemez.Özellikle farklı ortamlar arasında esneklik için, bağlantı noktası eşlemelerinde ortam değişkenleri kullanabilirim:
Bu söz dizimi, ortam değişkeni (
WEB_PORT) ile ana makine bağlantı noktasını belirtmeme olanak tanır; ayarlanmamışsa varsayılan olarak 8081 kullanılır.Docker Bağlantı Noktalarını Dışa Açma - Uygulamalı Örnek
Bir veritabanı arka ucu olan bir web uygulaması için Docker bağlantı noktalarını dışa açmanın tam bir örneğini birlikte inceleyelim.
Python Flask API hizmeti ve bir PostgreSQL veritabanından oluşan basit bir web uygulaması geliştirdiğimizi hayal edin. API hizmeti
5000portunda dinler ve PostgreSQL varsayılan5432portunu kullanır.Basit Flask uygulamamızın (
app.py) şu şekilde göründüğünü varsayalım. Bu uygulama birmyappveritabanı oluşturur ve veritabanında bu tablo oluşturulduktan sonraitemstablosundan verileri çeker.Ardından,
requirements.txtdosyamızı oluşturacağım:Şimdi Python API hizmetimiz için bir Dockerfile oluşturmam gerekiyor:
Son olarak, her iki hizmeti orkestre etmek için bir Docker Compose dosyası oluşturacağım:
Bu yapılandırmada:
5000portunu yayınlar; böylece ana makineden erişilebilir hale gelir.5432portunu dışa açar ancak yayınlamaz; böylece yalnızca Compose ağı içindeki diğer hizmetler tarafından erişilebilir olur.5432portunu kullanarak veritabanına erişebilir.Bu uygulamayı çalıştırmak için şunu kullanın:
Artık API’ye
http://localhost:5000adresinden erişebilirim; ancak PostgreSQL örneğine Docker ağı dışından doğrudan erişilemez; bu da veritabanı hizmetleri için iyi bir güvenlik uygulamasıdır. Ancak çalışan kapsayıcıdan PostgreSQL’e erişebilirsiniz:Bu komut PostgreSQL CLI’a erişir; burada veritabanını görüntüleyebilir ve bir
itemstablosu oluşturabilirsiniz. Oluşturulduktan sonra verilerihttp://localhost:5000/itemsadresinde görebilirim.Birden fazla Docker bağlantı noktasını nasıl dışa açarım
Python uygulamamın birden fazla bağlantı noktasını dışa açması gerekiyorsa, bunların hepsini Dockerfile’da belirtebilirim:
Bu Dockerfile şunları dışa açar:
5000portu (şu anda aktif)8081portu9090portuDockerfile’da
8081ve9090bağlantı noktalarını dokümantasyon amaçlı olarak dışa açmış olsam da, mevcut Flask uygulamam yalnızca5000portunu dinlemek üzere yapılandırılmıştır. Ek dışa açılan bağlantı noktaları gelecekte hangi işlevlerin uygulanabileceğini işaret eder.Dışa açılmış bağlantı noktaları nasıl yayınlanır
Bir Dockerfile’da dışa açılan bağlantı noktalarını yayınlamak için, kapsayıcıyı çalıştırırken
-pveya-Pbayrağını kullanırım:Bu, kapsayıcıdaki (Dockerfile’da dışa açılan ve Flask’ın dinlediği)
5000portunu ana makinede8081portuna eşler. Bu komutu çalıştırdıktan sonra tarayıcımdahttp://localhost:8081adresine giderek Flask uygulamama erişebilirim.Ayrıca -P bayrağını kullanarak dışa açılmış tüm bağlantı noktalarını ana makinede rastgele bağlantı noktalarına otomatik olarak yayınlayabilirim:
Hangi bağlantı noktalarının yayınlandığını kontrol etmek için şunları kullanabilirim:
Daha ayrıntılı bilgi için şunu kullanabilirim:
Bu komut, belirli bir kapsayıcı için tüm bağlantı noktası eşlemelerini gösterir. Örneğin, Flask uygulamam yalnızca
5000portunu dinliyor olsa da Dockerfile’da birden fazla bağlantı noktasını dışa açmışsam, Docker port bana hangi ana makine bağlantı noktalarının hangi kapsayıcı bağlantı noktalarına eşlendiğini tam olarak gösterecektir. Dolayısıyla,5000portu 32768’e eşlenmişse Flask uygulamamahttp://localhost:32768adresinden erişebilirim.Teşhis ve Sorun Giderme Teknikleri
Dikkatli yapılandırmaya rağmen Docker bağlantı noktası eşlemelerinde sorunlar ortaya çıkabilir. Yaygın problemleri teşhis etmek ve çözmek için kullandığım bazı teknikler aşağıdadır.
Bağlantı noktası eşlemesini inceleme
Bağlantı noktasıyla ilgili sorunları teşhis etmenin ilk adımı, eşlemelerin doğru kurulduğunu doğrulamaktır. Şu komutları kullanırım:
Bağlantı noktası eşlemeleriyle çalışan tüm kapsayıcıları listeleyin:
Belirli bir kapsayıcı hakkında ayrıntılı bilgi alın:
Belirli bir kapsayıcı için bağlantı noktası eşlemelerini kontrol edin:
docker inspect komutu, ağ ayarları da dahil olmak üzere ayrıntılı bilgi sağlar. Ağla ilgili ayrıntılara odaklanmak için şunu kullanın:
Daha derin trafik analizi yapmanız gerekirse,
tcpdumpvenetstatgibi araçlar çok yararlı olabilir. Öncelikle bunların kapsayıcı içinde kurulu olduğundan emin olun. Kapsayıcı bu araçları içermiyorsa, aşağıdaki komutu çalıştırarak kurabilirsiniz:Uygulamanın kapsayıcı içinde hangi bağlantı noktalarını dinlediğini görmek için:
Bu çıktı örneğin Flask uygulamasının tüm arayüzlerde
5000portunu dinlediğini gösterir.Kapsayıcının ana ağ arayüzündeki (genellikle eth0) gelen ve giden trafiği izlemek için:
Bu komut, trafiği izleyip isteklerin kapsayıcıya ulaşıp ulaşmadığını veya paketlerin düşürülüp düşürülmediğini ya da yanlış yönlendirilip yönlendirilmediğini tespit etmenizi sağlar.
Iptables kural analizi
Docker, Ağ Adresi Çevirisi’ni (NAT) yönetmek ve ana makine ile kapsayıcılar arasındaki trafik akışını kontrol etmek için
iptables’ı kullanır. Ana makine bağlantı noktalarını uygun kapsayıcı IP’lerine ve bağlantı noktalarına yönlendirmek için kuralları otomatik olarak ekler; böylece kapsayıcılı hizmetlere kesintisiz erişim sağlanır.Yerel Linux ana makinelerinde, bu kuralları şu gibi komutlarla inceleyebilirsiniz:
Bu komut, belirli ana makine bağlantı noktalarındaki gelen trafiğin Docker tarafından kapsayıcı uç noktalarına nasıl yönlendirildiğini gösterir. Daha önceki Docker Compose dosyasına göre iletilen bağlantı noktalarını göreceksiniz:
Burada:
DNATkuralları, trafiği ana makineden kapsayıcıya yeniden yönlendirir.RETURNkuralları, dahili Docker ağı trafiğinin doğru yönlendirilmesini sağlar.Ancak ortamınıza bağlı olarak (örneğin Windows üzerinde Docker Desktop veya WSL2), Docker bağlantı noktası yönlendirmesini farklı şekilde ele alabilir ve
iptableskuralları sistem içinde görünmez veya değiştirilemez olabilir. Bu durumda, bağlantı noktası yönlendirmesini aşağıdaki komutla kontrol edebilirsiniz:Sorun giderme ipuçları:
docker psvedocker port [container]ile bağlantı noktası eşlemelerini doğrulayın.netstat,tcpdumpgibi ağ araçlarını kullanın.Sonuç
Docker bağlantı noktalarını dışa açmak, kapsayıcı yalıtımı ile pratik kullanılabilirlik arasındaki boşluğu kapatan temel bir beceridir. Bu yazı boyunca Docker’ın ağ modeli nasıl çalışır, bağlantı noktalarını dışa açma ve yayınlama arasındaki fark nedir açıkladım ve çeşitli senaryolar için pratik örnekler sundum.
Şu önemli noktaları aklınızda tutun:
EXPOSE’u Dockerfile’larda uygulamanızın hangi bağlantı noktalarını kullandığını belgelemek için kullanın-pveya-PkullanınBu kavram ve tekniklerde ustalaşmak, hem dahili olarak hem de dış dünya ile etkili şekilde iletişim kuran daha sağlam kapsayıcılı uygulamalar tasarlamanızı sağlar. İster basit bir web uygulaması ister karmaşık bir mikro hizmet mimarisi geliştiriyor olun, doğru bağlantı noktası yönetimi başarının kritik unsurudur.
Kapsayıcılar modern uygulama dağıtım stratejilerine hükmetmeye devam ettikçe, Docker ağ yapılandırmasını ve bağlantı noktalarını güvenle yönetebilme yeteneği her geliştiricinin araç setinde vazgeçilmez bir beceri olarak kalacaktır.
Öğrenmeye devam etmek için şu kaynaklara göz atmayı unutmayın: