2022년 4월 12일 화요일

[ AWS ] Athena query 처리량 증가 ( Service Quotas )

 

AWS Athena 사용시, 여러 계정에서 query를 실행할 때

처리량의 한계에 의해 athena rate exceeded 에러가 나타난다.


aws servicequotas를 통해 DDL, DML의 처리량 증가 요청을 한다.

Athena 외에도 DynamoDB, Lambda와 같은 서비스의 할당량을 조정할 수 있다.



servicequotas 콘솔 :

https://ap-northeast-2.console.aws.amazon.com/servicequotas/home/


참조 Doc :

https://docs.aws.amazon.com/ko_kr/general/latest/gr/aws_service_limits.html

2022년 4월 7일 목요일

[ Laravel ] Centos에서 Laravel 설치

 

Centos에서 Laravel 설치


[ APM설치 ]

yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum -y install epel-release yum-utils
yum-config-manager --enable remi-php74
yum install httpd
yum install php php-cli php-bcmath php-bz2 php-common php-curl php-dba php-gd php-json php-mbstring php-opcache php-readline php-soap php-xml php-xmlrpc php-zip php-ctype php-pdo php-redis php-mysql php-imagick php-intl

vi /etc/yum.repos.d/MariaDB.repo
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.4/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

yum install MariaDB-server MariaDB-client
systemctl enable httpd
systemctl enable mariadb


[ Apache /etc/httpd/conf/http.conf 설정 ] (빨간색 추가 및 변경)

LoadModule rewrite_module modules/mod_rewrite.so

<Directory "/home/centos">
    AllowOverride None
    # Allow open access:
    Require all granted
</Directory>

<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>

# Virtual hosts
Include conf/extra/httpd-vhosts.conf


[ /etc/httpd/conf/extra/httpd-vhosts.conf 설정 ]

<VirtualHost *:80>
    ServerAdmin mygmail@gmail.com
    DocumentRoot "/home/centos/laravel_project/public"
    ServerName 11.22.333.44
    #ServerAlias 11.22.333.44
    ErrorLog "/home/centos/laravel_project/logs/error_log"
    CustomLog "/home/centos/laravel_project/logs/access_log" common
        <Directory /home/centos/laravel_project/public/>
                AllowOverride All
                Allow from all
        </Directory>
        <Directory /home/centos/laravel_project/storage/>
                AllowOverride All
                Allow from all
        </Directory>
</VirtualHost>


[ 라라벨 설치 ]

timedatectl set-timezone Asia/Seoul
# 라라벨을 인스톨을 제공하는 composer설치
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/bin/
ln -s /usr/bin/composer.phar /usr/bin/composer

# 라라벨 설치
composer global require laravel/installer
echo 'export PATH="$PATH:$HOME/.config/composer/vendor/bin"' >> ~/.bashrc
source .bashrc

# 새 프로젝트 생성
laravel new laravel_project


[ 폴더 권한 변경 ]

1. 라라벨 폴더 경로가 /home/centos/laravel_project 라면 3개폴더 모두 chmod 755
2. chmod -R 777 laravel_project/storage (정확히 framework, logs 폴더때문)


[ 실행 ]

systemctl restart httpd
web url창에 11.22.333.44로 접속


[ 실행 화면 ]






2022년 4월 4일 월요일

[ Python ] AWS boto3를 이용한 S3 Path Wild Card


s3의 list_objects를 이용해 prefix를 사용할 수 있지만, 

prefix안에 wild card를 활용할 순 없다.


s3경로가 s3://my-bucket/country/city/town/20220404/myfile.parquet 일 때

  • Prefix='country/city/town/20220404 ( 0 )
  • Prefix='country/*/*/20220404 ( X ) 


pip install awswrangler 

모듈 설치 후 와일드카드를 사용한 S3경로로 필터링 가능


[ Sample Code ]

import boto3
import awswrangler

BUCKET = 'my-bucket' 
S3_PATH = 'country/*/*/20220404/*

s3_paths = awswrangler.s3.list_objects(f's3://{BUCKET}/{S3_PATH}')
for path in s3_paths:
    print(path)



2022년 3월 29일 화요일

[ Python ] AES 양방향 암호화

 

모듈 설치

$ pip install pycryptodome


파이썬 코드

import base64
from Crypto import Random
from Crypto.Cipher import AES

class AES256():

    def __init__(self, key):
        self.bs = 128
        self.key = key.encode('utf-8')
        self.key = AES256.str_to_bytes(key)

    @staticmethod
    def str_to_bytes(data):
        u_type = type(b''.decode('utf8'))
        if isinstance(data, u_type):
            return data.encode('utf8')
        return data

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * AES256.str_to_bytes(chr(self.bs - len(s)%self.bs))

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

    def encrypt(self, raw):
        raw = self._pad(AES256.str_to_bytes(raw))
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw)).decode('utf-8')

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')


aes256 = AES256('mypassword')
e_aes256 = aes.encrypt('password_encrypt')
print(e_aes256)    # VvDWrD2aDyc+2rsdfDhDKosnc2odl2HD2
print(aes256.decrypt(e_aes256))    # password_encrypt



2022년 3월 16일 수요일

[ Python ] No module named 'numpy.core._multiarray_umath' Error


[ 에러 ] 

numpy패키지 설치시 발생 



[ 원인 ]

1. Numpy가 지원하는 최신 Python version은 3.8로 3.9버전 이상 사용시 에러

2. 윈도우(개발환경)에서 pip install numpy로 설치한 패키지는 리눅스에서 컴파일이 안되므로, 

powershell이나 hyper-v를 통해 numpy를 재설치



2022년 3월 14일 월요일

[ Lambda ] 다른 계정의 IAM권한 사용


다른 계정의 IAM을 사용하여 

Lambda함수에서 다른계정의 S3, Athena, Glue 등을 컨트롤 

예제 : AAAA 계정의 람다함수를 통해 BBBB계정의 S3와 athena, glue테이블에 접근



[ 1 ] AAAA 계정에서 람다를 실행하는 iam role(my-lambda-etl-role)에 

AccessCrossIAMBBBB라는 정책을 생성한 후, 아래 스크립트 추가

(기존 role에 추가시 policy로 생성 후 연동)

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "arn:aws:iam::BBBB:role/bbbb-lambda-etl-role"
} }



[ 2 ] BBBB 계정에서 'bbbb-lambda-etl-role' im role에 

신뢰 관계 탭에서 아래 스크립트 추가

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AAAA:role/service-role/aaaa-lambda-etl-role"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

권한 탭에서 AAAA계정이 접근할 서비스 추가 (S3, Athena, Glue)




[ 3 ] AAAA계정의 lambda에서 코드 작성

# 샘플코드

def lambda_handler(event, context):
    print('start function')

    sts_connection = boto3.client('sts')
    acct_b = sts_connection.assume_role(
        RoleArn="arn:aws:iam::BBBB:role/role-on-source-account",
        RoleSessionName="cross_acct_lambda"
    )

    ACCESS_KEY = acct_b['Credentials']['AccessKeyId']
    SECRET_KEY = acct_b['Credentials']['SecretAccessKey']
    SESSION_TOKEN = acct_b['Credentials']['SessionToken']


    # create service client using the assumed role credentials
    session = boto3.Session(
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
        aws_session_token=SESSION_TOKEN,
    )



[ 4 ] LakeFormation 사용시

각 계정에서 role에 대한 table/location 공유설정


[ 5 ] 참조하는 BBBB계정의 S3 권한 설정

버킷->권한->버킷정책

{ "Version": "2012-10-17", "Statement": [ { "Sid": "DelegateS3Access", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::AAAA:root" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::my-bucket-name/*", "arn:aws:s3:::my-bucket-name" ] } ] }




참조 : 
https://aws.amazon.com/ko/premiumsupport/knowledge-center/lambda-function-assume-iam-role/?nc1=h_ls

2022년 3월 6일 일요일

[ Docker ] 도커파일

[ 도커파일이란? ]

  • Docker상에서 실행시킬 컨테이너의 구성 정보(미들웨어, OS, 어플리케이션 등)을 기술하기 위한 파일
  • 확장자는 필요없음
  • Dockerfile이란 파일명 말고 다른 파일명으로 쓸 수 있지만 build시 명시해줘야 함



[ Docker File을 이용한 Sample ]

Dockerfile

# 베이스 이미지 설정

FROM ubuntu:latest

(or dighests로 지정: FROM ubuntu@sha256:se21f... )


# Nginx 설치

RUN apt-get update && apt-get install -y -q nginx


# 파일 복사

COPY index.html /usr/share/nginx/html


# Nginx 시작

CMD ["nginx", "-g", "daemon off;"]


도커 build

# 도커 파일 build

$ docker build -t webapp:1.0 /dockerfile_path


# 빌드된 이미지 실행

$ docker run -d --name "web_nginx" -p 80:80 webapp


[ 도커파일 작성 명령어 ]

RUN

# Shell 형식으로 bin/sh 를 거쳐서 실행

RUN apt-get install -y nginx

# Shell을 경유하지 않고 실행

RUN ["/bin/bash","-c","apt-get install -y nginx"]


CMD

이미지를 바탕으로 생성된 컨테이너 안에서 명령을 실행

하나만 지정 가능하며, 여러 개 지정 시 마지막 명령만 유효

# 베이스 이미지 설정

FROM ubuntu:16.04

# Nginx설치

RUN apt-get -y install nginx

# 포트 지정

EXPOSE 80

# 서버 실행

CMD nginx -g 'daemon off;'  [or]  CMD ["nginx", "-g", "daemon off;"]


ENTRYPOINT

docker container run 명령을 실행했을 때 실행

# Docker file

# 베이스 이미지 설정

FROM ubuntu:16.04


# top 실행

ENTRYPOINT ["top"]

CMD ["-d", "10"]

실행

# CMD 명령에서 지정한 10초 간격

$ docker run -it --name sample sample-app

# 인자를 다시 주어 2초 간격으로 갱신

$ docker run -it --name sample sample-app -d 2



ONBUILD

ONBUILD 구문을 포함한 Dockerfile이 다음 빌드에서 

베이스 이미지로 설정 하였을 때, ONBUILD로 지정한 명령어를 설정

1.베이스 이미지 작성(Dockerfile.base)

# 베이스 이미지 설정

FROM ubuntu:16.04

# Nginx 설치

RUN apt-get -y update && apt-get -y upgrade

RUN apt-get -y install nginx

# 포트 지정

EXPOSE 80

# 웹 콘텐츠 배치

ONBUILD ADD website.tar /var/www/html

# Nginx 실행

CMD nginx -g "daemon off;'

 2. 베이스 이미지 빌드

$ docker build -t web-base -f Dockerfile.base .

3. 본 이미지  작성

From web-base

4. 본 이미지 빌드

$ docker build -t web-app .

$ docker run -d -p 80:80 web-app

# 이후 website.tar로 구성된 html, css 화면이 나오는지 확인


STOPSIGNAL

컨테이너를 종료할 때 송신하는 시그널 설정

STOPSIGNAL [시그널]


HEALTHCHECK

컨테이너 안에 프로세스 정상 작동 확인

#5분마다 가용 중인 웹서버를 5초 안에 표시할 수 있는지 확인

HEALTHCHECK --interval=5m(체크간격) --timeout=5s (체크타임아웃) CMD curl -f http://localhost/ || exit1

# 헬스 체크 결과는 docker contain inspect로 확인


ENV

key value형태로 환경변수 설정

# Docker file

ENV myName = "42 fire user" \   

    myOrder = book\ desck\ chair \

지정한 환경변수 변경시

docker run --env를 통해


WORKDIR

작업용 디렉토리 지정, 없으면 새로 생성

# Docker file

ENV DIRPATH second

WORKDIR /first/$DIRPATH


USER

도커파일의 명령어를 실행 할 사용자 지정

# Docker file

RUN ["adduser", "42F"]

RUN ["whoami"]      # root

USER 42F

RUN ["whoami"]      #42F


EXPOSE

실행 중인 컨테이너의 공개 포트 지정

# Docker file

EXPOSE 8080     # docker run -p 로도 설정 가능


ARG

도커파일 안에서 사용할 변수를 정의

# Docker file

ARG MYNAME = "42F"

RUN echo $MYNAME

실행 시

$ docker build . --build-arg    # MYNAME = "42F"

$ docker build . -build-arg MYNAME=70F    # MYNAME이 정의 되었어도 "70F"로 변수 재정의 됨


ADD

빌드 시, 이미지에 파일이나 디렉토리를 추가

# Docker file

ADD host.txt /docker_dir/


# 파일명 패턴 사용

ADD ho* /docker_dir/

ADD hos?.txt /docker_dir       # ? : 임의의 한 문자


# WORKDIR 명령어와 같이 사용 (경로 : /docker_dir/web/ ) cd역할

WORKDIR /docker_dir

ADD host.html /web


# 원격 파일 추가

ADD http://www.site.com/index.php /docekr_dir/web/

# 퍼미션이 600인 파일이 추가, URL을 통해 다운로드시 인증이 필요한 경우면 wget, curl을 사용


VOLUME

이미지에 볼륨을 추가

# Docker file

VOLUME /Mount PATH