반응형
작성일: 2024년 4월 16일

 

 

Network(특히 ONOS, VPN), Linux OS, Kubernetes, GNS3, Raspberry Pi 등 관련 내용을 구글링하다보면, 자주 '톨티의 공작소'가 검색 결과로 뜬다.

그래서 의도하지 않게 '톨티의 공작소' 블로그를 보게 된다.

 

인터넷 문서(블로그)에 이렇게 정성과 공을 들여서 컨텐츠를 만들어주니, 나 같은 열람자(Reader) 입장에서는 고맙다.

문서 중간에 그림, 표 등이 많이 있어서 바쁠 때는 쓱 훑어보기에도 좋다.

 

https://m.blog.naver.com/love_tolty

 

톨티의 공작소 : 네이버 블로그

Tolty의 하드웨어 소프트웨어 공작소 입니다.^^

m.blog.naver.com

 

 

 

 

 

 

반응형
작성일: 2024년 4월 12일

 

Jinja2를 사용해서 리스트(목록)이 있는 문서를 만들다보면 리스트의 각 컬럼의 폭을 맞춰야 할 때가 있다.

 

예를 들어, 아래와 같은 경우.

## 컬럼이 들쑥 날쑥한 리스트
redmine  IN  A  10.1.1.8
git  IN  A  10.1.1.7
jenkins  IN  A  10.1.1.11
chat-server  IN  A  10.1.1.12

 

 

Jinja2 파일(즉, example.j2 파일)에 아래와 같이 기술하면, 왼쪽 또는 오른쪽으로 정렬할 수 있다.

 

## 문자열의 오른쪽으로 공백 문자를 채우기 (Right-side Whitespace Padding)
{{ "{:<17}".format("test string") }}

## 문자열의 왼쪽으로 공백 문자를 채우기 (Left-side Whitespace Padding)
{{ "{:>17}".format("test string") }}

 

 

아래 출력 예시는 가장 왼쪽 컬럼(예: redmine, git, jenkins, ...)에 대해서 오른쪽 공백 문자를 채운 것이다.

## 컬럼 폭(너비)를 맞춘 리스트
redmine      IN  A  10.1.1.8
git          IN  A  10.1.1.7
jenkins      IN  A  10.1.1.11
chat-server  IN  A  10.1.1.12

 

 


 

반응형
작성일: 2024년 4월 12일

 

 

Jinja 파일(*.j2)과 YAML 파일(*.yml *.yaml)을 VIM으로 편집할 때

문서 내용이 적절한 Syntax Color로 보여지지 않는다면, 아래 절차를 따라서 VIM 편집기를 설정해보자.

 

 

Pathogen 설치하기

## 관련 폴더를 미리 만든다.
$ mkdir -p ~/.vim/autoload ~/.vim/bundle 

## pathogen.vim 파일을 다운로드한다.
$ curl -LSso ~/.vim/autoload/pathogen.vim https://tpo.pe/pathogen.vim

## ~/.vimrc 파일에 아래의 내용을 추가한다.
$ cat ~/.vimrc
... 중간 생략 ...
execute pathogen#infect()
syntax on
filetype plugin indent on
... 중간 생략 ...

 

 

VIM Bundle 추가하기

$ cd ~/.vim/bundle

## Ansible, YAML 관련 번들 파일을 다운로드
$ git clone https://github.com/chase/vim-ansible-yaml.git

## Jinja 관련 번들 파일을 다운로드
$ git clone https://github.com/lepture/vim-jinja.git

 

 

테스트하기

$ vim test.j2

 

Jinja 파일 하이라이트 기능

 

 


 

반응형

 

작성일: 2024년 4월 9일

 

Amazon AWS, Microsoft Azure, Google GCP, Oracle Cloud Infra 등 CSP에서 Compute resource를 생성하려고 보면,

이 Compute instance(또는 VM instance)를 생성한 것 때문에 비용이 얼마나 되는지 감을 잡기가 어렵다.

 

마침, Oracle Cloud의 연간 Credit 구입한 것이 많이 남아 있고, 5일 후에 Expire되기 때문에 남는 Credit을 소진해볼겸

VM instnace를 Scale-up, Scale-down하면서 비용 증가/감소 정도를 체크해봤다.

 

1개 VM instance를 대상으로 CPU/Memory Scale-up 수행 후 비용 증감을 체크

초기 VM instance의 Spec Scale-up 이후의 Spec 비용 증가분(Delta)
CPU: 1 core (2 thread)
MEM: 2GB
Storage: 50 GB (Boot volume)
CPU: 8 core (16 thread)
MEM: 128 GB
Storage: 50 GB (Boot volume)
11,479 원   (Daily Cost)

 

참고:
  CPU 종류: AMD EPYC 7J13
  CPU Caches: 
      L1d:  512 KiB (8 instances)
      L1i:   512 KiB (8 instances)
      L2:   4 MiB (8 instances)
      L3:   32 MiB (2 instances)

 

 

 

위에 내가 실제로 VM instance를 Scale-up한 이후의 비용 증가분을 계산한 것은
클라우드 테넌트 계약 조건과 현재 원/달러 환율 따라 30% 정도 차이가 날 것이다.
특히 클라우드 테넌트 계약시, 3년 이상 장기 계약한 경우 많은 할인율이 적용되서  Scale-up에 대한 증가분이 크지 않을 수 있다.
1년 단위로 단기 계약한 테넌트라면, CPU/Memory를 Scale-up할 때 비용 증가분이 위의 계산 결과보다 클 수 있다.

 

 

반응형
작성일: 2024년 4월 9일

 

Microsoft Azure, AWS(Amazon), GCP(Google Cloud Platform), Oracle Cloud Infra 등 Cloud Infra 서비스를 사용하다보면

예상한 것보다 비용이 더 지출되는 경우가 있다.

내 경우, Cloud Infra를 1년간 사용하는 중에 Storage(Block Volume)과 VCN(Virtual Cloud Network) 리소스 사용 비용이 계속 증가만 하길래 이 비용 증가 원인을 찾는 작업을 했다.

 


 

나는 회사 업무 때문에 CSP(Cloud Service Provider)가 제공하는 Managed Kubernetes를 종종 이용하는데, 

이 Managed Kubernetes의 cluster를 생성하고 삭제하는 과정에서 찌꺼기 리소스가 계속 발생하고 있었다.

찌꺼기 리소스가 발생하게 된 이유에 대해 좀더 자세히 설명하면 아래와 같다.

 

  1. Managed Kubernetes 서비스를 이용하여 Cluster-A를 생성한다.
  2. Cluster-A에 Pod, LoadBalancer Type의 Service 리소스 등을 생성한다.
  3. 몇달 동안 사용 후 Cluster-A를 삭제한다.    <-- 이 순간부터 찌꺼기 리소스에 대한 과금이 시작된다 (일명, 숨겨진 비용 발생)

 

위와 같은 순서로 Managed Kubernetes Cluster를 사용하면,

Pod가 사용했던 Storage(즉, PV)와 Public IP Address를 사용했던 LoadBalancer 리소스가 찌꺼기로 남게 된다.

즉, 실제로는 K8s Cluster가 없지만 Storage와 Public IP address는 내 테넌트 내의 자원으로 할당된 상태로 남게 된다.

이 찌꺼기 자원이 계속 비용을 유발하므로, 발견한 즉시 삭제해야 한다.

내 경우, 1년 동안 사용하면서 Pod, PVC, PV, Service Resoruce(LB Type) 등을 먼저 삭제하지 않은 상태에서

K8s cluster를 삭제한 경우가 2번 있었는데... 이것들을 정리하고 나니까 Cloud 사용 요금이 50% 수준으로 떨어졌다. ㅠㅠ

그 동안 쓰지 않아도 될 돈을 지출하고 있었던 것이다.

 

Cloud 서비스를 사용할 때는 Kubernetes cluster를 삭제하는 순서에 대해서 꼭 주의하자!

 

  1. Kubernetes cluster 내부에서 사용했던 Pod, PVC, PV, Service Resoruce를 모두 삭제한다.
  2. PV, Service Resource가 삭제되었는지 여부를 반드시 확인한 후,
  3. Kubernetes cluster를 삭제한다.

 


 

반응형

 

2024년 4월 2일

 

 

일단, 메모만 해놓고 나중에 자세히 스터디하기~

 

 

https://www.ntop.org/products/packet-capture/pf_ring/

 

PF_RING

 

 

 

 

PF_RING Modules

 

 

 

 

https://www.ntop.org/products/packet-capture/pf_ring/pf_ring-zc-zero-copy/

 

 

 

Zero Copy Operations to KVM VM instances

 

 

 

 

 

 


 

 

반응형

 

 

작성일: 2024년 3월 27일

 

 

업무 때문에 이틀 정도 Python 코드를 작성할 일이 생겼는데, On-line tutorial을 보고 너무 잘 만들어져 있어서 깜짝 놀랐다.

Python 책을 따로 구입하지 않아도 될 정도로 공식 Tutorial 문서만으로 스터디가 가능하다.

 

Python 학습에 도움이 되는 문서

Python 자습서 (Tutorial)

Python에 관한 모든 문서(공식 문서)

  위 문서에 담겨있는 내용

  • Library reference
  • Language reference
  • Python setup, usage
  • Howto
  • Python Module 설치
  • C/C++ 언어를 이용한 구현 확장(Extending and embedding)
  • Python's C API
  • FAQ

 

 

 


 

반응형

 

작성일: 2024월 3월 26일

 

내 밥벌이가 Python 언어로 개발하는 일이 아니다보니, Python으로 뭔가 만드는 일이 1년에 한 번 있을까 말까한다.
(누가 시켜서 만든다기 보다는 일하다가 자동화가 필요한 상황이 생길 때 ~~~)

오늘도 Python Logging 기능을 5년 만에 쓸 일이 있어서 다시 작성하려고 보니,
구글링해야 하고.. 예제 코드 작성해서 확인하고, 그런 후에 작성하려고 한 application에 적용하고...
이렇게 시간을 보내고 나니까 나 스스로 참 답답한 느낌이다.
다음 5년 뒤에도 이런 답답함이 없기를 바라면서 오늘 작성한 것을 잘 메모해야 겠다 ^^

 

 

#!/usr/bin/python3

import logging
import logging.handlers
import os
import datetime
import threading
import time


class MyLog():
    def __init__(self, dir, logname) -> None:
        self.logname = logname
        self.dir = os.path.join(dir,logname)
        self.InitLogger()

    def InitLogger(self):
        ## Log format 설정하기
        formatter = logging.Formatter("[%(asctime)s] %(levelname)s %(filename)s:%(lineno)d - %(message)s")
        if os.path.exists(self.dir) == False :
            os.makedirs(self.dir)

        log_File = os.path.join(self.dir,  self.logname + ".log")
        timedfilehandler = logging.handlers.TimedRotatingFileHandler(filename=log_File, when='midnight', interval=1, encoding='utf-8')
        timedfilehandler.setFormatter(formatter)
        timedfilehandler.suffix = "%Y%m%d.log"

        self.logger = logging.getLogger(self.logname)
        self.logger.addHandler(timedfilehandler)
        self.logger.setLevel(logging.INFO)

        self.delete_old_log(self.dir, 3)

        now = datetime.datetime.now()
        self.toDay = "%04d-%02d-%02d" % (now.year, now.month, now.day)
        self.th_auto_delete = threading.Thread(target=self.auto_delete, daemon=True)
        self.th_auto_delete.start()

    '''
    함수 인자 설명:
      - fpath:삭제할 파일이 있는 디렉토리,
      - age:경과일수
    '''
    def delete_old_log(self, fpath, age):
        for fp in os.listdir(fpath):
            fp = os.path.join(fpath, fp)
            if os.path.isfile(fp):
                timestamp_now = datetime.datetime.now().timestamp()
                if os.stat(fp).st_mtime < timestamp_now - (age * 24 * 60 * 60):
                    try:
                        os.remove(fp)
                    except OSError:
                        print(fp, 'this log file is not deleted')

    def auto_delete(self):
        while True:
            now = datetime.datetime.now()
            day = "%04d-%02d-%02d" % (now.year, now.month, now.day)
            if self.toDay != day:
                self.toDay = day
                self.delete_old_log(self.dir, 3)
            time.sleep(600)


## This is test code.
if __name__ == '__main__':
    log = MyLog("my_log_test_dir", logname="sejong")
    for idx in range(3):
        log.logger.info(f"로그 메시지가 잘 기록되는지 테스트 중 {idx}")

 

 

테스트는 아래와 같이 하면 된다. 일단, 잘 동작함, OK !!

$ ./my_log.py
...

 

 

위 'MyLog' 클래스를 다른 Application code에서 참고한다면, 아래 예제와 같이 작성하면 된다.

참고: my_log.py는 아래 소스 코드 my_sample_app.py와 같은 디렉토리에 있어야 한다.
#!/usr/bin/python3

import my_log

...
... 중간 생략 ...
...

if __name__ == '__main__':
    log = my_log.MyLog("log_my_sample_dir", logname="my_sample")
    log.logger.info("#####  Start program  #####")
    
... 중간 생략 ...

 

$ ./my_sample_app.py
...

 


 

+ Recent posts