Act - Run your GitHub Actions locally

로컬 머신에서 Gitub Actions를 실행할 수 있는 도구 Act https://github.com/nektos/act/{:target="_blank"} .github/workflows/ 에서 GitHub Actions를 읽고 로컬 환경 실행 Docker 기반 컨테이너로 운영 macOS 에서는 Docker Desktop 필요 Linux, MacOS, Windows 지원 설치 및 실행 $ brew install act actions-test/.github/workflows/simple.yml # This is a basic workflow to help you get started with Actions name: CI on: workflow_dispatch: jobs: build: runs-on: ubuntu-latest steps: # - uses: actions/checkout@v3 - name: echo test run: | cat /etc/*-release $ git clone https://github.com/cdecl/actions-test $ cd actions-test $ act [CI/build] 🚀 Start image=catthehacker/ubuntu:act-latest [CI/build] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true [CI/build] 🐳 docker create image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] [CI/build] 🐳 docker run image=catthehacker/ubuntu:act-latest platform= entrypoint=["tail" "-f" "/dev/null"] cmd=[] [CI/build] ⭐ Run Main echo test [CI/build] 🐳 docker exec cmd=[bash --noprofile --norc -e -o pipefail /var/run/act/workflow/0] user= workdir= | DISTRIB_ID=Ubuntu | DISTRIB_RELEASE=22.04 | DISTRIB_CODENAME=jammy | DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS" | PRETTY_NAME="Ubuntu 22.04.2 LTS" | NAME="Ubuntu" | VERSION_ID="22.04" | VERSION="22.04.2 LTS (Jammy Jellyfish)" | VERSION_CODENAME=jammy | ID=ubuntu | ID_LIKE=debian | HOME_URL="https://www.ubuntu.com/" | SUPPORT_URL="https://help.ubuntu.com/" | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" | UBUNTU_CODENAME=jammy [CI/build] ✅ Success - Main echo test [CI/build] 🏁 Job succeeded Secret 및 Env 적용 VAR1=1111 VAR2=2222 $ act --env-file my.env --secret-file my.secrets Github Actions 와 모든것이 호환되지는 않음 (e.g. 스케쥴) 테스트 및 개발 용도로 사용 적합 ...

April 26, 2023 · Byung Kyu KIM

OrbStack

Docker Desktop 대체제, Docker containers and Linux machines on macOS OrbStack https://orbstack.dev/{:target="_blank"} MacOS 환경에서 Docker Desktop 대체제로 Docker containers를 실행 가능하고 추가적으로 리눅스 VM도 운영가능함 OrbStack vs. Docker Desktop{:target="_blank"} Docker Desktop 에 비해 적은 리소스 및 빠른 속도 Linux machines 지원 및 Rosetta x86 emulation 가능 Kubernetes는 계획중 OrbStack vs. Colima{:target="_blank"} Docker Desktop 대체체로 많이 언급되는 Colima 와의 비교 사용하고있는 Docker Desktop 과 Multipass 2개를 대체 가능할 것으로 보임 Quick start https://docs.orbstack.dev/quick-start{:target="_blank"} brew install orbstack

April 25, 2023 · Byung Kyu KIM

Jq 활용, Json to CSV 변환

jq 명령어를 통한 Json to CSV 변환 Jq 명령어 활용 https://stedolan.github.io/jq/{:target="_blank"} jq is a lightweight and flexible command-line JSON processor. jq를 사용하여 JSON 배열과 NDJSON 형식의 데이터를 CSV 형식으로 변환하는 예제 JSON 배열은 여러 개의 JSON 객체를 대괄호로 묶은 형식이고, NDJSON은 Newline Delimited JSON의 약자로, 한 줄에 하나의 JSON 객체를 나열한 형식 NDJSON은 MongoDB나 Elasticsearch 등에서 사용되는 데이터 형식 Json 배열에서 CSV 데이터 변환 [ { "fs": "/dev/mapper/vgubuntu-root", "type": "ext4", "size": "915G", "used": "135G", "avail": "734G", "usedpercentage": "16%", "mounted": "/" }, { "fs": "/dev/nvme0n1p2", "type": "ext4", "size": "1.4G", "used": "378M", "avail": "939M", "usedpercentage": "29%", "mounted": "/boot" }, { "fs": "/dev/nvme0n1p1", "type": "vfat", "size": "511M", "used": "30M", "avail": "482M", "usedpercentage": "6%", "mounted": "/boot/efi" } ] Header 추출 CSV 파일의 헤더(keys)를 추출하기 위해 다음과 같은 명령어를 사용 ...

September 1, 2022 · Byung Kyu KIM

K3s traefik ingress

K3s traefik ingress 사용 서비스 테스트 traefik ingress traefik : https://cdecl.github.io/devops/traefik-proxy/{:target="_blank"} traefik 을 활용한 ingress 구현체 : K3s 에서 번들로 제공 서비스 테스트 traefik/whoami 서비스 테스트 type: NodePort # whoami-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: whoami spec: selector: matchLabels: app: whoami replicas: 2 template: metadata: labels: app: whoami spec: containers: - name: whoami image: traefik/whoami imagePullPolicy: Always ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: whoami spec: type: NodePort selector: app: whoami ports: - port: 80 targetPort: 80 nodePort: 30080 $ kubectl apply -f whoami-deploy.yaml $ kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system local-path-provisioner-7b7dc8d6f5-jnmt5 1/1 Running 0 11m kube-system coredns-b96499967-brb9f 1/1 Running 0 11m kube-system helm-install-traefik-crd-hrfr5 0/1 Completed 0 11m kube-system metrics-server-668d979685-xj5jj 1/1 Running 0 11m kube-system helm-install-traefik-nr5jq 0/1 Completed 1 11m kube-system svclb-traefik-632fd507-mdwnl 2/2 Running 0 11m kube-system traefik-7cd4fcff68-47ms4 1/1 Running 0 11m default whoami-6bbfdbb69c-phxts 1/1 Running 0 102s default whoami-6bbfdbb69c-9rpxv 1/1 Running 0 102s $ kubectl get svc -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 26m kube-system kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 26m kube-system metrics-server ClusterIP 10.43.90.12 <none> 443/TCP 26m kube-system traefik LoadBalancer 10.43.147.171 192.168.136.5 80:32391/TCP,443:31718/TCP 25m default whoami NodePort 10.43.116.252 <none> 80:30080/TCP 16m $ curl localhost:30080 Hostname: whoami-6bbfdbb69c-9rpxv IP: 127.0.0.1 IP: ::1 IP: 10.42.0.10 IP: fe80::7c46:beff:fe57:f495 RemoteAddr: 10.42.0.1:43930 GET / HTTP/1.1 Host: localhost:30080 User-Agent: curl/7.81.0 Accept: */* Ingress 적용 # ingress-rule.yml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: main-ingress spec: rules: # - host: domain - http: paths: - path: / pathType: ImplementationSpecific backend: service: name: whoami port: number: 80 Ingress 가 Proxy 역할로 X-Forwarded-For 등이 추가됨 ...

August 23, 2022 · Byung Kyu KIM

trino(presto) nested json 예제

trino(presto) nested json 를 처리하기 위한 table schema 예제 trino(presto) - create table row : json object (nested json) 타입을 위한 sub column 정의 array : 배열 Example {"id":1,"name":"Alice"} {"id":2,"name":"Bob"} {"id":3,"name":"Carol"} {"id":4,"name":"David", "etc1": [{"key": "key-data11"}, {"key": "key-data22"}] } {"id":5,"name":"Elise", "etc2": ["data1", "data2", "data3"]} create table hive.default.sample ( id varchar, name varchar, etc1 array(row(key varchar)), etc2 array(varchar) ) with ( format = 'json', external_location = 's3a://data/sample/' ) trino cli trino> use hive.default; USE trino:default> select * from sample; id | name | etc1 | etc2 ----+-------+--------------------------------------+----------------------- 1 | Alice | NULL | NULL 2 | Bob | NULL | NULL 3 | Carol | NULL | NULL 4 | David | [{key=key-data11}, {key=key-data22}] | NULL 5 | Elise | NULL | [data1, data2, data3] (5 rows) Query 20220824_000627_00008_qpvtj, FINISHED, 1 node Splits: 1 total, 1 done (100.00%) 0.27 [5 rows, 212B] [18 rows/s, 777B/s]

August 23, 2022 · Byung Kyu KIM

trino(presto), minio docker 테스트 환경

trino(presto), minio docker 활용 테스트 환경 trino (hive connector) to minio trino 의 hive connector 를 활용해서 minio 데이터 분석 환경 Hive connector : https://trino.io/docs/current/connector/hive.html{:target="_blank"} 참고 : https://github.com/cdecl/trino-minio-docker{:target="_blank"} docker-compose (trino, minio) version: '3' services: trino: image: trinodb/trino container_name: trino restart: always ports: - "8080:8080" volumes: - ./etc:/etc/trino minio: image: minio/minio restart: always command: server /data --console-address ":9001" container_name: minio environment: MINIO_ROOT_USER: minio MINIO_ROOT_PASSWORD: minio1234 restart: always ports: - "9000:9000" - "9001:9001" volumes: - ./minio-data:/data minio (hive) properties etc/catalog/hive.properties metastore 는 minio catalog 버킷에 저장 s3a://catalog/trino/ minio 세팅 정보 : access-key, secret-key, endpoint connector.name=hive-hadoop2 hive.metastore=file hive.metastore.catalog.dir=s3a://catalog/trino/ hive.recursive-directories=true hive.non-managed-table-writes-enabled=true hive.allow-drop-table=true hive.s3.path-style-access=true hive.s3.ssl.enabled=false hive.s3select-pushdown.enabled=true hive.s3.aws-access-key=minio hive.s3.aws-secret-key=minio1234 hive.s3.endpoint=http://minio:9000 docker-compose 실행 및 초기값 세팅 ## 실행 $ docker-compose up -d reating network "trino_default" with the default driver Creating minio ... done Creating trino ... done rclone 으로 minio 버킷 생성 # rclone 설정 $ cat local.conf [local] type = s3 provider = Minio env_auth = false access_key_id = minio secret_access_key = minio1234 endpoint = http://localhost:9000 # create catalog, data directory $ rclone --config local.conf mkdir local:catalog $ rclone --config local.conf mkdir local:data # sample json (ndjson) data) $ cat 1.json {"id":1,"name":"Alice"} {"id":2,"name":"Bob"} {"id":3,"name":"Carol"} # test data copy $ rclone --config local.conf copy 1.json local:data/sample/ schema, table 생성 default schema (db) 생성 및 external_location table 생성 -- hive 의 schema(db) 생성 create schema hive.default; -- table 생성 create table hive.default.sample ( id varchar, name varchar ) with ( format = 'json', external_location = 's3a://data/sample/' ); -- select select * from sample; 쿼리 테스트 (dbeaver)

August 19, 2022 · Byung Kyu KIM

CSV to SQLite3

CSV 파일을 SQLite3 Import 및 Query CSV to SQLite3 CSV 파일을 SQLite3로 Import 쿼리 CSV 샘플 데이터 확인 $ cat cities.csv "LatD", "LatM", "LatS", "NS", "LonD", "LonM", "LonS", "EW", "City", "State" 41, 5, 59, "N", 80, 39, 0, "W", "Youngstown", OH 42, 52, 48, "N", 97, 23, 23, "W", "Yankton", SD 46, 35, 59, "N", 120, 30, 36, "W", "Yakima", WA ... TIP: cat 대신 bat 사용하면 더 나은 뷰어를 제공 $ bat cities.csv CSV Import .mode csv : csv 모드로 전환 .import ./cities.csv ci : ./cities.csv 파일을 ci 테이블로 Import .import --skip 1 ./cities.csv ci : ./cities.csv 테이블이 존재 할때 header 제외 .import --csv ./cities.csv ci : ./cities.csv csv 모드 inline 옵션 # ci.db 생성 및 인터랙티브 모드 $ sqlite3 ci.db SQLite version 3.37.0 2021-12-09 01:34:53 Enter ".help" for usage hints. sqlite> .mode csv sqlite> .import ./cities.csv ci sqlite> .tables ci sqlite> select count(*) from ci; count(*) 129 sqlite> .mode list sqlite> .header on sqlite> select * from ci limit 10; LatD| "LatM"| "LatS"| "NS"| "LonD"| "LonM"| "LonS"| "EW"| "City"| "State" 41| 5| 59| "N"| 80| 39| 0| "W"| "Youngstown"| OH 42| 52| 48| "N"| 97| 23| 23| "W"| "Yankton"| SD 46| 35| 59| "N"| 120| 30| 36| "W"| "Yakima"| WA 42| 16| 12| "N"| 71| 48| 0| "W"| "Worcester"| MA 43| 37| 48| "N"| 89| 46| 11| "W"| "Wisconsin Dells"| WI 36| 5| 59| "N"| 80| 15| 0| "W"| "Winston-Salem"| NC 49| 52| 48| "N"| 97| 9| 0| "W"| "Winnipeg"| MB 39| 11| 23| "N"| 78| 9| 36| "W"| "Winchester"| VA 34| 14| 24| "N"| 77| 55| 11| "W"| "Wilmington"| NC 39| 45| 0| "N"| 75| 33| 0| "W"| "Wilmington"| DE Inline command $ sqlite3 /tmp/t.db ".import -csv ./cities.csv ci" "select * from ci" -header LatD| "LatM"| "LatS"| "NS"| "LonD"| "LonM"| "LonS"| "EW"| "City"| "State" 41| 5| 59| "N"| 80| 39| 0| "W"| "Youngstown"| OH 42| 52| 48| "N"| 97| 23| 23| "W"| "Yankton"| SD 46| 35| 59| "N"| 120| 30| 36| "W"| "Yakima"| WA 42| 16| 12| "N"| 71| 48| 0| "W"| "Worcester"| MA 43| 37| 48| "N"| 89| 46| 11| "W"| "Wisconsin Dells"| WI 36| 5| 59| "N"| 80| 15| 0| "W"| "Winston-Salem"| NC 49| 52| 48| "N"| 97| 9| 0| "W"| "Winnipeg"| MB 39| 11| 23| "N"| 78| 9| 36| "W"| "Winchester"| VA 34| 14| 24| "N"| 77| 55| 11| "W"| "Wilmington"| NC 39| 45| 0| "N"| 75| 33| 0| "W"| "Wilmington"| DE

August 9, 2022 · Byung Kyu KIM

ripgrep, rg

하위 디렉토리에서 정규식 패턴을 재귀적으로 검색하는 라인 지향 검색 도구 ripgrep https://github.com/BurntSushi/ripgrep{:target="_blank"} rust로 만들어진 크로스플랫폼 지향 grep 대체도구 특징 코드 검색에 특화되고 기본적으로 재귀적 디렉토리 검색 사용 자동 필터링 : 기본적으로 디렉토리를 검색할 때 아래 조건은 검색하지 않음 .gitignore .ignore .rgignore 명시되어 있는 파일은 기본적으로 검색하지 않음 → --no-ignore 로 회피 숨겨진 파일 및 디렉토리 → --hidden 로 회피 바이너리 파일 (ripgrep은 NUL바이트 있으면 바이너리로 간주) → --text, -a 로 회피 심볼릭 링크 연결 → --follow, -L 로 연결 전체 필터링을 회피하기 (단계별) → -u or -uu or -uuu (quivalent to ‘grep -r’) ...

July 27, 2022 · Byung Kyu KIM

Ansible dynamic inventory - AWS EC2

Ansible aws_ec2 plugin 활용, AWS EC2 동적 Inventory 구성 Ansible plugin : aws_ec2 https://docs.ansible.com/ansible/2.9/plugins/inventory/aws_ec2.html{:target="_blank"} Get inventory hosts from Amazon Web Services EC2 Requirements python package : boto3, bo YAML 설정 파일 이름이 aws_ec2.(yml|yaml) 로 끝나야 함 $ ansible --version ansible 2.9.6 config file = /etc/ansible/ansible.cfg configured module search path = ['/home/cdecl/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3/dist-packages/ansible executable location = /usr/bin/ansible python version = 3.8.10 (default, Jun 2 2021, 10:49:15) [GCC 9.4.0] # install boto3, bo $ pip3 install boto3 기본설정 aws_ec2.yaml plugin : 프러그인 이름, 필수 regions : 지정하면 더 빠른 조회 plugin: aws_ec2 regions: - ap-northeast-2 # .aws/credendial 파일이 없으면 aws_access_key_id: AKIA3************** aws_secret_access_key: 1oxRajyBX********************** ~/.aws/credentials [default] aws_access_key_id = AKIA3************** aws_secret_access_key = 1oxRajyBX********************** Inventory 확인 기본 aws_ec2 그룹으로 생성 # json 형태로 ec2 node 정보 및 group 정보 리스트 $ ansible-inventory -i aws_ec2.yaml --list ... "all": { "children": [ "aws_ec2", "ungrouped" ] }, "aws_ec2": { "hosts": [ "ip-10-211-20-159.ap-northeast-2.compute.internal", "ip-10-211-20-229.ap-northeast-2.compute.internal", "ip-10-211-20-45.ap-northeast-2.compute.internal" ] } } # inventory 정보를 그래프 형태로 표시 $ ansible-inventory -i aws_ec2.yaml --graph @all: |--@aws_ec2: | |--ip-10-211-20-159.ap-northeast-2.compute.internal | |--ip-10-211-20-229.ap-northeast-2.compute.internal | |--ip-10-211-20-45.ap-northeast-2.compute.inte # ansible 명령으로 확인 $ ansible -i aws_ec2.yaml --list-hosts all hosts (3): ip-10-211-20-229.ap-northeast-2.compute.internal ip-10-211-20-159.ap-northeast-2.compute.internal ip-10-211-20-45.ap-northeast-2.compute.internal 필터 및 그룹화 예제 : https://docs.ansible.com/ansible/2.9/plugins/inventory/aws_ec2.html#examples{:target="_blank"} filters : 필터로 원하는 항목만 가져옴 AWS CLI 명령 describe-instances –filters 항목 참고 https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options{:target="_blank"} keyed_groups : Inventory 그룹화 항목 plugin: aws_ec2 regions: - ap-northeast-2 filters: # tag 정보가 AutoDelete:False 인 인스턴스 tag:AutoDelete: "False" # running 상태 인스턴스 instance-state-name: 'running' keyed_groups: # tag 를 기준으로 그룹화, "prefix_key_value" 형식의 그룹이름 - prefix: tag key: tags # tag 로 그룹화 $ ansible-inventory -i aws_ec2.yaml --graph @all: |--@aws_ec2: | |--ip-10-211-20-159.ap-northeast-2.compute.internal | |--ip-10-211-20-229.ap-northeast-2.compute.internal | |--ip-10-211-20-45.ap-northeast-2.compute.internal |--@tag_AutoDelete_False: | |--ip-10-211-20-159.ap-northeast-2.compute.internal | |--ip-10-211-20-229.ap-northeast-2.compute.internal | |--ip-10-211-20-45.ap-northeast-2.compute.internal ... |--@tag_Name_kube01: | |--ip-10-211-20-45.ap-northeast-2.compute.internal |--@tag_Name_kube02: | |--ip-10-211-20-159.ap-northeast-2.compute.internal |--@tag_Name_kube03: | |--ip-10-211-20-229.ap-northeast-2.compute.internal |--@ungrouped: # ansible 명령으로 확인 $ ansible -i aws_ec2.yaml tag_AutoDelete_False --list-hosts hosts (3): ip-10-211-20-229.ap-northeast-2.compute.internal ip-10-211-20-159.ap-northeast-2.compute.internal ip-10-211-20-45.ap-northeast-2.compute.internal $ ansible -i aws_ec2.yaml tag_Name_kube01 --list-hosts hosts (1): ip-10-211-20-45.ap-northeast-2.compute.internal Host 연결을 위한 inventory parameters 추가 multiple inventory로 정보 추가 https://docs.ansible.com/ansible/2.9/user_guide/intro_inventory.html#connecting-to-hosts-behavioral-inventory-parameters{:target="_blank"} # aws.host [win:children] tag_AutoDelete_False [win:vars] ansible_user=rundeck ansible_password=<passowrd> ansible_connection=winrm ansible_port=5985 $ ansible-inventory -i aws_ec2.yaml -i aws.host --vars --list { "_meta": { "hostvars": { "ip-10-211-20-159.ap-northeast-2.compute.internal": { "ami_launch_index": 1, "ansible_connection": "winrm", "ansible_password": "<passowrd>", "ansible_port": 5985, "ansible_user": "ansible", "architecture": "x86_64", ... ansible-inventory --list 옵션으로 hosts 파일 형식 구성 $ ansible-inventory -i aws_ec2.yaml --list | jq -r '._meta.hostvars[] | "\(.private_ip_address) \(.tags.Name) "' 10.211.20.159 kube02 10.211.20.229 kube03 10.211.20.45 kube01 Ansible EC2 Dynamic inventory minimum IAM policies https://stackoverflow.com/questions/30519470/ansible-ec2-dynamic-inventory-minimum-iam-policies{:target="_blank"} { "Version": "2012-10-17", "Statement": [ { "Sid": "Demo201505282045", "Effect": "Allow", "Action": [ "ec2:Describe*", "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": "*" } ] }

July 16, 2022 · Byung Kyu KIM

Multipass, Ubuntu VM 설정

Canonical 재단에서 지원하는 단일 명령으로 Ubuntu VM 구성 할 수 있는 도구 Multipass https://multipass.run/{:target="_blank"} 최소한의 오버헤드를 위한 각 플랫폼 지원 Windows : Hyper-V macOS : QEMU, HyperKit Linux : LXD Multipass install https://multipass.run/install{:target="_blank"} 플랫폼 별 패키지 설치 방법 # windows $ choco install multipass # macOS $ brew install multipass Multipass 주요 명령 및 VM Instance 생성 주요 명령어 launch : Ubuntu instance 생성 및 시작 start, stop, restart : 시작 중지 delete : Ubuntu instance 삭제 purge : 삭제된 이미지 영구 삭제 shell : Instance 내부 shell 로 접속 list : 생성된 Instance 확인 info : Instance 정보 확인 $ multipass --help ... Available commands: alias Create an alias aliases List available aliases authenticate Authenticate client delete Delete instances exec Run a command on an instance find Display available images to create instances from get Get a configuration setting help Display help about a command info Display information about instances launch Create and start an Ubuntu instance list List all available instances mount Mount a local directory in the instance networks List available network interfaces purge Purge all deleted instances permanently recover Recover deleted instances restart Restart instances set Set a configuration setting shell Open a shell on a running instance start Start instances stop Stop running instances suspend Suspend running instances transfer Transfer files between the host and instances umount Unmount a directory from an instance unalias Remove an alias version Show version details Ubuntu VM Instance 생성 : 기본 생성 # node1 이름의 instance 생성 $ multipass launch -n node01 Launched: node01 # 기본 lts 이미지로 생성 : Ubuntu 20.04 LTS $ multipass list Name State IPv4 Image node01 Running 192.168.196.207 Ubuntu 20.04 LTS # instace 정보 $ multipass info node01 Name: node01 State: Running IPv4: 192.168.196.207 Release: Ubuntu 20.04.4 LTS Image hash: 75a04c7eed58 (Ubuntu 20.04 LTS) Load: 0.38 0.15 0.05 Disk usage: 1.4G out of 4.7G Memory usage: 162.4M out of 912.5M Mounts: -- 기본 설정으로 Instance 생성시, Disk 등의 리소스가 부족 할 수 있음 ...

July 4, 2022 · Byung Kyu KIM