ASP.NET Core Uygulamasını GCP Kubernetes'de Yayınlama

26.03.2022 | dakika okuma

1. Giriş

Bu yazı serisinin konusu, ASP.NET Core ile geliştirdiğimiz API'mizi kubernetes'de nasıl yayınlayacağımız olacak. Bulut sağlayıcısı olarak GCP'yi(Google Cloud Platform) kullanacağız.

Bu bölümde senaryoyu ortaya koyacağım ve çıktının ne olacağı konusunda ön bilgilendirme yapacağım. Ayrıca kubernetes'deki bazı kavramlara kısaca değineceğim.

Tek endpoint'li bir API geliştireceğiz.
Bu API'yi dockerize edeceğiz. Bunun için dockerfile oluşturacağız.
Bu dockerfile ile oluşturacağımız image'ı GCR'ye(Google Cloud Container Registry) göndereceğiz.
Bu image'dan üç tane container ayağa kaldıracağız.
Uygulamaya gelen istekleri container'lara dağıtacak "LoadBalancer" servisini oluşturacağız.

Kubernetes'deki beş tane kavramdan kısaca bahsetmek istiyorum.

Cluster
Cluster, kubernetes sunucusudur. Cluster oluştururken kaç tane "master" kaç tane "node" olacağı gibi tanımlamalar yapılır.

Pod
Pod, uygulamayı temsil eder. Yani uygulamalar pod'larda çalışır. Docker'daki container'a karşılık gelir.

Daha fazla bilgi için aşağıdaki adrese uğrayabilirsiniz.
https://cloud.google.com/kubernetes-engine/docs/concepts/pod

Deployment
Deployment, pod'ların yönetilmesini sağlar. Kaç tane pod ayağı kaldırılacağını, pod'ların hangi image'ı kullanacağını, bu pod'lara hangi environment'ların atanacağını deployment ile tanımlarız.

Daha fazla bilgi için aşağıdaki adrese uğrayabilirsiniz.
https://cloud.google.com/kubernetes-engine/docs/concepts/deployment

Service
Service, pod'larda çalışan uygulamaların dışarıdan erişilebilir hale getirilmesini sağlar. Biz servisimizi "LoadBalancer" olarak yapılandıracağız.

Daha fazla bilgi için aşağıdaki adrese uğrayabilirsiniz.
https://cloud.google.com/kubernetes-engine/docs/concepts/service

Namespace
Cluster içerisinde izolasyon sağlar. Pod'ların, deployment'ların ve service'lerin bir "namespace" altında toplanmasını sağlar. Cluster'da birden fazla uygulama olması durumunda uygulamaların birbirinden izole olmasına imkan verir. Yani her uygulama kendine ait bir namespace altında çalışır.

Daha fazla bilgi için aşağıdaki adrese uğrayabilirsiniz.
https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/

2. Geliştirme Ortamının Hazırlanması

Bu bölümde geliştirme ortamımızı ayarlayacağız.

Gereksinimler

    • Visual Studio Code
    • Docker Desktop
    • Google Cloud Hesabı
    • Google Cloud SDK
2.1. Docker Desktop'ın Kurulması

Makinemizde Docker Desktop'ın kurulu olması gerekiyor. Aşağıdaki adresten uygulamayı indirebilirsiniz ve next next yordamı ile kurabilirsiniz :)

https://www.docker.com/products/docker-desktop

2.2. Google Cloud Hesabı Açılması

Google hesabımız ile Google Cloud hesabı açmamız gerekiyor. Cloud hesabı açtığımızda bir yıl içerisinde kullanmamız için promosyon tanımlanıyor. Bu promosyonu kullanarak denemeler yapabilirsiniz.

Aşağıdaki bağlantıya tıklayarak Google Cloud hesabı açabilirsiniz. Hesabı açtıktan sonra sitenin en üst tarafında bir bant çıkacak. Etkinleştir düğmesine tıklayarak promosyonunuzu aktif edebilirsiniz.

https://console.cloud.google.com/?hl=tr

Google Cloud Platform Faturalandırma
Google Cloud Platform Faturalandırma
2.3. Google Cloud SDK'nın Kurulması

Komutlarımızı local makinemizde çalıştıracağımız için Google Cloud SDK'nın kurulu olması gerekiyor. Aşağıdaki adresten uygulamayı indirebilirsiniz ve next next yordamı ile kurabilirsiniz :)

Not : Beşinci adımda yüklenilmesi istenilen komponentleri sorduğunda "Beta Commands" seçeneğini de aktif etmelisiniz.

https://cloud.google.com/sdk/docs/quickstart-windows

Google Cloud SDK kurulduğunda "gcloud init" komutu otomatik olarak çalışacak. Local makinenizden Google Cloud'a erişebilmeniz için yetkilendirme yapılacak. Bu sebeple google hesap bilgilerinizi girmeniz gerekecek.

Bir proje oluşturmak istiyor musunuz diye sorduğunda hayır diyebilirsiniz. Projeyi kendimiz oluşturacağız.

gcloud init
gcloud init
2.4. GCR'nin Tanımlanması

Image'ların DockerHub yerine GCR'ye gönderilmesi için konfigürasyon yapmamız gerekli. Terminalden aşağıdaki komutu çalıştırmalısınız.

    gcloud auth configure-docker
gcloud auth configure-docker
gcloud auth configure-docker

3. GCP'nin Hazırlanması

3.1. Kubernetes API'nin Aktifleştirilmesi

Google Cloud API'lerinden Kubernetes Engine API'nin aktifleştirilmesi gerekli. Terminalden aşağıdaki komutu çalıştırmalısınız.

    gcloud services enable container.googleapis.com
3.2. Projenin Oluşturulması

Google Cloud hizmetlerini kullanabilmemiz için öncelikle proje oluşturmamız gerekli. Terminalden aşağıdaki komutu çalıştırmalısınız. PROJECT_ID ve PROJECT_NAME alanlarını kendinize göre güncelleyebilirsiniz.

    gcloud projects create [PROJECT_ID] --name=[PROJECT_NAME]
gcloud projects create my-k8s-api-project-1 --name="My K8S API Project"
gcloud project create
gcloud project create

Oluşturulan projeyi görmek için aşağıdaki komutu çalıştırabilirsiniz.

    gcloud projects list
3.3. Projenin Seçilmesi

Local makinemizde google cloud config'e oluşturduğumuz projeyi tanımlamamız gerekiyor. Terminalden aşağıdaki komutu çalıştırmalısınız. PROJECT_ID alanını kendi bilginize göre güncellemeyi unutmayın.

    gcloud config set project [PROJECT_ID]
gcloud config set project my-k8s-api-project-1
gcloud config set project
gcloud config set project

Projenin konfigürasyona eklendiğini görmek için aşağıdaki komutu çalıştırabilirsiniz.

    gcloud config get-value core/project
3.4. Faturalandırmanın Etkinleştirilmesi

Cluster oluşturmadan önce oluşturduğumuz projeye fatura hesabı bağlamalıyız. Account Id'nizi öğrenmeniz için terminalden aşağıdaki komutu çalıştırmalısınız.

    gcloud beta billing accounts list

Google SDK'nın alpha komutlarını yüklemek için aşağıdaki komutu çalıştırmalısınız.

    gcloud components install alpha
gcloud components install alpha
gcloud components install alpha

İşlem tamamlandığında Account Id'yi projenize bağlamak için aşağıdaki komutu çalıştırmalısınız. PROJECT_ID ve ACCOUNT_ID alanlarını kendi bilgilerinize göre güncellemeyi unutmayın.

    gcloud alpha billing projects link [PROJECT_ID] --billing-account [ACCOUNT_ID]

Projenize faturanın başarılı şekilde bağlandığını görmek için aşağıdaki komutu çalıştırabilirsiniz. ACCOUNT_ID alanını kendi bilginize göre güncellemeyi unutmayın.

    gcloud beta billing projects list --billing-account=[ACCOUNT_ID]
3.5. Cluster'ın Oluşturulması

Cluster'ı oluşturmak için aşağıdaki komutu çalıştırmalısınız. CLUSTER_ID ve PROJECT_ID alanlarını kendi bilgilerinize göre güncellemeyi unutmayın.

    gcloud beta container clusters create [CLUSTER_ID] --project=[PROJECT_ID] --addons=Istio --istio-config=auth=MTLS_STRICT --cluster-version=latest --machine-type=n1-standard-2 --num-nodes=1 --region europe-west1

gcloud beta container clusters create my-k8s-api-cluster-1 --project=my-k8s-api-project-1 --addons=Istio --istio-config=auth=MTLS_STRICT --cluster-version=latest --machine-type=n1-standard-2 --num-nodes=1 --region europe-west1
gcloud beta container clusters create
gcloud beta container clusters create

Oluşturulan cluster'ı görmek için aşağıdaki komutu çalıştırabilirsiniz.

    gcloud container clusters list

Tüm hazırlıklarımız tamam. Artık projemizi Kubernetes'de yayınlayabiliriz.

4. Uygulamanın Yayınlanması

Basit bir API oluşturdum. Bu API'yi aşağıdaki komut ile Github'dan çekebilirsiniz.

    git clone https://github.com/ahmetkucukoglu/aspnetcore-k8s-sample.git
cd aspnetcore-k8s-sample
4.1. Dockerfile'ın Oluşturulması ve Image'ın GCR'ye Gönderilmesi

Projenin içerisine .Dockerfile dosyası oluşturuyoruz.

Aşağıdaki komut ile docker'da image oluşturmalıyız. IMAGE_ID alanını kendinize göre belirleyebilirsiniz.

    docker build -t [IMAGE_ID] -f K8SSampleAPI/Dockerfile .
docker build -t my-k8s-api-image:1.0 -f K8SSampleAPI/Dockerfile .

Oluşturduğumuz bu image'ı GCR'ye göndermek için öncelikle tag oluşturalım. LOCAL_IMAGE_ID, PROJECT_ID ve IMAGE_ID alanlarını kendi bilgilerinize göre güncellemeyi unutmayın.

    docker tag [LOCAL_IMAGE_ID] gcr.io/[PROJECT_ID]/[IMAGE_ID]
docker tag my-k8s-api-image:1.0 gcr.io/my-k8s-api-project-1/my-k8s-api-image:1.0

Şimdi bu tag'i kullanarak image'ı GCR'ye gönderelim.

    docker push gcr.io/[PROJECT_ID]/[IMAGE_ID]
docker push gcr.io/my-k8s-api-project-1/my-k8s-api-image:1.0
docker push gcr.io
docker push gcr.io

GCR'ye gönderilen image'ı görmek için aşağıdaki komutu terminalden çalıştırabilirsiniz.

    gcloud container images list
4.2. Namespace'in Oluşturulması

İlk bölümde namespace'den bahsetmiştim. Projenin içerisine namespace.yaml dosyası oluşturuyoruz.

4.satırda namespace'e isim tanımlıyoruz.
6.satırda label tanımı yapıyoruz. Label'ları etiket olarak kullanıyoruz. İstediğimiz şekilde anahtar değer ikilisi olarak label tanımlayabilirsiniz.

Şimdi Kubernetes cluster'ı içerisine bu namespace'i tanımlayalım.

    kubectl create -f K8SSampleAPI/namespace.yaml
kubectl create namespace
kubectl create namespace

Oluşturulan namespace'i görmek için aşağıdaki komutu terminalden çalıştırabilirsiniz.

    kubectl get namespaces --show-labels
4.3. Deployment'ın Oluşturulması

İlk bölümde deployment'dan bahsetmiştim. Projenin içerisine deployment.yaml dosyası oluşturuyoruz.

7. satırda kaç tane pod kaldırılacağını belirtiyoruz.
11. satırda yine label tanımı yapıyoruz. app anahtarı ile uygulamanın ismini belirtiyoruz. Tanımlanan değere service tanımlarken ihtiyacımız olacak.
15. satırdaki image alanına GCR'ye gönderdiğimiz image'ı veriyoruz.

Şimdi Kubernetes cluster'ı içerisine bu deployment'ı tanımlayalım.

    kubectl create -f K8SSampleAPI/deployment.yaml
 kubectl create deployment
kubectl create deployment

Oluşturulan deployment'ı görmek için aşağıdaki komutu terminalden çalıştırabilirsiniz.

    kubectl get deployments --show-labels --namespace development

Deployment yapıldığında üç tane pod ayağa kalkacak. Aşağıdaki komutu çalıştırarak görebilirsiniz.

    kubectl get pods --show-labels --namespace development
4.4. Service'in Oluşturulması

İlk bölümde service'den bahsetmiştim. Projenin içerisine service.yaml dosyası oluşturuyoruz.

9.satırda deployment tanımlarken belirttiğimiz app anahtarındaki değeri yazıyoruz. Bu şekilde service'e gelen istekler belirtilen deployment'daki pod'lara yönledirilir. Yukarıda deployment'da üç tane pod ayağa kaldırılıcağını belirtmiştik.
12. satırda uygulamanın 1453 port'undan yayın yapılması gerektiğini tanımlıyoruz.

Şimdi Kubernetes cluster'ı içerisine bu service'i tanımlayalım.

    kubectl create -f K8SSampleAPI/service.yaml
kubectl create service
kubectl create service

Oluşturulan service'i görmek için aşağıdaki komutu terminalden çalıştırabilirsiniz.

    kubectl get services --show-labels --namespace development

Bu komutu çalıştırdığınızda External-IP bölümünü pending durumunda görebilirsiniz. Uygulama için IP tanımlanması bir dakika kadar sürebilir. IP ataması tamamlandığında uygulama 1453 port'undan yayına açılmış demektir.

kubectl get services
kubectl get services
K8SSampleAPI
K8SSampleAPI

ApiKey ve ApiSecret bilgilerini deployment.yaml'de belirtmiştik. Değerleri environment variable olarak tanımlamıştık. Uygulama içerisinde başarılı bir şekilde bu variable'lara erişildiğini görmüş olduk.

ApplicationId bilgisini uygulama ayağa kalkarken Startup dosyasında belirledim. Deployment'da üç tane uygulama ayağa kaldırıldığı için her uygulamanın kendisine göre ApplicationId bilgisi oluyor. Farklı tarayıcılardan istek yaparsanız bu üç tane farklı ApplicationId'nin döndüğünü görmüş olursunuz. Bu şekilde isteklerin üç farklı pod'a yönlendirildiğini görmüş olduk.

Cluster'ı silmek için aşağıdaki komutu çalıştırabilirsiniz. Cluster silindiğinde namespace, deployment, service ve pod'lar silinecek. CLUSTER_ID alanını kendi bilginize göre güncellemeyi unutmayın.

    gcloud container clusters delete [CLUSTER_ID] --region europe-west1
gcloud container clusters delete my-k8s-api-cluster-1 --region europe-west
gcloud container clusters delete
gcloud container clusters delete

Projenin son haline Github’dan erişebilirsiniz.

ahmetkucukoglu/aspnetcore-k8s-sample

C#
3
0

Kolay gelsin.

Yazıyı Paylaş

Yorumlar

serdar yurtsever
4 yıl önce
selam ahmet,
4.Cluster’ın Oluşturulması sırasında. hata almaktayım. sebebi ne olabilir.

C:\Users\serdaryurtsever\AppData\Local\Google\Cloud SDK>gcloud beta container clusters create my-seyu-api-cluster-1 --project=my-seyu-api-project-1 --addons=Istio --istio-config=auth=MTLS_STRICT --cluster-version=latest --machine-type=n1-standard-2 --num-nodes=1 --region europe-west1
WARNING: Currently VPC-native is not the default mode during cluster creation. In the future, this will become the default mode and can be disabled using `--no-enable-ip-alias` flag. Use `--[no-]enable-ip-alias` flag to suppress this warning.
WARNING: Newly created clusters and node-pools will have node auto-upgrade enabled by default. This can be disabled using the `--no-enable-autoupgrade` flag.
WARNING: Starting in 1.12, default node pools in new clusters will have their legacy Compute Engine instance metadata endpoints disabled by default. To create a cluster with legacy instance metadata endpoints disabled in the default node pool, run `clusters create` with the flag `--metadata disable-legacy-endpoints=true`.
WARNING: Your Pod address range (`--cluster-ipv4-cidr`) can accommodate at most 1008 node(s).
This will enable the autorepair feature for nodes. Please see https://cloud.google.com/kubernetes-engine/docs/node-auto-repair for more information on node autorepairs.
ERROR: (gcloud.beta.container.clusters.create) ResponseError: code=403, message=Kubernetes Engine API is not enabled for this project. Please ensure it is enabled in Google Cloud Console and try again: visit https://console.cloud.google.com/apis/api/container.googleapis.com/overview?project=my-seyu-api-project-1 to do so.
Yanıtla
ahmetkucukoglu
4 yıl önce
Merhaba Serdar,

Terminalden aşağıdaki komutu çalıştırarak Kubernetes Engine API'yi aktif edebilirsin.

gcloud services enable container.googleapis.com
Yanıtla

Yorum bırak

Yanıtla

Yanıtlamayı iptal et
Bu site reCAPTCHA tarafından korunmaktadır ve Google Gizlilik Politikası ve Hizmet Şartları geçerlidir. Yorumunuz başarılı şekilde gönderildi reCaptcha doğrulanamadı
Muhabbetle ASP.NET Core ile geliştirildi.