Docker sistemimize ilk kez kurulduğu zaman docker0 adında varsayılan olarak bridge network tanımlaması yapılmakta ve gerekli konfigürasyon oluşturulmaktadır.
Biz bir değişiklik yapmadığımız sürece docker0 default olarak kullanılır, container’lar da bu switch sayesinde hem birbirleri ile hem de dış dünya ile iletişim sağlayabiliyorlar.
Container’ların birbirleriye veya dış dünyayla iletişim kurabilmesi için 2 farklı standart geliştirilmiştir.
- CNM (Container Network Model)
- CNI (Container Network Interface)
Bu modeller sayesinde birden fazla ağ driver kulanabilen container’lar network tanımlama işlemlerinde bir standarta göre oluşturulmaktadır. Docker container sistemi CNM standartını desteklemektedir.
CNM (Container Network Model)
Docker üzerinde oluşturulan container’lar arasında bağlantı sağlanmasından ve farklı ağ modellerinin oluşturulmasından sorumludur. Madde madde sıralayacak olursak:
- Aynı ağdaki tüm container’ların birbirleriyle sorunsuzca iletişim kurabilmesini sağlar.
- Container’lar ve desteklenen drivler’lar arasında çoklu network trafiğinin bölümlere syrılmasını sağlar.
- Bir container’ın aynı anda birden fazla network’e sorunsuzca dahil olabilmesini sağlar.
- Ağ bağlantısı için sandbox içerisine endpoint eklenmesini sağlar.
CNM, 3 ana bileşen üzerine kuruludur:
- Sandbox: Container yönetim arayüzü, ip, mac adresleri, rooting tabloları ve dns ayarları gibi konfigürasyon yapılandırma işlemlerinden sorumludur. Container’ların dış dünyadan izole olmasını ve container’ların iç networkten birbirleri ile iletişime geçmesini engellemektedir.
- Endpoint: Snadbox bileşenini dış network’e bağlamakla görevlidir. Bir Endpoint sadece bir network’e bağlanabilir.
- Network: Birbirleriyle iletişim kurabilen Endpoint’leri ifade etmektedir. Network, Endpoint – to – Endpoint ve Container – to – Container taşınan yol belirlemektedir.
CNM, 2 interface’e sahiptir:
- Network Driver: Network eklemek ve silmek, container’ların network’e eklenmesi ve çıkartılması işlemlerinden sorumludur.
- IPAM (IP Address Management) Driver): Adres havuzu oluşturmak ve silmek, container’a ip adresi aatamak ve geri almak işlemlerinden sorumludur.
Libnetwork
Docker, 2015’te bünyesine kattığı Socket Plane ekibi tarafından geliştirildi. Temel olarak yazılımcıların network driver yazabilecekleri bir çalışma alanı sunmaktadır. CNM standartlarına göre çalışır. Docker Daemon ile Network Driver arasında bir arabirim sağlamaktadır.
Libnetwork’ün uzun vadeli hedefi Docker ve Linux üzerinde bağımsız çalışan modüller sunmaktır. Docker, Libnetwrok ile network ihtiyaçlarını karşılamayı ve container’a bağlanmak için bir standart getirmeyi planlamaktadır.
Libnetwork kütüphanesi Docker’dan bağımsız olarak kullanılabilir. Ayrıca farklı driver paketlerini desteklemektedir. 2 temel driver tipi bulunmaktadır:
- Local (Dahili) Driver’lar: Ekstra modül gerektirmezler ve default olarak Docker Engine’de yüklüdürler. Bu sebeple direkt olarak container üzerinde tanımlanabilmektedirler. Dahili driverler:
- Bridge
- Host
- None
- Overlay
- MACVlan
- Remote Driver’lar: 3rd Party Plugins
Docker Network Komutları
Docker üzerinden network komutları, docker network ile başlar.
create
Yeni bir network oluşturmak için kullanırız. Bu şekilde bir dizi container’ınızı veya isterseniz sadece birini de izole bir network oluşturarak diğer container’lardan erişimi kapatabiliriz.
1 |
docker network create --driver {dahili driver türü} network_adı |
Ör:
1 |
docker network create --driver bridge sv0-ntwrk |
Yukarıda tanımladığımız yeni network’ü görebiliyoruz. Öncesinde listelenen 3 network ise default olarak Docker tarafından oluşturulanlardır. Bir sistemin çalışması için gerekli olduklarından silinemezler.
Oluşturmuş olduğumuz bir network’te container’ın çalışmasını istiyorsak:
1 |
docker container run --network sv0-ntwrk --name OzelNetworkContainer alpine:latest |
connect
Çalışan bir container’ı, başka bir network’e dahil etmek için kullanılır.
1 |
docker network connect sv1-ntwrk container_adı |
disconnect
Çalışan bir container’ı bir network’ten çıkarmak için kullanılır.
1 |
docker network disconnect sv0-ntwrk container_adı |
inspect
Bir veya daha fazla network’ün detaylarını görmemizi sağlar.
1 |
docker network inspect sv0-ntwrk |
ls
Networkleri listeler
1 |
docker network ls |
prune
Kullanılmayan tüm networkü siler.
1 |
docker network prune |
rm
Bir veya daha fazla sayıda network’ü siler.
1 |
docker network rm sv0-ntwrk |
Docker Network Türleri (Local Driver’lar)
Bridge
docker0 networkünün de dahil olduğu türdür. Bir container özellikle belirtilmediği sürece bridge network tipinde bir network’e tanımlı çalışırlar.
Bu modelde host sunucu ile container’lar arasında özel bir ağ oluşturulur. Ayrıca aynı networkteki container’lar da birbirleri ile iletişime geçebilirler.
IP’ler dhcp atacılığı ile otomatik olarak dağıtılır ve oluşan her container bu dhcp üzerinden bir ip atanarak hayatını devam ettirir; fakat istenirse özel bir ip ve subnet ataması yapmakta mümkündür.
Örnek bir çalışma yapalım.
Örneğimizde 3 container ve 2 network’ümüz olacak. Frontend networkünü dışarı ile konuşur hale getireceğiz, backend network’ü ise dabatase’i ortamdan izole edrek erişilmesinin önüne geçeceğiz. Aradaki bağlantı ise ürünkatalog container tarafından yapılacak.
Network’lerimizi oluşturalım:
1 2 |
docker network create --driver bridge --subnet "192.168.80.0/24" --gateway "192.168.80.1" frontend-ntwrk docker network create --driver bridge backend-ntwrk |
Şimdi sırasıyla container’larımızı oluşturalım:
1 2 3 4 |
docker container run --name webAPI -d --network frontend-ntwrk --ip "192.168.80.100" alpine sleep 60m docker container run --name database -d -e MYSQL_ROOT_PASSWORD=password --network backend-ntwrk mysql docker container run --name urunkatalog -d --network frontend-ntwrk alpine sleep 60m docker network connect backend-ntwrk urunkatalog |
Şimdi frontend-ntwrk detaylarına bakalım ve container’larımız var mı görelim:
1 |
docker network inspect frontend-ntwrk |
Şimdi backend-ntwrk detaylarına bakalım ve container’larımız var mı görelim:
1 |
docker network inspect backend-ntwrk |
Şimdi urunatalog container’ımızdan iki database ve webAPI’a erişebiliyor mu bakalım:
Görüldüğü gibi sorun yok. Şimdi de webAPI erişebilir mi ona bakalım:
Erişemediğimiz ve biririnden yalıtmış olduğumuz görülüyor. İstediğimiz de tam olarak buydu.
Host
Bu modelde host bilgisayarın network’ü doğrudan container network’ü ile eşleştirilmektedir. Bu sebeple container için bir sanal network kartı tanımlanmaz ve doğal olarak bir ip de atanmaz.
Normal şartlar altında bu tür bir şey yapmanız asla tavsiye edilmez. Bunun güvenlik açısından çok fazla sakıncası vardır. Buna rağmen bir container üzerinden kendi bilgisayarınız ve ağınızı tarayacağınız container’lar ayağa kaldırmak isterseniz kullanabilirsiniz.
Bu tür container’lara open container denir. Hostun tüm kaynalarına erişebileceği için bu şekilde isimlendirilirler.
1 |
docker container run --rm -it --network host alpine sh |
None
Bu modelde container herhangi bir network’e dahil olmadan kullanılırlar. Bunlara closed container denir. Bu şekilde tüm diğer container’ardan tamamen izole hale gelmiş olur.
1 |
docker container run --rm -it --network none alpine sh |
Overlay
Birden fazla, çoklu host haberleşmesinde kullanılmaktadır. Docker Swarm konusu olduğu için o kısımda incelenecektir.
MACVlan
Bu modelde container içerisine mac adresi ataması yapılmaktadır. Bu sayede container’ın network üzerinde fiziksel bir aygıtmış gibi görünmesi sağlanmaktadır. Docker, mac adresine göre trafiği container’lara yönlendirmektedir. Bu model, trafiğin doğrudan fiziksel ağa bağlanması istendiği durumlar için idealdir.
Container’lar Arasında Link İşlemleri
Link işlemi, container’ların birbirlerini keşfetmesine, bir container’dan bir başka container kaynaklarına güvenli bir şekilde veri aktarmasına olanak sağlamak için kullanılmaktadır.
Container’lar arasındaki link işlemlerini yapabilmek için –link komutu ile yapılmaktadır. Örnek kullanımı şöyledir:
1 |
docker container run --name container1 --link linklenecek_container_adı:alias container1_image |
Örneğin elimizde database ve web adında iki tane container olsu. Database’i oluşturup, sonra bu database’e web container’ından bir link oluşturalım:
1 |
docker container run --name database -d -e MYSQL_ROOT_PASSWORD=password mysql |
Şimdi de web container’ımızı oluşturalım:
1 |
docker container run --name web -d --link database:db nginx |
Bu işlemi farklı şekilde de yapabiliyoruz. Çalışan bir container’a bu işlemi yapmak için:
1 |
docker network connect --link linklenecek_container_adı:alias network_adı linki_kullanacak_container_name |
Aynı örnek üzerinde bunu gösterecek olursak:
1 |
docker network connect --link database:db sv0-ntwrk web |