Google Kubernetes Engine에서 Django 실행

Google Kubernetes Engine(GKE)에서 실행되는 Django 앱은 모든 Google 제품과 동일한 인프라에서 실행되므로 쉽게 확장할 수 있습니다.

이 가이드는 Django 웹 개발에 익숙하신 분을 대상으로 하며, Django 개발이 처음이면 계속하기 전에 첫 번째 Django 앱을 작성하는 것이 좋습니다. 이 가이드에서 앱 모델은 질문이 포함된 설문조사를 나타내고, Django 관리 콘솔을 사용해서 모델과 상호작용할 수 있습니다.

이 가이드는 Python 2.7 또는 3.4 이상이 필요합니다. Docker도 설치되어 있어야 합니다.

시작하기 전에

  1. Google 계정으로 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기 페이지로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. Cloud SQL, and Compute Engine API를 사용 설정합니다.

    API 사용 설정

  5. Cloud SDK 설치 및 초기화

앱 다운로드 및 실행

기본 요건을 완료한 후 Django 샘플 앱을 다운로드하고 배포합니다. 다음 섹션에서는 앱 구성, 실행, 배포를 안내합니다.

Django 앱 복제

Django 샘플 앱용 코드는 GitHub의 GoogleCloudPlatform/python-docs-samples 저장소에 있습니다.

  1. ZIP 파일로 샘플을 다운로드하고 이를 추출하거나 저장소를 로컬 머신에 클론할 수 있습니다.

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

  2. 샘플 코드가 있는 디렉터리로 이동합니다.

cd python-docs-samples/kubernetes_engine/django_tutorial

로컬 환경 설정

배포된 앱은 App Engine 환경에 기본 제공되는 Cloud SQL 프록시를 사용하여 Cloud SQL 인스턴스와 통신합니다. 하지만 앱을 로컬에서 테스트하려면 프록시의 로컬 사본을 개발 환경에 설치하여 사용해야 합니다.

Cloud SQL 프록시 자세히 알아보기

Cloud SQL 인스턴스에서 기본 관리 작업을 수행하려면 PostgreSQL 클라이언트를 사용하면 됩니다.

Cloud SQL 프록시 설치

Cloud SQL 프록시를 다운로드하고 설치합니다. Cloud SQL 프록시는 로컬에서 실행되는 Cloud SQL 인스턴스에 연결됩니다.

Linux 64비트

  1. 프록시를 다운로드합니다.
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy
    
  2. 프록시를 실행 가능하도록 합니다.
    chmod +x cloud_sql_proxy
    

Linux 32비트

  1. 프록시를 다운로드합니다.
    wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.386 -O cloud_sql_proxy
    
  2. 프록시를 실행 가능하도록 합니다.
    chmod +x cloud_sql_proxy
    

macOS 64비트

  1. 프록시를 다운로드합니다.
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
    
  2. 프록시를 실행 가능하도록 합니다.
    chmod +x cloud_sql_proxy
    

macOS 32비트

  1. 프록시를 다운로드합니다.
    curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.386
    
  2. 프록시를 실행 가능하도록 합니다.
    chmod +x cloud_sql_proxy
    

Windows 64비트

https://dl.google.com/cloudsql/cloud_sql_proxy_x64.exe를 마우스 오른쪽 버튼으로 클릭하고 다른 이름으로 링크 저장을 선택하여 프록시를 다운로드합니다. 파일 이름을 cloud_sql_proxy.exe로 바꿉니다.

Windows 32비트

https://dl.google.com/cloudsql/cloud_sql_proxy_x86.exe를 마우스 오른쪽 버튼으로 클릭하고 다른 이름으로 링크 저장을 선택하여 프록시를 다운로드합니다. 파일 이름을 cloud_sql_proxy.exe로 바꿉니다.

Docker 프록시 이미지

편의를 위해 Cloud SQL팀은 고객이 사용할 Cloud SQL 프록시가 포함된 컨테이너 이미지 여러 개를 유지보수합니다. 이러한 이미지에 대한 자세한 내용은 GitHub의 Cloud SQL 프록시 저장소를 참조하세요. 다음 명령어로 Docker를 사용하여 최신 이미지를 로컬 머신으로 가져올 수 있습니다.
docker pull gcr.io/cloudsql-docker/gce-proxy:1.19.1

기타 OS

여기에 포함되지 않은 다른 운영체제의 경우 소스에서 프록시를 컴파일할 수 있습니다.

Cloud SQL 인스턴스 만들기

  1. <a{: class="internal" l10n-attrs-original-order="href,track-type,track-name,track-metadata-position,track-metadata-end-goal,class,target" l10n-encrypted-href="lsL4NbV5FI0DRuRANJcTZKJysOQGKX761P3ItELRG1PjHEtGnUIGGfDSUdzN6k/z" target="_blank" track-metadata-end-goal="createInstance" track-metadata-position="body" track-name="internalLink" track-type="python" }=""> PostgreSQL용 Cloud SQL 인스턴스를 만듭니다.

    인스턴스 이름을 polls-instance 또는 유사하게 지정합니다. 인스턴스가 준비되는 데 몇 분 정도 걸릴 수 있습니다. 인스턴스가 준비되면 인스턴스 목록에 표시됩니다.

    </a{:>
  2. Cloud SDK를 사용하여 다음 명령어를 실행합니다. 여기서 [YOUR_INSTANCE_NAME]은 Cloud SQL 인스턴스 이름을 나타냅니다.
    gcloud sql instances describe [YOUR_INSTANCE_NAME]

    표시되는 [CONNECTION_NAME] 값을 기록해 둡니다.

    [CONNECTION_NAME] 값의 형식은 [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]과 같습니다.

Cloud SQL 인스턴스 초기화

  1. 이전 단계의 [CONNECTION_NAME] 값을 사용하여 Cloud SQL 프록시를 시작합니다.

    Linux/macOS

    ./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:5432

    Windows

    cloud_sql_proxy.exe -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:5432

    [YOUR_INSTANCE_CONNECTION_NAME]을 이전 단계에서 기록한 [CONNECTION_NAME] 값으로 바꿉니다.

    이 단계에서는 로컬 테스트를 위해 로컬 컴퓨터에서 Cloud SQL 인스턴스로 연결을 설정합니다. 앱을 로컬에서 테스트하는 동안 Cloud SQL 프록시를 계속 실행합니다.

  2. Cloud SQL 사용자 및 데이터베이스를 만듭니다.

    Cloud Console

    1. Cloud SQL 인스턴스 polls-instanceCloud Console을 사용하여 새 데이터베이스를 만듭니다. 예를 들어 polls라는 이름을 사용할 수 있습니다.
    2. Cloud SQL 인스턴스 polls-instance에 대해 Cloud Console을 사용하여 새 사용자를 만듭니다.

    Postgres 클라이언트

    1. 별도의 명령줄 탭에서 Postgres 클라이언트를 설치합니다.
      sudo apt-get install postgresql
    2. Postgres 클라이언트 또는 비슷한 프로그램을 사용하여 인스턴스에 연결합니다. 메시지가 표시되면 구성한 루트 비밀번호를 사용합니다.
      psql --host 127.0.0.1 --user postgres --password
    3. 다음 명령어를 사용하여 Cloud SQL 데이터베이스에서 필수 데이터베이스, 사용자, 액세스 권한을 만듭니다. [POSTGRES_USER][POSTGRES_PASSWORD]를 사용할 사용자 이름과 비밀번호로 바꿉니다.
      CREATE DATABASE polls;
      CREATE USER [POSTGRES_USER] WITH PASSWORD '[POSTGRES_PASSWORD]';
      GRANT ALL PRIVILEGES ON DATABASE polls TO [POSTGRES_USER];
      GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO [POSTGRES_USER];
      

서비스 계정 만들기

프록시를 사용하려면 Cloud SQL 인스턴스에 대한 편집자 권한을 가진 서비스 계정이 필요합니다. 서비스 계정에 대한 자세한 내용은 Google Cloud 인증 개요를 참조하세요.

  1. Google Cloud Console의 서비스 계정 페이지로 이동합니다.

    서비스 계정 페이지로 이동

  2. Cloud SQL 인스턴스가 포함된 프로젝트를 선택합니다.
  3. 서비스 계정 만들기를 클릭합니다.
  4. 서비스 계정 만들기 대화상자에 서비스 계정을 설명하는 이름을 입력합니다.
  5. 역할에서 다음 중 하나를 선택합니다.
    • Cloud SQL > Cloud SQL 클라이언트
    • Cloud SQL > Cloud SQL 편집자
    • Cloud SQL > Cloud SQL 관리자
  6. 서비스 계정 ID를 고유하고 알아볼 수 있는 값으로 변경합니다.
  7. 새 비공개 키 제공을 클릭하고 키 유형이 JSON인지 확인합니다.
  8. 만들기를 클릭합니다.

    비공개 키 파일이 머신에 다운로드됩니다. 파일을 다른 위치로 이동할 수 있습니다. 키 파일을 안전하게 보관하세요.

데이터베이스 설정 구성

다음 명령어를 사용하여 데이터베이스 액세스를 위한 환경 변수를 설정합니다. 이러한 환경 변수는 로컬 테스트에 사용됩니다.

Linux/macOS

export DATABASE_USER=<your-database-user>
export DATABASE_PASSWORD=<your-database-password>

Windows

set DATABASE_USER=<your-database-user>
set DATABASE_PASSWORD=<your-database-password>

GKE 구성 설정

  1. 이 애플리케이션은 polls이라는 단일 Kubernetes 구성에서 표시됩니다. polls.yaml에서 <your-project-id>를 Google Cloud 프로젝트 ID로 바꿉니다.

  2. 다음 명령어를 실행하고 connectionName 값을 기록합니다.

    gcloud beta sql instances describe [YOUR_INSTANCE_NAME]
    
  3. polls.yaml 파일에서 <your-cloudsql-connection-string>connectionName 값으로 바꿉니다.

로컬 컴퓨터에서 앱 실행

  1. Django 앱을 로컬 컴퓨터에서 실행하려면 Python, pip, virtualenv를 포함한 Python 개발 환경을 설정합니다.

  2. 격리된 Python 환경을 만들고 종속 항목을 설치합니다. Python 3 설치 이름이 다른 경우 첫 번째 명령어에 사용합니다.

    virtualenv env
    source env/bin/activate
    pip install -r requirements.txt
    
  3. Django 마이그레이션을 실행하여 모델을 설정합니다.

    python manage.py makemigrations
    python manage.py makemigrations polls
    python manage.py migrate
    
  4. 로컬 웹 서버를 시작합니다.

    python manage.py runserver
    
  5. 브라우저에서 http://localhost:8000으로 이동합니다.

    다음과 같은 텍스트가 표시된 페이지를 보게 됩니다: 'Hello, world. 설문 조사 색인에 있습니다.' 컴퓨터에서 실행되는 Django 웹 서버가 샘플 앱 페이지를 전송합니다.

  6. Control+C를 눌러서 로컬 웹 서버를 중지합니다.

Django 관리 콘솔 사용

  1. 수퍼유저를 만듭니다. 사용자 이름과 비밀번호를 지정해야 합니다.

    python manage.py createsuperuser
    
  2. 기본 프로그램을 실행합니다.

    python manage.py runserver
    
  3. 브라우저에서 http://localhost:8000/admin으로 이동합니다.

  4. createsuperuser를 실행할 때 사용한 사용자 이름과 비밀번호를 사용하여 관리 사이트에 로그인합니다.

GKE에 앱 배포

앱이 Google Cloud에 배포되면 Gunicorn 서버가 사용됩니다. Gunicorn은 정적 콘텐츠를 제공하지 않기 때문에 앱은 Cloud Storage를 사용하여 정적 콘텐츠를 제공합니다.

정적 리소스 수집 및 업로드

  1. Cloud Storage 버킷을 만들고 공개적으로 읽을 수 있도록 설정합니다. [YOUR_GCS_BUCKET]을 원하는 버킷 이름으로 바꿉니다. 예를 들어 버킷 이름으로 프로젝트 ID를 사용할 수 있습니다.

    gsutil mb gs://[YOUR_GCS_BUCKET]
    gsutil defacl set public-read gs://[YOUR_GCS_BUCKET]
    
  2. 모든 정적 콘텐츠를 폴더 하나로 로컬에 수집합니다.

    python manage.py collectstatic
    
  3. 정적 콘텐츠를 Cloud Storage에 업로드합니다.

    gsutil -m rsync -r ./static gs://[YOUR_GCS_BUCKET]/static
    
  4. mysite/settings.py에서 STATIC_URL 값을 다음 URL로 설정하고 여기서 [YOUR_GCS_BUCKET]을 버킷 이름으로 바꿉니다.

    http://storage.googleapis.com/[YOUR_GCS_BUCKET]/static/
    

GKE 설정

  1. GKE를 초기화하려면 클러스터 페이지로 이동합니다.

    클러스터 페이지로 이동

    프로젝트에서 처음으로 GKE를 사용하는 경우 'Kubernetes Engine이 준비되고 있으며 1분 이상 걸릴 수 있습니다' 라는 메시지가 사라질 때까지 기다립니다.

  2. GKE 클러스터를 만듭니다.

    gcloud container clusters create polls \
      --scopes "https://www.googleapis.com/auth/userinfo.email","cloud-platform" \
      --num-nodes 4 --zone "us-central1-a"
    

    'Project [PROJECT_ID] 프로젝트가 기본 서비스 계정으로 완전히 초기화되지 않았습니다' 오류가 발생했나요?

    GKE 초기화

    오류가 발생하면 Google Cloud Console로 이동하여 프로젝트에서 GKE를 초기화합니다.

    클러스터 페이지로 이동

    'Kubernetes Engine을 준비하는 중이며 1분 이상 걸릴 수 있습니다' 메시지가 사라질 때까지 기다립니다.

  3. 클러스터를 만든 후 gcloud 도구와 통합된 kubectl 명령줄 도구를 사용하여 GKE 클러스터와 상호작용합니다. gcloudkubectl는 별도의 도구이므로 kubectl가 올바른 클러스터와 상호작용하도록 구성되었는지 확인하세요.

    gcloud container clusters get-credentials polls --zone "us-central1-a"
    

Cloud SQL 설정

  1. GKE 앱이 Cloud SQL 인스턴스와 연결할 수 있으려면 여러 개의 비밀번호가 필요합니다. 하나는 인스턴스 수준 액세스(연결)를 위해 필요하고 다른 2개는 데이터베이스 액세스용으로 필요합니다. 2가지 수준의 액세스 제어에 대한 자세한 내용은 인스턴스 액세스 제어를 참조하세요.

    1. 인스턴스 수준 액세스용으로 보안 비밀을 만들려면 서비스 계정을 만들 때 다운로드한 JSON 서비스 계정 키의 위치([PATH_TO_CREDENTIAL_FILE])를 제공합니다. (서비스 만들기 계정참조).

      kubectl create secret generic cloudsql-oauth-credentials --from-file=credentials.json=[PATH_TO_CREDENTIAL_FILE]
      
    2. 데이터베이스 액세스 보안 비밀을 만들려면 Cloud SQL 인스턴스 초기화의 2단계에서 정의된 SQL [DATABASE_USERNAME][PASSWORD]를 사용합니다.

      kubectl create secret generic cloudsql --from-literal=username=[DATABASE_USERNAME] --from-literal=password=[PASSWORD]
      
  2. Cloud SQL 프록시용 Docker 공개 이미지를 검색합니다.

    docker pull b.gcr.io/cloudsql-docker/gce-proxy
    
  3. Docker 이미지를 빌드하고 <your-project-id>를 프로젝트 ID로 바꿉니다.

    docker build -t gcr.io/<your-project-id>/polls .
    
  4. gcloud를 사용자 인증 정보 도우미로 사용하도록 Docker를 구성하여 이미지를 Container Registry로 내보냅니다.

    gcloud auth configure-docker
    
  5. Docker 이미지를 푸시합니다. <your-project-id>를 프로젝트 ID로 바꿉니다.

    docker push gcr.io/<your-project-id>/polls
    
  6. GKE 리소스를 만듭니다.

    kubectl create -f polls.yaml
    

앱을 GKE에 배포합니다.

리소스가 만들어진 후 클러스터에 3개의 polls pod가 있어야 합니다. pod의 상태를 확인하세요.

    kubectl get pods

pod 상태가 Running로 표시될 때까지 몇 분 정도 기다립니다. pod가 준비되지 않았거나 다시 시작되는 경우 특정 Pod의 로그를 가져와서 문제를 파악할 수 있습니다. [YOUR-POD-ID]는 이전 kubectl get pods 명령어에서 반환된 출력의 일부입니다.

    kubectl logs [YOUR_POD_ID]

Google Cloud에서 앱 실행 확인

pod가 준비되면 부하 분산기의 공개 IP 주소를 가져올 수 있습니다.

kubectl get services polls

브라우저에서 EXTERNAL-IP 주소로 이동하여 Django 기본 방문 페이지를 확인하고 관리 콘솔에 액세스합니다.

코드 이해하기

Django 샘플 앱은 표준 Django 도구를 사용하여 생성되었습니다. 다음 명령어는 프로젝트 및 설문조사 앱을 만듭니다.

django-admin startproject mysite
python manage.py startapp polls

settings.py에는 SQL 데이터베이스의 구성이 포함되어 있습니다.

DATABASES = {
    'default': {
        # If you are using Cloud SQL for MySQL rather than PostgreSQL, set
        # 'ENGINE': 'django.db.backends.mysql' instead of the following.
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'polls',
        'USER': os.getenv('DATABASE_USER'),
        'PASSWORD': os.getenv('DATABASE_PASSWORD'),
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

polls.yaml 파일은 2개의 Kubernetes 리소스를 지정합니다. 첫 번째는 서비스로서 Django 웹 앱의 일관된 이름과 비공개 IP 주소를 정의합니다. 두 번째는 HTTP 부하 분산기로서 공개용 외부 IP 주소를 사용합니다.

# The polls service provides a load-balancing proxy over the polls app
# pods. By specifying the type as a 'LoadBalancer', Container Engine will
# create an external HTTP load balancer.
# For more information about Services see:
#   https://cloud.google.com/container-engine/docs/services/
# For more information about external HTTP load balancing see:
#   https://cloud.google.com/container-engine/docs/load-balancer
apiVersion: v1
kind: Service
metadata:
  name: polls
  labels:
    app: polls
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: polls

이 서비스는 네트워크 이름과 IP 주소를 제공하고 GKE Pod는 서비스 뒤의 앱 코드를 실행합니다. polls.yaml 파일은 GKE Pod의 선언적 업데이트를 제공하는 배포를 지정합니다. 이 서비스는 서비스 선택기를 배포 라벨과 일치시켜 트래픽을 배포로 보냅니다. 이 경우 선택기 polls가 라벨 polls와 일치합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: polls
  labels:
    app: polls
spec:
  replicas: 3
  selector:
    matchLabels:
      app: polls
  template:
    metadata:
      labels:
        app: polls
    spec:
      containers:
      - name: polls-app
        # Replace  with your project ID or use `make template`
        image: gcr.io/<your-project-id>/polls
        # This setting makes nodes pull the docker image every time before
        # starting the pod. This is useful when debugging, but should be turned
        # off in production.
        imagePullPolicy: Always
        env:
            - name: DATABASE_USER
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: username
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: cloudsql
                  key: password
        ports:
        - containerPort: 8080

      - image: gcr.io/cloudsql-docker/gce-proxy:1.16
        name: cloudsql-proxy
        command: ["/cloud_sql_proxy", "--dir=/cloudsql",
                  "-instances=<your-cloudsql-connection-string>=tcp:5432",
                  "-credential_file=/secrets/cloudsql/credentials.json"]
        volumeMounts:
          - name: cloudsql-oauth-credentials
            mountPath: /secrets/cloudsql
            readOnly: true
          - name: ssl-certs
            mountPath: /etc/ssl/certs
          - name: cloudsql
            mountPath: /cloudsql
      volumes:
        - name: cloudsql-oauth-credentials
          secret:
            secretName: cloudsql-oauth-credentials
        - name: ssl-certs
          hostPath:
            path: /etc/ssl/certs
        - name: cloudsql
          emptyDir: {}

삭제

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하는 방법은 다음과 같습니다.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.

개별 리소스 삭제

프로젝트를 삭제하지 않으려면 개별 리소스를 삭제합니다.

  1. Google Kubernetes Engine 클러스터를 삭제합니다.

    gcloud container clusters delete polls
    
  2. Container Registry에 푸시한 Docker 이미지를 삭제합니다.

    gcloud container images delete gcr.io/${PROJECT_ID}/polls
    
  3. Cloud SQL 인스턴스를 삭제합니다.

    gcloud sql instances delete $INSTANCE_NAME