1. Genel Bakış
Bu laboratuvarda, container mimarisine alınmış bir ortamda Python uygulamaları geliştirmekle görevli yazılım mühendisleri için geliştirme iş akışını kolaylaştırmak amacıyla tasarlanmış özellikler ve beceriler gösterilmektedir. Tipik container geliştirme yöntemleri, kullanıcının container ayrıntılarını ve container derleme sürecini anlamasını gerektirir. Buna ek olarak, geliştiricilerin uzak ortamlarda uygulamalarını test etmek ve hata ayıklamak için genellikle akışlarını kesmeleri, IDE'lerinden çıkmaları gerekir. Geliştiriciler, bu eğitimde bahsedilen araçlar ve teknolojiler sayesinde, IDE'lerinden ayrılmadan container mimarisine alınmış uygulamalarla verimli bir şekilde çalışabilirler.
Öğrenecekleriniz
Bu laboratuvarda, GCP'de container'larla geliştirme yapmaya yönelik aşağıdaki gibi yöntemleri öğreneceksiniz:
- Yeni Python başlangıç uygulaması oluşturma
- Geliştirme sürecini adım adım gösterme
- Basit bir CRUD dinlenme hizmeti geliştirin
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
- Google Cloud Console'da oturum açıp yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.
- Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir ve bunu istediğiniz zaman güncelleyebilirsiniz.
- Proje Kimliği, tüm Google Cloud projelerinde benzersiz olmalıdır ve değiştirilemez (belirlendikten sonra değiştirilemez). Cloud Console, otomatik olarak benzersiz bir dize oluşturur. bunun ne olduğunu umursamıyorsunuz. Çoğu codelab'de, Proje Kimliğine referans vermeniz gerekir (ve bu kimlik genellikle
PROJECT_ID
olarak tanımlanır). Beğenmezseniz başka bir rastgele kod oluşturun ya da kendi proje kimliğinizi deneyip mevcut olup olmadığına bakın. Sıcaklık "soğudu" takip etmeniz gerekir. - Bazı API'lerin kullandığı üçüncü bir değer, yani Proje Numarası daha vardır. Bu değerlerin üçü hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
- Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i çalıştırmanın maliyeti, yüksek değildir. Bu eğitim dışında faturalandırmayla karşılaşmamak için kaynakları kapatmak istiyorsanız tüm "temizleme" işlemlerini uygulayın buradaki talimatları uygulayın. Yeni Google Cloud kullanıcıları, 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Cloudshell Düzenleyiciyi Başlat
Bu laboratuvar, Google Cloud Shell Düzenleyici ile birlikte kullanılmak üzere tasarlanmış ve test edilmiştir. Düzenleyiciye erişmek için
- https://console.cloud.google.com adresinden Google projenize erişin.
- Sağ üst köşedeki Cloud Shell düzenleyici simgesini tıklayın.
- Pencerenizin alt kısmında yeni bir bölme açılır
- Düzenleyiciyi Aç düğmesini tıklayın.
- Düzenleyici, sağ tarafta bir gezgin, orta alanda ise düzenleyici açılır.
- Ekranın alt kısmında da bir terminal bölmesi bulunmalıdır
- Terminal AÇIK DEĞİLSE yeni bir terminal penceresi açmak için "ctrl+"" tuş kombinasyonunu kullanın.
Ortam Kurulumu
Cloud Shell'de projenizin kimliğini ve proje numarasını ayarlayın. Bunları PROJECT_ID
ve PROJECT_ID
değişkenleri olarak kaydedin.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
--format='value(projectNumber)')
Kaynak kodunu alma
- Bu laboratuvarın kaynak kodu, GitHub'daki GoogleCloudPlatform'da bulunan container-developer-workshop'ta bulunmaktadır. Aşağıdaki komutla klonlayın, ardından dizine değiştirin.
git clone https://github.com/GoogleCloudPlatform/container-developer-workshop.git &&
cd container-developer-workshop/labs/python
mkdir music-service && cd music-service
cloudshell workspace .
Terminal AÇIK DEĞİLSE yeni bir terminal penceresi açmak için "ctrl+"" tuş kombinasyonunu kullanın.
Bu laboratuvarda kullanılan altyapıyı sağlayın
Bu laboratuvarda, GKE'ye kod dağıtacak ve bir Spanner veritabanında depolanan verilere erişeceksiniz. Aşağıdaki kurulum komut dosyası, bu altyapıyı sizin için hazırlar. Temel hazırlık işlemi 10 dakikadan uzun sürer. Kurulum işlenirken sonraki birkaç adımla devam edebilirsiniz.
../setup.sh
3. Yeni bir Python başlangıç uygulaması oluşturun
requirements.txt
adında bir dosya oluşturun ve aşağıdaki içeriği bu dosyaya kopyalayın
Flask
gunicorn
google-cloud-spanner
ptvsd==4.3.2
app.py
adında bir dosya oluşturun ve aşağıdaki kodu dosyaya yapıştırın
import os
from flask import Flask, request, jsonify
from google.cloud import spanner
app = Flask(__name__)
@app.route("/")
def hello_world():
message="Hello, World!"
return message
if __name__ == '__main__':
server_port = os.environ.get('PORT', '8080')
app.run(debug=False, port=server_port, host='0.0.0.0')
- Dockerfile adlı bir dosya oluşturun ve aşağıdakini bu dosyaya yapıştırın
FROM python:3.8
ARG FLASK_DEBUG=0
ENV FLASK_DEBUG=$FLASK_DEBUG
ENV FLASK_APP=app.py
WORKDIR /app
COPY requirements.txt .
RUN pip install --trusted-host pypi.python.org -r requirements.txt
COPY . .
ENTRYPOINT ["python3", "-m", "flask", "run", "--port=8080", "--host=0.0.0.0"]
Not: FLASK_DEBUG=1, kod değişikliklerini bir Python flask uygulamasına otomatik olarak yeniden yüklemenize olanak tanır. Bu Dockerfile, bu değeri derleme bağımsız değişkeni olarak iletmenize olanak tanır.
Manifest Oluşturma
Terminalinizde varsayılan bir skaffold.yaml ve deployment.yaml oluşturmak için aşağıdaki komutu yürütün.
- Aşağıdaki komutla Skaffold'ı başlatın
skaffold init --generate-manifests
İstendiğinde imlecinizi hareket ettirmek için okları, seçenekleri belirlemek için boşluk çubuğunu kullanın.
Seçin:
- Taşıma işlemi için
8080
- Yapılandırmayı kaydetmek için
y
Skaffold Yapılandırmalarını Güncelle
- Varsayılan uygulama adını değiştirme
skaffold.yaml
uygulamasını aç- Şu anda
dockerfile-image
olarak ayarlanmış olan resim adını seçin - Sağ tıklayın ve Tüm Tekrarları Değiştir'i seçin
- Yeni adı
python-app
olarak yazın - Derleme bölümünü daha sonra düzenleyerek
FLASK_DEBUG=1
pasosunadocker.buildArgs
eklendi*.py
dosyalarında yapılan değişiklikleri IDE'den çalışan kapsayıcıya yüklemek için ayarları senkronize et
Düzenlemelerden sonra skaffold.yaml
dosyasındaki derleme bölümü aşağıdaki gibi olacaktır:
build:
artifacts:
- image: python-app
docker:
buildArgs:
FLASK_DEBUG: 1
dockerfile: Dockerfile
sync:
infer:
- '**/*.py'
Kubernetes Yapılandırma Dosyasını Değiştirme
- Varsayılan adı değiştirme
deployment.yaml
dosyasını aç- Şu anda
dockerfile-image
olarak ayarlanmış olan resim adını seçin - Sağ tıklayın ve Tüm Tekrarları Değiştir'i seçin
- Yeni adı
python-app
olarak yazın
4. Geliştirme sürecinde rehberlik etme
Eklenen iş mantığı ile uygulamanızı dağıtıp test edebilirsiniz. Aşağıdaki bölümde Cloud Code eklentisinin kullanımı vurgulanmaktadır. Diğer işlevlerinin yanı sıra, bu eklenti skaffold ile entegre olarak geliştirme sürecinizi kolaylaştırır. Aşağıdaki adımlarda GKE'ye dağıtım yaptığınızda Cloud Code ve Skaffold, container görüntünüzü otomatik olarak derler, Container Registry'ye aktarır ve ardından uygulamanızı GKE'ye dağıtır. Bu, perde arkasında olup ayrıntıları geliştirici akışından uzaklaştırarak gerçekleşir.
Kubernetes'e dağıtma
- Cloud Shell Düzenleyici'nin alt kısmındaki bölmeden Cloud Code'u seçin.
- Üst kısımda gösterilen panelde Run on Kubernetes'i (Kubernetes'te çalıştır) seçin. İstenirse geçerli Kubernetes bağlamını kullanmak için Evet'i seçin.
Bu komut, kaynak kodun bir derlemesini başlatır ve ardından testleri çalıştırır. Derleme ve testlerin çalıştırılması birkaç dakika sürer. Bu testler, birim testlerini ve dağıtım ortamı için ayarlanmış kuralları kontrol eden bir doğrulama adımını içerir. Bu doğrulama adımı zaten yapılandırılmıştır ve geliştirme ortamınızda çalışmaya devam ederken bile dağıtım sorunlarıyla ilgili uyarı almanızı sağlar.
- Komutu ilk kez çalıştırdığınızda ekranın üst kısmında geçerli Kubernetes bağlamını kullanmak isteyip istemediğinizi soran bir istem görünür, "Evet"i seçin geçerli bağlamı kabul edip kullanmak.
- Ardından, hangi container kayıt defterinin kullanılacağını soran bir istem gösterilir. Sağlanan varsayılan değeri kabul etmek için Enter tuşuna basın
- İlerleme durumunu ve bildirimleri görüntülemek için alt bölmede Çıkış sekmesini seçin
- "Kubernetes: Çalıştır/Hata Ayıklama - Ayrıntılı" seçeneğini belirleyin "sağdaki kanal açılır menüsünü tıklayıp ek ayrıntıları ve kapsayıcılardan canlı yayınlanan günlükleri görüntüleyin"
Derleme ve testler tamamlandığında Çıktı sekmesinde Attached debugger to container "python-app-8476f4bbc-h6dsl" successfully.
görüntülenir ve http://localhost:8080 URL'si listelenir.
- Cloud Code terminalinde çıkıştaki ilk URL'nin (http://localhost:8080) üzerine gelin. Ardından, görünen araç ucunda Web Önizlemesini Aç'ı seçin.
- Yeni bir tarayıcı sekmesinde şu mesaj gösterilir:
Hello, World!
Sıcak Yeniden Yükle
app.py
dosyasını aç- Karşılama mesajını
Hello from Python
olarak değiştir
İzleyicinin, Output
penceresinde, Kubernetes: Run/Debug
görünümünde, güncellenen dosyaları Kubernetes'teki kapsayıcıyla senkronize ettiğine hemen dikkat edin.
Update initiated Build started for artifact python-app Build completed for artifact python-app Deploy started Deploy completed Status check started Resource pod/python-app-6f646ffcbb-tn7qd status updated to In Progress Resource deployment/python-app status updated to In Progress Resource deployment/python-app status completed successfully Status check succeeded ...
Kubernetes: Run/Debug - Detailed
görünümüne geçerseniz dosyalardaki değişiklikleri algılayıp uygulamayı derleyip yeniden dağıttığını görürsünüz
files modified: [app.py]
Syncing 1 files for gcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Copying files:map[app.py:[/app/app.py]]togcr.io/veer-pylab-01/python-app:3c04f58-dirty@sha256:a42ca7250851c2f2570ff05209f108c5491d13d2b453bb9608c7b4af511109bd
Watching for changes...
[python-app] * Detected change in '/app/app.py', reloading
[python-app] * Restarting with stat
[python-app] * Debugger is active!
[python-app] * Debugger PIN: 744-729-662
- Güncellenen sonuçları görmek için tarayıcınızı yenileyin.
Hata ayıklama
- Hata Ayıklama görünümüne gidin ve mevcut iş parçacığını (
) durdurun.
- Uygulamayı
debug
modunda çalıştırmak için alt menüdeCloud Code
simgesini tıklayın veDebug on Kubernetes
seçeneğini belirleyin.
Output
penceresininKubernetes Run/Debug - Detailed
görünümünde, skaffold'un bu uygulamayı hata ayıklama modunda dağıttığına dikkat edin.
- Bu ilk kez çalıştırıldığında bir istem, kaynağın kapsayıcının içinde nerede olduğunu sorar. Bu değer, Dockerfile'daki dizinlerle ilgilidir.
Varsayılanı kabul etmek için Enter tuşuna basın
Uygulamanın derlenmesi ve dağıtılması birkaç dakika sürer.
- İşlem tamamlandığında. Eklenmiş bir hata ayıklayıcı görürsünüz.
Port forwarding pod/python-app-8bd64cf8b-cskfl in namespace default, remote port 5678 -> http://127.0.0.1:5678
- Alttaki durum çubuğunun rengi maviden turuncuya dönüşür ve bu da Hata Ayıklama modunda olduğunu gösterir.
Kubernetes Run/Debug
görünümünde, Hata Ayıklanabilir bir container'ın başlatıldığına dikkat edin
**************URLs***************** Forwarded URL from service python-app: http://localhost:8080 Debuggable container started pod/python-app-8bd64cf8b-cskfl:python-app (default) Update succeeded ***********************************
Kesme noktalarından yararlanma
app.py
dosyasını açreturn message
yazan ifadeyi bulun- Satır numarasının solundaki boş alanı tıklayarak bu satıra bir ayrılma noktası ekleyin. Kesme noktasının ayarlandığını belirten kırmızı bir gösterge görünür.
- Tarayıcınızı yeniden yükleyin. Hata ayıklayıcının işlemi kesme noktasında durdurduğunu ve GKE'de uzaktan çalışan uygulamanın değişkenlerini ve durumunu incelemenize olanak tanıdığını unutmayın
- DEĞİŞKENLER bölümünü tıklayın.
- Yerel'i tıkladığınızda
"message"
değişkenini görürsünüz. - "Mesaj" değişken adını çift tıklayın pop-up'ta değeri
"Greetings from Python"
gibi farklı bir değerle değiştirin. - Hata ayıklama kontrol panelinde Devam düğmesini
tıklayın.
- Az önce girdiğiniz güncellenmiş değeri gösteren yanıtı tarayıcınızda inceleyin.
- "Hata ayıklama"yı durdurma kesme noktasını
tıklayın.
5. Basit Bir CRUD Dinlenme Hizmeti Geliştirme
Bu noktada uygulamanız, container mimarisine alınmış geliştirme için tamamen yapılandırıldı ve Cloud Code ile temel geliştirme iş akışını öğrendiniz. Aşağıdaki bölümlerde, Google Cloud'da yönetilen bir veritabanına bağlanan dinlenme hizmeti uç noktaları ekleyerek öğrendiklerinizi uygulayacaksınız.
Geri kalan hizmeti kodlayın
Aşağıdaki kod, uygulamayı destekleyen veritabanı olarak Spanner'ı kullanan basit bir dinlenme hizmeti oluşturur. Aşağıdaki kodu uygulamanıza kopyalayarak uygulamayı oluşturun.
app.py
öğesini aşağıdaki içeriklerle değiştirerek ana uygulamayı oluşturun
import os
from flask import Flask, request, jsonify
from google.cloud import spanner
app = Flask(__name__)
instance_id = "music-catalog"
database_id = "musicians"
spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
@app.route('/singer', methods=['POST'])
def create():
try:
request_json = request.get_json()
singer_id = request_json['singer_id']
first_name = request_json['first_name']
last_name = request_json['last_name']
def insert_singers(transaction):
row_ct = transaction.execute_update(
f"INSERT Singers (SingerId, FirstName, LastName) VALUES" \
f"({singer_id}, '{first_name}', '{last_name}')"
)
print("{} record(s) inserted.".format(row_ct))
database.run_in_transaction(insert_singers)
return {"Success": True}, 200
except Exception as e:
return e
@app.route('/singer', methods=['GET'])
def get_singer():
try:
singer_id = request.args.get('singer_id')
def get_singer():
first_name = ''
last_name = ''
with database.snapshot() as snapshot:
results = snapshot.execute_sql(
f"SELECT SingerId, FirstName, LastName FROM Singers " \
f"where SingerId = {singer_id}",
)
for row in results:
first_name = row[1]
last_name = row[2]
return (first_name,last_name )
first_name, last_name = get_singer()
return {"first_name": first_name, "last_name": last_name }, 200
except Exception as e:
return e
@app.route('/singer', methods=['PUT'])
def update_singer_first_name():
try:
singer_id = request.args.get('singer_id')
request_json = request.get_json()
first_name = request_json['first_name']
def update_singer(transaction):
row_ct = transaction.execute_update(
f"UPDATE Singers SET FirstName = '{first_name}' WHERE SingerId = {singer_id}"
)
print("{} record(s) updated.".format(row_ct))
database.run_in_transaction(update_singer)
return {"Success": True}, 200
except Exception as e:
return e
@app.route('/singer', methods=['DELETE'])
def delete_singer():
try:
singer_id = request.args.get('singer')
def delete_singer(transaction):
row_ct = transaction.execute_update(
f"DELETE FROM Singers WHERE SingerId = {singer_id}"
)
print("{} record(s) deleted.".format(row_ct))
database.run_in_transaction(delete_singer)
return {"Success": True}, 200
except Exception as e:
return e
port = int(os.environ.get('PORT', 8080))
if __name__ == '__main__':
app.run(threaded=True, host='0.0.0.0', port=port)
Veritabanı Yapılandırmaları Ekleyin
Spanner'a güvenli bir şekilde bağlanmak için uygulamayı İş Yükü Kimlikleri kullanacak şekilde ayarlayın. Bu, uygulamanızın kendi hizmet hesabı gibi davranmasını ve veritabanına erişirken ayrı izinlere sahip olmasını sağlar.
deployment.yaml
adlı cihazı güncelleyin. Dosyanın sonuna aşağıdaki kodu ekleyin (aşağıdaki örnekte sekme girintilerini koruduğunuzdan emin olun)
serviceAccountName: python-ksa
nodeSelector:
iam.gke.io/gke-metadata-server-enabled: "true"
Uygulamayı Dağıtma ve Doğrulama
- Cloud Shell Düzenleyici'nin alt kısmındaki bölmede
Cloud Code
simgesini ve ardından ekranın üst kısmındakiDebug on Kubernetes
öğesini seçin. - Derleme ve testler tamamlandığında Çıkış sekmesinde
Resource deployment/python-app status completed successfully
görüntülenir ve bir URL listelenir: "python-app hizmetinden yönlendirilen URL: http://localhost:8080" - Birkaç giriş ekleyin.
Cloudshell Terminal'den aşağıdaki komutu çalıştırın
curl -X POST http://localhost:8080/singer -H 'Content-Type: application/json' -d '{"first_name":"Cat","last_name":"Meow", "singer_id": 6}'
- Terminalde aşağıdaki komutu çalıştırarak GET operatörünü test edin.
curl -X GET http://localhost:8080/singer?singer_id=6
- Test Silme: Şimdi aşağıdaki komutu çalıştırarak bir girişi silmeyi deneyin. Gerekirse item-id değerini değiştirin.
curl -X DELETE http://localhost:8080/singer?singer_id=6
This throws an error message
500 Internal Server Error
Sorunu belirleme ve düzeltme
- Hata ayıklama moduna geçip sorunu bulun. Aşağıda bazı ipuçları verilmiştir:
- DELETE ile ilgili bir sorun olduğunun farkındayız çünkü bu komut istenen sonucu döndürmüyor. Bu nedenle, ayrılma noktasını
delete_singer
yöntemindekiapp.py
içinde ayarlarsınız. - Yürütmeyi adım adım çalıştırın ve sol penceredeki yerel değişkenlerin değerlerini gözlemlemek için her adımdaki değişkenleri izleyin.
singer_id
verequest.args
gibi belirli değerleri gözlemlemek için bu değişkenleri İzleme penceresine ekleyin.
singer_id
öğesine atanan değerinNone
olduğuna dikkat edin. Sorunu düzeltmek için kodu değiştirin.
Düzeltilmiş kod snippet'i şöyle görünür.
@app.route('/delete-singer', methods=['DELETE', 'GET']) def delete_singer(): try: singer_id = request.args.get('singer_id')
- Uygulama yeniden başlatıldıktan sonra, silmeyi deneyerek tekrar test edin.
- Hata ayıklama araç çubuğundaki kırmızı kare simgesini tıklayarak hata ayıklama oturumunu durdurun
6. Temizleme
Tebrikler! Bu laboratuvarda, sıfırdan yeni bir Python uygulaması oluşturdunuz ve bu uygulamayı container'larla etkili bir şekilde çalışacak şekilde yapılandırdınız. Ardından geleneksel uygulama yığınlarında bulunan geliştirici akışını izleyerek uygulamanızı uzak bir GKE kümesine dağıttınız ve hatalarını ayıkladınız.
Laboratuvarı tamamladıktan sonra yer açmak için:
- Laboratuvarda kullanılan dosyaları silme
cd ~ && rm -rf container-developer-workshop
- İlgili tüm altyapı ve kaynakları kaldırmak için projeyi silin