İçeriğe geç →

ASP.NET Core Serisi 03: RESTful API’ı Containerize Edip Azure Container Service ile Kubernetes’e Deploy Etmek

Merhaba .NET Core severler.

Daha önce ASP.NET Core serisinin 1. bölümünde bir RESTful API geliştirip, Azure App Services’e deploy işlemini gerçekleştirmiştik. Şimdi bu 3. bölümünde ise, daha önce geliştirmiş olduğumuz bu RESTful API‘ı, nasıl containerize edebileceğimizi ve ardından Azure Container Service ile Kubernetes‘e nasıl deploy edebiliriz gibi konulara, çalışmakta olduğum firmada .NET Core transformation sürecinde elde edebildiğim tecrübeler doğrultusunda değinmeye çalışacağım.

Konu başlıkları sırasıyla:

  1. Docker Image’i Oluşturma ve Docker Hub Üzerine Push Etmek
  2. Azure Container Service Kullanarak Kubernetes Cluster’ı Oluşturmak
    1. SSH RSA Public Key Oluşturma
    2. Service Principal Client ID and Secret Oluşturma
    3. Kubernetes Cluster’ı Oluşturma
    4. Kubernetes Cluster’ına Bağlanmak
    5. Kubernetes Cluster’ı İçerisindeki Bir Pod’da ASP.NET Core RESTful API’ını Çalıştırma
    6. Kubernetes Service ile Pod’u Expose Etmek
    7. Kubernetes Deployment Controller’ı Oluşturma ve Expose Etme

NOT: Bu makale içerisinde detaylı olarak Docker nedir, neden ihtiyaç duyarız gibi konulara değinmeyeceğim. Bu makale için Docker hakkında biraz bilgiye sahip olmanız gerekmektedir.

Bildiğimiz gibi container image’i lightweightstand-alone ve her an çalışmaya hazır application parçalarıdır. Container’lar ile uygulamalarımız, aynı infrastructure altında birbirlerinden izole bir şekilde  çalışabilmektedir. Böylece development ve staging ortam farklılıkları birbirlerinden ayrılabileceği için, oluşabilecek conflict’lerin azaltılmasına da yardımcı olmaktadır.

Containerizing işlemi için “ASP.NET Core Serisi 01: Dapper ile RESTful API Tasarlama ve Azure App Services’e Deploy” isimli makale içerisinde geliştirdiğimiz örnek projeyi kullanacağız. Örnek projeyi GitHub üzerinden download edelim ve masaüstüne unzip işlemini gerçekleştirelim.

1. Bölüm – Docker Image’i Oluşturma ve Docker Hub Üzerine Push Etmek

NOT: Gerçekleştireceğim işlemler için, Windows platformu üzerinde DockerToolbox kullanmaktayım.

Bu aşamada ilk olarak, bir image build edebilmemiz için unzip yaptığımız projenin root dizininde, aşağıdaki gibi bir Dockerfile oluşturalım.

Dockerfile içerisinde base olarak offical compiled ASP.NET Core image’ini kullanacağımızı ve “5000” port’u üzerinden ise expose edeceğimizi tanımladık. Entrypoint olarak ise, projeyi publish ettikten sonra elde edecek olduğumuz “aspnetcore-rest-api-with-dapper.dll” dosyasını belirttik.  Şimdi projenin root dizinine herhangi bir command tool’u ile girelim ve projeyi aşağıdaki gibi build edelim.

NOT: “dotnet restore” komutu ile package’ları restore etmeyi unutmayın.

Build işleminin başarıyla gerçekleşmesinden sonra, aşağıdaki komutu kullanarak projeyi publish edelim.

Artık, publish işleminin ardından Dockerfile’ı kullanarak bir image build edebiliriz. Image build edebilmemiz için aşağıdaki komutu çalıştırmamız yeterli olacaktır.

Publish sonrası elde ettiğimiz “bin\Release\netcoreapp1.1\publish” path’ini kullanarak, “aspnetcorerestapionlinux” isminde bir image build ettik. Aşağıdaki komutu kullanarak, oluşturulan image’leri görebiliriz.

Yukarıdaki resimde, “aspnetcorerestapionlinux” ismi ile image’in oluştuğunu görebiliriz.

Şimdi, yaptığımız işlemlerin doğru gittiğinden emin olabilmek için oluşturmuş olduğumuz image’i, bir container içerisinde aşağıdaki gibi çalıştıralım.

Oluşturmuş olduğumuz “aspnetcorerestapionlinux” image’ini, bir container içerisinde “5000” port’u üzerinden expose ederek çalıştırdık. Şimdi browser üzerinden “http://192.168.99.100:5000/swagger” URL’ine girelim ve projenin çalıştığından emin olalım.

Tadaa! Oluşturmuş olduğumuz image, container içerisinde başarılı bir şekilde çalışmaktadır. Buraya kadar olan kısımda, ASP.NET Core ile geliştirmiş olduğumuz RESTful bir API’ın containerizing işlemini tamamladık.

Şimdi ise oluşturmuş olduğumuz bu “aspnetcorerestapionlinux” image’ini, Docker Hub üzerine push edeceğiz. Bu sayede Azure Container Service içerisinde bu image’i pull ederek, Kubernetes cluster’ı içerisinde çalıştıracağız. Öncelikle push işlemini gerçekleştirebilmemiz için, Docker Hub account’ına sahip olmamız gerekmektedir. Eğer account’a sahip değilsek, buradan oluşturabiliriz.

İlk olarak oluşturmuş olduğumuz image’e, aşağıdaki gibi bir tag eklememiz gerekmektedir.

NOT: “gokgokalp” olan kısmı, kendi Docker Hub kullanıcı adınız ile değiştirmeyi unutmayın.

Şimdi ise Docker Hub üzerine login olmamız gerekmektedir.

Login olma işlemi başarıyla gerçekleştikten sonra aşağıdaki gibi oluşturmuş olduğumuz image’i, Docker Hub üzerine push edelim.

2. Bölüm – Azure Container Service Kullanarak Kubernetes Cluster’ı Oluşturmak

Azure Container Service, containerize hale getirdiğimiz uygulamalar için basit ve hızlı bir şekilde sanal makineler oluşturabilmemizi, yapılandırabilmemizi ve cluster yapımızı yönetebilmemizi kolaylaştırmak için çözümler sunmaktadır. Microsoft‘un bir kaç ay önce Kubernetes container orchestration service’ini de tamamen available hale getirmesiyle beraber, efficiently bir şekilde containerize edilmiş uygulamalarımızı deploy ve on the fly olarak scale edebilmek kolay bir hal almıştır.

Şimdi Azure Container Service‘ini kullanarak, basic bir şekilde Kubernetes cluster’ı oluşturacağız. Cluster oluşturabilmek için öncelikle aşağıdaki maddelere ihtiyaç duymaktayız:

  • Azure subscription – “ASP.NET Core Serisi 01” makalesinde, nasıl elde edeceğimizden bahsetmiştim.
  • SSH RSA public key – Virtual machine’lere authenticate olabilmek için oluşturmamız gerekmektedir.
  • Service Principal client ID and secret – Orchestrator olarak Kubernetes kullanacağımız için “Azure Active Directory service principal client ID” ye ve “secret” a ihtiyacımız var.

Haydi ozaman başlayalım.

2.1 SSH RSA Public Key Oluşturma

Windows üzerinde oluşturabilmek için, Git for Windows‘un kurulu olması gerekmektedir. Eğer kurulu değilse: https://git-for-windows.github.io/

Git Bash‘i açalım ve aşağıdaki komut satırı ile “openssl.exe” yi kullanarak, “myPrivateKey” ve “myCert” certificate’ini oluşturalım.

Bu işlem sırasında size “Country Name, State, E-mail, Organization Name” gibi bir kaç bilgi soracaktır. Gerekli bilgileri girdikten sonra, “myPrivateKey” ve “myCert” certificate’i, ilgili path altında oluşacaktır.

Şimdi ise aşağıdaki komutu kullanarak, oluşturmuş olduğumuz private key ile “myPublicKey” adında bir public key oluşturacağız.

PuTTY SSH client’ını kullanabilmemiz için, ek bir key daha oluşturmamız gerekmektedir. Bunun için:ddddddd

Bununla birlikte “myPrivateKey_rsa” isminde bir private key daha elde ettik.

Şimdi oluşturmuş olduğumuz bu “myPrivateKey_rsa” key’ini kullanarak, Azure portal üzerinde Linux VM yaratırken kullanacağımız public key’i oluşturacağız. Bunun için öncelikle buradanPuTTY ‘i indirelim ve kuralım. Kurulum işleminin ardından “PuTTYgen” uygulamalasını çalıştıralım ve “Load” kısmından oluşturmuş olduğumuz “myPrivateKey_rsa” key’ini seçelim.

Yukarıdaki resimde gördüğümüz gibi “ssh-rsa” prefix’i ile başlayan bir public key daha elde etmiş olduk. Makalenin ilerleyen bölümünde kullanabilmek için, bu key bilgisini de kaydedelim.

2.2 Service Principal Client ID and Secret Oluşturma

Bu noktada Azure AD (Active Directory) service principal oluşturma işlemini, portal üzerindeki terminal’den gerçekleştireceğiz. Azure portal‘a login olduktan sonra, sağ üst menüde bulunan “Cloud Shell” i açalım.

Cloud Shell” i açtıktan sonra, öncelikle aşağıdaki komut ile “aspnetcore-test-restapi” adında bir resource group oluşturalım.

Resource group’u oluşturmanın ardından, aşağıdaki komut içerisindeki “mySubscriptionID” bölümüne kendi subscription ID bilgimizi girelim çalıştıralım.

Bu işlemin ardından aşağıdaki gibi bir output elde edeceğiz.

Buradaki “appId” yi principal client ID olarak, “password” u ise secret olarak kullanacağız.

2.3 Kubernetes Cluster’ı Oluşturma

  1. Azure portal üzerine login olalım.
  2. Sol üst menüden “New” kısmına tıklayalım.
  3. Açılan menüden aşağıdaki gibi “Containers > Azure Container Service” kısmını seçelim.

  4. Basics” kısmında, resource group altındaki “Use existing” butonuna tıklayalım ve daha önce oluşturmuş olduğumuz resource group olan “aspnetcore-test-restapi” ı seçelim ve diğer alanları da aşağıdaki gibi dolduralım. (Sizler de kendinize uygun doldurabilirsiniz)
  5. Şimdi ise “Master configuration” kısmından orchestrator gibi önemli bilgileri tanımlayacağız. “Orchestrator” olarak “Kubernetes” i seçelim ve ardından “DNS name prefix” gibi field’ları aşağıdaki gibi dolduralım.
    Devamında ise “SSH public key” ve “Service principal” bölümlerini yukarıda elde ettiğimiz bilgiler doğrultusunda tamamlayalım.
  6. Agent configuration” bölümü üzerinden de demo olduğu için “Agent count” olarak “1” ve “Standard DS2” seçiyorum.

Artık bir Kubernetes cluster’ına sahibiz.

2.4 Kubernetes Cluster’ına Bağlanmak

Local makinemizden Kubernetes cluster’ına bağlanabilmemiz için, “kubectl” i kurmamız gerekmektedir. Bunun için buradan, ilgili işletim sistemimize göre Azure CLI‘ı indirelim ve kuralım. Kurulum işleminin ardından, command tool açalım ve aşağıdaki komut ile “kubectl” in kurulumunu gerçekleştirelim.

Şimdi ise Kubernetes cluster configuration bilgilerini download etmemiz gerekmektedir. Öncelikle aşağıdaki komut ile, portal bilgilerimizi kullanarak Azure üzerine login olalım.

Login olduktan sonra, aşağıdaki komut üzerinde gerekli değişiklikleri yapalım ve çalıştıralım.

Cluster configuration bilgilerinin başarıyla download edildiğinden emin olabilmek için, aşağıdaki komutu da çalıştıralım ve node listesini görelim.

2.5 Kubernetes Cluster’ı İçerisindeki Bir Pod’da ASP.NET Core RESTful API’ını Çalıştırma

Dokümantasyonunda da olduğu gibi, Pod’u tek bir cümle ile tanımlamak gerekirse eğer:

Kubernetes içerisindeki küçük, deployable computing birimleridir.

Pod, bir veya birden fazla application container’larını içerebilmektedir. Şimdi Kubernetes cluster’ı içerisinde bir pod oluşturabilmemiz için, projenin root klasörü altında “aspnetcore-rest-api-pod.yaml” adında aşağıdaki gibi bir YAML file’ı tanımlayalım.

Yukarıda tanımlamış olduğumuz YAML file’ı içerisindeki “image” kısmına, Docker repo’ya push yaptığımız image’i belirtiyoruz. Hatırlarsak API‘ı container içerisinde de “5000” port’u üzerinden expose etmiştik.

Şimdi aşağıdaki komutu, projenin root dizini altında command tool’u üzerinden çalıştıralım.

Gördüğümüz gibi pod’u başarıyla oluşturduk. Şimdi aşağıdaki komut ile oluşturmuş olduğumuz pod’a bir bakalım.,

Yukarıdaki resimde oluşturmuş olduğumuz “aspnetcore-restapi” pod’unun, “running” statüs’ünde çalıştığını görebiliriz. Bu pod içerisinde, demo projemiz olan ASP.NET Core RESTful API’ı çalışmaktadır. Artık yapmamız gereken tek şey, bu pod’u dışarıya Kubernetes Service ile expose etmek olacaktır.

2.6 Kubernetes Service ile Pod’u Expose Etmek

Kubernetes Service, logical pod’lar seti tanımlayabilmek ve policy’ler oluşturabilmek için olan bir abstraction’dır. Detaylı bilgiye ise, buradan ulaşabilirsiniz.

Şimdi Kubernetes Service için “aspnetcore-rest-api-ks.yaml” adında bir YAML file daha oluşturalım.

Yukarıdaki YAML file’ı ile “aspnetcore-restapi-service” adında, target TCP port’u “5000” olan bir Kubernetes Service‘i oluşturacağız. Ayrıca “selector” kısmında bulunan “app: aspnetcore-restapi” değerinin, oluşturmuş olduğumuz pod’un label’ı ile aynı olduğuna dikkat edelim. Şimdi service’i oluşturabilmek için, aşağıdaki komutu çalıştıralım.

Service oluşturma işleminin ardından, aşağıdaki komut ile de service listesine bir bakalım.

Yukarıdaki resme dikkat edersek “aspnetcore-restapi-service” adlı service’in, otomatik olarak assign edilen “52.232.119.105” external IP‘si ile expose olduğunu görebiliriz.

NOTIP assign edilme işlemi, bir kaç dakika sürebilir.

Browser üzerinden eriştiğimizde ise, aşağıdaki gibi Swagger UI karşımıza gelecektir.

Şimdi geriye sadece Deployment Controller‘ı oluşturmak kaldı.

2.7 Kubernetes Deployment Controller’ı Oluşturma ve Expose Etme

Bu noktaya kadar Azure Container Service‘i kullanarak bir Kubernetes cluster’ı oluşturduk ve içerisinde RESTful API’ımızın container’ının çalıştığı bir pod tanımladık. Daha sonra bir Kubernetes Service‘i tanımlayarak, Load Balancer ile “80” port’u üzerinden dışarıya expose ettik.

Buraya kadar her şey yolunda. Eğer pod’larla ilgili buradan Durability of pods (or lack thereof)” başlığını okursak: pod’ların durable entities olmadıklarını ve scheduling failures, node failures gibi durumlarda yeniden kullanılamadıklarını görebiliriz. Buda demek oluyor ki ilgili pod öldüğünde, ilgili service ulaşılamaz olacaktır. Production ready olup bu gibi durumlara maruz kalmamamız için, Kubernetes Controller‘ları kullanmalıyız. Kubernetes içerisinde, Deployments ve Replication Controller gibi controller’lar mevcuttur. Biz burada Replication Controller‘ın yeni nesli olan Deployments‘ı kullanacağız. Deployments genel olarak self-healing, rollout management, scaling gibi önemli işlemleri sağlamaktadır.

Şimdi, aşağıdaki gibi “aspnetcore-rest-api-deployment.yaml” adında bir deployment YAML file’ı tanımlayalım.

Dikkat edersek “replicas” bölümünü “3” olarak tanımladık ve ardından “containers” bölümü altında ise tıpkı pod oluşturma YAML file’ında olduğu gibi, ilgili image bilgilerini ve port bilgilerini belirttik. Artık bu template doğrultusunda Deployment, scheduling failures ve node failures gibi durumlar karşısında bizim için “3” adet replika’nın var olduğundan emin olacaktır.

Aşağıdaki komut ile deployment’ı oluşturmadan önce, daha önce oluşturmuş olduğumuz “aspnetcore-rest-api-pod.yaml” pod’unu ve “aspnetcore-rest-api-ks.yaml” service’ini silelim.

Şimdi deployment’ı oluşturabiliriz. Bunun için:

ve deployment oluşmuş durumda. Hemen oluşan pod’lara bir bakalım:

Yukarıda gördüğümüz gibi deployment, 3 adet “running” statüs’ünde pod oluşturmuş durumdadır. Ayrıca deployment ile daha fazla yükü otomatik olarak scale edebilmekte mümkündür. Bunun için detaylı bilgiye, buradan erişebilirsiniz.

Şimdi ise geriye kalan tek şey, bir service oluşturarak bu 3 pod’u dışarıya tekrardan expose etmek olacaktır. Bu işlem için daha önce kullanmış olduğumuz “aspnetcore-rest-api-ks.yaml” file’ını tekrardan kullanacağız. Hatırlarsak deployment controller ile pod’ları oluşturabilmek için service’i silmiştik.

Bu service “app: aspnetcore-restapi” label’ına sahip olan 3 pod’u, “80” port’u üzerinden dışarıya expose edecektir.

Sonunda hazırız. 🙂 Yukarıdaki resimler görebildiğimiz gibi bu 3 pod’u dışarıya bir Load Balancer service’i ile expose ettik. Hangi endpoint’leri expose ettiğine bakmak gerekirse eğer, aşağıdaki komutu çalıştırmamız yeterli olacaktır.

Yukarıdaki komutu çalıştırmanın ardından Load Balancer service’inin “10.244.1.7:5000“, “10.244.1.8:5000” ve “10.244.1.9:5000” pod’larını “http://52.232.119.105” URL’i üzerinden expose ettiğini görebiliriz.

Biraz uzun bir makale oldu ama gerçekten zevkli ve önemli bir konu. Şuan çalışmakta olduğum firmada, bazı projeler için .NET Core transformation’ı ile birlikte Containerizing ve Kubernetes konuları üzerinde yoğun bir şekilde çalışmaktayım. Bu makale umarım ihtiyacı olanlara yardımcı olur.

Bir sonraki .NET Core makale serisinde ise, Jenkins kullanarak CI pipeline süreçlerine nasıl dahil edebiliriz konusunu ele almaya çalışacağım.

Takip de kalın!

https://github.com/GokGokalp/containerizing-and-kubernetes-sample-files

Bazı Referanslar ve Kaynaklar

https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/container-service/container-service-tutorial-kubernetes-prepare-app.md
https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/container-service/container-service-tutorial-kubernetes-prepare-acr.md
https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/container-service/container-service-tutorial-kubernetes-deploy-cluster.md
https://github.com/MicrosoftDocs/azure-docs/blob/master/articles/container-service/container-service-tutorial-kubernetes-deploy-application.md
https://www.docker.com/what-container
https://docs.microsoft.com/tr-tr/azure/container-service/container-service-intro
https://kubernetes.io/docs/concepts/overview/what-is-kubernetes
https://docs.microsoft.com/en-us/azure/container-service/container-service-deployment
https://docs.microsoft.com/en-us/azure/virtual-machines/linux/ssh-from-windows
https://docs.microsoft.com/en-us/azure/container-service/container-service-kubernetes-walkthrough
http://www.c-sharpcorner.com/blogs/containerizing-a-net-core-application-using-docker-acs-and-kubernetespart-4
https://kubernetes.io/docs/concepts/services-networking/service/

Bu makale toplam (3381) kez okunmuştur.

25
0



Kategori: ASP.NET Core Azure Containerizing

2 Yorum

  1. mustafa mustafa

    süper bir konu kalemine sağlık

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.