Restic Basic

Snapshots 기능을 제공하는 modern backup program restic https://restic.net/{:target="_blank"} Go로 만들어진 백업 프로그램, 크로스프랫폼 지원 - from Linux, BSD, Mac and Windows - to many different storage types, including self-hosted and online services - easily, being a single executable that you can run without a server or complex setup - effectively, only transferring the parts that actually changed in the files you back up - securely, by careful use of cryptography in every part of the process - verifiably, enabling you to make sure that your files can be restored when needed - freely - restic is entirely free to use and completely open source Install Package 설치 및 Binary 지원 Package : https://restic.readthedocs.io/en/stable/020_installation.html{:target="_blank"} Binary : https://github.com/restic/restic/releases/tag/v0.12.1{:target="_blank"} $ curl -LO https://github.com/restic/restic/releases/download/v0.12.1/restic_0.12.1_linux_amd64.bz2 # install bzip2 $ sudo yum install bzip2 -y $ bunzip2 restic_0.12.1_linux_amd64.bz2 $ mv restic_0.12.1_linux_amd64 restic $ sudo mv restic /usr/local/bin $ restic restic is a backup program which allows saving multiple revisions of files and directories in an encrypted repository stored on different backends. Usage: restic [command] Available Commands: backup Create a new backup of files and/or directories cache Operate on local cache directories cat Print internal objects to stdout check Check the repository for errors copy Copy snapshots from one repository to another diff Show differences between two snapshots dump Print a backed-up file to stdout find Find a file, a directory or restic IDs forget Remove snapshots from the repository generate Generate manual pages and auto-completion files (bash, fish, zsh) help Help about any command init Initialize a new repository key Manage keys (passwords) list List objects in the repository ls List files in a snapshot migrate Apply migrations mount Mount the repository prune Remove unneeded data from the repository rebuild-index Build a new index recover Recover data from the repository restore Extract the data from a snapshot self-update Update the restic binary snapshots List all snapshots stats Scan the repository and show basic statistics tag Modify tags on snapshots unlock Remove locks other processes created version Print version information .... Backup & Restore Backup Repository 생성 # Repository 접근을 위한 패드워스 필요, 일단 1111 # -r, --repo repository repository to backup to or restore from (default: $RESTIC_REPOSITORY) $ restic init -r repo enter password for new repository: enter password again: created restic repository 7f3cfb3e9a at repo Please note that knowledge of your password is required to access the repository. Losing your password means that your data is irrecoverably lost. # password 파일 생성, -p 옵션으로 지정 $ echo 1111 > passwd Backup : snapshots 생성 # Backup # restic -r <repository> -p <passwd file> backup <Source> # -p, --password-file file file to read the repository password from (default: $RESTIC_PASSWORD_FILE) $ restic -r repo -p passwd backup /home/cdecl/temp/mvcapp repository e4ccc49d opened successfully, password is correct no parent snapshot found, will read all files Files: 79 new, 0 changed, 0 unmodified Dirs: 40 new, 0 changed, 0 unmodified Added to the repo: 4.854 MiB processed 79 files, 4.811 MiB in 0:00 snapshot 9aff8447 saved # 파일생성 및 다시백업 $ touch /home/cdecl/temp/mvcapp/test.txt $ restic -r repo -p passwd backup /home/cdecl/temp/mvcapp repository e4ccc49d opened successfully, password is correct using parent snapshot 9aff8447 Files: 1 new, 0 changed, 79 unmodified Dirs: 0 new, 4 changed, 36 unmodified Added to the repo: 7.742 KiB processed 80 files, 4.811 MiB in 0:00 snapshot f4b94d9b saved Snapshots 확인 # snapshots 2개 화인 확인 $ restic -r repo -p passwd snapshots repository e4ccc49d opened successfully, password is correct ID Time Host Tags Paths ------------------------------------------------------------------------------ 9aff8447 2021-11-25 15:17:52 centos1 /home/cdecl/temp/mvcapp f4b94d9b 2021-11-25 15:22:24 centos1 /home/cdecl/temp/mvcapp ------------------------------------------------------------------------------ 2 snapshots Snapshots 비교 $ restic -r repo -p passwd diff 9aff8447 f4b94d9b repository e4ccc49d opened successfully, password is correct comparing snapshot 9aff8447 to f4b94d9b: + /home/cdecl/temp/mvcapp/test.txt Files: 1 new, 0 removed, 0 changed Dirs: 0 new, 0 removed Others: 0 new, 0 removed Data Blobs: 0 new, 0 removed Tree Blobs: 5 new, 5 removed Added: 7.742 KiB Removed: 7.456 KiB Restore : Snapshots 에서 복원 # restic -r <repository> -p <passwd file> restore <snapshots id> -t <Target> $ restic -r repo -p passwd restore 9aff8447 -t restore-mvcapp repository e4ccc49d opened successfully, password is correct restoring <Snapshot 9aff8447 of [/home/cdecl/temp/mvcapp] at 2021-11-25 15:17:52.115925352 +0900 KST by cdecl@centos1> to restore-mvcapp MinIO & RClone Backend 지원 https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html{:target="_blank"} Local, SFTP, REST Server, Amazon S3, Minio Server, Microsoft Azure Blob Storage, Google Cloud Storage, Other Services via rclone 등 지원 MinIO Repository 만들기 $ export AWS_ACCESS_KEY_ID=key $ export AWS_SECRET_ACCESS_KEY=passwd $ restic init -r s3:http://minio.server:9000/restic enter password for new repository: enter password again: created restic repository 65a27250da at s3:http://minio.server:9000/restic Please note that knowledge of your password is required to access the repository. Losing your password means that your data is irrecoverably lost. # Backup $ restic -r s3:http://minio.server:9000/restic -p passwd backup /home/cdecl/temp/mvcapp # snapshots $ restic -r s3:http://minio.server:9000/restic -p passwd snapshots repository 65a27250 opened successfully, password is correct ID Time Host Tags Paths ------------------------------------------------------------------------------ 73d37fbd 2021-11-25 15:37:34 centos1 /home/cdecl/temp/mvcapp ------------------------------------------------------------------------------ 1 snapshots RClone Backend 로 사용 $ rclone config show [infradb] type = s3 env_auth = false access_key_id = key secret_access_key = passwd region = us-east-1 endpoint = http://minio.server:9000 # rclone config 사용 respository 만들기 $ restic init -r rclone:infradb:restic enter password for new repository: enter password again: created restic repository ce850667c9 at rclone:infradb:restic Please note that knowledge of your password is required to access the repository. Losing your password means that your data is irrecoverably lost. # Backup $ restic -r rclone:infradb:restic -p passwd backup /home/cdecl/temp/mvcapp # snapshots $ restic -r rclone:infradb:restic -p passwd snapshots Snapshots 관리 https://restic.readthedocs.io/en/stable/060_forget.html{:target="_blank"} $ restic -r rclone:infradb:restic -p passwd snapshots repository ce850667 opened successfully, password is correct ID Time Host Tags Paths ------------------------------------------------------------------------------ a3737738 2021-11-25 15:44:05 centos1 /home/cdecl/temp/mvcapp 00f16d70 2021-11-25 15:44:50 centos1 /home/cdecl/temp/mvcapp 0e83568a 2021-11-25 15:44:51 centos1 /home/cdecl/temp/mvcapp 4041e3ca 2021-11-25 15:44:53 centos1 /home/cdecl/temp/mvcapp eb1e56c7 2021-11-25 15:44:54 centos1 /home/cdecl/temp/mvcapp d81b3d2a 2021-11-25 15:44:55 centos1 /home/cdecl/temp/mvcapp ------------------------------------------------------------------------------ 6 snapshots # snapshots 1개 지우기 $ restic -r rclone:infradb:restic -p passwd forget d81b3d2a repository ce850667 opened successfully, password is correct [0:00] 100.00% 1 / 1 files deleted # 스냅샷의 파일에서 참조한 데이터는 여전히 저장소에 저장 # 참조되지 않은 데이터를 정리하려면 prune 명령 실행 $ restic -r rclone:infradb:restic -p passwd prune repository ce850667 opened successfully, password is correct loading indexes... loading all snapshots... finding data that is still in use for 5 snapshots [0:00] 100.00% 5 / 5 snapshots searching used packs... collecting packs for deletion and repacking [0:00] 100.00% 9 / 9 packs processed to repack: 0 blobs / 0 B this removes 0 blobs / 0 B to delete: 2 blobs / 1004 B total prune: 2 blobs / 1004 B remaining: 125 blobs / 4.862 MiB unused size after prune: 0 B (0.00% of remaining size) rebuilding index [0:00] 100.00% 8 / 8 packs processed deleting obsolete index files [0:00] 100.00% 6 / 6 files deleted removing 1 old packs [0:00] 100.00% 1 / 1 files deleted done # 최근 1개만 놔두고 snapshots 삭제 및 prune $ restic -r rclone:infradb:restic -p passwd forget --keep-last 1 --prune repository ce850667 opened successfully, password is correct Applying Policy: keep 1 latest snapshots keep 1 snapshots: ID Time Host Tags Reasons Paths --------------------------------------------------------------------------------------------- eb1e56c7 2021-11-25 15:44:54 centos1 last snapshot /home/cdecl/temp/mvcapp --------------------------------------------------------------------------------------------- 1 snapshots remove 4 snapshots: ID Time Host Tags Paths ------------------------------------------------------------------------------ a3737738 2021-11-25 15:44:05 centos1 /home/cdecl/temp/mvcapp 00f16d70 2021-11-25 15:44:50 centos1 /home/cdecl/temp/mvcapp 0e83568a 2021-11-25 15:44:51 centos1 /home/cdecl/temp/mvcapp 4041e3ca 2021-11-25 15:44:53 centos1 /home/cdecl/temp/mvcapp ------------------------------------------------------------------------------ 4 snapshots [0:00] 100.00% 4 / 4 files deleted 4 snapshots have been removed, running prune loading indexes... loading all snapshots... finding data that is still in use for 1 snapshots [0:00] 100.00% 1 / 1 snapshots searching used packs... collecting packs for deletion and repacking [0:00] 100.00% 8 / 8 packs processed to repack: 39 blobs / 47.305 KiB this removes 2 blobs / 1007 B to delete: 6 blobs / 2.950 KiB total prune: 8 blobs / 3.934 KiB remaining: 117 blobs / 4.858 MiB unused size after prune: 0 B (0.00% of remaining size) repacking packs [0:00] 100.00% 2 / 2 packs repacked rebuilding index [0:00] 100.00% 5 / 5 packs processed deleting obsolete index files [0:00] 100.00% 1 / 1 files deleted removing 5 old packs [0:00] 100.00% 5 / 5 files deleted done # snapshots 확인 $ restic -r rclone:infradb:restic -p passwd snapshots repository ce850667 opened successfully, password is correct ID Time Host Tags Paths ------------------------------------------------------------------------------ eb1e56c7 2021-11-25 15:44:54 centos1 /home/cdecl/temp/mvcapp ------------------------------------------------------------------------------ 1 snapshots forget 주요 인수 --keep-last n never delete the n last (most recent) snapshots --keep-hourly n for the last n hours in which a snapshot was made, keep only the last snapshot for each hour. --keep-daily n for the last n days which have one or more snapshots, only keep the last one for that day. --keep-weekly n for the last n weeks which have one or more snapshots, only keep the last one for that week. --keep-monthly n for the last n months which have one or more snapshots, only keep the last one for that month. --keep-yearly n for the last n years which have one or more snapshots, only keep the last one for that year. --keep-tag keep all snapshots which have all tags specified by this option (can be specified multiple times).

November 25, 2021 · Byung Kyu KIM

HAProxy Basic

네트워크 L4, L7 기능 Reverse proxy 및 Load balancing, HA 기능을 제공하는 최적화된 S/W HAProxy Basic 공식 블로그인 만큼 가장 잘 정리된 링크로 상세 설명 대체 Basic Configuration https://www.haproxy.com/blog/haproxy-configuration-basics-load-balance-your-servers/{:target="_blank"} 최소 설정 및 기본 항목에 대한 설명 설치 및 적용 centos 7 # install $ sudo yum install haproxy # start $ sudo systemctl start haproxy # status $ sudo systemctl status haproxy ● haproxy.service - HAProxy Load Balancer Loaded: loaded (/usr/lib/systemd/system/haproxy.service; disabled; vendor preset: disabled) Active: active (running) since 화 2021-11-23 13:55:48 KST; 5s ago Main PID: 227598 (haproxy-systemd) Tasks: 3 Memory: 1.9M CGroup: /system.slice/haproxy.service ├─227598 /usr/sbin/haproxy-systemd-wrapper -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid ├─227599 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds └─227600 /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -Ds ... 버전 확인, 지원 모듈, 지원 polling 시스템 확인 epoll 사용 $ haproxy -vv HA-Proxy version 1.5.18 2016/05/10 Copyright 2000-2016 Willy Tarreau <willy@haproxy.org> Build options : TARGET = linux2628 CPU = generic CC = gcc CFLAGS = -O2 -g -fno-strict-aliasing -DTCP_USER_TIMEOUT=18 OPTIONS = USE_LINUX_TPROXY=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_PCRE=1 Default settings : maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200 Encrypted password support via crypt(3): yes Built with zlib version : 1.2.7 Compression algorithms supported : identity, deflate, gzip Built with OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017 Running on OpenSSL version : OpenSSL 1.0.2k-fips 26 Jan 2017 OpenSSL library supports TLS extensions : yes OpenSSL library supports SNI : yes OpenSSL library supports prefer-server-ciphers : yes Built with PCRE version : 8.32 2012-11-30 PCRE library supports JIT : no (USE_PCRE_JIT not set) Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND Available polling systems : epoll : pref=300, test result OK poll : pref=200, test result OK select : pref=150, test result OK Total: 3 (3 usable), will use epoll. 기본설정 : /etc/haproxy/haproxy.cfg global : 전역 설정 defaults : 디폴트 설정 frontend : client로 부터 접속 정보, 5000 Port 대기 backend : 요청을 수행하는 서버로 전달, 3대의 서버로 전달 listen : frontend + backend 한꺼번에 정리할 수 있는 섹션, Stats Monitoring UI 설정 global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon # turn on stats unix socket stats socket /var/lib/haproxy/stats defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen stats bind :8404 stats enable stats uri /monitor stats refresh 5s frontend front_main bind :5000 option forwardfor default_backend app backend app balance roundrobin server app1 192.168.28.15:30010 check server app2 192.168.28.16:30010 check server app3 192.168.28.17:30010 check SSL 인터페이스 https://serverfault.com/questions/738045/haproxy-to-terminate-ssl-also-send-ssl-to-backend-server{:target="_blank"} Frontend SSL Bind ... frontend front_main bind :5443 ssl crt /cert/path/domain_keypem.pem option forwardfor default_backend app ... Backend SSL 호출 ... backend app balance roundrobin mode http server app1 192.168.28.15:30443 ssl verify none server app2 192.168.28.16:30443 ssl verify none ... Four Essential Sections https://www.haproxy.com/blog/the-four-essential-sections-of-an-haproxy-configuration/{:target="_blank"} 4개의 기본 섹션 구조 설명 global # global settings here defaults # defaults here frontend # a frontend that accepts requests from clients backend # servers that fulfill the requests 기타 SSL 설정 : https://www.haproxy.com/blog/haproxy-ssl-termination/{:target="_blank"} 통계 Web UI : https://www.haproxy.com/blog/exploring-the-haproxy-stats-page/{:target="_blank"} ...

November 22, 2021 · Byung Kyu KIM

localhost.run과 ngrok - 로컬 서비스의 외부 노출 도구

로컬(localhost) 서비스를 터널링을 통해 외부에서 접근 가능하도록 만들어주는 도구들을 소개합니다. 개발 단계에서 로컬에서 실행 중인 서비스를 외부에 임시로 공개해야 할 때 유용합니다. (보안 및 안정성 문제로 실제 프로덕션 환경에서는 사용하지 않는 것을 권장합니다) 주요 사용 사례: 외부 API의 웹훅(webhook) 테스트 클라이언트에게 개발 중인 기능 데모 모바일 기기에서 로컬 개발 서버 접근 협업 시 로컬 개발 환경 공유 localhost.run https://localhost.run/{:target="_blank"} SSH 리버스 터널링을 활용하여 로컬 서비스를 외부에 노출 별도의 프로그램 설치가 필요 없고 SSH 클라이언트만 있으면 사용 가능 무료로 사용 가능하며 커스텀 도메인 지원 테스트용 서비스 실행 아래 예제에서는 간단한 웹 애플리케이션 컨테이너를 실행하여 테스트합니다. ...

November 10, 2021 · Byung Kyu KIM

Helm chart 생성, 배포

Kubernetes 패키지 매니저 도구인 helm을 통해 chart 생성 및 Kubernetes 배포 K3S 환경에서 테스트 Helm https://helm.sh/{:target="_blank"} Kubernetes 배포를 위한 패키지 매니저 툴 (e.g yum, choco) chart 라는 yaml 파일 기반의 템플릿 파일을 통해 패키지화 및 Kubernetes 설치 관리 Deployment, Service, Ingress 등 Kubernetes 서비스의 manifest 생성 및 설치 Helm Repository 를 통해 패키지 등록 및 다른 패키지 설치 가능 Helm Install 바이너리 직접 설치 및 설치 Script 활용 Homebrew, Chocolatey 등의 패키지로도 설치 가능 바이너리 다운로드 https://github.com/helm/helm/releases $ curl -LO https://get.helm.sh/helm-v3.7.1-linux-amd64.tar.gz $ tar -zxvf helm-v3.7.1-linux-amd64.tar.gz $ tree linux-amd64 linux-amd64 ├── LICENSE ├── README.md └── helm $ sudo cp linux-amd64/helm /usr/local/bin/ 설치 Script 활용 $ chmod 700 get_helm.sh $ ./get_helm.sh Creating Your Own Charts kubernetes 설치를 위한 chart 생성 및 세팅 https://helm.sh/docs/helm/helm_create/{:target="_blank"} # chart 생성 $ helm create mvcapp Creating mvcapp Chart directory 구조 Chart.yaml : Chart 버전, 이미지버전, 설명등을 기술하는 파일 values.yaml : manifest template 파일 기반, 기준 값을 세팅하는 파일 templates/ : kubernetes manifest template 파일 charts/ : chart 의존성 파일 $ tree mvcapp mvcapp ├── Chart.yaml ├── charts ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ └── test-connection.yaml └── values.yaml Chart.yaml 수정 version : Chart 버전 appVersion : Deploy 되는 image 버전 apiVersion: v2 name: mvcapp description: .net core test mvc application # ... 생략 type: application # ... 생략 version: 0.1.0 # ... 생략 appVersion: "0.6" # appVersion: "1.16.0" values.yaml 수정 replicaCount : Pod 의 replica 개수, 2개로 수정 image.repository : docker image 이름, cdecl/mvcapp 로 수정 service.type : On-Premise에서 테스트 목적, NodePort로 수정 service.nodePort : nodePort를 적용하기 위해 신규 추가 # Default values for mvcapp. # This is a YAML-formatted file. # Declare variables to be passed into your templates. replicaCount: 2 image: repository: cdecl/mvcapp pullPolicy: IfNotPresent # Overrides the image tag whose default is the chart appVersion. tag: "" imagePullSecrets: [] nameOverride: "" fullnameOverride: "" # ... 생략 service: type: NodePort # ClusterIP port: 80 nodePort: 30010 ingress: # ... 생략 resources: {} # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little # resources, such as Minikube. If you do want to specify resources, uncomment the following # lines, adjust them as necessary, and remove the curly braces after 'resources:'. # limits: # cpu: 100m # memory: 128Mi # requests: # cpu: 100m # memory: 128Mi # ... 생략 templates/service.yaml 수정 nodePort 를 적용하기 위해 template 수정 spec.ports.nodePort: {{ .Values.service.nodePort }} 추가 apiVersion: v1 kind: Service metadata: name: {{ include "mvcapp.fullname" . }} labels: {{- include "mvcapp.labels" . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - port: {{ .Values.service.port }} targetPort: http pro name: http nodePort: {{ .Values.service.nodePort }} selector: {{- include "mvcapp.selectorLabels" . | nindent 4 }} helm lint : chart 파일 검사 https://helm.sh/docs/helm/helm_lint/{:target="_blank"} $ helm lint mvcapp ==> Linting mvcapp [INFO] Chart.yaml: icon is recommended 1 chart(s) linted, 0 chart(s) failed helm template : kubernetes manifest 생성 https://helm.sh/docs/helm/helm_template/{:target="_blank"} values.yaml 에 세팅한 기준으로 manifest 생성 $ helm template mvcapp --- # Source: mvcapp/templates/serviceaccount.yaml apiVersion: v1 kind: ServiceAccount metadata: name: RELEASE-NAME-mvcapp labels: helm.sh/chart: mvcapp-0.1.0 app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME app.kubernetes.io/version: "0.6" app.kubernetes.io/managed-by: Helm --- # Source: mvcapp/templates/service.yaml apiVersion: v1 kind: Service metadata: name: RELEASE-NAME-mvcapp labels: helm.sh/chart: mvcapp-0.1.0 app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME app.kubernetes.io/version: "0.6" app.kubernetes.io/managed-by: Helm spec: type: NodePort ports: - port: 80 targetPort: http pro name: http selector: app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME --- # Source: mvcapp/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: RELEASE-NAME-mvcapp labels: helm.sh/chart: mvcapp-0.1.0 app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME app.kubernetes.io/version: "0.6" app.kubernetes.io/managed-by: Helm spec: replicas: 2 selector: matchLabels: app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME template: metadata: labels: app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME spec: serviceAccountName: RELEASE-NAME-mvcapp securityContext: {} containers: - name: mvcapp securityContext: {} image: "cdecl/mvcapp:0.6" imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 pro livenessProbe: httpGet: path: / port: http readinessProbe: httpGet: path: / port: http resources: {} --- # Source: mvcapp/templates/tests/test-connection.yaml apiVersion: v1 kind: Pod metadata: name: "RELEASE-NAME-mvcapp-test-connection" labels: helm.sh/chart: mvcapp-0.1.0 app.kubernetes.io/name: mvcapp app.kubernetes.io/instance: RELEASE-NAME app.kubernetes.io/version: "0.6" app.kubernetes.io/managed-by: Helm annotations: "helm.sh/hook": test spec: containers: - name: wget image: busybox command: ['wget'] args: ['RELEASE-NAME-mvcapp:80'] restartPolicy: Never helm install : chart 활용 kubernetes service install https://helm.sh/docs/helm/helm_install/{:target="_blank"} install : helm install [NAME] [CHART] [flags] # 설치하지는 않고 테스트 $ helm install mvcapp-svc mvcapp --dry-run # 로컬 Chart 를 통한 설치 $ helm install mvcapp-svc mvcapp NAME: mvcapp-svc LAST DEPLOYED: Thu Nov 4 13:29:38 2021 NAMESPACE: default STATUS: deployed REVISION: 1 NOTES: 1. Get the application URL by running these commands: export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services mvcapp-svc) export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}") echo http://$NODE_IP:$NODE_PORT $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 78d mvcapp-svc NodePort 10.43.202.254 <none> 80:31503/TCP 29s $ kubectl get pod NAME READY STATUS RESTARTS AGE mvcapp-svc-78ff4d97f9-hd9rf 1/1 Running 0 37s mvcapp-svc-78ff4d97f9-x4984 1/1 Running 0 37s KS3 export KUBECONFIG=/etc/rancher/k3s/k3s.yaml 세팅 ...

November 3, 2021 · Byung Kyu KIM

MySQL BinLog

MySQL BinLog (Binary Log) 설정 및 확인 MySQL Binlog https://dev.mysql.com/doc/internals/en/binary-log-overview.html{:target="_blank"} https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html{:target="_blank"} 데이터 수정에 대한 정보를 포함하는 로그 파일 세트 Binlog 를 사용하는 목적 복제 : 마스터 복제 서버에서 슬레이브 서버로 보낼 명령문의 기록으로 사용 데이터 복구 : 백업 파일이 복원된, 특정 시점 이후의 데이터 복구를 위해 사용 Binlog 기록하는 방법 binlog-format STATEMENT : 이벤트에는 데이터 변경(삽입, 업데이트, 삭제)을 생성하는 SQL 문이 포함 MySQL 5.7.7 이전 버전까지 Default ROW : 행 기반 로깅: 이벤트는 개별 행의 변경 사항을 설명합니다. MySQL 5.7.7 버전 부터 Default MIXED : 기본적으로 STATEMENT 로깅, 필요에 따라 자동으로 ROW 로깅으로 전환 일관성 NDB Cluster 경우 Default STATEMENT 경우 ISOLATION LEVEL이 READ-COMMITTED 경우 복구시, Dirty Read 에 의한 일관성이 문제가 될 수 있음 ...

October 27, 2021 · Byung Kyu KIM

Keepalived Basic

Loadbalancing & High-Availability 를 위한 Keepalived 설정 및 테스트 Keepalived https://www.keepalived.org/{:target="_blank"} VRRP 를 활용 가상IP (VIP) 기반 서버 다중화 도구 VRRP 는 여러 대의 라우터를 그룹으로 묶어 하나의 가상 IP 어드레스를 부여, 마스터로 지정된 라우터 장애시 VRRP 그룹 내의 백업 라우터가 마스터로 자동 전환되는 프로토콜입니다. Install # install $ sudo yum install keepalived # service start $ sudo systemctl start keepalived $ sudo systemctl status keepalived ● keepalived.service - LVS and VRRP High Availability Monitor Loaded: loaded (/usr/lib/systemd/system/keepalived.service; disabled; vendor preset: disabled) Active: active (running) since 화 2021-10-26 11:37:04 KST; 4s ago Process: 18356 ExecStart=/usr/sbin/keepalived $KEEPALIVED_OPTIONS (code=exited, status=0/SUCCESS) Main PID: 18357 (keepalived) Tasks: 3 Memory: 1.6M CGroup: /system.slice/keepalived.service ├─18357 /usr/sbin/keepalived -D ├─18358 /usr/sbin/keepalived -D └─18359 /usr/sbin/keepalived -D 10월 26 11:37:05 node1 Keepalived_vrrp[18359]: VRRP_Instance(VI_1) forcing a new MASTER ...on 10월 26 11:37:06 node1 Keepalived_vrrp[18359]: VRRP_Instance(VI_1) Transition to MASTER STATE 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: VRRP_Instance(VI_1) Entering MASTER STATE 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: VRRP_Instance(VI_1) setting pro 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: Sending gratuitous ARP on eth0 for 192.16...00 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: VRRP_Instance(VI_1) Sending/queueing grat...00 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: Sending gratuitous ARP on eth0 for 192.16...00 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: Sending gratuitous ARP on eth0 for 192.16...00 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: Sending gratuitous ARP on eth0 for 192.16...00 10월 26 11:37:07 node1 Keepalived_vrrp[18359]: Sending gratuitous ARP on eth0 for 192.16...00 Hint: Some lines were ellipsized, use -l to show in full. 기본 설정 https://www.redhat.com/sysadmin/keepalived-basics{:target="_blank"} https://www.redhat.com/sysadmin/advanced-keepalived{:target="_blank"} 테스트 환경 CentOS 7 (Hyper-v) node1 (MASTER) : 192.168.137.201 node2 (BACKUP) : 192.168.137.202 VIP : 192.168.137.200 /etc/keepalived/keepalived.conf vrrp_instance : 인터페이스에서 실행되는 프로토콜의 개별 인스턴스 정의 state : 인스턴스에서 시작해야 하는 초기 상태 interface : 네트워크 인터페이스 virtual_router_id : 네트워크 가상 ID priority : 우선 순위 advert_int : VRRP 패킷 송신 간격 (sec) authentication : 서로 서버간, 인증 계정 정보 virtual_ipaddress : 가상 IP vip MASTER 설정 : 192.168.137.201 vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 210 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.200 } } BACKUP 설정 : 192.168.137.202 vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 51 priority 200 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.137.200 } } MASTER 노드에 우선순위 priority 210 를 높게 줌 ...

October 25, 2021 · Byung Kyu KIM

Oracle, Sqlldr

Oracle 대량 Bulk Insert Tool 구성요소 Control File : sqlldr 명령행을 실행하기 위한 제어, 설정 파일 sqlldr : SQL*Loader, Oracle 데이터 Insert Tool Control File 기본 구성 OPTIONS (DIRECT=TRUE,ERRORS=100000,readsize=204800000) LOAD DATA CHARACTERSET AL32UTF8 INFILE 'infile/${CTL_INFILE}.csv' TRUNCATE INTO TABLE ${CTL_TABLE} FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY " " TRAILING NULLCOLS ( ${CTL_TABLE_COLS} ) OPTIONS DIRECT ERRORS : 허용하는 에러수, default 50 DIRECT=TRUE : Direct Path, 쿼리를 실행하지 않고 메모리에 블록을 만들어 테이블에 저장 LOAD DATA INFILE : 데이터 파일, 다수의 파일 등록 가능 TRUNCATE INTO TABLE INSERT : 신규 데이터, 데이터 존재하면 에러 APPEND : 중복되지 않은 데이터 추가 REPLACE, TRUNCATE: 모든 행을 지우고 추가 FIELDS TERMINATED FIELDS TERMINATED : 필드 구분자 ENCLOSED BY " " : 텍스트 한정자 ( ${CTL_TABLE_COLS} ) 테이블 컬럼 리스트 DATE TIMESTAMP 이나 NULL 처리 등의 가공이 필요 할 수 있음 Control File Sample CREATE TABLE IPMAN ( IP varchar2(128), SERVERNAME varchar2(128), ETC varchar2(128) ) OPTIONS (DIRECT=TRUE,ERRORS=100000,readsize=204800000) LOAD DATA CHARACTERSET AL32UTF8 INFILE 'infile/IPMAN.csv' TRUNCATE INTO TABLE IPMAN FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY " " TRAILING NULLCOLS ( IP "NVL(:IP, ' ')" , SERVERNAME "NVL(:SERVERNAME, ' ')" , ETC "NVL(:ETC, ' ')" ) SQLLDR 실행 Control File 설정으로 SQL*Loader 실행 $ sqlldr 'dev/<PASSWD>@<SERVER>:1521/<SID>' control=ctl/IPMAN.ctl log=log/IPMAN.log bad=log/IPMAN.bad Control File 자동 생성 스크립트 ctl.sh : 테이블 이름으로 스키마를 쿼리하여 Control File 생성 및 sqlldr 명령어 출력 ctl.template : Control File 템플릿, envsubst 명령으로 내용 치환 ctl.sh #!/bin/bash if [[ -z "$1" ]]; then echo "$0 [TABLE_NAME]" exit -1 fi TABLE_NM="$1" echo "TABLE NAME: " $TABLE_NM FD_LIST=$(sqlplus -s ${CTL_CONN} << SQLEOF set pagesize 0 feedback off verify off heading off echo off SELECT (CASE WHEN DATA_TYPE = 'DATE' OR DATA_TYPE LIKE 'TIMESTAMP%' THEN COLUMN_NAME || ' TIMESTAMP "YYYY-MM-DD HH24:MI:SS.FF3" @' WHEN DATA_TYPE = 'NUMBER' THEN COLUMN_NAME || ' "NVL(:' || COLUMN_NAME || ', 0)" @' WHEN DATA_LENGTH > 255 THEN COLUMN_NAME || ' CHAR(65535) @' ELSE COLUMN_NAME || ' "NVL(:' || COLUMN_NAME || ', '' '')" @' END) COLUMN_NAME FROM user_tab_cols WHERE table_name = '${TABLE_NM}' AND column_id IS NOT NULL ORDER BY COLUMN_ID; exit; SQLEOF ) FD_LIST=`echo ${FD_LIST} | sed 's/@/,/g'` FD_LIST=${FD_LIST%*,*} export CTL_INFILE=$TABLE_NM export CTL_TABLE=$TABLE_NM export CTL_TABLE_COLS=$FD_LIST envsubst < ctl.template > ctl/$CTL_TABLE.ctl echo sqlldr \${CTL_CONN} control=ctl/${CTL_TABLE}.ctl log=log/${CTL_TABLE}.log bad=log/${CTL_TABLE}.bad ctl.template OPTIONS (DIRECT=TRUE,ERRORS=100000,readsize=204800000) LOAD DATA CHARACTERSET AL32UTF8 INFILE 'infile/${CTL_INFILE}.csv' TRUNCATE INTO TABLE ${CTL_TABLE} FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY " " TRAILING NULLCOLS ( ${CTL_TABLE_COLS} ) 실행 예시 CTL_CONN DB 연결 환경변수 세팅 # infile : Data Directory / ctl : Control File / log : Log $ mkdir -p infile ctl log # DB 연결 변수 $ export CTL_CONN='dev/<PASSWD>@<SERVER>:1521/<SID>' 테이블 명으로 Control File 생성 및 sqlldr 명령어 출력 $ ./ctl.sh IPMAN TABLE NAME: IPMAN sqlldr ${CTL_CONN} control=ctl/IPMAN.ctl log=log/IPMAN.log bad=log/IPMAN.bad sqlldr 명령 실행 infile path : infile/테이블명.csv log= : 실행 로그 bad= : 실패 데이터 $ sqlldr ${CTL_CONN} control=ctl/IPMAN.ctl log=log/IPMAN.log bad=log/IPMAN.bad SQL*Loader: Release 21.0.0.0.0 - Production on Tue Oct 19 11:36:00 2021 Version 21.3.0.0.0 Copyright (c) 1982, 2021, Oracle and/or its affiliates. All rights reserved. Path used: Direct Load completed - logical record count 200. Table IPMAN: 199 Rows successfully loaded. Check the log file: log/IPMAN.log for more information about the load.

October 18, 2021 · Byung Kyu KIM

SQL Server, BCP

SQL Server 대량 복사 프로그램 유틸리티(b ulk c opy p rogram utility, bcp) BCP https://docs.microsoft.com/ko-kr/sql/tools/bcp-utility{:target="_blank"} SQL Server 의 Bulk 대량 데이터 Export 및 Import 유틸리티 설치 Windows 다운로드 : Microsoft® Command Line Utilities 14.0 for SQL Server{:target="_blank"} Linux SQL Server 의 리눅스 지원으로 사용 가능 Linux에서 SQL Server 명령줄 도구 sqlcmd 및 bcp 설치{:target="_blank"} Export 기본 cvs 파일로 테이블(쿼리 데이터) Export $ bcp 사용법: bcp {dbtable | query} {in | out | queryout | format} 데이터 파일 [-m 최대 오류 수] [-f 서식 파일] [-e 오류 파일] [-F 첫 행] [-L 마지막 행] [-b 일괄 처리 크기] [-n 네이티브 유형] [-c 문자 유형] [-w 와이드 문자 유형] [-N 비텍스트 네이티브 유지] [-V 파일 형식 버전] [-q 따옴표 붙은 식별자] [-C 코드 페이지 지정자] [-t 필드 종결자] [-r 행 종결자] [-i 입력 파일] [-o 출력 파일] [-a 패킷 크기] [-S 서버 이름] [-U 사용자 이름] [-P 암호] [-T 트러스트된 연결] [-v 버전] [-R 국가별 설정 사용] [-k Null 값 유지] [-E ID 값 유지][-G Azure Active Directory 인증] [-h "힌트 로드"] [-x xml 서식 파일 생성] [-d 데이터베이스 이름] [-K 애플리케이션 의도] [-l 로그인 제한 시간] Export csv $ bcp "SELECT * FROM dbname.dbo.tablename" queryout tablename.csv -c -t "," -r "\n" -S <SERVER> -U <USER> -P <PASSWD> 테이블 지정 Export : out $ bcp "dbname.dbo.tablename" out output.csv ... 쿼리 실행 결과 Export : queryout $ bcp "query" queryout output.csv ... Export 데이터 형식 -n : 네이티브 포맷, SQL Server로 데이터 이전 할때 유용 (종결자 등의 이유로 데이터 이슈 해결) -c : 문자유형, OS의 기본 Charset을 따라감 한글 Windows : EUC-KR Linux : UTF-8 -w : 와이드 문자유형, 유니코드 UTF-16 LE Import $ bcp "dbname.dbo.tablename" in input.csv -c -t "," -r "\n" -S <SERVER> -U <USER> -P <PASSWD> 특이사항 길이가 0인 문자열의 경우 데이터 내에 NULL 문자를 삽입 SQL Server의 경우 문제는 없지만, 다른 DB 에 Import 의 경우 NULL 문자가 들어감 INSERT INTO tablename (filed) SELECT CHARACTER(0) -- MySQL 5.7 SELECT * FROM tablename WHERE filed = ''; -- Not Working SELECT * FROM tablename WHERE ASCII(filed) = 0; -- Working -- MySQL 8 SELECT * FROM tablename WHERE filed = ''; -- Working SELECT * FROM tablename WHERE ASCII(filed) = 0; -- Working

October 14, 2021 · Byung Kyu KIM

MySQL LOAD DATA

MySQL 테이블에 Text 파일을 빠르게 Insert 하는 방벙 MySQL LOAD DATA https://dev.mysql.com/doc/refman/8.0/en/load-data.html{:target="_blank"} The LOAD DATA statement reads rows from a text file into a table at a very high speed LOAD DATA statement 사전 준비 : secure_file_priv secure_file_priv 의 설정값이 NULL 로 되어 있는데 빈문자열로 수정해야 함 SHOW VARIABLES LIKE 'secure_file_priv' -- NULL my.cnf 에서 수정 및 재시작 필요 [mysqld] secure-file-priv="" LOAD DATA 최소 설정 LOAD DATA INFILE '/path/data.txt' INTO TABLE data_table Field and Line Handling : Default 설정 LOAD DATA INFILE '/path/data.txt' INTO TABLE data_table FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY '' 헤더 라인 무시 LOAD DATA INFILE '/path/data.txt' INTO TABLE data_table IGNORE 1 LINES LOAD DATA 기본 설정 (CSV) LOAD DATA INFILE '/path/data.txt' IGNORE INTO TABLE data_table FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '"' LINES TERMINATED BY '\n' (filed1, filed2, filed3 ) Duplicate-Key and Error Handling IGNORE : unique key 값이 있으면 새로운 행은 버려짐 default REPLACE : unique key 값 기준으로 새로운 행으로 변경 필드 개수, 순서 기본적으로 파일의 구분자 기준 순서와 필드와 1:1 매치됨 필드 지정을 통해 순서 조정 가능 파일의 구분자 필드가 많으면 : 버려짐 테이블의 필드가 많으면 : 나머지 필드는 Default 값이나 NULL 처리 (NULL 허용시) Input Preprocessing 테이블의 중간 필드를 무시 (Default 값 or NULL 처리) 하려면 @dummy 키워드로 필드 지정 필드 가공은 SET 명령으로 처리 @변수 명으로 받아서 가공후 필드에 지정할 수 있음 LOAD DATA INFILE '/path/data.txt' IGNORE INTO TABLE data_table FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n' (filed1, @dummy, filed3, @var1, filed5 ) SET filed2 = CURRENT_TIMESTAMP, filed4 = @var1 * 2; Index Handling : LOAD DATA 문의 성능향상을 위한 Index check option unique index checks option : SET unique_checks = 0 SET unique_checks = 1 foreign key check option : SET foreign_key_checks = 0 SET foreign_key_checks = 1 로컬(클라이언트) 데이터 원격 INSERT https://dev.mysql.com/doc/refman/8.0/en/load-data-local-security.html{:target="_blank"} 사전 준비 : local_infile 설정 (server and client) server : local_infile 의 설정값이 ON(1) 로 수정해야 함 client : 접속시 --local-infile 옵션 추가 SHOW VARIABLES LIKE 'local_infile' ; -- OFF SET GLOBAL local_infile = 1 ; SHOW VARIABLES LIKE 'local_infile' ; -- ON LOCAL PATH 지정 LOAD DATA LOCAL INFILE ... LOAD DATA LOCAL INFILE '/path/data.txt' INTO TABLE data_table

October 13, 2021 · Byung Kyu KIM

Docker in Docker / Docker out of Docker

Docker 내부에서 Docker 실행 Docker in Docker : DinD Docker 내부에서 Docker 를 실행 하기 위해서는 추가적인 호스트 머신의 권한을 획득 해야함 --privileged : Give extended privileges to this container 호스트 머신의 커널 기능 및 장치에 접근 가능하게 됨 --privileged 의 문제점 안전하지 않은 컨테이너로 인한 호스트 머신의 커널이나 장치를 활용하여 취약점에 노출되게 됨 http://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/{:target="_blank"} 서비스 환경에서의 여러가지 약점은 가지고 있지만, Workflow 등의 내부 Devops 툴로서의 유용하다고 판단 Docker in Docker 실행 alpine 이미지 활용 테스트 $ docker run -it --rm --privileged --name=dind alpine Docker 설치 및 실행 # 설치 $ apk add docker fetch http://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz (1/13) Installing ca-certificates (20191127-r5) ... (13/13) Installing docker (20.10.7-r2) Executing docker-20.10.7-r2.pre-install Executing busybox-1.33.1-r3.trigger Executing ca-certificates-20191127-r5.trigger OK: 253 MiB in 27 packages # 실행 $ dockerd 2> /dev/null & $ ps -ef PID USER TIME COMMAND 1 root 0:00 /bin/sh 125 root 0:00 dockerd 133 root 0:00 containerd --config /var/run/docker/containerd/containerd.toml --log-le 260 root 0:00 ps -ef Docker in Docker 테스트 $ cat /etc/*-release 3.14.2 NAME="Alpine Linux" ID=alpine VERSION_ID=3.14.2 PRETTY_NAME="Alpine Linux v3.14" HOME_URL="https://alpinelinux.org/" BUG_REPORT_URL="https://bugs.alpinelinux.org/" $ docker run --rm ubuntu cat /etc/*-release cat: /etc/alpine-release: No such file or directory NAME="Ubuntu" VERSION="20.04.3 LTS (Focal Fossa)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 20.04.3 LTS" VERSION_ID="20.04" 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" VERSION_CODENAME=focal UBUNTU_CODENAME=focal $ docker run --rm centos cat /etc/*-release cat: /etc/alpine-release: No such file or directory NAME="CentOS Linux" VERSION="8" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="8" PLATFORM_ID="platform:el8" PRETTY_NAME="CentOS Linux 8" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:8" HOME_URL="https://centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-8" CENTOS_MANTISBT_PROJECT_VERSION="8" Docker out of Docker : DooD --privileged 사용의 피하기위한 방법 CLI 명령 API인 docker.sock 을 활용, 볼륨을 통해 호스트 머신의 명령을 전달하여 호스트 머신에서 실행 하는 방법 /var/run/docker.sock /var/run/docker.sock docker daemon 에서 인터페이스용으로 노출한 unix domain socket Docker ouf of Docker 실행 # volume 으로 docker.sock 을 연결 $ docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock --name=dood alpine Docker 설치 및 실행 # 설치 $ apk add docker fetch http://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz (1/13) Installing ca-certificates (20191127-r5) ... (13/13) Installing docker (20.10.7-r2) Executing docker-20.10.7-r2.pre-install Executing busybox-1.33.1-r3.trigger Executing ca-certificates-20191127-r5.trigger OK: 253 MiB in 27 packages # 호스트머신에서 명령을 실행 하므로 자신의 컨테이너가 보임 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1a391d12768c alpine "/bin/sh" 2 minutes ago Up 2 minutes dood $ docker run -d --rm --name=ubuntu ubuntu sleep 10 d14cfc9ff9cd2b4faecfed5af9e1e1b6dd4a7d1497bed4a6d34faaad64a442f9 # 자신의 컨테이너와 동일한 환경에서의 별도 docker 실행 확인 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES d14cfc9ff9cd ubuntu "sleep 10" 3 seconds ago Up 2 seconds ubuntu 1a391d12768c alpine "/bin/sh" 6 minutes ago Up 6 minutes dood

September 23, 2021 · Byung Kyu KIM