레이블이 computer인 게시물을 표시합니다. 모든 게시물 표시
레이블이 computer인 게시물을 표시합니다. 모든 게시물 표시

[컴] AWS snapshot archive 정보

 

스냅샷

AWS snapshot archive 정보

금액

금액 정보 : Archive Amazon EBS snapshots - Amazon Elastic Compute Cloud

  • snapshot 금액 : 월 GB당 $0.05
  • archived snapshot
    • 월 GB당 $0.0125
    • 100 GB, 월 $1.25(100GiB * $0.0125)가 청구
  • 복원비용 : 데이터 GB당 0.03 USD
    • 100GiB 스냅샷을 복원하면 3달러 청구(100GiB * $0.03).
    • 1회성 비용
  • snapshot 이 standard tier 로 복원된 뒤로는 snapshot 요금인 월 GB당 $0.05

[컴] terraform 에서 for_each에서 map 에 list 를 감싸는 이유

 테라폼 코딩 / 꼼수 / 트릭 /

terraform 에서 for_each에서 map 에 list 를 감싸는 이유

다음 module code를 보다가 궁금한게 생겼다.

code from : https://github.com/terraform-aws-modules/terraform-aws-alb/blob/a1a54c5b0a26919eda7bdd50da6b9eed5fedcc1c/main.tf#L343

resource "aws_lb_listener_rule" "redirect_to_https" {
  # rules = { <each.key> = each.value }
  for_each = local.rules

  ...

  dynamic "condition" {
    for_each = try(each.value.conditions, [])

    content {
      dynamic "host_header" {
        for_each = try([condition.value.host_header], [])

        content {
          values = host_header.value.values
        }
      }
    }
  }

  ...
}

위코드의 input은 다음과 같다.

...
  conditions = [{
    host_header = {
      values = ["/onboarding", "/docs"]
    }
  }]
...

여기서 왜 아래처럼 condition.value.host_header를 iterate 할 때, condition.value.host_header로 감쌌는지 궁금했다.

...
      dynamic "host_header" {
        for_each = try([condition.value.host_header], [])
        # 여기서 host header 는 아래와 같다.
        # host_header = { values = ["/onboarding", "/docs"] },

        content {
          values = host_header.value.values
        }
      }
...

아래처럼 바로 map 을 이용할 수도 있는데 말이다.

...
      dynamic "host_header" {
        for_each = try(condition.value.host_header, {})
        # 여기서 host header 는 아래와 같다.
        # host_header.key = values, host_header.value = ["/onboarding", "/docs"]

        content {
          values = host_header.value
        }
      }
...

input 에서 map 의 특정key 를 사용하게 하도록 하기 위해

이것은 host_header.values 를 명시적으로 하기 위함인 듯 하다. 아래 input 값을 가지고 test 를 해보면 이해가 쉽다.

...
  conditions = [{
    path_pattern = {
      vals = ["/onboarding", "/docs"]
    }
  }]
...

만약 map을 그대로 이용한 경우에는 values를 사용하지 않아도, 첫번째 item 이 가지고 있는 값을 사용하게 된다. 하지만 list 로 감싸면, iterate 에서 map 을 그대로 사용하게 되기때문에, 명시적으로 values 를 사용해줘야만 한다.

그로인해 input 은 ’values’라는 key 를 사용해야 만 한다.

[컴] 무한스크롤 vs pagination

비교

무한스크롤 vs pagination

ref.1 은 infinte scroll 과 pagination 의 비교한 글이다.

일부를 정리하면 다음과 같다.

  • 좀 더 목적이 있는 글에는 pagination 이 낫다.

  • 유저가 빠르게 소비하는 content 에는 infinite 이 낫다.

  • 구글 search 의 결과는 pagination 이지만, google image 의 결과는 infinite 인 이유가 image 를 보는 속도가 빠르기 때문이다.

예외 상황

모든 페이지의 모습이 ref.1 의 글안에 들어맞는 것은 아니다.

몇몇 무한스크롤은 명시적으로 콘텐츠를 더 불러오기 위해 클릭을 필요로 한다.

  • 덕덕고의 검색 결과는 infinite 이다.
  • 덕덕고에서는 페이지 이후에 명시적으로 다음 페이지 로드를 하도록 한다.
    • 이것은 footer를 보여줄 수 있다.
    • 다만 여전히 클릭을 해야 한다.

개인적인 생각

개인적으로 무한스크롤의 가장 큰 단점은 명시적으로 그 곳을 찾아가기가 어렵다는 것이라고 생각한다.

그것을 극복하는 방법중에 각 글에 대한 url을 제공하는 것이 의미가 있다고 본다. 이 경우 viewer에 대한 구현은 2가지가 있을 수 있다.

  • 하나는 url의 내용만 보여주는것,
  • 다른 하나는 스크롤등의 흐름안에서 그것을 보여주는 법.
    • 이것은 '텔레그램 채널'이 가장 적절한 구현의 예를 보여준다거 생각한다.

Reference

  1. UX: Infinite Scrolling vs. Pagination

[컴] MariaDB에서 binaray logging 이 되어 있다면, trigger 를 만들때 super 권한이 필요하다.

aws mysql / aws mariadb

MariaDB에서 binaray logging 이 되어 있다면, trigger 를 만들때 super 권한이 필요하다.

"You do not have the SUPER privilege and binary logging is enabled" 

자동 백업 기능(automated backups)은 MySQL에 대해 바이너리 로깅(binary logging)을 켤지, 끌지를 결정한다.

  • 바이너리 로깅 on: 백업 보존 기간(backup retention period)을 0이 아닌 양수 값으로 설정한다.
  • 바이너리 로깅 off: 백업 보존 기간을 0으로 설정한다.

자동백업을 활성화하는 법: Working with backups - Amazon Relational Database Service

  • Creating triggers with binary logging enabled requires SUPER privilege | Troubleshooting for Amazon RDS - Amazon Relational Database Service

    • 바이너리 로깅(binary loggin)이 활성화된 경우 trigger를 사용하려면 SUPER 권한이 필요하다.
    • 이 권한은 RDS for MySQL 및 RDS for MariaDB DB instance에서는 제한이 되어있다.(참고로, 자동으로 만들어지는 user 계정도 SUPER 를 가지고 있지 않다.)
    • SUPER 권한이 없어도 log_bin_trust_function_creators 매개 변수를 true로 설정하여 binary logging이 활성화된 상황에서 trigger를 만들 수 있다.
    • log_bin_trust_function_creators를 true로 설정하려면 새 DB parameter group을 생성하거나 기존 DB parameter group을 수정하면 된다.
      (참고로, 이미 RDS 가 run 하고 있을때 수정했다면, reboot 이 필요할 수 있다.)

현재 RDS 의 binray logging 이 활성화됐는지 확인

현재 RDS 의 binray logging 이 활성화됐는지는 다음 query 로 알 수 있다.

show global variables like 'log_bin'; 

version 확인

참고로 binary log 가 활성됐을 때 db version 을 확인하면 아래처럼 ‘-log’ 가 붙어서 보인다.

-- binary loggin on
> select version();
'10.6.10-MariaDB-log'

-- binary loggin off
> select version();
'10.6.10-MariaDB'

[컴] terraform 에서 ebs block 을 추가하고, user_data 사용하는 예시

디버그 요령 / 테라폼 요령 /

terraform 에서 ebs block 을 추가하고, user_data 사용하는 예시

data "template_file" "my_user_data" {
  # template = file("../../scripts/init-fish.yml")
  template = templatefile(
    "../../scripts/init-fish.tftpl",
    {
      bashrc  = "${indent(6, file("../../scripts/.bashrc"))}"
    }
  )
}


output "debug_user_data_output" {
  value = data.template_file.my_user_data.rendered
}

resource "aws_instance" "stage_a" {
  ...

  user_data = data.template_file.my_user_data.rendered
}

resource "aws_ebs_volume" "stage_a" {
  availability_zone = "ap-northeast-2a"
  size              = 10 # GB
  iops              = 3000
  type              = "gp3"
}

resource "aws_volume_attachment" "ebs_att" {
  device_name = "/dev/sdf"
  volume_id   = aws_ebs_volume.stage_a.id
  instance_id = aws_instance.stage_a.id
}
#cloud-config

packages:
  - curl

# .bashrc file
write_files:
  - path: /home/admin/.bashrc
    content: |
      "${bashrc}"
  - path: /home/admin/.profile
    content: |
      if [ -n "$BASH_VERSION" ]; then
          # include .bashrc if it exists
          if [ -f "$HOME/.bashrc" ]; then
              . "$HOME/.bashrc"
          fi
      fi

bootcmd:
  # format 하고
  - test -z "$(blkid /dev/nvme1n1)" && mkfs -t ext4 -L home_admin /dev/nvme1n1
  - mkdir -p /home/myuser

mounts:
  # mount
  - [ "/dev/nvme1n1", "/home/myuser", "ext4", "defaults,nofail", "0", "2" ]

runcmd:
  # set .bashrc
  - cp -f /home/bashrc_template_by_cloud_init /home/myuser/.bashrc
  - chown admin:admin /home/admin/.bashrc
# .bashrc, ${}를 사용하려면 $${} 를 사용해야 한다. terraform 에서도 ${} 를 사용하기 때문에. 나머지 $ 들은 괜찮다.
if [ -n "$force_color_prompt" ]; then
  if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
      # We have color support; assume it's compliant with Ecma-48
      # (ISO/IEC-6429). (Lack of such support is extremely rare, and such
      # a case would tend to support setf rather than setaf.)
      color_prompt=yes
  else
      color_prompt=
  fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='$${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$$ '
else
    PS1='$${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi

data template 의 output 을 확인

다음 처럼 output 을 추가하고, terraform plan 을 하면 output 이 template_file이 어떤 모습으로 생성되는지 확인할 수 있다.

...
output "debug_user_data_output" {
  value = data.template_file.my_user_data.rendered
}

aws cloud init debug

  1. aws management console 에서 stop instance 를 한 후 Actions -> Instance settings -> Edit user data 를 하자.
  2. 수정후 start instance
  3. cat /var/log/cloud-init-output.log

/var/log/cloud-init-output.log

aws 에서 cloud init 에 대한 log는 /var/log/cloud-init-output.log 에서 확인할 수 있다.

See Also

  1. 쿠…sal: [컴] aws 에서 cloud-init 을 이용해서 ebs attach

Reference

  1. grep - How to escape special characters in Terraform local-exec command line - Stack Overflow

[컴] aws 에서 cloud-init 을 이용해서 ebs attach

 

aws 에서 cloud-init 을 이용해서 ebs attach

aws 에서 ebs block 을 attach 하는 경우, instance 가 생성된 후 로그인을 하고, mkfs 를 해줘야 한다.

이것을 cloud-init 을 통해 해보려 했다.

ref. 2 에서 이야기처럼, 문제는 instance 가 run 되고 나서 ebs 가 인식되는 듯 하다. 그래서 cloud-init 시점에 mount 나 mkfs 명령어가 제대로 동작하지 않았다.

그래서 결론은 runcmd 에 sleep 을 주는 것으로 해결했다.

첫번째 시도, disk_setup, fs_setup

fs_setup을 통한 방법은 ref.1 을 보면, 이제 amazon linux 에서도 지원한다고 한다. 그래서 일단 시도해봤다. 아래 cloud-config 에서 ‘2nd Attempt’ 대신 1st Attempt 를 사용했다.

이 경우에는 처음 실행후, 다시 cloud-init 을 하는 경우에 mount 가 됐다.

  • instance running
  • login
  • sudo cloud-init clean
  • reboot
#cloud-config

packages:
  - curl

bootcmd:
 - mkdir -p /services

# ----------------
#
# 1st Attempt
#
# ----------------
# disk_setup:
#   /dev/nvme1n1:
#     table_type: gpt
#     layout: true
#     overwrite: false
#
# fs_setup:
#   - label: fs1
#     filesystem: ext4
#     device: /dev/nvme1n1
#     partition: auto
#     cmd: mkfs -t %(filesystem)s -L %(label)s %(device)s
#
# mounts:
#  - [ "/dev/nvme1n1", "/services"]

# ----------------
#
# 2nd Attempt
#
# ----------------
runcmd:
  - chown -R admin:admin /home/admin/
  - sleep 1m
  - test -z "$(blkid /dev/nvme1n1)" && mkfs -t ext4 -L fds1 /dev/nvme1n1
  - mount /dev/nvme1n1 /services
  - echo '/dev/nvme1n1  /services auto defaults,nofail,comment=cloudconfig 0 2' >> /etc/fstab

2번째 시도, sleep 1m

약 1분 정도 sleep 을 줬다. 참고로 sleep 중에도 ssh login 은 가능했다.

이 경우 정상적으로 mount 를 완료했다.

See Also

  1. cloud init debugging 방법 : Debugging cloud-init — cloud-init 22.2.2 documentation

Reference

  1. amazon linux 2023 에서 fs_setup이 가능한 듯 보인다.
  1. amazon ec2 - cloud-init: delay disk_setup and fs_setup - Stack Overflow : volume attachment 가 instance 가 완전히 실행이 된 이후에 되는 경우가 있다. 그 경우에 대한 fs_setup을 위해서 reboot 을 하게 하는 cloud-config 를 보여준다. sleep 에 대한 이야기도 여기에 있다.

[컴] terraform 에서 공통 변수 사용법

 

테라폼 / 사용법 / common / global variable /

terraform 에서 공통 변수 사용법

terraform 에서 환경변수 예시

export TF_VAR_test_var="testvar"

terraform에서 다음처럼 변수를 선언하고 사용하면 된다.

variable "test_var" {
    type        = string
    description = "This is an example input variable using env variables."
    default = "testvar"
}

resource "aws_instance" "tf-dev-auth-c" {
  tag = {
    test = var.test_var
  }
  ...
}

See Also

  1. 쿠…sal: [컴] Terraform 사용법

[컴] Airflow 에서 일정기간 후에 log 를 지우는 법

 

log retention / 보존기간 설정 /

Airflow 에서 일정기간 후에 log 를 지우는 법

기본적으로 airflow 에서 지원하는 retention 설정은 없는 듯 하다. 다음 글들에서는 airflow 를 이용해서 주기적으로 airflow 의 log 를 지우는 방법을 보여준다.

  1. A Simple DAG to Quickly Purge Old Airflow Logs | by Christine Betadam | EatCodePlay
  2. python - Configure logging retention policy for Apache airflow - Stack Overflow

airflow.cfg 를 변경후 server restart

설정에 따라 다르다는 듯, 어떤 값들은 reload 하려면 airflow 를 restart 해야 한다.

airflow restart 방법

kill -HUP <scheduler_process_id>
kill -HUP <webserver_process_id>

nohup airflow webserver --port 8080 1> /dev/null 2>&1 &
nohup airflow scheduler 1> /dev/null 2>&1 &
  • airflow scheduler -- DagFileProcessorManager 이 죽지 않는 경우가 있다. 이 경우는 수동으로 kill 해주자. 참고로 scheduler 가 떠 있으면, ‘DagFileProcessorManager’ 를 kill 해도 다시 실행된다.
  • webserver 는 ‘airflow webserver’ 가 아닌 ’gunicorn’을 kill 한다.

[컴] AWS IAM policy 설정관련 참고자료

 

aws iam 정책 설정

AWS IAM policy 설정관련 참고자료

IAM policy 를 설정은 AWS management console 에 대한 세부적인 제어는 어렵다.

현재 시도해본 바로는 list 에 대한 설정은 힘들다. 즉, 같은 region 에 있는 ec2 나 rds 등의 list 를 보여줄때 내가 원하는 것만 보여주도록 하고 싶었으나, 실패했다. 

시도해 보진 않았으나, region 으로 구분해서 작업하면 좋은 결과가 나올 수도 있을 듯 싶다.

내가 원하는 service에만 권한을 주면 list 가 보이지 않았다.

여기에서도 이야기지만, 모든 action 이 resource level 로 되어 있지 않아서 쉽지 않은 듯 하다.

자세한 사항은 Example policies for working in the Amazon EC2 console - Amazon Elastic Compute Cloud 를 읽어보는 것이 도움이 될 듯 하다.

[컴] kafka outbox pattern, Transactional outbox pattern

debzium /

kafka outbox pattern, Transactional outbox pattern

분산시스템에서 2번 write 되는 상황을 해결해준다.

예를 들어, 하나의 작업(operation) 이 ‘db write opertion’ 과 ‘message notification’ 을 갖고 있는 작업이라면, db 에 한번, message 쪽에 이렇게 두번의 write 를 해야 한다.

이 경우 failure(실패)가 날 때 data 의 일관성이 깨진다.(inconsistent), 그래서 이 작업은 atomically 하게 이뤄져야 한다.

예를 들어보자, 만약 가입을 완료하면, 가입완료 email을 보내는 작업이 있다고 하자.

  1. user table에 row를 만들고,
  2. email worker에게 email 을 보내라고 한다.(email event)

우리는 user 가 생성됐다면, email 이 나갔다고 확신하고 싶지만, 위 2개중 1개가 실패하면 data 가 inconsistent 하게 된다.

1. DB table 을 이용

outbox table 을 하나 만들고, email event 를 저장한다.(timestamp, sequence number), 그리고 이 table 의 변동사항을 보고, kafka event 를 보내는 것이다.(당연히, 이 작업을 하는 worker가 필요하다.)

2. Change Data Capture(CDC)를 이용하는 방법

여긴 outbox 에 표시를 하고, 그러면 그것이 transaction 이 log 에 기록되고, 이 log 의 Change Data Capture(CDC)를 보고, kafak event 를 보내는 방법을 취한다.

다만 위 2개의 글에서 이야기하는 방식은 ref.1 에서 이야기하는 Using CDC 와 조금 차이를 보인다.

ref.1 에서는 user table 의 row 가 만들어지면, 그것에 대한 binary log 등을 CDC로 사용해서 kafka 에 event 를 보내도록 한다. 하지만 위의 2개의 글에서는 user table 에 insert 가 끝나고, outbox table 에 다시 insert 를 하게 하고, 그 outbox table 의 CDC 를 이용해서 kafka를 보낸다.

둘다 틀린 접근은 아니다. db 에 기록을 남기느냐 마느냐는 선택의 문제인듯 하다.

kafka 에 send 를 확인하고 나서, user table 을 insert 하는 방식

’kafka 에 send 를 확인하고 나서, user table 을 insert 하는 방식’은 어떨까 ?

이것의 문제는 kafka send 가 성공하고나서, user table의 insert 가 실패하는 경우다. 이 경우 rollback 이 불가능하다.

See Also

  1. 강남언니, 분산 시스템에서 메시지 안전하게 다루기

Reference

  1. Transactional outbox pattern - AWS Prescriptive Guidance

[컴] rust llama-chat.wasm 을 wasmedge 에서 실행

rust llama-chat.wasm 을 wasmedge 에서 실행

wasmedge, rust llama-chat 을 실행하는 이야기다. ref. 2 를 확인하면 된다.

여기서는 ref.2 의 내용을 직접 해봤다.

실행한 사양

  • windows wsl2 의 ubuntu 20.04
  • ram 16gb
  • cpu i5-9400F @ 2.90GH

짤막한 소감

wsl2 여서 그런지 gpu 인식을 제대로 안됐다. 그래서 CPU 만으로 추론(inference)이 된다.

개인적으로 wsl2의 memory 는 대략 8GB까지 올라갔다.

1번째 질문은 1분내에 응답을 했다. 다만 2번째 질문부터는 5분정도 기다려도 답변이 나오지 않았다.

실행

curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- --plugin wasi_nn-ggml
# After installing the wasmedge, you have to activate the environment.
# Assuming you use bash (the default shell on Ubuntu), you will need to run the following command
source $HOME/.bashrc

pre-built Wasm app

curl -LO https://github.com/second-state/llama-utils/raw/main/chat/llama-chat.wasm
sudo apt update
sudo apt install -y libopenblas-dev
wasmedge --dir .:. --nn-preload default:GGML:AUTO:llama-2-7b-chat-q5_k_m.gguf llama-chat.wasm

Reference

  1. WasmEdge-WASINN-examples/wasmedge-ggml-llama-interactive/README.md at master · second-state/WasmEdge-WASINN-examples · GitHub
  2. Fast and Portable Llama2 Inference on the Heterogeneous Edge

[컴] AWS 의 instance에서 IAM role 사용

security credential, IAM role

AWS 의 instance에서 IAM role 사용

AWS의 instance에서 IAM role 을 사용할 수 있다. 예를 들어 EC2에서 s3를 사용할때 access key 를 발급받고, 그것을 instance 에 넣고, 그것을 application 이 사용하게 된다. 그런데 이 IAM role 을 사용하면, 실제적으로 application 이 access key 를 사용하는 것과 비슷하게 주기적으로 refresh 되는 security token 을 사용하게 된다.

그래서 IAM 을 사용하는 것은 이전에 access key 를 만들고, 그것을 넣어주는 작업을 좀 더 간편하게 해준다.


+-------------------------------------------+
| EC2 instance                              |
|    - iam/security-credentials/<role-name> |
|  +-------------+                          |
|  | Application |                          |
|  +-------------+                          |
+----------|---^----------------------------+
           |   |                          |
           |   |                          V
           |   |                       +---------+     +------------+
           |   |                       | Profile |---> | IAM role   |               
 role name |   |                       +---------+     | + policy   |
           |   |                                       | + policy   |
           |   |                                       +------------+
           V   |         
+------------------------------+
| Security Token Service(STS)  |
+------------------------------+

  • IAM role에 policy 를 만들어서 permission 을 명시하게 된다. resource-level 로 permission들을 적용할 수 있다.
  • IAM role 을 만들때 trusted entities 에 이 role을 사용할 수 있는 aws service 를 정의해주게 된다.
  • 이 IAM role을 ’instance의 profile’에 할당할 수 있다. 이 profile 은 1개의 IAM role 만 담을 수 있다.
    • 현재 run 하고 있는 instance 에도 attach 할 수 있다.
  • IAM console에서 IAM role 을 만들면, IAM console 은 instance profile 을 자동으로 생성한다.
  • 이 IAM role 에 policy 가 있다. 이 policy 에 어떤 action/resource 에 어떤 permission 이 허락되는지를 표시하게 된다.
  • instance 에 있는 application 은 STS 에다가 security credential 을 retrieve 한다.(아래 AssumeRole api 참고)
    • application 에서 사용하는 AWS SDK 에서 이 작업을 해주게 된다.
    • instance metadata item(iam/security-credentials/<role-name>) 을 보고 해당하는 security credential 을 retrieve 한다.
    • 이러한 security credentials은 임시적이며 자동으로 교체된다. 이전 credential이 만료되기 최소 5분 전에 새 credential을 사용할 수 있게 한다.

Retrieve instance metadata - Amazon Elastic Compute Cloud : aws는 http://169.254.169.254/latest/meta-data/ 에 각 instance 들의 meta-data들이 있다.

security credential 을 요청하는 command

아래는 s3access 라는 IAM role 에 대한 security credential 을 요청하는 command이다.

# s3access 라는 IAM role 에 대한 security credential 을 요청하는 command
#
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access


{
  "Code" : "Success",
  "LastUpdated" : "2012-04-26T16:39:16Z",
  "Type" : "AWS-HMAC",
  "AccessKeyId" : "ASIAIOSFODNN7EXAMPLE",
  "SecretAccessKey" : "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "Token" : "token",
  "Expiration" : "2017-05-17T15:09:54Z"
}

만약 instance 에서 AWS SDK를 사용해서 application 을 만들었다면, AWS SDK 가 자동으로 credential 들을 ec2 instance metadata service 로 부터 가져가서 사용하게 된다. (iam/security-credentials/<role-name>)

AssumeRole api

이 api 는 STS(security token service) 에서 제공한다.

이 api 를 호출하면 credential 을 return 해준다.

sts_client = boto3.client('sts')

assumed_role_object=sts_client.assume_role(
    RoleArn="arn:aws:iam::account-of-role-to-assume:role/name-of-role",
    RoleSessionName="AssumeRoleSession1"
)

credentials=assumed_role_object['Credentials']

s3_resource=boto3.resource(
    's3',
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken'],
)

terraform code

terraform 으로 구성하면 아래와 같다.

설명:

  • ec2 가 사용할 수 있는 IAM role 을 만들고,
  • 그 role 에 s3 mycorp-myapp bucket 을 사용할 수 있는 권한을 준다.
  • 그리고 instance profile 을 이용해서 ec2 에 attach 한다.
// ----------------------------
//
// IAM Role
//
// ----------------------------

resource "aws_iam_role" "tf-myapp-s3" {
  name = "myapp-s3"
  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Sid    = "exmyapp"
        Action = "sts:AssumeRole",
        Effect = "Allow",
        Principal = {
          // entities that can use this role
          Service = "ec2.amazonaws.com"
        }
      }
    ]
  })
  tags = {
    Name = "my-app"
  }
}

resource "aws_iam_role_policy" "tf-myapp-s3" {
  name = "myapp-s3"
  role = aws_iam_role.tf-myapp-s3.name
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Action = "s3:ListBucket",
        Effect = "Allow",
        Resource = [
          "arn:aws:s3:::mycorp-myapp",
          "arn:aws:s3:::mycorp-myapp/*"
        ],
      },
      {
        Action = [
          "s3:DeleteBucket",
        ],
        Effect = "Deny",
        Resource = [
          "arn:aws:s3:::mycorp-myapp",
        ]
      }
    ]
  })
}


// ----------------------------
//
// instance profile
//
// ----------------------------
resource "aws_iam_instance_profile" "tf-myapp-s3" {
  name = "myapp-s3"

  role = aws_iam_role.tf-myapp-s3.name
}



// ----------------------------
//
// EC2
//
// ----------------------------
resource "aws_instance" "tf-myapp" {
  ...

  iam_instance_profile = aws_iam_instance_profile.tf-myapp-s3.name
  ...
}

Reference

[컴] AWS RDS 의 Multi-AZ

가격 / rds 가격 / multi az 가격

AWS RDS 의 Multi-AZ

2가지 종류가 있다. 1개의 standby DB instance 가 있는것과 2개의 standby DB instances 가 있는 경우.

1개가 있는 경우는 ‘Multi-AZ DB instance deployment’ 라 부르고 2개가 있는 경우 ’Multi-AZ DB cluster deployment’라고 부른다.

  1. Multi-AZ DB instance deployment : 1개의 standby DB instance
    • 동기화된 standby replica 를 다른 AZ(Availability Zone)에 갖고 있는다.
    • 동기화 될때 전송 비용은 무료[ref. 2]
  2. Multi-AZ DB cluster deployment : 2개의 read 가능한 standby DB instances
    • 같은 region
    • 3개의 Availability Zone에
    • 1 writer DB instance + 2 reader DB instances
    • 이것은 ‘PostgreSQL’와 ’MySQL’ 만 가능

가격(pricing)

multi-az 를 사용하면 1개의 standby 를 사용하는 것도 사용하지 않는 것보다 비싸다. 대략 2배가 된다.

On-Demand 가격

Reference

  1. Configuring and managing a Multi-AZ deployment - Amazon Relational Database Service
  2. Amazon RDS Multi AZ Deployments | Cloud Relational Database | Amazon Web Services

[컴] 데이터 정제하는 툴

데이터 정제 / refine / 값 변경 / 보안 / 가공 / data refine

데이터 정제하는 툴

원하는 데이터를 불러서 이것의 일부내용을 변경할 수 있다. 변경된 data 는 excel, sql, csv 등 여러 형태로 추출할 수 있다.

사용

이것은 local 에서 test 할 때 실데이터를 사용하는 것은 보안이슈가 있다. 그런 문제의 소지가 있는 값들(예를들어, 이름, 전화번호등)을 이상한 값으로 변경해서 저장후 테스트용 data 로 배포할 때 쓸 수 있을 듯 하다.

[컴][머신러닝] E5-large-v2 로 블로그글에 대한 답변 얻기

E5-large-v2 로 블로그글에 대한 답변 얻기

Disclaimer

이글은 필자의 이해를 바탕으로 재작성했다. 틀린 부분이 있을 수 있다.

overview

보통 우리의 검색은 indexing 된 정보를 가져다 준다. 그래서 A라는 키워드를 넣으면, 그에 맞는 값들을 던져준다. 이것을 chatgpt 에게 대신할 수 있다. 다만 chatgpt 는 blog 의 모든 글을 읽고 그것을 재구성해서 우리에게 던져줄 수 있다.

이 e5-large-v2 모델은 질문을 던지면, 가지고 있는 답변 문장중에 가장 근접한 것을 던져준다.

Contrastive Learning

ML(machine learning)방법중 Contrastive Learning(대조적 학습)이 있다. self-supervised learning의 일종이다.

이 학습은 positive pair(양성쌍), negative pair(음성쌍)의 data 를 만들고, 이러한 쌍들을 이용해서 모델을 학습시키는 방법이다.

이 data pair 는 사람이 labeling 해서 줄 수도 있고, AI 가 특정 알고리즘을 이용해서 스스로 할 수 도 있다. 이렇게 얻어진 data 로 model 을 학습하게 되면, 이를 통해 이 model 은 데이터 간의 비슷한점(similarity)과 차이점(difference)을 이해하고 패턴을 학습하게 된다.

E5-large-v2 model

E5-large-v2 model 은 질문(query)과 그에 맞는 답변(passage)를 가지고 학습한 model이다.(query, passage 의 pair) 그래서 질문을 던지는 경우, 그 질문을 embdding 하고, 그 값을 현재 저장된 embedding 에서 similarity 가 높은 것들을 가져온다.

query 에 대한 embedding 을 뽑고, 이것을 저장된 embedding 인 blog-paragraphs 에서 찾아 본다. 그러면 유사한 query 를 찾아낼 수 있다. 그러면 그 query 에 딸려있는 passage 를 결과로 주면 된다.

llm similar blog-paragraphs -c 'query: what is LLM?'

HuggingFace Inference API

https://huggingface.co/intfloat/e5-large-v2 에서 ‘Inference API’ 로 테스트를 해보면 이 모델이 질문을 던질때 어떤 답변을 줄지 확인해 볼 수 있다.

  • Source Sentence 에는 내가 model 에 input 으로 넣고 싶은 값
  • Sentences to compare to 에는 input texts, 즉 내가 model 에게 줄 context

값을 넣으면 된다.

llm

pip install llm
llm install llm-sentence-transformers

자신이 쓰려는 model 을 local 에 설치한다.

llm sentence-transformers register intfloat/e5-large-v2 -a lv2

sentence transformer

embedding들을 위한 python framework 이다. 기술적인 문장(state-of-the-art sentence), 문서, 이미지에 대해 embedding 을 해준다. 원하는 model 을 선택하고, 그 model 을 기준으로 한 embedding 을 얻을 수 있다.

여기서 사용하는 pretrained model 은 HuggingFace 같은 곳에서 serve 하는 model들이다.

SentenceTransformer는 아래 예시를 보면 이해가 될 것이다.

#
# source from : [Usage](https://www.sbert.net/#usage)
#
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')

#Our sentences we like to encode
sentences = ['This framework generates embeddings for each input sentence',
    'Sentences are passed as a list of string.',
    'The quick brown fox jumps over the lazy dog.']

#Sentences are encoded by calling model.encode()
embeddings = model.encode(sentences)

#Print the embeddings
for sentence, embedding in zip(sentences, embeddings):
    print("Sentence:", sentence)
    print("Embedding:", embedding)
    print("")

intfloat/e5-large-v2 · Hugging Face

from sentence_transformers import SentenceTransformer
model = SentenceTransformer('intfloat/e5-large-v2')
input_texts = [
    'query: how much protein should a female eat',
    'query: summit define',
    "passage: As a general guideline, the CDC's average requirement of protein for women ages 19 to 70 is 46 grams per day. But, as you can see from this chart, you'll need to increase that if you're expecting or training for a marathon. Check out the chart below to see how much protein you should be eating each day.",
    "passage: Definition of summit for English Language Learners. : 1  the highest point of a mountain : the top of a mountain. : 2  the highest level. : 3  a meeting or series of meetings between the leaders of two or more governments."
]
embeddings = model.encode(input_texts, normalize_embeddings=True)

local 의 model 사용

local 의 model 을 이용하려면 local 에 model 을 다운로드 하고, local path 를 적어주면 된다. (참고: How to load huggingface model/resource from local disk? - Stack Overflow)

huggingface 를 git clone 하면, model file들이 download 된다. 이것을 SentenceTransformer에서 사용하면 된다.

Reference

  1. Embedding paragraphs from my blog with E5-large-v2 | Simon Willison’s TILs

[컴] google SRE 팀이 20년간 사이트를 운영하면서 얻은 교훈

구글 / 레슨 / lesson /

google SRE 팀이 20년간 사이트를 운영하면서 얻은 교훈

20년전 구글:

  • 2개의 소규모 데이터 센터, 각각 수천개 서버를 보유
  • 서버끼리는 한쌍의 2.4G network link 로 ring 연결
  • private cloud 를 운영
  • Assigner, Autoreplacer, Babysitter 같은 python script 로 운영
  • 이 script 들은 각각의 서버이름들로 가득찬 config file들을 기반으로 동작했다.
  • 작은 DB 기기가 있었다. 이 DB는 개별서버에 대한 정보를 체계적이고, 안정적이게(durable) 유지하는데 도움을 줬다.
  • 다음 이유로 script들과 config 들을 사용했다.
    • 일반적인 문제들을 자동으로 해결하기위해
    • 작은 서버 무리를 관리하는데 필요한 수작업을 줄이기 위해

현재:

2016년 Youtube global outage 에서 얻은 교훈

YouTube’s distributed memory caching system 으로 글로벌한 중단(global outage)를 15분간 경험으로 얻은 3가지 교훈

  1. The riskiness of a mitigation should scale with the severity of the outage (장애 완화조치의 위험성은 장애(outage)의 심각성에 비례한다.)
    • SRE 팀은 장애를 해결하기위해 한 조치가, 장애 자체보다 더 큰 위험을 초래한 경험이 있다.
    • 유투브 팀이 장애완화로 load-shedding을 했는데(일부 서비스나 기능을 의도적으로 중단시키는 방법), 이것이 장애를 해결하진 못하고, 이로 인해 연쇄적인 문제가 터졌다.
    • 장애상황에서는 모니터링과 상황의 심각성을 평가해야만 하고, 그리고 나서 장애의 심각성과 비슷한 수준의 위험을 갖는 장애완화조치(mitigation path)를 선택해야만 한다.
  2. Recovery mechanisms should be fully tested before an emergency (복구 절차들은 긴급상황전에 완전히 테스트돼야만 한다.)
    • 복구절차에 대해서 다음사항에 대해 테스트해라. 이것이 이 행동이 수행될때 위험을 줄여줄 것이다.
      • 그것이 원하는대로 동작하는지
      • 당신이 그것을 어떻게 사용하는지 아는지
    • 이번 중단을 겪고, 복구과정 testing 에 2배의 시간을 할당함.
  3. Canary all changes (모든 변화들을 미리 점검해라)

Google calendar 이슈 에서 얻은 교훈

  1. Have a “Big Red Button” (큰 빨간 버튼을 가져라)
    • 잠재적으로 위험한 작업을 하기전에 어떤것이 빨간 버튼들이 될 지 파악하는것이 중요하다.
    • 예를 들어, 어떤 것을 작업했는데, 그것이 퍼지기전에 plug 를 뽑아서 막을 수 있다면 그것이 빨간버튼이 되는 것이다.
    • Generic mitigations – O’Reilly
  2. Unit tests alone are not enough - integration testing is also needed (유닛테스트들 만 하는 것은 충분치 않다. 통합테스트 또한 필요하다.)
    • 유닛테스트는 runtime 환경과, 모든 production 의 요구사항을 그대로 복제해서 하는 테스트가 아니다.
    • 우리는 통합테스트들을 cold start 를 수행할 수 있다는 것을 확인하는데 사용할 수 있다.
    • 우리가 원하는 대로 동작하는가?
    • 구성요소들(components)가 우리가 원하는대로 함께 동작하는가?
    • 이 component 들이 성공적으로 우리가 원하는 system을 만드는가?
    • 우리의 test들이 실제 사용방법을 따르지 않았다. 그결과로 많은 테스트들이 변경이 실제로 어떻게 수행될지 평가하는데 도움이 되지 않았다.

2017년 2월 사건의 교훈

OAuth token 이 사용불가 되자 많은 기기가 logout 하고, OnHub 및 google wifi 기기가 공장초기화를 수행했다. 수동 계정복구 요청이 10배 급증.

  1. COMMUNICATION CHANNELS! AND BACKUP CHANNELS!! AND BACKUPS FOR THOSE BACKUP CHANNELS!!!

    • Google Hangout과 , Google Meet 로 사건을 관리하려 했지만, 사람들이 log out 돼서 연락이 안됐다.
    • 테스트가 된 의존성없는 대체 소통 채널들을 가져야만 한다.
    • 이 사건은 graceful degradation | Google - Site Reliability Engineering 에 대한 더 나은 이해를 하게 해줬다.
  2. Intentionally degrade performance modes (의도적인 성능저하 모드)

    • 모든것이 작동하지 않더라도, 최소의 기능이 꾸준히 제공되도록 하는 것이 때로는 더 일관된 사용자경험을 제공할 수 있기도 한다.
    • 신중하고, 의도적인 저하된 성능모드를 구축했다. 성능저하도 gracefully 하게 이뤄져야 하고, 예외적인 상황에서도 동작해야 한다.

자연적인 재해, 또는 사이버 공격등을 막으려면:

  1. Test for Disaster resilience (재해 복원력 테스트)
    • Resiliance testing 은 오류, 대기시간 또는 중단이 발생해도 서비스나 시스템이 유지될 수 있는지 확인
    • recovery testing 은 완전한 shutdown 된 이후에 다시 homeostasis(항상성) 로 돌아갈 수 있는지를 확인
    • 둘 다 사업의 연속적인 전략에 중요한 부분이 돼야 한다.
    • 유용한 활동: 다같이 앉아서 만약의 사태가 일어났을때 시나리오를 살펴보는 것
  2. Automate your mitigations (재해복구 자동화)
    • 2023년 3월, 몇몇 데이터 센터에서 여러 네트워킹 장치에 거의 동시에 장애가 발생하여 광범위한 패킷 손실이 발생
    • 이런 경우 복구하는 동작을 자동화 해놓으면, MTTR(mean time to resolution, 해결평균시간)을 줄일 수 있다.
    • 만약 특정 사건이 일어날때 왜 그 복구방법을 자동으로 실행할 수 없나? 때론 복구를 먼저해서 사용자영향을 피하고, 주요원인을 저장하는 것이 낫기도 하다.
  3. Reduce the time between rollouts, to decrease the likelihood of the rollout going wrong (배포(rollout)들 간의 시간을 줄여서 배포(rollout)가 잘못될 가능성을 줄인다.)
    • 2022년 3월, 결제 시스템의 광범위한 중단
    • database field 한개를 지웠는데, 그것이 문제가 됨.
    • 그 field 를 사용하는 모든 code를 그전에 지웠기 때문에 문제는 없었다.
    • 시스템의 한부분의 rollout 이 느렸는데, 그로인해 그 filed 가 live system 에서 사용되게 되었다.
    • 여러 구성요소가 있는 복잡한 시스템에서 이런 배포사이에 긴 지연이 있으면, 변경사항에 대한 안정성을 추측하기가 어려워 진다.
    • 빈번한 rollout 이 이런 종류의 실패에 대한 갑작스러운 놀람을 줄여준다.
    • Use Four Keys metrics like change failure rate to measure your DevOps performance | Google Cloud Blog
  4. A single global hardware version is a single point of failure (하나의 글로벌 하드웨어 버전은 실패 지점이 된다.)
    • 중요한 기능을 하는 기기가 특정 모델을 사용하는 것이 좀 더 간단한 운영과 유지를 하게 해주긴 한다.
    • 그러나 그 모델이 문제가 있을 경우, 중요한 기능은 더이상 동작하지 않는다.
    • 2020년 3월, 네트워킹장비가 발견되지 않은 zero-day bug 가 있었는데, 트래픽패턴의 변화가 생겨서 그 버그가 터져나왔다.
    • 네트워크 모두에 같은 모델과 버전의 기기들이 사용중이었어서, 상당한 지역적 중단은 발생했다.
    • 높은 우선순위 트래픽을 잘 동작하는 다른 기기로 전달해주는 여러개의 network backbone 들이 존재해서 전채적인 중단을 막을 수 있었다.
    • diverse infrastructure 를 유지하는 것은 그 자체로 비용이 들지만, 이것이 완전한 서비스 장애를 벗어나게 해줄 수 있다.

See Also

  1. Lessons Learned from Twenty Years of Site Reliability Engineering | Hacker News : 다양한 경험과 관련된 이야기들
  2. Building Secure and Reliable Systems
  3. > Automate your mitigations Think long and hard about this one. Multiple times i… | Hacker News : 자동화된 복구처리가 가져다 주는 복잡성과의 균형을 잡아야 한다.

[컴] CloudWatchFullAccess 와 CloudWatchFullAccessV2 의 차이

diff / policy / CloudWatchFullAccess / CloudWatchFullAccessV2

CloudWatchFullAccess 와 CloudWatchFullAccessV2 의 차이

  • 좀 더 명시적이 됐다. 이전의 *(asterisk)로 표현했던 부분을 개별 객체로 바꿨다.
  • Sid 가 추가됨
json policy document 비교

Reference

  1. CloudWatchFullAccessV2 - AWS Managed Policy
  2. CloudWatchFullAccess - AWS Managed Policy

[컴] wsl2 에서 microk8s 사용

kubernetes dashboard 접근방법 / 사용법 / 쿠베 / 쿠버네티스

wsl2 에서 microk8s 사용

sudo apt update && sudo apt upgrade -y
sudo snap install microk8s --classic
sudo usermod -a -G microk8s ${USER}
microk8s.kubectl get node

kubernetes dashboard 사용

microk8s enable dns dashboard storage
microk8s.kubectl get all --all-namespaces

curl https://10.152.183.192 --insecure 로 접근하면 된다.

windows 에서 wsl2 의 kubernetes에 접근

windows 에서 wsl2 에 접근하려면 kubectl proxy 를 이용하면 된다.

# wsl2 에서 proxy 를 띄운다.
$ kubectl proxy

windows에서 다음 url 로 접근한다.

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#/login

login

kubernetes dashboard의 login 에서 token 으로 login 하는 option 이 있다. 그것으로 login 하면 된다.

token 생성은 wsl2 에서 다음처럼 하면 된다.

token=$(microk8s.kubectl -n kube-system get secret | grep default-token | cut -d " " -f1) microk8s.kubectl -n kube-system describe secret $token

See Also

[컴] wsl2 에서 minikube 실행

kubernetes 실행/ 쿠베 / 쿠버네티스 실행 / dev local / k8s windows

wsl2 에서 minikube 실행

1. docker 설치

  1. 필요한 package설치

    sudo apt-get install -y \
        apt-transport-https \
        ca-certificates \
        curl \
        software-properties-common
  2. add official Docker PGP key

    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  3. add repo

    • add repo:

      sudo add-apt-repository \
         "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
         $(lsb_release -cs) \
         stable"
    • package update:

      sudo apt-get update -y
  4. install docker community edition :

    sudo apt-get install -y docker-ce
  5. docker group 에 추가

    sudo usermod -aG docker $USER && newgrp docker

systemctl 설치

git clone https://github.com/DamionGans/ubuntu-wsl2-systemd-script.git
cd ubuntu-wsl2-systemd-script/
bash ubuntu-wsl2-systemd-script.sh

sudo apt install -y conntrack

systemd 사용

2. minikube 설치

minikube 설치:

# Download the latest Minikube
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

# Make it executable
chmod +x ./minikube

# Move it to your user's executable PATH
sudo mv ./minikube /usr/local/bin/

#Set the driver version to Docker
minikube config set driver docker

kubectl 설치:

이것이 필요한지는 확인이 필요

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

# Make it executable
chmod +x ./kubectl

# Move it to your user's executable PATH
sudo mv ./minikube /usr/local/bin/

3. minikube 실행

namh@DESKTOP-H:~$ minikube start
😄  minikube v1.31.2 on Ubuntu 20.04 (amd64)
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.27.4 preload ...
    > preloaded-images-k8s-v18-v1...:  393.21 MiB / 393.21 MiB  100.00% 10.18 M
    > gcr.io/k8s-minikube/kicbase...:  447.62 MiB / 447.62 MiB  100.00% 10.86 M
🔥  Creating docker container (CPUs=2, Memory=3900MB) ...
❗  This container is having trouble accessing https://registry.k8s.io
💡  To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳  Preparing Kubernetes v1.27.4 on Docker 24.0.4 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔗  Configuring bridge CNI (Container Networking Interface) ...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🔎  Verifying Kubernetes components...
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
$ kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE     VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION                       CONTAINER-RUNTIME
minikube   Ready    control-plane   7m50s   v1.27.4   192.168.49.2   <none>        Ubuntu 22.04.2 LTS   5.15.133.1-microsoft-standard-WSL2   docker://24.0.4

stop | minikube


$ minikube stop

Reference

  1. Install Minikube in WSL 2 with Kubectl and Helm - Virtualization Howto

[컴] 차세대 기록 장치, 유리

 

https://m.clien.net/service/board/news/18370348?od=T31&po=1&category=0&groupCd= 유리 가 저장장치로 쓰인다.

disk / storage / 영구적인 저장소 / 디스크 / 스토리지 / ssd / cd / 테이프 / 데이터센터 저장

차세대 기록 장치, 유리

  • ultrafast femtosecond laser 사용
  • 현재 기술은 plate 하나에 TB 저장 가능
  • datacenter 에 쓰일 것이라고.[ref. 2]
  • 대략 1만년정도 보존 가능하다. (기존의 자기 저장소는 보존기간이 5년정도다.)

Reference

  1. Project Silica proof of concept stores Warner Bros. ‘Superman’ movie on quartz glass
  2. Sealed in glass – Microsoft Unlocked