민트 리눅스에서 OpenvSwitch 설정하기

민트 리눅스(Mint Linux) 21.03 을 쓰고 있는데, 네트워킹이 NetworkManager 으로 되어 있다. Ubuntu 22.04 LTS 에서는 networkd 였지만 민트 리눅스는 같은 Ubuntu 라고 하더라도 네트워킹 운영을 NetworkManager 가 담당하고 있다.

이 문서는 민트 리눅스에서 OpenvSwitch 설정에 대한 것이다. Ubuntu 와 다른 네트워킹을 사용하기 때문에 nmcli 명령어를 이용한 방법을 소개 한다.

민트 리눅스 네트워킹 설정

이렇게 NetworkManager 일 경우에는 네트워크 인터페이스 관련 설정을 nmcli 로 하게된다. 물론 민트 리눅스 이기 때문에 GUI 를 통해서 손쉽게 할 수 있다.

GUI 툴을 이용해서 이렇게 설정을 하게 되면, nmcli 명령어를 사용해서 하는 것과 동일하게 nmcli 관련 설정파일이 변경 된다. 다음과 같은 경로에 파일이 존재한다.

GUI 툴을 이용해 설정한 내용이 위 파일에 적용된다.

OpenvSwitch 설치

OpenvSwitch 를 설치를 먼저 해야 한다. Ubuntu 를 사용하고 NetworkManager 일 경우에 OpenvSwitch 도 NetworkManager 와 연관된 패키지를 설치하는 경우가 많지만 민트 리눅스에는 다음과 같은 패키지를 설치 한다.

systemd 에 설정이 되었고 시작도 되었다. 다음과 같이 명령어가 문제없이 출력되는 확인한다.

위와같이 정상적으로 버전이 출력되어야 한다.

network-manager 패키지 문제

민트 리눅스 21.03 에서는 network-manager 패키지에 문제가 있다. OpenvSwitch 플러그인이 비활성화된 패키지라는 거다. 다음과 같다.

ovs 를 활성화하기 위해서는 network-manager 를 재패키징 해야 한다. 이를 위해서는 소스 deb 를 다운로드 받아야 한다.

이렇게하면 디렉토로에 network-manager 관련 패키징을 위한 파일과 디렉토리가 생성된다. 여기서 다름과 같이 deb 패키징을 위한 configure 파일이라 할 수 있는 rules 파일을 수정해 줘야 한다.

rules 파일을 열면 configure 설정을 볼 수 있다. 여기서 –disable-ovs 를 삭제한다. 이렇게 되면 ovs 를 위한 설정파일이 생성되고 이 파일에 대한 처리가 없으면 deb 패키징이 실패한다. 설치를 위한 파일 목록은 network-manager.install 파일이다. 여기서 다음을 추가해 준다.

lib/systemd/system/NetworkManager.service.d/NetworkManager-ovs.conf

이제 deb 패키지를 만들어야 하는데, network-manager 의 의존성 라이브러리를 설치해 줘야 한다.

그리고 debuild 명령어로 패키징을 제작해야 한다.

위와같이 하면 deb 패키지가 만들어진다. deb 패키지는 network-manager-1.36.6 디렉토리 밖에 만들어 진다.

이제 다음과 같이 재설치를 해준다.

nmcli 명령어를 이용한 openvswitch 설정

이제 nmcli 명령어를 이용해서 openvswitch 설정을 다음과 같이 한다. IP는 각자 자신의 네트워크 설정으로 바꾸면 된다. 먼저 명령어로 device 상태를 봐본다.

‘유선 연결 1’ 을 connection name 이라고 하는데, 한글이라 앞으로 설정하는데 문제가 될 수 있다. 이것을 DEVICE와 동일하게 설정해준다. 이것은 앞서 GUI 툴을 이용해서 변경해서 적용하면 간단하게 바꿀 수 있다. 변경이 되면 다음과 같다.

이제 nmcli 명령어를 다음과 같이 입력해준다.

IP 와 gateway 그리고 DNS 를 자신에 맞게 고쳐준다. 위와 같이하고 ovs-vsctl show 명령어로 제대로 되었는지 확인한다.

그리고 ip a 명령어로 제대로 ip가 세팅되었는지 확인한다.

잘되어 보인다. 이제 nmcli 명령어를 이용해 enp5s0 connection 을 삭제한다.

최종적인 모습은 다음과 같다.

이제 재부팅을 한 후에 네트워크가 잘된다면 끝난다.

kubeadm join 시 discovery-file 이용하기

새로운 Worker 노드를 추가하기 위한 문법은 대략 다음과 같다.

그런데, token 값은 시간이 지나면 만료되 사용할 수 없게 된다. 설사 token 을 알아도 ca-cert-hash 값을 알아야 한다. 이를 위해서 K8S 의 루트 CA 인증서를 이용해 hash 값을 알아내는 명령어를 사용한다.

Discovery-file 만들기

하지만 이 방법외에도 discovery-file 을 이용하는 방법도 있다. 이는 kube-public 네임스페이스에 ConfigMap 에서 cluster-info 의 정보를 가지고 오면 된다. 다음과 같다.

위 파일을 추가하고자 하는 새로운 Worker 노드에 복사해준다.

Discovery-file 을 이용한 새로운 Worker 노드 추가

이제 discovery-file 를 이용해 새로운 Worker 노드를 추가할 수 있다. 다음과 같다.

CSR Approved

이렇게 한 후에 csr 을 보면 pending 상태의 인증서들이 보인다. 이를 Approved 해주면 된다.

쿠버네티스, 새로운 Worker 노드 Join 시 토큰 값 확인하기

쿠버네티스(Kubernetes) 를 운영하다가 새로운 Worker 노드를 추가할때에 kubeadm 명령어와 함께 join 옵션을 함께 쓴다. 이때 token 값과 hash 값을 줘야 하는데, 최초 설치할때에 값을 출력해주지만 시간이 지나서 잃어버리면 어떻게 해야 할까..

Token 확인

불행하게도 Token 값은 영구적이지 않다. 어디다 잘 적어놨어도 시간이 지나면 자동으로 폐기되도록 되어 있다.

아무것도 안나온다. 이는 자동 폐기 됐기 때문이다.

Token 생성

Token 값을 확인할 수 없다면 새로운 worker 노드를 추가할 수 없다. 아니, 정확하게는 Token 값을 이용해 추가할 수 없다. Token 값을 이용하기 위해서는 새로운 Token 값을 만들어 주면 된다.

위와같이 새로운 토큰이 생성되었다. 만료일이 기재되어 있어 이 기간동안만 유효하다.

AWS CloudFront 인증서는 ACM eu-east-1 에서 해야 한다

AWS CloudFront 인증서는 ACM eu-east-1 (N. Virginia) 에서 발급 받아야 한다. 왜냐하면 CloudFront 때문인데, CloudFront 의 메인 리즌이 eu-east-1 로 되어 있어서 다른 리즌에 발급받은 인증서는 CloudFront 에서 사용할 수 없게 된다.

Q: 어느 리전에서 ACM을 사용할 수 있나요?

AWS 서비스를 사용할 수 있는 현재 리전을 확인하려면 AWS 글로벌 인프라 페이지를 참조하세요. Amazon CloudFront에서 ACM 인증서를 사용하려면 미국 동부(버지니아 북부) 리전에서 ACM 인증서를 요청하거나 가져와야 합니다. CloudFront 배포와 연동되어 있는 이 리전의 ACM 인증서는 해당 배포에 대해 구성된 모든 지리적 위치에 배포됩니다.

Windows, x509: certificate signed by unknown authority 오류 해결

윈도우즈(Windows) 에서 개발을 할때에 사설 인증서를 사용한 서버에 접속하게 되면 제목과 같이 인증서 오류가 발생한다. 사설 인증서를 사용한 서버에 인증을 위해서는 Root CA 인증서를 내장하고 있어야 한다. Root CA 인증서는 공개키를 가지고 있고 이를 사용해서 서버에 사설 인증서에 내장된 해쉬값과 인증서명을 해독한다.

인증서 추가

윈도우즈(Windows) 도 이제는 인증서를 시스템에서 다룬다. 과거에는 브라우져에서 다루었지만 이제는 시스템에서 통합해 다루도록 변경되었다.

인증서를 추가하는 방법은 다양하지만, certutil.exe 커맨드 라인을 사용하는게 쉽다. certutils.exe 는 인증서 추가는 물론 파일의 해쉬값도 구할 수 있는 기능도 있다.

다양한 인증서 추가

certutil.exe 를 이용하면 다양한 인증서를 추가할 수 있다. 여기서 다양한 인증서는 Root CA 인증서, Intermediate 인증서, Server 인증서를 말한다. 이것을 구분해서 certutil.exe 를 사용해야 한다.

Root CA 인증서 추가

다음과 같이 Root CA 인증서를 추가 할 수 있다.

Root CA 인증서는 각 브라우져에 탑재되어 있는 것으로 공개키가 내장되어 있다. 모든 인증서는 Root 인증기관에서 암호화를 하는데, 인증기관에서 인증된 모든 인증서는 인증기관의 Root CA 인증서로 해독이 가능해 진다.

사설 인증서 관련해서 x509: certificate signed by unknown authority 오류가 발생하는 것은 사설 인증서를 받아서 해독을 할 수 없는 경우임으로 Root CA 인증서를 가지고 있으면 해독이 가능해진다. 따라서 제목의 문제 해결은 Root CA 인증서를 추가하면 된다.

혹은 클라이언트 인증서를 활용해도 문제는 해결되지만, 시스템에 설치되는 인증서는 Root CA 인증서임으로 클리이언트 인증서는 특정 애플리케이션에서 활용된다.

인터미데이트 인증서 추가

인터미데이트 인증서는 루트 인증기관에서 인증한 중간의 인증기관에 배포되어 인증이된 인증서를 말한다. 인증서는 3단계 인증서가 존재하는데, 루트 인증기관의 루트 인증서, 중간자 인증기관의 인터미데이트 인증서, 최종적으로 사용자 인증서다.

루트 인증기관의 인증서는 인터미데이트, 사용자 인증서 모두를 해독할 수 있다. 인터미데이터 인증서가 만들어진 이유는 중간에 카테고리를 하나 더 둠으로 인해서 인증서 유출에 따른 파급력을 줄이려는 의도다. 모든 사용자 인증서를 루트 인증기관으로부터 인증을 받은 상태에서 루트 인증서가 유출되면 그 파급력은 매우 크게 된다. 이를 쪼개기 위한 방안으로 인터미데이트 인증서가 필요해졌다.

재미있는 것은 인터미데이트 인증서는 보통 Root CA, Server 인증서를 모두 가지고 있다. 파일을 열어보면 인증서가 3개가 담겨 있는 경우가 대부분이다.

사용자 인증서 추가

윈도우즈 메뉴얼에는 사용자 인증서라고 되어 있는데, 이게 클라이언트 인증서인지 서버 인증서인지는 모르겠다. 추가하는 방법은 다음과 같다.

로컬 머신 인증서 관리 코솔(Certificate Local Machine)

로컬 머신 인증서 관리 콘솔이 있다. certlm.msc 명령어를 이용하면 되는데, 관리자 권한을 요구한다. 이는 시스템 와이드 적용이 되는 것으로 전체 사용자에게 영향을 준다.

Root CA 인증서를 추가된 것을 확인해 볼 수 있다.

사용자 인증서 콘솔(Certificate Manager)

사용자 인증서 관리 콘솔이 있다. 이는 아마도 개인 계정 범위내에서 사용되는 것을 보인다. certmgr.msc 로 실행해 확인해 볼 수 있다.

인증서 삭제

인증서 삭제는 관리 콘솔에서 가능하다.

Gitlab, CI/CD 변수가 사용되지 않을때

Gitlab 에서 Settings -> CI/CD -> Variables 에서 CI/CD 에서 사용가능한 변수를 지정할 수 있다. 여기서 지정한 변수는 CI/CD 에서 활용되며 CI/CD 진행할때 운영체제의 환경변수로 자동 지정된다. 따라서 빌드시에 운영체제에 환경변수를 활용하고자 한다면 여기서 변수를 설정하면 된다.

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 등은 운영체제 환경변수로 지정하면 AWS API 통신이 가능해진다. 소스코드에 하드코딩하는 것보다야 낫다.

Merge Request Pipeline 에서 변수가 활용 불가 문제

그런데, Merge Request Pipeline 에서는 이 변수가 적용되지 않았다. TF_USERNAME 이 적용되어야 하는데, 적용되지 않았다.

이는 CI/CD 변수의 Protect 기능 때문이다. 위에 스크린샷을 보면 변수 아래에 Protected 라고 적혀 있다. Gitlab 문서에는 다음과 같이 기술 되어 있다.

Protect a CI/CD variable

You can configure a project, group, or instance CI/CD variable to be available only to pipelines that run on protected branches or protected tags.

Merged results pipelines, which run on a temporary merge commit, not a branch or tag, do not have access to these variables.
Merge request pipelines, which do not use a temporary merge commit, can access these variables if the branch is a protected branch.

이런 제약을 없애기 위해서는 Protect 를 해제 하면 되는데, 변수 설정에서 체크 박스를 해제하면 된다. 기본값은 체크박스 체크된 상태이다.

“Protect variabe” 체크를 해제해주면 된다. 이렇게 되면 protected branches, protected tags 가 아니여도 변수가 적용된다.

Gitlab, Docker 빌드시 x509: certificate signed by unknown authority 오류 해결

Gitlab 은 CI/CD 를 내장하고 있다. 이는 Gitlab-runner 를 통해서 이루어진다. gitlab-ci.yaml 파일을 이용해 CI/CD 명세를 작성하면 Gitlab-Runner 가 이 파일을 읽어 실행해 준다. Gitlab-Runner 에는 타입이 존재하는데, docker 로 할 경우에 Docker 를 이용해서 CI/CD 를 진행하게 된다. 다시말해서, Docker 를 이용해서 Container 안에서 빌드, 테스트, 배포가 이루어진다는 것이다.

Private Certificate

문제는 사설 인증서다. Docker 컨테이너내에서 외부 접속을 하기 위해서 HTTPS 통신이 필요한데, 하필이면 HTTPS 가 사설 인증서를 사용한 것이라면 다음과 같은 오류가 발생한다.

Docker 컨테이너 안이라 사설 인증서에 대한 인증서를 붙여놔야 하는데, 어떻게 해야하는 문제가 있다.

Self-signed certificates or custom Certification Authorities

다음의 Gitlab 문서에 이에 대한 내용이 나와 있다.

Self-signed certificates or custom Certification Authorities

문서가 조금 부족한 감이 있는데, 두가지 절차가 필요하다.

Gitlab-Runner 에 볼륨 마운트

Pipeline 에서 사용할 Gitlab-Runner 에서, 당연히 Docker 타입, 볼륨 마운트 설정을 해준다. 이 설정은 Docker 명령어의 -v 옵션과 동일하다. 볼륨 마운트를 할때에 ca.crt (Root CA 인증서) 파일을 마운트 해준다.

Pipeline 이 실행되고 Docker 컨테이너가 시작되면 설정한 볼륨을 마운트 해준다. 그러면 Docker 컨테이너 내에 /tmp/ca.crt 파일이 존재하게 된다.

이제 Docker 컨테이너에 ca.crt 파일을 설치해주면 된다.

gitlab-ci.yaml 에 job 내에 ca.crt 설치

이제 gitlab-ci.yaml 파일에 job 내에 ca.crt 를 설치해 준다. 다음과 같다.

위 내용은 Alpine 이미지를 사용할 경우, ca.crt 파일을 설치하는 방법을 기술한 것이다. 아래 두번째에 보면 Gitlab-Runner 설정에서 마운트 되었던, /tmp/ca.crt 파일을 Alpine 이 CA 설정 디렉토리로 복사해주고 있다.

이렇게 하면 build 단계에서 인증서를 설치하게 된다.

결론

Gitlab-Runner 를 사용하다보면 대부분 Docker 기반으로 빌드,테스트,배포를 하게 된다. Shell 타입도 Docker 기반일 경우에 별도의 프로그램 설치와 설정이 필요 없기 때문이다. 하지만 사설 인증서를 사용할 경우에 통신이 되지 않을 수도 있는데, 위와 같은 방법으로 해결 할 수 있다.

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 를 설정해서 사용하고 있다는 것을 알 수 있습니다.