Git 브랜치 목록 동기화

Git 를 사용할때에 원격과 로컬의 브랜치를 동기화되서 동작한다. 그런데, 원격 브랜치를 삭제하고 난후에 로컬 브랜치를 보면 동기화 되지 않는다.

위 예제를 보면 원격 브랜치가 여러개 보인다. 하지만 실제 원격 브랜치를 보면 main 빼고는 전부 삭제된 상태 이다. 이럴때는 다음과 같이 하면 된다.

위와같이 로컬에 원격 브랜치 목록이 실제 원격 브랜치 목록과 동기화 되었다.

Gitlab 을 위한 opentofu 도커 이미지 제작

Gitlab 에서 사용할 opentofu 도커 이미지를 제작해보자. Gitlab 에서 Auto DevOps 를 이용할 경우에 Docker 이미지를 이용해서 Terraform 빌드, 배포 하는게 가능하다. 지금은 Terraform 을 위한 Docker 이미지만 존재하는데, Opentofu 를 위한 도커 이미지를 제작해서 사용할 수 있도록 이미지를 만들어 보자.

Dockerfile

Docker 빌드를 위해서 Dockerfile 이 있어야 한다. 다음과 같다.

내용을 보면 gitlab-terraform.sh 스크립트 파일이 있어야 한다. 이 파일은 실제 Gitlab 을 이용해서 CI/CD 를 할 경우에 실제로 사용하게 되는 스크립트 파일이다.

Docker Build

Docker 빌드는 다음과 같은 명령어로 가능 하다.

빌드를 하고 난 후에 Docker Hub 에 푸쉬를 해줬다.

GitLab, Merge Request 일때만 Auto DevOps 되도록 하기

Gitlab 은 매우 강력한 툴이다. 이거 하나면 다 된다. 문제는 다루기가 여간 쉽지가 않다는데 있다. 많은 것을 알고 있는 상태라면 Gitlab 을 손댈 필요가 없지만 그것을 몰랐을 때에는 예기치 않은 반응과 결과를 보게 된다.

Gitlab 은 CI/CD Pipeline 을 지원하는데, 이에 대한 설정은 Auto DevOps 에서 하게 된다. 정확하게 말하면 CI/CD Pipeline 을 Auto DevOps 라고 부른다고 이해해도 된다. 각 프로젝트 마다 Auto DevOps 설정이 존재한다. 이 설정의 기본은 다음과 같다.

“Default Auto DevOps pipeline” 이 체크되어 있는데, 아래 설명에 따라 별도의 CI 설정이 없을 경우에 Auto DevOps 를 실행한다는 의미다. 이 말은 저장소에 .gitlab-ci.yaml 파일이 존재할 경우에 무조건 실행 된다는 것을 의미한다.

이렇게 되면 CI/CD 를 실행하는데 있어서 조건을 달 수가 없다. 그래서 많은 사람들이 별도의 메뉴로 존재하는 줄 알고 열심히 찾아보지만 그런거 없다. 그러다보니 Gitlab 을 사용하면서 당황하게 된다. “나는 main(혹은 master) 브랜치를 기반으로 배포를 하고 싶은데, Gitlab 은 그냥 아무 브랜치에 push 만 되면 그냥 실행 된다… 별로 안좋네..” 이런 식으로 결론이 난다.

workflow

Gitlab 은 Auto DevOps (혹은 CI/CD) 관련해서는 .gitlab-ci.yaml 파일에서 모두 처리할 수 있도록 했다. 특정 조건에 맞게 실행되도록 workflow 라는 문법을 지원 한다. 예를들면 다음과 같다.

위 예제는 merge request 가 발생하거나 기본 브랜치에 push 가 발생하면 동작하도록 규칙(rule)를 정의한다. 위 예제 내용을 .gitlab-ci.yaml 맨 위에 적어놓게 되면 된다.

아니면 다음과 같은 예제도 있다.

commit branch 가 main (main 은 Gitlab 의 기본 브랜치) 도 아니고 파이프라인 소스가 merge request 도 아니면 CI/CD 를 실행하지 말라는 예제다.

rules

여기서 한가지 짚고 넘어가면, rules 다. rules 는 반드시 workflow 에서만 사용되는게 아니다. 각 stage 마다 사용 될 수 있다. 다음의 예제입니다.

terraform 를 위한 gitlab-ci 예제 중 일부 입니다. stage 단계에서 rules 를 설정해서 사용하고 있다는 것을 알 수 있습니다.

Gitlab 으로 terraform 상태(state) 관리하기

Terraform 을 여러명이 사용할때에 필요한 것이 Terraform 의 상태를 변경하지 못하도록 하는 것이다. terraform 을 실행할때마다 상태(state) 파일이 갱신되는데, 여러사람이 같이 일을 할때에는 이 파일을 공유해서 사용해야 한다.

대부분이 terraform state 파일을 AWS S3 저장소와 Dynamo DB 를 이용해 lock 을 거는 방식이 많이 거론된다. 이 방법은 AWS 클라우드를 사용해야 한다는 강제가 필요한데, 물론 Terraform 이 클라우드를 빠르게 코드로 만들도록 도와주기 때문에 어짜피 AWS 클라우드 인프라를 구성할 거면 S3 를 사용하는 것이 문제가 되지 않는다.

또, 인터넷상에 보면 Gitlab 을 이용한 상태관리 관련한 문서, 심지여 Gitlab 의 공식문서조차도 잘못된 내용이 있어 이 글을 작성한다.

하지만 꼭 AWS S3와 DynamoDB 를 이용해야만 가능하냐 하는 질문에는 그렇지 않다는 답이 존재한다. 이 문서는 AWS 클라우드 서비스를 이용하지 않고 Gitlab 을 이용해 Terraform 의 상태(state) 파일을 관리하는 방법에 대해서 알아 본다.

GitLab

매우 훌륭한 시스템이다. 소스코드 저장소는 물론이고 Container Registry, Terraform state 저장소, CI/CD, Wiki, Ticket 시스템등 거의 모든 IT 업무를 한곳에서 수행할 수 있게 해준다.

Terraform state 파일 저장소를 네이티브 기능으로 사용할 수 있도록 만들어져 있어서 이걸 이용하면 클라우드 저장소의 도움 없이도 Terraform 의 상태 파일을 관리 할 수 있다.

저장소 생성하기

Terraform 상태 파일 저장을 위한 저장소를 만들어 준다.

Terraform 상태 파일을 저장하기 위한 저장소 생성

Gitlab 에서 저장소 생성은 단순한 절차임으로 큰 어려움 없이 생성이 된다.

Terraform 파일 작성

간단하게 Terraform 파일을 작성해 보자. provider 와 backend, 그리고 AWS Resource 중에 Security Group 하나를 만들어 보자. 파일은 main.tf 와 backend.tf 두개로 작성 됐다.

main.tf

backend.tf

위 코드를 보면 변수 3개가 보인다. $PROJECT_ID 는 Gitlab 에 프로젝트 Settings -> General 을 보면 번호가 부여된 Project ID 를 알 수 있다.

API 통신을 위해서 인증 토큰이 필요하다. 공식문서에는 사용자 계정 토큰을 발행하라고 되어 있다. 사용자 계정 토큰은 사용자 Profile -> Access Tokens 에서 생성이 가능하다.

하지만, 여기서 한가지 주의해야 할게 있다. 인터넷을 검색해보면 개인 토큰으로는 인증 실패가 발생한다고 하는데, API 통신을 위해서는 Maintainer 권한을 필요로 한다. 그러니까 계정의 권한이 Maintainer 를 가지고 있지 않는다면 토큰을 발행이 되어도 인증에 실패하게 된다.

Gitlab 에서 API 통신을 위해서는 적절한 권한을 필요로하게 되는데, Maintainer 권한이 필요하게 된다. 이 말은 Access Tokens 은 Maintainer 권한만 있다면 사용자 구분 없이 사용이 가능하게 된다.

그러면, 프로젝트 Access Tokens 을 이용할 수 있지 않을까? 당연히 가능 하다. 앞서 생성한 프로젝트 -> Settings -> Access tokens 에서 토큰 발생이 가능하다. 프로젝트 토큰 발생은 사용자도 함게 생성되는데, 그 사용자는 bot 이다.

한가지 주의해야 할 것은 프로젝트 access token 을 생성할때에 권한(role) 을 Maintainer 권한으로 해야 한다. 그리고 이렇게 생성을 하게 되면 bot 계정이 생성이 되는데, 이 계정이 access token 소유자가 된다.

이 계정의 Id 는 @ 로 시작하는 문자열이다.

어떤 Access Tokens 을 사용해도 상관은 없다. 핵심은 권한(Role) 이다. 반드시 Maintainer 권한이 있어야 한다.

Terraform init

이제 Terraform 을 초기화 한. 초기화는 다음과 같은 명령어를 사용 한다.

TF_USERNAME 은 Project Access Token 소유자인 bot 이고 TF_PASSWORD 는 Project Access Token 이다.

terraform plan

이 명령어를 실행하면 드디어 Gitlab 저장소에 Terraform state 에 상태 파일이 생성된다. Operate -> Terraform states 에서 확인이 가능하다.

결론

인터넷을 살펴보면 Gitlab 을 이용한 Terraform state 관련 내용에서 Personal Access Token 으로 되지 않는다는 내용이 많다. 핵심은 Access Token 의 권한이다. 반드시 Maintainer 권한이 있어야 하며 이 권한만 있다면 Personal 이던 Project 이던 상관이 없다.

Terraform 을 위한 VSCode 세팅

VSCode 에서 Terraform 을 사용하기 위한 세팅은 다음과 같다.

필요한 Extensions

  • HashiCorp Terraform
  • IntelliCode
  • Prettier – Code formatter

위와같은 Extensions 들을 설치하면 Terraform 을 사용하기가 편하다.

사용자 설정

Terraform 을 위한 사용자 설정은 다음과 같다.

위 설정은 Prettier – Code formatter 가 설치되어 있어야 한다.

Kafka 설치하기

이벤트 스트림을 제공하는 브로커 이다. 더블어 메시지 스트림도 지원한다. Scala 로 제작되었으며 JVM 위에서 동작한다. 따라서 Java 가 있어야 한다.

환경

서버는 3대로 준비했다. Production 에서는 적어도 3대의 Broker 를 권장대로 설치한 것이다. 서버 3대는 다음과 같다.

  • klab-master1.systemv.local(192.168.96.60)
  • klab-worker1.systemv.local(192.168.96.61)
  • klab-worker2.systemv.local(192.168.96.62)

배포판은 Rocky Linux 9.3 최신 버전이다.

요구사항

Apache Kafka 를 실행하기 위해 JVM 이 필요하다. Kafka 버전에 따라서 Java 버전도 선택해야 한다. 최신의 Kafka 는 Java 11 을 필요로 한다.

Java 11 을 설치는 패키지로 설치 했다.

Kafka 다운로드 및 설치

Apache Kafka 는 AWS 의 MSK 에 버전과 동일하게 선택했다.

다음과 같이 /app 디렉토리에 압축해제로 설치를 완료 한다.

Zookeeper 설정

kafka 에 zookeeper 가 내장되어 있다. 설정은 /app/kafka/config 디렉토리에 zookeeper.properties 파일이다. 다음은 예시다.

systemd Unit을 작성해서 관리한다.

Kafka 설정

kafka 의 설정은 /app/kafka/conf/server.properties 파일이다. 주요한 설정은 다음과 같다.

systemd Unit을 작성해서 관리한다.

토픽 테스트

이제 토픽을 생성해 테스트를 해본다. 다음과 같이 Topic 을 생성한다.

파티션 1개 복제는 3개로 토픽이 생성되었다. consumer 명령어를 이용해서 토픽에 접속한다.

접속을 하면 아무런 일도 발생하지 않는다.

이제 producer 를 이용해서 메시지를 생산한다.

이렇게 메시지를 생성하면 앞서 접속한 consumer 화면에 똑같이 내용이 나와야 한다.

topic 의 통계 정보를 다음과 같이 확인해 볼 수 있다.

참고

Amazon MSK 2-AZ

Kafka 를 보게 되면서 Amazon MSK 를 보고 있는데, 문서를 보기에는 운영 환경에서 3-AZ 를 권장하고 있다. 성능 문서를 보았을때에도 3-AZ 를 권장하고 있고 Kafka 의 일반적은 환경에서도 3개의 브로커를 사용하도록 하고 있다.

하지만 Amazon MSK 에서는 2-AZ 로도 얼마든지 가능하다고 한다. 2019년 10월 16일 문서에 다음과 같이 되어 있다.

You can now expand your Amazon MSK clusters and deploy new clusters across 2-AZs

The new capability to expand allows your Amazon MSK cluster to scale out as your business grows by dynamically increasing the number of brokers within a cluster. The use of 2-AZ clusters is a good option for customers who already run Apache Kafka brokers in two AZs or use a replication factor of 2 by default.

Replication Factor 를 2로 할 경우에 얼마든지 2-AZ 로 할 수 있다고 되어 있다.

SRE 를 보고 느끼는 점들..

SRE(Site Reliability Engineering) 이라고 부르는게 요새 자주 들린다. 모든 내용을 다 아는건 아니지만, 이것저것 살펴보고 난 후 웃음이 났다. 그동안 내가 바라보는 관점이 그대로 같았기 때문이다. 나는 오래전부터 인프라 시스템, 좁게는 리눅스를 개발자 관점에서 다룰 수 있어야 한다고 생각해왔다.

나는 오랫동안 인프라 분야에 몸 담았다. 이렇게 말을 하면 대부분 서버, WAS 등을 다루는 것으로 생각할지 모른다. 실제로 내가 지원하는 분야는 TA 인데, 각 프로젝트마다 다르지만 그래도 TA 하면 인프라적인 요소를 많이 생각한다.

하지만 나는 적어도 인프라를 그야말로 전통적인 운영(Traditional Organizations) 을 지향하지 않았다. 대학교때에는 리눅스(Linux) 에 미쳐살았지만 그것을 벗어나 PHP 웹 개발하면서 취업도 개발자로 했다. 그러던 것이 인프라 팀으로 적을 옮겼는데, 정확하게는 인프라 개발팀이였다. Python 을 그때 배웠다. 그리고 인프라 백엔드 개발과 서버운영을 같이하는 일을 하게되면서 자연스럽게 OSS 와 인프라 개발을 위한 각가지 프로그래밍을 익혔다.

SRE 을 한국에 적용한다면 “인프라 개발팀” 이 가장 현실적이다. SRE 의 정의는 대략 다음과 같다.

https://newrelic.com/sites/default/files/2021-08/site-reliability-engineering-handbook.pdf
Google defines an SRE as an operationally minded software engineer, but what does that mean? At Google, SRE teams are responsible for both capacity planning and provisioning. The teams are different from purely operational teams in that they seek software engineering solutions to problems.

소프트웨어 엔지니어 마인드로 운영을 다룬다는 것인데, 오래전부터 개발자 관점에서 인프라 시스템을 바라보고 다루어야 한다고 생각했었다.

문제는 현실이 그렇지 않다는 것이다. 더군다나 프리랜서 직업에서 프로젝트에 투입되보면 대부분 OS, WAS, 최근에는 Cloud 까지 구축과 운영을 하는 경우가 많았다. 이런 경우에 소프트웨어 엔지니어, 더나가 개발자적 시각으로 일을 할만큼 여건이 되지 않았다. 그리고 그런걸 원하지도 않았다. 전통적인 운영과 구축이였다.

한국의 상황이 안타까움이 있다. TA 직군에서 계약을하고 프로젝트를 하게되면 기술적인 부분에 있어서 그런대로 최근의 트랜드를 따라가긴 한다. 자동화, IaC, 데이터 분석등이 그런 것이다. 문제는 기술적인 부분만 강조할 뿐, 이것을 기반으로 SRE 까지는 가지 못한다는데 있다.

TA 들도 문제다. TA 들은 전통적인 구축, 운영에 적어 있다. 이들에게 Python 정도는 할 줄 알아야 하지 않느냐는 질문에 “그걸 왜 우리가 알아야 하냐?” 식의 답변이 대부분이다. OS 를 명령어를 통해서 세팅하고, WAS 서버를 세팅하고 로그 분석하고 JVM 설정과 덤프 분석등이 그들이 하는 일이라고 생각한다. 그러다보니 Python 은 고사하고 Cloud 에서 많이 쓰이는 Terraform 과 같은 툴을 익히는데 게을리 한다. 어떤 문제가 발생하면 서버에 직접 접속해서 봐야 속이 시원하고 JVM 덤프를 떠서 분석을 해야지만 뭔가 일을 제대로 하는 것마냥 생각한다.

이제 TA 도 소프트웨어 엔지니어를 넘어서 개발자가 되어야 한다. 진정으로 개발을 하는 건 아니지만 적어도 자신이 자신있게 하나 정도의 언어는 능숙하게 다룰 수 있어야 한다.

구글의 SRE 는 팀의 Role 이다. 정확하게는 운영에 대한 Role. 그래서 작금의 TA 직업군에게 적용되어지는 대상이다.

https://newrelic.com/sites/default/files/2021-08/site-reliability-engineering-handbook.pdf
To enforce this, Google caps the amount of time SREs spend on purely operational work at 50%. This means that, at a minimum, 50% of a Google SRE’s time should be allocated to engineering tasks, such as automation and improvements to the service.

문제는 편견과 돈…

지금까지 TA 경력으로 일해오면서 한 마디 했다가 바보 된 경우가 있었다.

100% 장애 안나는 시스템은 없습니다. 대충 해봐도 90%정도 가동률을 보이면 진짜 잘한 겁니다. 장애 안나게 어떻게 시스템을 만듭니까?

특히나 금융 프로젝트에 투입된 상황에서 저런말을 하면 십중팔구 고객으로부터 짐 쌓라는 말을 들을 수 있다. 공공 프로젝트는 더 하지 않나? 100% 장애 안나는 시스템을 구축해야 하는거지, 금융 시스템 운영하다가 장애 날껄 생각하면서 구축하냐?

하지만 SRE 는 100% 장애를 커버하지 않는다. 이것도 나의 생각과 동일 했었는데, 장애 발생하더라도 서비스에 영향이 없다면 어떨까? 장애라는 것이 특정 서버가 다운되거나 네트워크 장비가 이상이 생길 수 있다. 이런 상황에서도 고객 서비스에 아무런 영향을 주지 못했다면 그 시스템은 신뢰성이 높다고 할 수 있지 않을까? 신뢰성(Reliability) 라는 말이 가지는 함의가 이와 같다고 생각한다.

돈.. 기업은 항상 돈을 먼저 생각한다. 기업이 힘들면 IT 부서가 먼저 짤린다는 슬픈 이야기는 더 이상 슬픈 이야기도 아니다. 100% 장애가 나지 않도록 해야지만 고객에 대한 보상도 없을 것이니 장애 발생이 가능할 수도 있다는 말을 꺼내는 순간 돈이 나갈 수 있다는 생각을 먼저 하게 된다. 장애가 나면 그것을 분석하고 장애를 예방하기 위한 일련의 활동이 필요한데, 그렇게 되면 전문가가 항시 있어야 한다. 언제 생길지도 모르는 장애 때문에 전문가를 고용한다는 건 기업에서는 있을 수 없는 일이다.

구축 프로젝트가 끝나면 대부분의 인력이 철수를 한다. 운영으로 넘어가게 되면 안타갑게도 인프라 관련 전문 인력은 뽑지도 않는다. 인프라 담당자를 뽑아 놨다고 하지만 그냥 용어만 잘 알고 있을뿐 실무적인 익숙함도 없는 사람들인 경우가 많다. 어짜피 구축된 시스템은 100% 장애가 발생하지 않도록 구축되었다는 신념이 있기 때문에 운영은 그냥 모니터링 요원정도로만 생각하는 것이다.

Kubernetes 관련 기술 스택..

쿠버네티스 관련된 기술들이 워낙 많다보니 뭘 어디서부터 손대야할지 모를때도 있고 하다보면 어디에 서 있는지도 모를때가 있다. 더 나가 쿠버네티스를 시작하려고할때에 이게 어디에 있는건지를 알고 싶을때가 종종 있는데, 웹 서핑을 하다가 주운걸 기록해본다.

딱봐도 채용공고에 내용인데, 굵직하게 정리가 되어서 긁어왔다. 여기서 한가지 추가해야 한다면 IaC 부분인데, 요새는 쿠버네티스에 뭔가를 설치할때는 다음과 같은 걸 많이 사용한다.

  • Helm
  • Operator

ArgoCD 도 있지만 이것은 사실 애플리케이션 배포에 쓰인다고 보면 된다.

요새 하도 공부를 하지 않아서 잃어버리는 기억도 많고 이제는 쓰지 않는 기술들도 많은데, 슬슬 다시 공부를해야 겠다고 다짐한다. 해야할게 얼마나 많은지… 덕분에 잘 심심하지 않게 살수 있다는 것에 위안을 받는다.

Linux HotSwap 사용하기

컴퓨터 하드웨어가 발달하면서 기존 서버시스템의 기능을 데스크탑에서도 사용할 수 있게 되었다. 그중에 하나가 Hot Swap 이다. 스토리지(Storage) 를 컴퓨터를 끄지 않고도 교체할 수 있는게 Hot Swap 기능이다.

BIOS 설정

Hot Swap 을 이용하기 위해서는 BIOS 에 기능을 활성화 해줘야 한다. 제조사마다 BIOS 설정 메뉴가 다르지만 내가 사용하는 메인보드의 경우에는 다음과 같이 설정이 가능하다.

Hot Plug 라고 이름이 다르지만 이것이 Hot Swap 이다. 만을 BlOS 에서 이 메뉴가 없다면 메인보드에서 Hot Swap 기능을 제공하지 않는 것이다.

Linux 에서 사용하기

대부분의 최근의 Linux 커널에서는 Hot Swap 를 지원 한다. 별다른 설정없이 리눅스 배포판이라면 모두 사용이 가능하도록 되어 있다. 먼저 작동하고 있는 Disk 하나를 예를들어 Hot Swap 을 사용해보자.

먼저 다음과 같이 Disk 의 파워를 꺼야 한다. 이는 Disk 꺼내기 위한 것으로 전원을 끄지 않고 갑자기 꺼내버리면 Disk 가 파손될 우려가 있기 때문에 파워를 꺼야 한다.

sdc 디스크에 대해서 파워를 끄도록 한 명령어다. 커널 파라메터 설정으로 파워를 끄게 된다. 그렇게되면 lsblk 명령어로 디스크가 안보이게 된다. 그리고 커널 메시지에 다음과 같이 표시 된다.

이제 하드디스크를 꺼내고 새로운 하드 디스크를 장착하면 된다. 새로운 하드 디스크를 장착하게 되면 최근의 리눅스 커널에서 자동으로 새로운 하드 디스크를 알아 차린다. 이 내용은 커널 메시지로 다음과 같이 나온다.

lsblk 로 보면 새로운 디스크가 인식된게 보이게 된다.

만약 이렇게 자동으로 디스크가 인식되지 않는다면 SCSI 디스크 ReScan 기능을 이용해야 한다. Hot Swap 은 SCSI 의 host 번호를 이용해 작동됨으로 SCSI host 번호를 알아야 한다. 하지만 리눅스에서는 /dev/sdc 형식인데 SCSI host 번호와는 다른데, 다음과 같이 알아내야 한다.

위 결과에서 중간에 host4, host5 가 바로 SCSI host 번호 이다. 이렇게 확인된 SCSI host 번호를 이용해서 ReScan 하도록 다음과 같이 할 수 있다.

이렇게 수동으로 ReScan 를 하게 되며 하드 디스크를 인식하게 된다.

  • Camera: SM-F711N
  • Taken: 28 9월, 2023
  • Focal length: 4.25mm
  • ISO: 640
  • Shutter speed: 1/30s