Docker Registry Kurulumu ve SSL/TLS Aktivasyonu
Docker Registry, Docker image’leri depolayan ve dağıtmanıza olanak tanıyan, durum bilgisi olmayan, yüksek düzeyde ölçeklenebilir bir sunucu tarafı uygulamasıdır. Docker private / local registry ile imageleri kendi sunucunuzda depolayabilir, erişimi kısıtlayabilir ve internet band genişliğinizi rahatlatabilirsiniz.
Local/Private Docker Registry kullanarak şu imkanlara sahip olabilirsiniz;
- İnternet erişimi olmayan ortamlarda istemcilerinizin kullanabilmesi için bir local docker repository oluşturabilirsiniz.
- Registry’e parola ayarlayarak sadece yetkilendirilmiş kullanıcıların erişebilmesini sağlayabilirsiniz.
- Sadece dilediğiniz image’leri yükleyerek belirli ortamlara özel registry’ler oluşturabilirsiniz.
- Registry’i dilediğiniz yere taşıyabilirsiniz (internetsiz bir ortam gibi)
Öyleyse hemen kuruluma başlayalım. Docker local registry kurulumunu Centos 8 ortamına yapacağız. Siz OS seçimini özgürce yapabilirsiniz.
1. Local Docker Registry Kurulumu
İlk olarak Docker registry kurulumunu yapacağımız cihazda registry:2 image’ini run ederek local image’lerimiz arasına indiriyoruz ve aşağıdaki parametrelerle çalıştırıyoruz.
docker run -d -p 5000:5000 --restart=always --name registry registry:2
Docker run
Docker run
komutu, pull
komutunu da içerir. Önce pull
edip ardından run
etmek yerine tek seferde run
komutu kullanarak daha pratik bir kullanım elde edersiniz.
Container çalışmaya başladığında tarayıcımızdan kurulumu yaptığımız cihazın ip adresi ile http://[IPADRESI]:5000/v2/_catalog adresine giderek registry’i kontrol edebilirsiniz. Buradaki 5000 portu, containerı ayağa kaldırırken map ettiğimiz porttur. Dilediğiniz şekilde değiştirebilirsiniz.
Adreste gördüğünüz gibi private local registry artık hazır ve içi boş. Bu Docker Registry’i ilerleyen başlıklarda dolduracağız.
NOT: Docker registry local servera kurulmuş olsa da push
veya pull
etmeye çalıştığımızda hata verecektir. Önce hatayı yaratalım ve sebebi ile çözümünü açıklayalım.
2. Docker Registry Push ve Pull İşlemleri
Docker registry kurulum işlemini tamamladıktan sonra hemen ilk image’imizi local registry’imize push etmeye çalışalım. Bunun için push edeceğimiz image’e ilk olarak tag vermemiz gerekiyor. Aksi halde kendi registry’imize push etmek yerine Docher Hub‘a push etmiş oluruz. Çünkü docker push
kodunun default davranışı budur.
Localimize örnekte kullanmak için alpine image’ini pull
edelim. İndirme işleminden sonradocker images
komutu ile tüm image’leri görelim.
docker pull alpine
docker images
Ardından kendi registry’imize push etmek için tag verme işlemini yapacağız. Tag formatı ise [IPADRESI]:[PORT]/[IMAGE ADI]:[TAG] şeklinde olmalıdır. Böylece push
komutunu kullandığımızda image’i belirttiğimiz ip adresi ve portta yer alan Docker Regitry’e push
etmiş olacak.
docker tag alpine 192.168.1.11:5000/alpine:latest
Artık image’imiz push
etmeye hazır. Öyleyse hadi push edelim:
docker push 192.168.1.11:5000/alpine:latest
Evet, bahsettiğimiz hataya geldik. Docker push
ve pull
komutları HTTPS üzerinden iletişim kurduğu ve bizimde aktif bir SSL/TLS sertifikamız olmadığı için resimdeki hatayı aldık. Zaten hata mesajının başındaki Get “https://… kısmında da durum açıkça gözüküyor. Öyleyse hemen bu sorunu çözelim.
Yukarıdaki hatayı çözmek için iki yöntemimiz mevcut;
- Client üzerindeki docker konfigürasyonunda güvenli olmayan bağlantılara yani HTTP üzerinden haberleşmeye izin vermek.
- Docker registry kurduğumuz sunucuya SSL/TLS sertifikası kurmak ve registry container’ımıza bu sertifikayı eklemek.
Her iki yönteme de tek tek bakalım.
2.1 Docker Registry Güvenli Olmayan Bağlantılara İzin Vermek
Docker Registry Güvenli Olmayan Bağlantılar
Bu başlıkta anlatılan yöntemi kullanmanızı tavsiye etmiyoruz. Registry sunucunuz ile aranızdaki güvensiz bağlantı man-in-the-middle saldırılarına açıktır ve verileriniz tehdit altında olabilir.
Docker Registry’e yapılacak olan bağlantı ve istekler default olarak HTTPS üzerinden yapılır. Fakat sunucunuzda SSL/TLS sertifikası mevcut değilse push ve pull komutu çalıştıracak istemcilerin Docker konfigürasyonunda güvensiz bağlantılara izin vermemiz gerekir.
Docker Registry güvensiz bağlantılara Windows üzerinde izin vermek için Docker Client programına giriniz ve Ayarlar sayfasından Docker Engine sekmesine gelerek konfigürasyonun sonuna aşağıdaki parametreyi ekleyiniz. IP adresini ve portunu Docker Registry kurduğunuz cihazın IP adresi ve portuyla değiştirip kaydediniz ve Docker servisini yeniden başlatınız.:
"insecure-registries" : ["IPADRESI:PORT"]
Tekrar deneyelim.
Tebrikler! Windows tarafını hallettik. Şimdi de Docker Registry sunucusuna güvensiz bağlantılara Centos istemcide izin verelim. Bunun için /etc/docker/
dizininde daemon.json
isimli bir dosya oluşturalım ve vim/nano gibi bir editörle dosyayı açalım. Dosyaya aşağıdaki içeriği ekleyelim ve kendi IP adresimiz ve portumuzla değiştirelim.
{
"insecure-registries" : ["IPADRESI:PORT"]
}
Ardından docker servisimizi restart edelim.
systemctl restart docker
Hemen teste geçelim.
Tekrardan tebrikler! Artık Docker private / local registry’inizi özgürce kullanabilirsiniz.
2.2 Self-Signed Sertifikalar İle Docker Registry Sunucusuna SSL/TLS Eklemek
Bir önceki başlıkta yer alan yöntemin aksine Docker Registry sunucunuza SSL/TLS sertifikası ekleyerek bağlantılarınızın HTTPS üzerinden yapılmasını sağlayabilirsiniz.
Eğer sunucunuz bir domaine bağlıysa direkt CA (Certificate Authorites) üzerinden bu domaine geçerli bir sertifika alabilir ve güvenli bir bağlantı ile iletişim kurabilirsiniz. Fakat bir domaine sahip olsanız bile CA’ya ücret ödemeden domaininizi Self Signed sertifikalar ile imzalayabilirsiniz.
Sunucunuz eğer domaine bağlı değil ve sadece IP adresi ile bağlantı kuruyorsunuz mecbur olarak Self Signed sertifika kullanmanız gerekecek. Çünkü CA’lar sadece DNS üzerindeki domainleri imzalayabilir, IP adreslerini sertifikalandıramaz. Fakat IP adreslerini Self Signed sertifikalar ile imzalayabiliriz.
Self Signed Sertifikalar
Self Signed Sertifikalar, kendinden imzalı sertifikalardır. Kayıtlı bir dijital sertifika otoritesi yerine bizzat sertifikayı üreten tarafından imzalanmıştır. Bu nedenle imzalayanın güvenilirliğini teyit etmenin mümkün olmadığı, kendisinin güvenilirliği de teyit edilemeyen dijital sertifika çeşididir.
Self Signed Sertifika Kurulumu
Self signed sertifika oluşturabilmek için OpenSSL kullanacağız. Bunun için CentOS’ta bulunduğumuz dizinde (örnekte işlemleri registrycerts
isimli dizinde gerçekleştireceğim) config
isimli dosya oluşturalım ve vim/nano editör ile açalım. Ardından aşağıdaki satırları içine ekleyerek kendinize göre düzenleyiniz.
[req]
default_bits = 4096
default_md = sha256
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = TR
ST = AN
L = ANKARA
O = Kerteriz
OU = Blog
CN = 192.168.1.11
emailAddress = bilgi@kerteriz.net
[v3_req]
keyUsage = keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = kerteriz-dockerregistry.net
IP.1 = 192.168.1.11
DNS alanını IP adresi yerine domain kullanacaksanız ekleyebilirsiniz. Aksi halde yazmasanız da olur. Ek olarak CN
ve IP
alanı ise Docker Registry’nin kurulu olduğu cihazımızın IP adresi olmalıdır.
Dosyamız artık hazır olduğuna göre aşağıdaki openssl komutu registrycerts
dizininde çalıştıralım ve imzalarımızı oluşturalım.
openssl req -new -nodes -x509 -days 365 -keyout domain.key -out domain.crt -config config
Artık sertifikamızı elde ettik. Önceki çalışan registry container’ını durdurup siliniz ve aşağıdaki komutlar ile sertifikalarımızı da belirterek image’i yeniden çalıştırınız.
docker run -d -p 5000:5000 --restart=always --name registry \
-v /home/dataserver/registrycerts:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5000 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry:2
Bu komuttaki mount ettiğimiz dizin daha yeni oluşturduğumuz imzaların olduğu dizin (registrycerts
) olmalıdır. Container çalıştıktan sonra https://[IPADRESI]:5000/v2/_catalog adresini hem Windows hem CentOS cihazda ziyaret edelim.
Kısmen bravo! HTTPS bağlantısı ile Docker registry sayfamıza ulaştık fakat tarayıcımız sertifikanın güvenli olmadığını söylüyor. Şimdilik görüntülemeye devam et diyerek _catalog
sayfamıza bakalım ama birazdan bunu da düzeltmiş olacağız.
Sorunu düzeltmeden önce birde docker push
ve pull
komutu deneyelim.
Artık yeni bir hatayla karşı karşıyayız. Hata metnimiz ise “x509: certificate signed by unknown authority”. Hatanın sebebi tarayıcıda gördüğümüz hata ile aynı sebepten kaynaklanıyor. Çünkü Self-signed sertifikalar tanınan CA’lar tarafından imzalanmadığı için işletim sistemlerindeki Trusted Root Certification Authorities tarafından tanınmaz ve güvenilmez. Çözüm olarak ise bu sertifakaları OS ve docker servisimize tanıtacağız.
2.2.1 Windows – Self Signed Sertifikaların Os ve Docker Servisine Eklenmesi
Yukarıda gördüğünüz “x509: certificate signed by unknown authority” hatasını OS ve Docker tarafında çözerek pull ve push komutlarımızı çalışır hale getireceğiz.
Sorunu Windows tarafında çözebilmek için Docker Registry adresine giderek tarayıcıdaki güvenlik simgesine ve ardından Certificate yazısına tıklayınız. Açılan pencerede Details sekmesine eliniz ve Copy to File butonuna tıklayarak Next butonlarıyla sonuna kadar ilerleyiniz. Ardından sertifikayı dışarı aktarınız. Aşağıdaki gif ile nasıl yapacağınızı görebilirsiniz.
Windows Başlat menüsünden Manage User Certificates (certmgr) ayarlarına gidiniz. Açılan pencereden Trusted Root Certification Authorites ayarının altında yer alan Certificates‘e sağ tıklayınız ve All Tasks menüsündeki Import‘a tıklayınız.
Açılan pencereden kaydettiğiniz sertifikayı seçerek import ediniz. Aşağıdaki gif ile nasıl yapıldığını izleyebilirsiniz.
Bu işlemlerin geçerli olabilmesi bilgisayarınızı yeniden başlatınız. Kontrol için tekrar sayfamıza giriş yapalım.
Bravo! Windows artık sertifikamıza güveniyor ve güvenli olarak işaretliyor. Şimdi ise Docker pull ve push işlemini kontrol edelim.
Çok iyi gidiyoruz. Artık CentOS tarafında nasıl çözeceğimizi görelim.
2.2.2 CentOS – Self Signed Sertifikaların Os ve Docker Servisine Eklenmesi
Aynı sorunu CentOS tarafında da çözebilmek için iki işlem gerçekleştireceğiz. İlki CentOS için OS seviyesinde bu sertifikayı eklemek, ikincisi Docker servisine ilgili sertifikayı eklemek. İlk olarak Docker servisine oluşturduğumuz sertifikayı ekleyelim. Bunun için aşağıdaki komuttaki ip adresini ve portu düzenleyerek çalıştırınız ve ilgili dizini oluşturunuz. Ardından domain.crt
dosyasını bu dizine kopyalayıp docker servisini restart ediniz.
mkdir -p /etc/docker/certs.d/ip_address:5000
cp domain.crt /etc/docker/certs.d/ip_address:5000
systemctl restart docker
Şimdi push
komutumuzu tekrar deneyelim.
CentOS için OS seviyesinde oluşturduğumuz sertifikayı Trusted Authorities’e eklemek için ise aşağıdaki iki basit komutu uygulamanız yeterlidir.
cp domain.crt /usr/local/share/ca-certificates/ca.crt
cp domain.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust
2.3 Docker Registry Erişimini Parola İle Kısıtlama
Kurduğumuz Docker Local Registry’nin public olmasını istemiyor ve push/pull işlemlerini kısıtlamak gibi bir düşünceniz varsa Basic Authentication ile bunu yapabiliriz. Daha önceki HTTP Authentication methodlarında anlattığımız bir yöntem olan Basic Auth. burada işe yarayacak.
Erişim kısıtlamasına ulaşmanın en basit yolu, temel kimlik doğrulamadır [Basic Authentication] (bu, diğer web sunucularının temel kimlik doğrulama mekanizmasına çok benzer). Bu örnek, secret’ları depolamak için htpasswd kullanan yerel temel kimlik doğrulamasını kullanır.
Centos makinede ilk olarak test kullanıcısı için testuser
kullanıcı adı ve testpassword
parolası ile tek girişli bir şifre dosyası oluşturalım:
mkdir auth
docker run \
--entrypoint htpasswd \
httpd:2 -Bbn testuser testpassword > auth/htpasswd
Windows’ta çıktı dosyasının doğru şekilde kodlandığından emin olmak için yukarıdakini değil, aşağıdaki kodu kullanın.
docker run --rm --entrypoint htpasswd httpd:2 -Bbn testuser testpassword | Set-Content -Encoding ASCII auth/htpasswd
Eski çalışan registry container’ini durdurunuz.
docker container stop registry
Registry’i temel kimlik doğrulama ile başlatalım.
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v "$(pwd)"/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v "$(pwd)"/registrycerts:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
Registry’den bir image pull ve push tmeyi deneyin. Bu komutlar başarısız olur.
Kimlik doğrulamasından geçerek hatayı çözmek için önce login olmamız gerekiyor.
Artık push
ve pull
komutlarını başarıyla gerçekleştirebilirsiniz.
2.4 Docker Registry Storage Alanını Değiştirme
Docker Registry oluşturduğunuzda image’leriniz container’in içinde depolanır ve bu container silindiğinde registry’e şimdiye kadar push ettiğiniz tüm image’ler de silinmiş olur. Bunun önüne geçebilmek için Registry’e özel bir depolama alanı mount edeceğiz. Mount edebilmek için özel bir NAS veya HDD/SSD disk alanı verebilirsiniz. Karar tamamen sizin.
Örnekte CentOS /mnt/registry
dizinimi container’in içindeki /var/lib/registry/
dizinine mount edeceğiz.
docker run -d \
-p 5000:5000 \
--restart=always \
--name registry \
-v /mnt/registry:/var/lib/registry \
registry:2
Artık tüm imageleri bu dizin altında görebiliriz.
2.5 Docker Registry Default Port Değiştirme
Docker registry kurduktan sonra container içindeki default port 5000 olarak gelir. Siz port mappingte container’ın içindeki 5000 portunu map eden kısmı dilediğinizce değiştirebilirsiniz (Ör: -p 8000:5000
). Fakat container’ın içindeki portu değiştirmek isterseniz ne yapacaksanız?
Docker registry container içindeki default 5000
portu değiştirmek için REGISTRY_HTTP_ADDR
parametresini kullanıyoruz. Böylece sadece dışarıya map ettiğiniz portu değil, aynı zamanda container içindeki portu da değiştirmiş olursunuz.
docker run -d \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5001 \
-p 5001:5001 \
--name registry-test \
registry:2
3. SONUÇ
Docker Registry kurulumuna ait tüm detayları detaylıca ve örnekleriyle sizlere sunduk. Takıldığınız yerler ve sorularınız için aşağıdaki yorum kutusunu kullanabilirsiniz. İyi bloglar.
Docker serimizin sıradaki yazısı için aşağıdaki bağlantıyla devam edebilirsiniz.