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
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.
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
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"
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
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
İş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
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
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
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
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
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.
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
Projenin son haline Github’dan erişebilirsiniz.
Kolay gelsin.
Yorumlar
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.
Terminalden aşağıdaki komutu çalıştırarak Kubernetes Engine API'yi aktif edebilirsin.
gcloud services enable container.googleapis.com