반응형

https://www.cloudskillsboost.google/course_templates/1076?locale=ko

주요 기술 스택

  • Google Vertex AI: Google Cloud의 AI 플랫폼
  • Gemini 2.0 Flash: 텍스트 및 이미지 이해가 가능한 멀티모달 모델
  • Imagen 3.0: 텍스트로부터 고품질 이미지를 생성하는 모델

학습한 핵심 내용

1. 이미지 생성 (Imagen 3.0)

아래의 링크에서 배운 내용으로 첫번째 부테 이미지 생성하는 방법을 참고하여 코드를 작성하였습니다. 
https://www.cloudskillsboost.google/course_templates/1076/labs/584319?locale=ko

import argparse

import vertexai
from vertexai.preview.vision_models import ImageGenerationModel

def generate_image(
    project_id: str, location: str, output_file: str, prompt: str
) -> vertexai.preview.vision_models.ImageGenerationResponse:

    vertexai.init(project=project_id, location=location)

    model = ImageGenerationModel.from_pretrained("imagen-3.0-generate-002")

    images = model.generate_images(
        prompt=prompt,
        number_of_images=1,
        seed=1,
        add_watermark=False,
    )

    images[0].save(location=output_file)

    return images

generate_image(
    project_id='프로젝트 ID',
    location='리전',
    output_file='image.jpeg',
    prompt='프롬프트',
    )

2. 이미지 분석 및 텍스트 생성  + 스트림 

이미지를 불러오고 스트림을 이용하여 답을 리턴받는 내용을 학습하였습니다. 

 client.models.generate_content_stream

링크 에서 상세한 내용을 확인할 수 있습니다. 

https://www.cloudskillsboost.google/course_templates/1076/labs/584318?locale=ko 에서 학습한 `generate_content`의 스트림 사용 버전입니다. 

 

 

반응형
  1. API 활성화
    gcloud services enable \
    container.googleapis.com \ 컨테이너
    clouddeploy.googleapis.com \ 클라우드 배포
    artifactregistry.googleapis.com \ artifactregistry
    cloudbuild.googleapis.com  cloud build 

Google Cloud는 보안을 위해 기본적으로 모든 서비스가 비활성화 되어있기 때문에 사용할 서비스만 명시적으로 활성화 해야한다.

  1. Skaffold = Kubernetes 개발을 위한 빌드 자동화 도구
apiVersion: skaffold/v2beta7
kind: Config
build:
  artifacts:
  - image: leeroy-web    # 빌드할 이미지들
    context: leeroy-web  # Dockerfile 위치
  - image: leeroy-app
    context: leeroy-app
  googleCloudBuild:      # Cloud Build 사용
    projectId: my-project
deploy:
  kubectl:
    manifests:           # 배포할 K8s 매니페스트들
    - leeroy-web/kubernetes/*
    - leeroy-app/kubernetes/*
  1. 프로모션
    한 환경에서 다음 환경으로 애플리케이션을 승진 시키는 것
    스테이징 (자동배포) -> 프로덕션 (승인 필요)
    순서는 delivery-pipeline.yaml 에서 순서로 정함
    serialPipeline:
    stages:
    - targetId: staging     # 1단계
    - targetId: production      # 2단계
  1. 승인 시스템
    requireApproval = true -> deploy시 사람의 승인이 필요함

===

Google Kubernetes Engine Pipeline using Cloud Build를 이전 진행에서 실패한 이유...

Trigger생성시 아래 하단에 Repository service에서 
Cloud Build respositories 가 아닌 
Developer Connect를 실행했고, 
그로 인해서 Compute Engine default service account

관련 권한이 맞지 않아서 trigger생성 자체가 되지 않았다. 
설명에는 단순히 

Under Source, for Repository, click Connect new repository.

라고 되어있으니 다른 분들은 저와 같은 상황은 피하세용,,,

반응형

먼저 참고하기 좋은 github가 있어 공유 드립니다.

https://github.com/jesuispy/networking-101-gcp-sheet#vpcs-and-ip-addressing

 

GitHub - jesuispy/networking-101-gcp-sheet: This is a quick ref for general networking topics and google cloud networking stuff

This is a quick ref for general networking topics and google cloud networking stuff - jesuispy/networking-101-gcp-sheet

github.com

 

VPC Network

  • 프로젝트당 최대 5개까지 생성 가능 (기본 네트워크 포함)
  • 종류
    • 자동 VPC 네트워크
    • 커스텀 VPC 네트워크
  • 글로벌 리소스
    • 여러 리전에 걸쳐 존재하는 논리적 네트워크
    • 리전 간 통신이 Google 백본 네트워크를 통해 이루어짐
    • 리전 간 대역폭 제한 없음 (동일 VPC 내)
  • 논리적 격리
    • 서로 다른 VPC는 완전히 격리됨
    • VPC 간 통신은 별도 설정 필요 (VPC Peering, Shared VPC 등)GCP 프로젝트 계층 구조
프로젝트 (Project) 
└── VPC 네트워크 (VPC Network) 
    └── 서브네트워크 (Subnetwork) 
        └── VM 인스턴스 (VM Instance)

커스텀 네트워크 GCP Cloud Shell 로 생성하기

gcloud compute networks create {네트워크이름} --subnet-mode custom

기본 네트워크에 자동으로 만들어진 방화벽 규칙

  • 수동 VPC네트워크에는 자동 방화벽 규칙 없음
이름 내용
default-allow-internal 네트워크상의 인스턴스 간에 모든 프로토콜 및 포트의 네트워크 연결을 허용합니다.
default-allow-ssh 모든 소스에서 TCP 포트 22를 사용하여 네트워크의 모든 인스턴스에 SSH로 연결할 수 있도록 허용합니다.
default-allow-rdp 모든 소스에서 TCP 포트 3389를 사용하여 네트워크의 모든 인스턴스에 RDP로 연결할 수 있도록 허용합니다.
default-allow-icmp 모든 소스에서 네트워크의 모든 인스턴스에 이르는 ICMP 트래픽을 허용합니다.

subnet

  • 리전별로 생성되는 네트워크의 세부 분할
  • RFC1918 사설 IP 주소 공간 사용
  • 관련 리소스들을 논리적으로 그룹핑
  • 자동 서브넷 모드 (Auto Mode Network)
    • 새 프로젝트 생성 시 자동으로 생성
    • 각 리전마다 하나씩 서브넷 자동 생성
    • 미리 정의된 IP 범위와 게이트웨이 사용
    • 서브넷 이름 = 네트워크 이름과 동일
  • 커스텀 서브넷 모드 (Custom Mode Network)
    • 생성 시점에는 서브넷이 없음
    • 필요한 리전에만 수동으로 서브넷 생성
    • IP 범위를 직접 지정 가능
    • 리전별로 0개, 1개, 또는 여러 개의 서브넷 가능

Cloud Shell 로 서브넷 생성하기

# 미국 중부 서브넷 
gcloud compute networks subnets create {{subnet 이름}} \
     --network={{네트워크 이름}} \
    --range=10.0.0.0/16 \ 
    --region=us-central1 

# 유럽 서부 서브넷 
gcloud compute networks subnets create {{subnet 이름}} \ 
    --network={{네트워크 이름}} \ 
    --range=10.1.0.0/16 \ 
    --region=europe-west1 

# 아시아 동부 서브넷 
gcloud compute networks subnets create {{subnet 이름}} \ 
    --network={{네트워크 이름}} \ 
    --range=10.2.0.0/16 \ 
    --region=asia-east1

RFC1918이란?

  • "Address Allocation for Private Internets"
  • 인터넷에서 직접 라우팅되지 않는 사설 IP 주소 대역 정의
  • NAT(Network Address Translation)와 함께 사용하여 공인 IP 주소 절약
  • Classes
    • Class A : 10.0.0.0/8
    • Class B : 172.16.0.0/12
    • Class C : 192.168.0.0/16

방화벽 규칙

기본 정책

  • Ingress (인바운드): 기본적으로 모든 트래픽 차단
  • Egress (아웃바운드): 기본적으로 모든 트래픽 허용

규칙 평가 순서

  • 거부 규칙으로 허용 규칙 재정의 시 우선순위 등급 사용하여 재정의
  1. 우선순위 번호가 낮을수록 먼저 평가 (0이 최고 우선순위)
  2. 첫 번째 일치하는 규칙이 적용됨
  3. 일치하는 규칙이 없으면 기본 정책 적용
  • 기본 네트워크에는 자동으로 만들어진 방화벽 규칙 존재함
  • 네트워크 태그(인스턴스 태그)를 활용하여 VM 인스턴스 방화벽 규칙 적용
    • VM인스턴스 그룹간에 방화벽 규칙을 관리하는 강력한 도구
  • 전달하려는 트래픽 종류를 최소 허용 방화벽 규칙을 구성하는 것이 좋음

Cloud Shell을 이용하여 방화벽 규칙 생성하기

gcloud compute firewall-rules create {방화벽이름} \
    --allow tcp:80 --network {네트워크 이름} 
    --source-ranges 0.0.0.0/0 \
    --target-tags http // http 태그가 있는 VM들에게 적용 (네트워크 태그)
반응형

Cloud Shell 개념

Google Cloud Shell은 Google Cloud Console에서 제공하는 브라우저 기반 터미널 환경.

  • 사전 설치된 도구들: gcloud, kubectl, docker, git 등이 이미 설치됨
  • 자동 인증: Google Cloud 프로젝트에 이미 인증된 상태
  • 웹 기반: 별도 설치 없이 브라우저에서 바로 사용

Task 1. Create a Docker image and store the Dockerfile

목표: 제공되는 프로젝트, 도커 파일 생성 후 도커 이미지 빌드

1. Dockerfile이란?

Dockerfile은 Docker 이미지를 생성하기 위한 명령어들을 포함한 텍스트 파일

Dockerfile 기본 구조

# 베이스 이미지 지정
FROM golang:1.10

# 작업 디렉토리 설정
WORKDIR /go/src/app

# 파일 복사
COPY source .

# 패키지 설치 및 빌드
RUN go install -v

# 컨테이너 시작 명령어
ENTRYPOINT ["app","-single=true","-port=8080"]

2. Docker 이미지 Build

도커 이미지란?

Docker 이미지는 컨테이너를 생성하기 위한 읽기 전용 템플릿

도커 이미지 빌드 명령어

# 현재 디렉토리의 Dockerfile로 이미지 빌드
docker build -t valkyrie-app:v0.0.2 .

# 명령어 구성 요소 설명:
# docker build: 빌드 명령어
# -t: 태그 지정 옵션
# valkyrie-app:v0.0.2: 이미지명:태그
# .: 빌드 컨텍스트 (현재 디렉토리)

Task 2. Test the created Docker image

목표: 도커 실행하기

1. 도커 이미지 실행하기

기본 실행 명령어

#실행 
docker run valkyrie-app:v0.0.2

#실행 (터미널 점유 x)
docker run -d valkyrie-app:v0.0.2

컨테이너 상태 확인

# 실행 중인 컨테이너 확인
docker ps

# 모든 컨테이너 확인 (중지된 것 포함) (-a)
docker ps -a

# 컨테이너 로그 확인
docker logs my-app

# 실시간 로그 확인 (-f)
docker logs -f my-app

2. 포트 설정하기

포트 매핑 이해

# 포트 매핑 기본 형식
docker run -p [호스트포트]:[컨테이너포트] 이미지명
#          ↑           ↑
#        외부포트     내부포트

3. & 란?

Shell 백그라운드 실행 (&)

# Shell 백그라운드로 실행
docker run -p 8080:8080 valkyrie-app:v0.0.2 &

& 사용 시 특징:

  • 터미널이 즉시 다른 명령어 입력 가능
  • 터미널 세션에 종속됨 (터미널 종료 시 프로세스도 종료)
  • jobs 명령어로 백그라운드 작업 확인 가능

 


Task 3. Push the Docker image to the Artifact Registry

1. Artifact Registry란?

Artifact Registry 개념

Google Artifact Registry는 Google Cloud에서 제공하는 완전 관리형 컨테이너 이미지 및 아티팩트 저장소

Docker Hub vs Artifact Registry

구분 Docker Hub Artifact Registry
접근성 공개/비공개 비공개 (IAM 관리)
인증 Docker 계정 Google Cloud IAM
보안 기본적인 보안 고급 보안 기능
위치 글로벌 리전별 선택 가능
비용 공개 무료, 비공개 유료 사용량 기반 과금

2. Cloud Shell에서 Artifact Registry push 하는 방법

Step 1: 레포지토리 생성

Search 에서 Artifact Registry 검색 > 새로운 Artifact Registry 생성 > Docker 설정

Step 2: Docker 인증 설정

gcloud auth configure-docker us-east4-docker.pkg.dev

 

  • Docker가 Artifact Registry에 인증할 때 gcloud 자격 증명 사용
  • push/pull 시 자동으로 Google Cloud 토큰 사용

Step 3: 이미지 태그 재지정

# 현재 이미지 확인
docker images

# Artifact Registry 형식으로 태그 재지정
docker tag valkyrie-app:v0.0.2 \
    us-east4-docker.pkg.dev/$PROJECT_ID/valkyrie-repo/valkyrie-app:v0.0.2

# 태그 결과 확인
docker images | grep valkyrie-app

태그 형식 이해:

us-east4-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG
│                       │           │          │     │
│                       │           │          │     └─ 버전 태그
│                       │           │          └─ 이미지 이름
│                       │           └─ 레포지토리 이름
│                       └─ 프로젝트 ID
└─ Artifact Registry 호스트 (리전 포함)

Step 4: 이미지 푸시

docker push us-east4-docker.pkg.dev/$PROJECT_ID/valkyrie-repo/valkyrie-app:v0.0.2

 

 


Task 4. Create and expose a deployment in Kubernetes

1. 클러스터 인증하기

클러스터 인증 명령어

#리전 설정
gcloud config set compute/region us-east4

# 존 설정
gcloud config set compute/zone us-east4-a

# GKE 클러스터에 인증 설정
gcloud container clusters get-credentials valkyrie-dev --zone=us-east4-a

 

2. 왜 인증하는가?

Kubernetes 클러스터 접근 제어

  • 보안: 권한이 있는 사용자만 클러스터 접근 가능
  • 다중 클러스터: 여러 클러스터 중 특정 클러스터 선택
  • 권한 관리: RBAC (Role-Based Access Control)을 통한 세밀한 권한 제어

3. k8s 리소스 배포하기

deployment.yaml 구조 이해

apiVersion: apps/v1
kind: Deployment
metadata:
  name: valkyrie-dev
spec:
  replicas: 3                    # Pod 복제본 수
  selector:
    matchLabels:
      app: valkyrie-dev          # 관리할 Pod 선택 기준
  template:
    metadata:
      labels:
        app: valkyrie-dev        # Pod에 붙일 라벨
    spec:
      containers:
      - name: valkyrie-dev
        image: {{수정할곳}}
        ports:
        - containerPort: 8080    # 컨테이너 내부 포트

service.yaml 구조 이해

apiVersion: v1
kind: Service
metadata:
  name: valkyrie-dev
spec:
  type: LoadBalancer             # 외부 접근 가능한 서비스
  ports:
  - port: 80                     # 서비스 포트
    targetPort: 8080             # Pod 포트
  selector:
    app: valkyrie-dev            # 연결할 Pod 선택 기준

Step 3: Kubernetes 리소스 배포

kubectl apply -f .

4. 배포 상태 확인하기

Deployment 상태 확인

# Deployment 목록 확인
kubectl get deployments

 

Service 상태 확인

# Service 목록 확인
kubectl get services

 

 

반응형

1. Access Deny 

해당 에러가 뜨는경우는 두가지이다 해당 CopySource가 존재하지 않을때, 

존재하는데 해당 에러가 뜨는경우는 key값 앞에 해당 CopySource가 존재하는 버킷명을 추가하면 된다. 

 

2. the specified key does not exist

만약 utf-8로 key를 올렸다면 해당 에러가 뜰수도 있다. CopySource 값을 인코딩해서 보내면 된다! 

반응형

(개인 기록용)

최소 지원 버전

nodeJS : 16.13.0
TS : 4.7
PostgreSQL : 9.6

주요 변화

1. rejectOnNotFound 파라미터 제거

2. jsonProtocol 프리뷰 (graphQL)

3. array 단축키 (shortcut) 제거

- 대상 : `OR`, `in`, `notIn`, postgresql json `path`, scalar list, mogoDB composite list shorcuts
- 기존 싱글 요소들을 array 형식으로 변환해주는 기능 제거 
- ex ) 
    이전 
            ....
            OR : {id : 1},
            ....
    이후 
            ...
            OR : [{id : 1}],
            ...

4. CockroachDB사용시 provier에 cockroachdb로 연결 필요

5. generated client에서 runtime/index.js제거

https://www.prisma.io/docs/guides/upgrade-guides/upgrading-versions/upgrading-to-prisma-5#removal-of-runtimeindexjs-from-generated-client

반응형

https://jestjs.io/docs/mock-function-api#mockfnmockreturnvalueoncevalue

Mock Functions · Jest

Mock functions are also known as "spies", because they let you spy on the behavior of a function that is called indirectly by some other code, rather than only testing the output. You can create a mock function with jest.fn(). If no implementation is given

 

https://stackoverflow.com/questions/53887173/jest-mock-the-same-function-twice-with-different-arguments

 

jestmockReturnOnce기능을 이용하면됨

반응형

외부 API를 호출하고 해당 외부 API 호출을 실패했을때 기존 token을 갱신한 뒤에, 한번더 실행하는 코드를 작성하였는데, 

retry를 할때 갱신한 token의 값을 반영하지 않고 호출을 하는 것을 발견하였다. 

해결 방법 : defer사용 

추후에 더 자세한 내용을 작성할 예정!

 

반응형

https://github.com/typestack/class-validator/issues/1473

 

fix: ValidatedNested with transform not validating · Issue #1473 · typestack/class-validator

Versions: class-transformer: 0.4.0 class-validator: 0.13.2 Description Using Transform from class-transformer and ValidateNested of class-validator seems to skip validation of nested fields. Minima...

github.com

FormData로 데이터를 전달 받기 때문에 string형식으로 전달받은 object들을 JSON.parse()하기 위해서 @Transform을 사용하게 되었는데 그런경우에는 @Type()을 사용해서 @ValidateNested가 제대로 동작하지 않는 것을 발견함 

위의 이슈를 통해서 방법을 알게됨 

바로 JSON.parse()시 plainToInstance()를 사용하는 것! 

아래 링크는 문제를 해결하게 도와준 위의 이슈의 댓글!

https://github.com/typestack/class-validator/issues/1473#issuecomment-1260948193

 

fix: ValidatedNested with transform not validating · Issue #1473 · typestack/class-validator

Versions: class-transformer: 0.4.0 class-validator: 0.13.2 Description Using Transform from class-transformer and ValidateNested of class-validator seems to skip validation of nested fields. Minima...

github.com

 

그래서 따로 해당되는 decorator를 만들게됨 

export function TransformStringObject<T>(className?: ClassConstructor<T>) {
  return applyDecorators(
    Transform(({ value }) => {
      if (value === '') {
        return undefined;
      }

      return typeof value === 'string'
        ? className
          ? plainToInstance(className, JSON.parse(value))
          : JSON.parse(value)
        : value;
    }),
  );
}
반응형

.vscode/setting.json

{
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
  },
}

 

하고 formatOnSave하니깐 잘됨 

참고한 링크 : 

How to Format Code on Save in VS Code with ESlint | Aleksandr Hovhannisyan

반응형

 계속 

certbot renew --dry-run 

할 때 fail 떠서 뭐지 했는데 80포트 안열어놔서 그랬음. 

 

반응형

개인 기록용 

 

soft delete를 위해서 middleware로 delete, deleteMany 를 사용시에는 update, updateMany 로 변경하면서 deletedAt을 넣어주는 방식으로 개발을 하였는데, 

relation연산으로 연결된 데이터를 deleteMany를 사용시에는 그냥 delete 연산이 수행되더라... 

예 : 

A.update({
	data : {
    B : { 
    	deleteMany : [ {id} ] 
    	}
    },
    where : {
    id,
    }
})

relation 걸린 데이터 삭제시에 soft delete하고 싶으면 따로 쿼리작성하거나 ... 미들웨어를 다시 손 볼 수 있는지 확인해봐야지..

 

TODO : prisma 미들웨어 살펴보기 ... 

+ Recent posts