Docker, Kubernetes 네트워크

인터넷 검색을 하다보면 Docker, Kubernetes 네트워크에 관한 글이 많이 보인다. 기본적인 이론에서부터 응용까지 잘 설명된 글들이 꽤 많은데, 나는 눈에 보이는 상태를 한번 살펴보기로 했다.

Docker 네트워크

Docker 를 처음 설치하면 어떤 상태일까? 먼저 Docker 를 설치한 리눅스 시스템의 네트워크 상태는 다음과 같다.

docker0 라는 네트워크 인터페이스가 생성되면서 172.17.0.1/16 아이피가 할당되었다. 그리고 이 인터페이스는 Bridge 다.하지만 인터페이스는 DOWN 상태다. Docker 를 막 설치하고 난 후에 이런 모습이다.

Bridge 상태는 다음의 명령으로 확인이 가능하다.

nmcli 를 보면 TYPE 에 bridge 라고 나온다. 그리고 이 docker0 인터페이스는 docker 네트워크에서 Bridge 네트워크에 해당한다고 다음과 같이 확인해 볼수 있다.

“com.docker.network.bridge.name”: “docker0” 로 Docker Bridge 가 docker0 호스트 네트워크 인터페이스라는 걸 말해주고 있으며 여기에 붙은 Container 인 doc1 에 대한 정보를 보여주고 있다. doc1 컨테이너의 IP 는 172.17.0.2/16 이다.

bridge 명령어에서는 아무것도 안나온다. 이제 Docker 컨테이너를 하나 실행해 본다.

이렇게 Docker 컨테이너를 하나 생성하면 docker0 브릿지 인터페이스는 Down -> Up 상태로 변경되며 여기에 veth 가상의 인터페이스가 하나 붙는다.

“veth46d3de6@if8” 가 보인다. 이것은 필시 doc1 컨테이너가 실행되면서 생성되었을게 분명하다. 이것과 doc1 과는 무슨 상관일까?

doc1 컨테이너의 네트워크 인터페이스 eth0 는 8번이다. 그리고 if9 로 인터페이스 9번을 가리키고 있다고 명시하고 있다. 아래 호스트 네트워크 인터페이스를 보면 veth 라고 나오는데, if8 로 인터페이스 8번을 가리고 있다. 인터페이스 8번은 doc1 컨테이너의 네트워크 인터페이스를 말한다.

그러니까 네트워크 인터페이스에 번호로 서로 연관성을 보여주고 있다는 걸 알수 있다.

ip 명령어를 통해서 veth 인터페이스만 뽑아 볼 수 있다. veth 는 가상 이더넷(Virtual Ethernet) 인데, Docker 컨테이너가 생성될때마다 가상 이더넷 카드가 호스트에 하나 생성되고 이런 가상 이더넷은 Docker 컨테이너의 기본 네트워크 인터페이스 카드와 연결된다.

docker0 는 Docker 에 기본 Bridge 인터페이스이며 Docker 컨테이너가 하나도 없으면 DOWN 상태가 되며 단 하나의 컨테이너가 실행될 경우에 UP 상태로 변경되고 가상 이더넷을 생성하고 Bridge 에 붙이게 된다.

Kubernetes 네트워크

Kubernetes 를 설치하고 난후에 상태는 Docker 만 설치한 것과 동일하다. Kubernetes 는 CNI 를 설치를 해줘야 한다. CNI 는 Kubernetes 에 네트워크를 담당할 기능을 붙이기 위한 인터페이스로 다양한 네트워크 기능들을 제공하는 프로그램들이 있다.

Flannel, Weave, Calico 등등이 자주 쓰인다.

한가지 의문(?) 혹은 문제는 이 쿠버네티스 CNI 들은 구조가 모두 다르다. 테스트를 위해서 Flannel 을 사용했다.

정상적으로 설치되었다면 Flannel 이 Pod 로 올라온다. 더불어서 CoreDNS 도 정상으로 나온다.

한가지 쿠버네티스에 대해서 짚고 넘어가야 할게 있는데, 쿠버네티스는 마스터 노드라 불리는 Controller 와 워커 노드로 나뉜다. 적어도 2대의 호스트 서버가 필요하고 여기에 설치가 진행 된다.

Flannel 을 설치하고 nginx 파드(pod) 를 생성한 후에 워커 노드 상태다.

위 상태를 보면, cni0 네트워크 인터페이스가 보인다. 이는 Flannel 에서 생성한 것으로 Bridge 다.

위에 보면 Bridge 네트워크 인터페이스를 볼 수 있는데, Docker0 는 DOWN 이며 cni0 는 UP 상태다. 이 cni0 에 연결된 네트워크 인터페이스는 다음과 같이 확인할 수 있다.

이 인터페이스는 필히 nginx 파드에 것이다. master 브릿지로 cni0 를 사용하고 있다.

그러면, flannel.1 인터페이스는 대체 무엇일까? 다음의 명령어로 확인해 보자.

“vxlan id 1 local 192.168.96.39 dev enp0s3” 로컬 호스트의 enp0s3 에 연결된 vxlan 이라고 나온다.

Flannel 은 VXLAN 기반으로 호스트가 서로 다른 파드에 대한 연결을 만들어주게 되어 있다. 마스터 노드에서 다음의 명령어를 실행해 보자.

backend-type: vxlan 이라고 나오고 있으며 VTEP 도 보인다. 이 장치에 대한 Mac 주소도 나오는데, 이것은 flannel.1 에 있는것과 같다.

파드의 네트워크는 veth 장치를 통해서 패킷이 나가고 이것을 cni0 브릿지가 받는다. 그리고 flannel 이 이것을 flannel.1 장치로 보내게 된다.

이렇게 하는 이유가 있는데, Flannel 은 L2 Layer 스위치다. L2 Layer 스위치는 ARP 라우팅만 가능하다. 파드(Pod) 가 같은 호스트에 있는 경우에는 ARP 라우팅만으로 서로 통신이 가능하겠지만 호스트가 다를 경우, IP 대역이 변경될 경우에는 원격 호스트에 있는 파드를 ARP 라우팅만으로 찾을 수 없다.

그래서 Flannel 은 L3 Layer 계층의 가상의 스위칭 장비를 만들고, 이렇게 만들어진 각 호스트의 가상의 스위칭을 하나로 연결하는데 이것이 바로 VXLAN 이다. 가상의 스위칭 장비가 flannel.1 네트워크 인터페이스 이다. 이때, cni0 에서 올라온 데이터는 L2 Layer 에서 만든 프레임(Frame)으로 이것을 UDP 패킷형태로 IP 를 붙여 캡슐화 한다. 그리면 flannel.1 인터페이스는 다른 호스트와 연결된 또 다른 flannel.1 인터페이스로 브로드캐스팅을 한다.

다른 호스트로 받은 UDP 패킷은 flannel.1 장치에 의해서 까지고(디캡슐화) 자신의 네트워크 대역과 비교하는데, 맞으면 받은 프레임에 destination mac address 를 자신의 mac address 로 넣고 다시 UDP로 캡슐화해 돌려보낸다. 이렇게 함으로써 호스트가 다른 파드의 이더넷 주소(맥주소)를 얻게되어 연결이 이루어지는데, 이게 VXLAN 의 동작 방법이다.

VXLAN 는 L2 Layer 프레임을 UDP L3 Layer 로 캡슐화해 브로드캐스팅하고 목적지 맥주소를 얻는데 있다.

Flannel 은 이렇게 작동하지만 Calico 는 또 다르다. Calico 는 BGP 연결을 통해서 아예 L3 Layer 를 구현 한다. 완전한 Pure L3 Switch 기능을 제공하기 때문에 처음부터 IP 라우팅이 가능해진다. Calico 는 Tunnel.0 인터페이스를 통해서 서로 다른 호스트와 Peer to Peer 연결되어 있어서 IP 라우팅만으로 대상 호스트의 파드를 알아낼 수 있다. 그래서 동작 방법은 (Flannel 보다) 훨씬 간단하다.

메트릭 서버(Metric Server) 설치에 관한 오류들…

다양한 메트릭 서버 설치에 관한 오류들을 알아보자.

kubectl top node Error from server (ServiceUnavailable): the server is currently unable to handle the request (get nodes.metrics.k8s.io)

메트릭 서버(Metric Server) 의 파드(Pod)가 정상적으로 Running 상태라 하더라도 이와같은 오류 메시지를 만날 수 있다. 이 오류는 kube-apiserver 의 로그에 다음과 같이 관련 오류가 나온다.

뒤쪽에 삭제된 부분은 “net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)” 이다. 응답커넥션을 맺다가 안되서 timeout 으로 끝난 것이다.

이것은 kube-apiserver 다음의 커맨드 파라메터를 추가해줘야 한다.

  • –enable-aggregator-routing=true

메트릭 서버의 0.4.3 버전부터는 쿠버네티스의 Aggregator Layer 를 이용한다. API 서버가 실행중인 호스트에 kube-proxy 가 없을 경우에 위 파라메터를 추가해줘야 한다.

워커 노드 메트릭 수집 안됨

쿠버네티스의 Deployments.apps 리소스에 배포된 Metric Server 메니페스트를 다음과 같이 수정해 줘야 한다.

hostNetwork: true 를 추가해줘야 한다.

extension-apiserver 란?

쿠버네티스(Kubernetes)가 발전에 따라서 많은 변화를 겪었다. 최신의 버전에서 extension apiserver 라는 것을 필요로하는 경우가 많다. 이것은 쿠버네티스 문서에서는 aggregation layer 라고 설명하고 있다.

Configuring the aggregation layer allows the Kubernetes apiserver to be extended with additional APIs, which are not part of the core Kubernetes APIs

애그리게이션 레이어 설정은 쿠버네티스 API 코어의 일부가 아닌 추가적인 API를 가지고 확장될 수 있는 쿠버네티스 apiserver 를 가능하게 한다.

Configure the Aggregarion Layer

최근에 구축한 쿠버네티스 서버에 메트릭 서버(Metric Server) 를 설치했는데 제대로 작동되지 않아 왜 그런가 봤더니 바로 이 문제였다. 메트릭 서버 파드(Pod) 에 로그는 다음과 같다.

메시지를 보면 extension-apiserver-authentication 등의 메시지를 볼 수 있다. 문제는 이런 로그가 남는다고 해서 메트릭 서버 파드의 상태가 Running 으로 된다는 것이다. 파트 상태가 Running 이라고 해서 메트릭 서버가 정상으로 작동되는 것은 아닌게 문제의 핵심이다.

이 문제를 해결하기 위해서는 extension-apiserver 기능을 apiserver 가 가지도록 해야 한다. 이것은 kube-apiserver 에 커맨드 파라메터를 다음과 같이 추가 해주고 재시작 해줘야 한다.

요구사항을 보면 인증서가 필요하다는 것을 알게 된다. 인증서 제작은 Kubernetes Hard Way 문서에 잘 정리되어 있다. 필자는 쿠버네티스 하드 웨이 방법을 구축한 서버이기에 이 과정을 진행해 볼 수 있었다.

extension apiserver 를 위한 인증서 작성

인증서 작성은 다음과같이 CSR 파일을 작성함으로서 시작된다.

여기서 주의해야 할 것이 조직(O) 를 system:masters 로 해야 하며, CN 은 –requestheader-allowed-names 파라메터의 값과 동일해야 한다. 이제 다음과 같이 인증서를 제작한다.

이제 이것을 각 master 서버에 배포를 해준다.

kube-apiserver 커맨드 파라메터 수정

배포를 모두 했다면, 이제 kube-apiserver 에 커맨드 파라메터를 수정해 줘야 한다. systemd 에 kube-apiservere 를 등록했기 때문에 유닛 파일을 수정해주면 된다.

정상적으로 구동이 되었다면 이제 메트릭 서버를 재설치하면 정상적으로 작동 된다.

AWS CloudFormation 보안 모범 사례

이 문서는 다음의 내용을 번역한 것입니다.

AWS CloudFormation을 사용하면 개발자와 시스템 관리자가 AWS와 연관된 리소스 모음을 질서있고 예측 가능한 방식으로 프로비저닝하고 업데이트하여 쉽게 생성하고 관리 할 수 ​​있다. 우리의 많은 고객들은 그들의 AWS 환경에서 변경사항을 간단하게 캡쳐하고 버전 제어를 실행하고 인프라에서 다른 작업 중에서도 비용을 관리하는 등에 모든 리소스를 제어하기 위해 CloudFormation 을 사용한다.

고객들은 자주 어떻게 CloudFormation 스택에 허가권을 제어하는 우리에게 묻는다. 이 글에서, 우리는 CloudFormation 에 대한 AWS Identity 와 IAM 정책을 사용, CloudFormation 에 특화된 IAM 조건 그리고 CloudFormation 스택 정책들을 포함하는 몇가지 모범사례를 공유한다. 대부분의 CloudFormation 배포는 AWS CLI 나 SDK 를 통해서 이루어지기 때문에 우리는 모범 사례를 어떻게 구현하는지 보여주기 위해서 AWS CLI 와 SDK 사용에 포커스를 둘 것이다.

IAM 을 통한 CloudFormation 스택 접근 제한

IAM 을 통해서, 여러분은 정책이나 사용자 혹은 롤(role) 을 사용함으로써 AWS 서비스나 리소스 접근을 보안적으로 통제할 수 있다. CloudFormation 은 fine-grained(세분화된) 액세스 제어를 제공하기 위해서 IAM 을 지렛대로 사용한다.

모범사례를 통해서, 우리는 최소 권한 원칙을 적용된 IAM 정책들을 통해 AWS 서비스 및 자원 접근을 제한하기 권한다. 이것을 하는 가장 단순한 방법은 CloudFormation 에 특정 API 콜을 제한하는 것이다. 예를들어, 여러분은 특정 IAM 유저나 롤이 CloudFormation 스택을 삭제하거나 업데이트하길 원하지 않을 것이다. 다음의 단수한 정책들은 모든 CloudFormation API 접근을 허용하지만 여러분의 프로덕트 스택의 UpdateStackDeleteStack API 접근은 거부한다.

IAM 정책은 종종 특정 리소스를 생성할 수 있도록 허용해야 하지만 이러한 리소스를 CloudFormation의 일부로 생성하지 않을 수 있다. 이것이 CloudFormation 의 IAM 조건 지원이 제공된다.

CloudFormation 을 위한 IAM 조건

다음은 여러분의 IAM 정책에 추가할 수 있는 세가지 CloudFormation 특화된 IAM 조건들이다.

  • cloudformation:TemplateURL
  • cloudformation:ResourceTypes
  • cloudformation:StackPolicyURL

이러한 세가지 조건을 통해서, 여러분은 특정리소스 생성, 업데이트, 특정 템프릿 사용등과 같은 스택 작업을 API 로 가능해지거나 스택 업데이트 중에 의도하지 않게 업데이트나 삭제가 될수 있는 스택 리소스를 방지하는 스택 정책을 사용해 특정 리소스를 제한할 수 있다.

Condition: TemplateURL

첫째 조건, Condition: TemplateURL, 생성, 업데이트, reside 등과 같은 스택 작업에 대해 CloudFormation 템플릿을 지정하도록 하고 그것만 사용하도록 강제한다. IAM 정책에서, 다음과 같다.

첫번째 구분은 지정된 템플릿에 한해서 모든 CreateStack 과 UpdateStack API 콜을 활성화 한다. 두번째 구분에서 모든 CreateStack 이나 UpdateStack API 콜들은 TemplateURL 파라메터를 반드시 포함하도록 한다. CLI 에서 여러분의 호출들은 –template-url 파라메터를 포함해야 한다.

Condition: ResourceTypes

CloudFormation 은 IAM 정책을 통해서 템플릿 생성, 업데이트에 리소스 타입을 제어할 수 있도록 해준다. CloudFormation API는 ResourceTypes 파라메터를 받는다. API 호출에서, 생성이나 업데이트할 수 있는 리소스 유형을 지정할 수 있다. 하지만, 새로운 ResourceTypes 파라메터를 사용하기 위해서는 다음과 같이 컨디션 조건을 추가함으로서 특정한 파라메터 사용이 가능하도록 IAM 정책을 수정할 필요가 있다.

CLI 에서, 여러분의 호출은 –resource-types 파라메터 포함할 필요가 있다. 여러분의 스택을 업데이트하기 위한 호출은 다음과 같다.

쉘(Shell)에 따라서 명령어는 쌍따옴표를 사용해야할 수도 있다. 그렇지 않으면 “No JSON object could be decoded” 에러를 보게 될 것이다.

ResourceTypes 조건은 CLI 나 API 호출을 통해서 CloudFormation 이 올바른 리소스 타입과 템플릿을 생성, 업데이트 하도록 합니다. 첫번째 예제에서, 우리의 IAM 정책은 AWS::IAM 리소스를 포함한 예제였기 때문에 API 호출을 차단했을 것이다. 만약 우리의 템플릿이 오직 AWS::EC2::Instance 자원만 포함한다면, CLI 명령어는 다음과 같을 것이며 성공할 것입니다.

세번째 조건은 StackPolicyURL 조건이다. 어떻게 동작하는지 설명하기 전에, 우리는 스택 정책에 대해 몇가지 추가적인 컨텍스트를 제공할 필요가 있다.

Stack Policies

가끔, 최악의 운영 중단은 의도되지 않은 리소스에 변경으로 발생 된다. 이 리스크를 완화하는데 도움이 되기 위해, CloudFormation 은 스택 정책들을 제공는데 이것은 스택 업데이트 중에 의도치않은 업데이트나 삭제로부터 스택 리소스들을 보호해준다. IAM 과 함께 사용할 경우, 스택 정책들은 스택 리소스에 대해 악의적이고 의도치않은 변경 모두에 대해 두번째 방어 계층을 제공 한다.

CloudFormation 스택 정책은 스택 업데이트 작업의 일부로 업데이트할 수 있는 항목을 정의하는 JSON 문서다. 정책을 지정하거나 업데이트하기 위해서, 여러분의 IAM 사용자 혹은 롤(Role)은 반드시 우선적으로 Cloudformation::SetStackPolicy 액션을 호출 할 수 있어야 한다.

여러분 스택에 직접 스택 정책을 적용한다. 주의해야할 것은 이것은 IAM 정책이 아니다. 기본적으로, 스택 정책 설정은 명시적으로 Allow 지정하지 않는 한 업데이트를 거부하기 위해 Deny 를 사용해 모든 스택 리소스들을 보호한다. 이것은 만약 오직 몇가지 리소스들만 제한 하길 원한다면, 리소스 “*” 를 사용해 Allow 를 포함으로써 모든 업데이트를 반드시 명시적으로 허용해야 하며 특정 리소스를 Deny 해야 한다.

예를들면, 스택 정책은 라이브로 진행되는 데이터를 포함하고 있기 때문에 프로덕션 데이터베이스를 보호하는 데 종종 사용된다. 변경중인 필드에 따라 업데이트중에 전체 데이터베이스를 교체할 수 있는 경우가 있다. 다음의 예제는, 스택 정책은 명시적으로 프로덕션 데이터베이스 업데이트 시도를 거부한다.

여러분은 모든 RDS DB 인스턴스나 주어진 ResourceType 을 포함하도록 여러분의 스택 정책을 일반화 할 수 있다. 이것을 얻기 위해서는 컨디션 사용한다. 그러나, 우리의 예제는 와일드카드를 사용했기 때문에, condition 은 반드시 “StringEquals” 이 아닌 “StringLike” condition 을 사용해야 한다.

스택 정책에 대한 보다 많은 정보는  Prevent Updates to Stack Resources 참고하라.

마지막으로, 여러분의 모든 스택에 알맞은 미리 정의된 스택 정책을 가지고 있는지를 확인해라. 이것을 해결할려면 IAM 정책을 봐야 한다.

Condition:StackPolicyURL

여러분의 IAM 정책 내에서, 여러분은 모든 CloudFormation 스택이 StackPolicyURL 조건을 가지고 생성된 것과 연결된 스택 정책을 가지는지를 확인할 수 있다.

이 정책은 SetStackPolicy 가 호출될때마다 반드시 스택 정책 URL 이 지정되어 있는지 확인한다. 이 경우에, URL 은 https://s3.amazonaws.com/samplebucket/sampleallowpolicy.json 다. 유사하게, 모든 생성과 업데이트 스택 연산에서, 이 정책은 StackPolicyURL 은 S3 에 sampledenypolicy.json 문서로 지정되었고, StackPolicyURL 은 항상 지정된다. CLI 에서 create-stack 명령어는 다음과 같다.

주의해야 할 것은 만약 스택 업데이트에 새로운 스택 정책을 지정한다면, CloudFormation 은 이미 있는 스택 정책을 사용한다. 새로운 정책은 오직 이후 업데이트에만 새 정책을 사용한다. 예를들어, 현재 정책이 모든 업데이트를 거부하도록 지정되어 있다면, 딱 한개 업데이트를 허용하기 위해서 스택정책을 변경할려면 반드시 SetStackPolicy 명령어를 실행해야 한다. 그리고 여러분은 스택에 대해서 업데이트 명령어를 실행할 수 있다. 이미 생성된 스택 업데이트를 위해서 다음과 같이 실행 할 수 있다.

그리고 업데이트를 실행할 수 있다.

우리가 사용하는 IAM 정책은 스택이 생성 혹은 업데이트 될때마다 스택에 적용되어질 특정한 스택 정책을 보장한다.

Conclusion

CloudFormation 은 연관된 AWS 리소스를 생성, 관리하는 반복적인 방법을 제공한다. IAM 정책, 사용자, 롤, CloudFormation-specific IAM condition, 스택 정책을 조합해 사용함으로써, 여러분은 CloudFormation 스택을 의도한데로 사용하고 잘못된 업데이트, 삭제를 최소할 수 있다.

You can learn more about this topic and other CloudFormation best practices in the recording of our re:Invent 2015 session, (DVO304) AWS CloudFormation Best Practices, and in our documentation.

AWS EKS 클러스터 셋업

How to setup

AWS 의 EKS Cluster 를 셋업할 수 있는 방법에는 다음과 같다.

  • AWS Management Console
  • eksctl utility provided by AWS
  • IaC (Terrform, Ansible)

여기서는 AWS Management Console 를 이용한 방법을 사용할 것이다.

Prerequirement

AWS 를 사용하기 위해서는 권한이 있어야 한다. 다음과 같은 권한이 일단 필요하다.

  • AWS Account with Admin Privileges
  • AWS Cli Access to use Kubectl utility
  • Instance (To manage cluster by using Kubectl)

AWS 계정은 될수 있는한 관리자 권한이 필요하다.

Create IAM role for EKS Cluster

EKS Cluster 를 위한 IAM를 생성해야 한다. 이것은 IAM 서비스에서 역할(Role) 을 이용해서 생성한다.

각각의 허가권(Permission) 을 설정할 필요 없이 사용사례선택에서 EKS – Cluster 를 선택하고 Role 이름을 설정하면 끝나게 된다.

다음으로 일반 사용자가 이 Role 을 위임받을 수 있도록 신뢰관계를 맺어준다.

systemv 사용자에 대해서 신뢰관계를 만들어 줬다.

Create Dedicated VPC for the EKS Cluster

VPC 를 생성해야 하는데, 하나하나 생성할 수도 있다. 하지만, EKS 를 위해서 AWS 는 CloudFormation 템플릿을 제공하고 있다. 이 정보는 다음의 링크를 통해서 확인할 수 있다.

위 내용을 보면 S3 에 CloudFormation 용 템플릿을 제공한다. 이를 이용하면 손쉽게 VPC 를 생성할 수 있는데 생성되는 리소스는 대략 다음과 같다.

  • 퍼블릭 서브넷 2개, 모든 서브넷에는 로드밸런서 할당을 위해 태그가 지정된다.
  • 엘라스틱 IP 할당.
  • 프라이빗 서브넷 2개, 모든 서브넷에는 내부 로드밸러서 할당을 위해 태그가 지정된다.
  • NAT 게이트웨이 1개
  • 모든 인바운드 트래픽을 차단하고 아웃바운드 트래픽을 허용하는 보안그룹.

AWS EKS 는 Master Node, Worker Node 로 구성되는데, Master Node 는 Managed 서비스이며 이것은 퍼블릭 서브넷이 필요하게 된다. Worker Node 는 EC2 인스턴스에 Docker 가 설치되며 EKS 에 의해서 제어된다. 이것은 프라이빗 서브넷이 필요하게 된다.

모든 인바운드 트래픽은 차단되고 아웃바운드 트래픽을 허용하기 위해서 NAT 게이트웨이가 설치가 된다.

CloudFormation 을 이용해 이런 제반사항들을 손쉽게 만들 수 있다.

AWS EKS 생성을 위한 CloudFormation 스택 이름 변수 정하기
AWS EKS 생성을 위한 CloudFormation 스택 이름 변수 정하기

스택이름만 쓰고 나머지는 그냥 기본적으로 제공하는 값을 사용해도 된다. 다음화면에서 태그나 기타 필요 옵션등을 선택할 수 있는데, 아무것도 안하고 넘어가도 된다.

CloudFormation 을 이용한 AWS EKS VPC 생성완료
CloudFormation 을 이용한 AWS EKS VPC 생성완료

생성된 자원들을 보면 어떤 것을 생성했고 어떻게 연결을 했는지도 눈에 보인다. SecurityGroup 은 ControllPlane 에 접근을 위해서 만들어졌다.

Login AWS Account for creating Cluster

앞에 CloudFormation 작업은 AWS Root 계정으로 진행 된다. 어짜피 네트워크 작업이며 이를 제어하기 위한 퍼미션만 사용자가 가지고 있어도 되기 때문이다. 하지만 서비스는 다르다. 서비스는 Role 기반으로 작동되는 경우가 많아 반드시 일반 계정으로 생성을 해야 한다.

만일 AWS Root 계정으로 EKS Cluster 를 생성할 경웨 피고한 경우가 생길 수 있다. 따라서 반드시 일반 계정으로 로그인을 해준다. 그 계정에 다음과 같은 정책을 생성해 준다.

EKS Cluster 를 위한 권한이 대부분 다 들어 있다.

Create EKS Cluster

이제 네트워크 환경이 모두 구성됐으니 EKS Cluster 를 만들어야 한다. AWS 콘솔에서 EKS 를 검색해 서비스로 이동하면 된다.

AWS EKS Cluster 기본정보 입력
AWS EKS Cluster 기본정보 입력

Kubernetes 버전은 최신버전으로 했지만, 실제 서비스 운영은 기본값을 사용하길 권장한다. 클러스터 서비스 역할에는 맨처음에 만들었던 역할을 지정해 주면 된다.

AWS EKS Cluster 네트워킹 지정
AWS EKS Cluster 네트워킹 지정

네트워킹은 CloudFormation 으로 생성한 네트워크를 지정해 줘야 한다.

AWS EKS Cluster 클러스터 엔드포인트 액세스
AWS EKS Cluster 클러스터 엔드포인트 액세스

클러스터 엔드포이트 액세스는 퍼블릭 및 프라이빗으로 선택한다. 그리고 Amazon VPC CNI 는 최신버전으로 선택.

AWS EKS Cluster 클러스터 로깅
AWS EKS Cluster 클러스터 로깅

CloudWatch Logs 는 비활성화해서 넘어간다. 단, 실제 서비스를 운영할때는 활성화를 해준다. 적어도 Authenticator 정도는 해준다.

Install & Setup IAM Authenticator and Kubectl Utility

설치 aws-iam-authenticator 문서를 보고 authenticator 를 설치해 준다.

AWS EKS 를 위한 kubectl 명령어를 다운로드 받는다.

설치된 Client 버전과 AWS EKS 에서 버전이 같은지 확인한다.

이제 kubectl 명령어가 사용되는지를 확인해 본다.

접속을 위한 아무런 정보가 없기 에 localhost 에 접속을 시도했다.

접속을 위한 정보를 받아서 $HOME 에 .kube/config 에 저장이 된다. 이제 잘되는지 다음과 같이 확인해 보자.

위와같이 나오면 정상이다. 만일 위와같이 나오지 않는다면 Role 를 지정해줄 수도 있다.

이렇게 했는데도 안된다면 다음의 링크가 도움이 될지 모른다.

정상적으로 작동한다면 다음과 같이 Node 는 아무것도 안나올 것이고 Namespace 는 나올 것이다.

Create IAM Role for EKS Worker Nodes

EKS Cluster 는 Kubernetes 에서는 Master 작업이 끝난것이라고 보면 된다. 아직은 Work Node 가 없다. Work Node 는 NodeGroup 으로 묶여서 생성되고 Work Node 를 위한 Role 이 필요하다.

AWS Role for EKS WorkNodes
AWS Role for EKS WorkNodes

이와 더블어서 ssm.amazonaws.com, eks.amazonaws.com 을 신뢰관계에 추가 해준다.

많은게 필요가 없다. 이제 worknode 를 위한 group 를 생성해 보자.

AWS EKS WorkGroup 생성하기 - 기본정보 입력
AWS EKS WorkGroup 생성하기 – 기본정보 입력

이름과 역할을 지정해준다. 역할은 앞에서 생성한 역할이 자동으로 나올 것이다.

AWS EKS Workgroups 생성하기 - 컴퓨터 자원 생성
AWS EKS Workgroups 생성하기 – 컴퓨터 자원 생성

서비스 운영을 위한 시스템 자원을 선택해 준다. 이 시스템 작원은 물리적인 하드웨어를 선택하는 것이다. 이 자원 위에서 Docker 를 기반으로 Micro Service 가 돌아가게 된다.

AWS EKS Workgroups 설치하기 - 네트워크 설정
AWS EKS Workgroups 설치하기 – 네트워크 설정

서브넷은 AWS EKS 를 위한 서브넷을 선택되어 있어야 한다. 노드에 대한 액세스가 필요할 경우에 해주면 되고 보안 그룹은 기본보안 그룹(22 port 만 열려 있다)을 선택해 줬다. 서비스를 운영할때에는 적절하게 바꿔준다.

생성이 완료되면 다음과 같이 Node 가 나오게 된다.

이것이 Kubernetes 에서 Master, Work node 작업이 완료된것과 같은 AWS EKS Cluster 가 세팅이 완료가 된 것이다.


이 글은 초기버전이다. 큰 틀에서 대충 이렇게 한다는 것을 보여주는 것 외에는 깊이가 없다.

계약서를 쓰지도 않고 프로젝트 투입 – 자살골이다.

내가 적은 글을 보면 대부분이 ‘사업자’ 라고 규정하는 댓글들이 넘쳐난다. 글이 내용이 프리랜서들의 이중성을 고발하는 글이다보니, 프리랜서의 적은 사업자니까 그렇게 생각하는 모양이다.

나 아니면 적이라는 인식도 문제만, 몇자의 글로 사업자로 생각하는 흑백논리 밖에 모르는 사람들이 프리랜서를 하는 것도 큰 문제이자 프리랜서들의 권리를 찾는데 최대 걸림돌이 된다.

최근에 프로젝트를 옮기기 위해서 이력서를 여기저기 보내놨는데, 여전히 바뀌지 않는 중에 하나가 계약서 문제다.

이력서를 보고 연락을 했다고 하고 면접까지보고 언제 출근하라고까지 한것까지는 좋았지만 계약서에 대한 언급이 없었다. 더군다나 출근이 다음주 월요일, 지금은 금요일이다, 이라면 계약서를 검토할 시간조차 없다.

계약 담당자에게 연락을 하고 투입전에 계약서를 보고 싶다, 사인을 하는건 나중문제다라고 계약서를 요청했더니만 몇시간 후에..

프로젝트가 연기되서 안될거 같습니다.

원래 면접때는 3/2 출근 가능하다고 이야기를 했었는데, 업체측에서 다음주 월요일날 출근하라고 지시를 한다. 그래서 3/2 일날 출근 가능하다고 말해도 인수인계를 해야할거 있어서 다음주 월요일날에 출근을 하라는 것이다.

내가 지시하면 따르라.

갑질이라는게 결국에는 사람의 마음속에서 나오는 것이다. 나보다 내가 우월하다는 계급적의식의 본산이겠지. 면접시에 분명이 3/2 출근가능하다고 했다면 업체에서는 이것을 존중해줘야 하지만 업체가 생각은 다음과 같지 않았을까…

어짜피 놀고 있는 애니까 출근하라고 한들 뭔 대수냐..

하는 일이 없이 잠시 쉬고 있는데, 언제든 출근이 가능하지만 3/2일이 적절할거 같다는 말을 업체는

니 의견 따윌 내가 존중해줘야 하는 이유는 없다. 우리 스케줄이 중요하지.. 너는 우리 스케줄에 따라 움직여야 한다

이런 사고 방식을 엿볼 수 있는 것이였다. 더 웃긴건 면접당시에 어짜피 프로젝트는 4월달즘에 시작한다고 하니까 천천히 진행될거라고 말을 해놓고 갑자기 인수인계를 해야 하니까 다음주 2/22 에 출근을 하라고….

프리랜서의 권리는 막강하다. 업체와 프리랜서는 종속관계 계약이 아닌 상호 신의원칙에 따른 민사계약이기에 어떤 일을 진행할때에 합의를 기반을 해야 한다. 일방적으로 통보식으로 일을 진행하는 것은 지양해야 하지만 그게 될리가….

더 웃긴건 중간 계약 업체.

지금의 SI 가 문제가 되는 것이 바로 중간 계약 업체들이다. 이들 계약업체는 프로젝트를 책임질 의무가 있지만 계약만하고 중간에 몇분 돈을 띠고, 프로젝트 지시는 원청에서 하니까, 나몰라라 한다는 것이다.

SI 프로젝트를 하다보면 어떤 선을 넘는 행위를 하는 원청 업체들이 아주 많다. 갑이기에 그렇게 하는 거지만, 이랬을 경우에 프리랜서는 SI 계약업체에게 의존할 수밖에 없다. 하지만 이 중간업체는 언제나 갑의 입장에만 서기 때문에 어떤 갈등이나 문제 해결에 전혀 도움이 되지 않는다.

2/22 에 출근을 어떻게든 시키려고 온갖 노력을 다한 업체가 중간 계약 업체다. 놀면 뭐하냐… 출근해서 간단하게 인수인계 받으면 된다…. COVID-19 시대에 사람들 모여있는 곳에 빨리 오라고하는 정신나간 인간들, 아니 쌍욕을 퍼부어도 시원찮은 인간들일 뿐이다.

계약서 보여 주세요…. 나중에 보여드릴께요.

계약서는 반드시 투입전에 읽어볼 것을 권한다. 아니.. 권하는게 아니라 그렇게 해야 한다. 계약서는 프리랜서를 지켜주는 처음이자 마지막 방패다. 오직 계약서만이 법적 효력을 가진다.

그런데, SI 에서 만연한 것이 계약서를 나중에 보고 싸인한다는 것이다. 싸인은 나중에 해도 되지만 반드시 계약서는 투입전에 받아서 읽어 봐야 한다. 투입되서 일을 하고 이미 일을 하고 있는데, 계약서를 봤더니 독소조항이 가득하다면 어떻게 할건가. 그동안에 일한 것도 통째로 못 받을 수 있다.

하지만 업체는 이렇게 정당한 요구를 하는 사람들을 그져 까칠하고 성격이상자로 몰아가는 방향으로 일처리를 하고 있다는데 문제에 심각성이 있다. 한국 SI 의 정신병적인 증상이, 아니 한국인들의 병신병적 증상이 자신의 기준에 부합하지 않는다면 정심병자, 성격 이상자로 몰아간다는데 있다.

하지만 한국SI 업계에서는 그것이 마치 정상인것 마냥, 더 웃기게는 보도방이라고 불리는 거기서 영업을 뛴다는 이사놈들이 으스대고 있다는데 있다. 중간에 계약만하고 사람 투입하면 나몰라라에 원청업체에 Yes맨.. 계약서는 투입하고 나중에 싸인하자… 그러면 투입전 보여달라고 하면, 프로젝트 연기되서 없던일로…

슬픈 일이다.

이런 일이 벌어지는데에는 프리랜서들의 권익을 보호할 단체가 없다는데 가장 크다고 본다. IT 노조는 노동자들의 권익을 대변하는 곳이지 프리랜서들의 권익을 대변하는 곳은 아니다. 서울지부산하에 있는 IT 노조,,,, 민주노총 노동상담에 전화를 걸어 프리랜서라고하면 상담조차 않해주는 곳이 그곳이다.

불합리함을 알고도 투입먼저하고 계약서를 봤더니 ‘인수인계할때는 무상으로 한다’, ‘을이 프로젝트 중간에 철수할때는 받은 급여를 2/3로 제한한다’ 등의 독소조항에도 속수무책 당할 뿐이고 프리랜서들 조차도 그것이 정상이라고 생각하고 있으니…

나중에 억울해서 너무나 억울해서 민사재판을 건다고 가정해보자. 민사재판에서 판사가 가장 안타까워 하는 일은 계약서를 보지도 않고 프로젝트 투입했냐하는 부분이다. 이 말은 판사 조차도 프리랜서들의 그 부당함에 손을 들어줄 수 없다는 것을 뜻한다.

이렇게되면 프리랜서는 이제 노동자성을 인정해달라는 방향으로 선회하는데, 될리가 없다.

절대로 계약서를 쓰기전에 투입하는 무모한 행동을 하지 마시라… ‘뭐… 별 탈없이 잘 지내면 된다’ 노예의 도덕일 뿐이다. 최소한으로 지켜야하는 선이라는게 있는데, 프리랜서 계약서가 바로 그런 것이다. 법이 정한 최소한의 방어선이 계약서라는 걸 잃지 말아야 한다. 그리고 계약서는 투입전에 보여달라고 강력하게 요구하는 사람들이 점점 많아졌으면 하는데,, 그게 될리가…

한국 SI 를 망치는건 프리랜서들이다 2

이전에 한국 SI를 망치는건 프리랜서들이다 글을 달았더니 엉뚱한 댓글들이 마구 달리는 걸 보면서 모신문사에서 조사했던 독해력이 떨어진다는 글이 생각 났다.

주요 내용에 불법 소프트웨어 사용에 대한 내용을 다루기도 했지만 댓글에 그것에 대해서 이야기하는 사람들은 거의 없다. 마치 최근에 문재인 정부에 대한 정책을 비판하면 ‘너 토책왜구지?’ 하는 어뚱한 말을 하는 사람들처럼…

한국 SI 를 망치는 건 프리랜서들인건 변함이 없다. 일각에서는 능력없는 개발자들이 많다보니 그렇다고 하지만, 변명에 불과 하다. 독해력이 떨어지는 인간들이 댓글을 다는 것도 웃기지만 그것을 댓글 승인을 해주기도 그렇다고 안해주기도 그렇고 해서 아예 직설적으로 글을 한번 써보기로 한다.

의무를 다하지 않으면서 권리만 누리려는 인간 = 한국 IT 프리랜서들

권리를 주장할려거든 의무를 다해야 하는 건 상식이다. 세금을 내지 않으면서 국가로부터 온갖 해택을 다 누리려는 사람들이 비판을 받는건 당연한 것이다.

이런 유형의 인간들이 사회 여기저기에 있기는하지만 특정 직업군이 단체로 그러고 있다면 문제가 큰 것이다. 문제가 크다 못해 심각한 것이고 그러한 것들은 사회에서 도려내야하는 암적 존재에 불과할 뿐이다.

한국 IT 프리랜서들이 주장하는 건 다음과 같이 요약 가능하다.

  • 나는 경력이 5년차다. 당연히 단가 500은 받아야 한다.
  • 나는 프리랜서인데, 일을 정규직처럼 시킨다.
  • 노트북, MS Office 등 모든 걸 회사가 줘야 한다.

주로 두가지 정도로 요약이 된다. 문제는 이러한 주장이 그들이 의무와 무슨 관련이 있는지 조차도 모르는 인간들이 많다는 것이다.

프리랜서는 없다. 용역 계약자일 뿐이다.

프리랜서는 원래 없는 용어다. 법적으로는 용역 계약자라고 불린다. 대한민국에 법전을 다 뒤져봐도 용역 계약자라고만 적혀 있다. 그리고 프리랜서들이 싸인하는 계역사를 용역 계약서라고 부른다.

반면에 회사에 정식으로 취직을 할 경우에는 노동 계약자, 노동자라 한다. 그리고 그들은 회사에 노동 계약서를 작성한다.

벌써부터 차이가 난다는 걸 상기해야 한다. 법적인 적용 영역이 달라짐에 따라 이들에게 부과되는 의무 또한 달라진다는 것을 알아야 한다는 것이다.

법의 타입도 다르다. 노동법은 상법 개념이다. 하지만 용역 계약서는 민법 개념이다. 이둘의 차이를 모른다면 더 이상 이 글을 읽어 봤자 이해를 못하는 무지함만 들어낼 것임으로 여기서 그냥 멈추길 권한다.

노동 계약서는 노동법을 준용한다. 노동법에는 사용자와 노동자로 계급적 구분이 지어지는데, 노동 계약서를 작성하는 순간 노동자는 사용자에 종속되는 관계가 설정이 된다. 그래서 노동 계약서를 ‘종속관계 계약’ 이라고 불리운다.

종속관계….. 이 종속관계는 액면가 그대로 해석하면 완벽히 불평등한 현대 사회에서는 있어서는 안되는 계약이다. 한마디로 노예계약임 셈이다. 하지만 흥미롭게도 현대에 대부분의 민주주의 국가에서는 노동관계를 종속관계, 그러니까 노동자가 사용자에 귀속된 관계로 규정한다.

노동자가 일을 잘 못한다. 해고 사유가 될 수 있다. 매일 지각을 한다. 해고 사유가 될 수 있다. 지급되는 급여에 제재를 가할 수도 있다.

용역 계약자서는 민법을 준용한다. 민법은 계약 당사자간의 신의에 따른 약속에 지나지 않는다. 당사자간에 그 어떤 종속적 관계가 설정되지 않는다.

일을 못한다고 해서 계약 해지가 되지 않는다. 매일 지각한다고 해서 계약 해지사유가 되지 않는다. 계약 대금을 지급하지 않았다가는 역으로 문제가 될 수도 있다.

프리랜서가 가지는 권리

용역 계약자는 다음과 같은 권리를 가진다.

  • 근퇴관리를 당하지 않는다.
  • 특정 지역, 사무실에 종속해 근무할 필요가 없다.
  • 계약내에 일만 정해진 시간에 처리하면 그만이다.
  • 결과물을 제출할때에는 계약내에 정해진 문서, 소스코드도 함께 제출할 수 있다.

프리랜서는 일종의 사업자와 같은 동일한 직위를 갖는다.

예를들어, 자동차 회사 A 가 있다 치자. 타이어가 필요해서 타이어 공장 B 와 계약을 체결했다. 그렇다면 이 둘은 종속 관계가 아닌 민법성의 계약관계에 속한다. 자동차 회사 A 는 매달 100개, 많을때는 200까지 납품해줄 것을 요구하는 계약을 했다 치자.

타이어 공장 B 는 직원들을 고용하던 아니면 다시 프리랜서들을 채용하던 해서 타이어를 만들어야 한다. 그건 타이어 공장 B 가 알아서 할 일이다. 자동차 회사 A 가 타이어 공장 B 에게 이런 사람 뽑아라, 이래라 저래라 할 수 있는게 아니다.

계약을 맺고 보니 타이어 공장 B 가 보름이 다 되도록 공장이 돌지 않는걸 알게 된 자동차 회사 A는 타이어 공장 B에게 왜 일을 안하냐고 할 수 있을까? 안된다. 어짜피 매달 100개 타이어를 31일까지 납품만 하면 될 일이다. 납품 1주일 전에 100개를 찍어내서 납품하면 그만인 것이여서 보름동안 공장을 돌리지 않던 뭐하던 그건 타이어 공장 B가 알아서 할 일인 것이다.

자동차 회사 A 가 타이어를 만드는데 A 공장에 와서 일해라 할 수도 없는 것이다. 그건 타이어 공장 B가 알아서 할 일이고 여기서 일해라 저기서 일해라 할게 못된다는 것이다.

자동차 회사 A, 타이어 공장 B 를 IT 프리랜서에 대입해 보자.

특정 프로젝트에 지원해서 용역 계약서를 체결했다면 그 프로젝트에서 내가 해야하는 분야, 범위가 존재할 것이다. 계약 범위를 벗어나는 일을 안했다고 해서 내가 욕먹나 불이익을 받을 수는 없는 것이다.

프로젝트 기간 내내 어떤 일들이 주어질 텐데, 정해진 기간, 짧게는 일주일정도 시간이 필요해서 다음주 목요일까지 해드린다고 한다면 그때까지 결과물만 내놓으면 그만이다. 중간에 놀러가던 뭐하던 그건 문제가 되지 않는다.

휴가도 없다. 근퇴가 없다보니 휴가가 존재할 이유가 없는 것이다. 더 나가 그 사람이 성실하게 일을 사람인지, 능력이 있는 사람인지 따질 이유가 없다. 그져 돈, 그러니까 단가만 맞으면 일단 계약을 맺는 거다. 정해진 시간에 결과물만 받으면 그만인게 용역계약에 요체라고 할 수 있다.

그 누구도 법이 정한 프리랜서로 일하겠다는 사람 없다.

프리랜서들이 받는 돈을 월급이라고 부르지 않는다. 그건 용역 계약 대금이라고 부른다. 용역을 제공해 그 결과로 받는 대금인 것이다. 그래서 3.3%를 공제하는 것.

가만 들어보면 이보다 편한 곳은 없어 보인다. 근퇴 관리도 않하고 휴가도 없고.. 계약 기간내에 결과물만 돌려주면 돈은 받는 거니까.

하지만 대한민국 IT 프리랜서들 중에 이렇게 일하는 인간들 단 한명도 없다. 더 나가 이렇게 일하라고 해도 하겠다는 인간들은 존재하지 않는다.

법이 정한 기준을 따르지 않고 일을 하거나 일을 시키는 것을 불편하게 생각하고 개선하라고 정부나 사회에 요구해야 한다. IT 프리랜서들이라면 당연히 근퇴관리 부당함, 휴가 제도 부당함, 특정 사무실이나 장소를 지정하는데 부당함 등을 정부나 사회에 요구해야 한다.

하지만 그 누구도 그런 식으로 부당함을 겪고 있다고 말하는 사람은 존재하지 않는다. 그 어떤 프르랜서도 법대로 일을 하겠노라고 나서는 인간들이 없다.

왜 그렇게 주장하지 않나? 법이 정한 프리랜서들이 권리를 주장하지 않나?

당연히 주장할 수가 없다. 개인 사업자처럼 일을 혼자서 다 해야하는 지경인데, 그게 쉬울리가 없다. 그 누구도 법이 정한 프리랜서 권리를 다 지키면서 해본 사람이 거의 없다.

개인적으로 딱 2번 정도를 법이 정한 대로 한 적이 있다. 그것도 부득부득 우겨서… 그들이 보기에 내가 이상해 보일정도 였다고 한다. 다른 프리랜서들은 그렇게 말하는 그러니까 근퇴 없다, 휴가 없다, 집에서 일하고 결과물만 정해진 시간에 돌려주겠다 등 이런 것을 주장하면서 계약하자고 하는 인간이 없었다고 한다.

해보면 알게 된다고… 인간이 할 짓이 못 된다. 특히나 IT 처럼 24x7days 를 유지해야 하는 산업의 특성상 정해진 시간에만 결과물을 돌려주면 된다는 생각 자체가 모순적일 수도 있다.

예를들어, 특정 기능을 개발을 하고 컨펌을 받아 프로덕트 서버에 올렸는데 몇일 동안 문제가 없었지만 시간이 지나면서 문제가 생기기 시작했다. 하필이면 그것도 새벽에…

이럴 경우에 문제를 파악하기 위해서 문제가 발생되는 순간에 상태를 지켜보고 프로그램의 로그를 같이 봐야 하는 경우가 생긴다. 용역 계약서을 체결한 상태였기 때문에 이런 순간에 계약자가 요청을하면 봐줘야 하는 경우가 생길 수도 있다. 물론 계약서에 그런 처리를 하지 않는다고 명시해 계약하면 되겠지만 IT 특성상 그것이 쉽게 받아 들여지지 않는다. 왜냐하면 만든 사람이 문제를 제일 빠르게 파악하고 해결할 수 있기 때문에 당사자가 나서길 바란다.

이런 IT 특성때문에 법이 정한 프리랜서의 권리를 모두 충족한 상태에서 일을 할 경우에 24x7days 에 어떤 시간에만 일을 처리하기가 쉽지가 않다는데 있다.

딱 3개월 정도를 법이 정한 프리랜서로 일을 해보면 알게 된다. 인간이 할 짓이 못된다는 것… 일의 강도는 정규직 보다 프리랜서가 훨씬 쎄다.

나는 프리랜서인데, 정규직 처럼 일을 시킨다…….. 불만 가질 상황이냐..

한국의 IT 프리랜서들은 이미 이러한 것을 다 알고 있는 상황이다. 그들이 법이 정한 프리랜서들의 권리를 주장하지 않는 이유….. 개고생이 눈에 보이니까, 일이 강도가 정규직들보다 수십배는 쎄다는 것을 알고 있으니까…

그런데도 그들은 정규직처럼 일을 시킨다고 불만을 토로 한다. 그렇다고 법이 정한 프리랜서처럼 일을 하겠다고 주장하지도 않는다.

더 웃긴건 지역 노동위원회에 부당노동행위 신고를 하는 사람들이 존재하는데, 그들이 신고서에는 여지없이 근퇴, 휴가등이 들어간다. 최근 대법원의 판례들이 프리랜서 용역 계약을 한 상태에서 근퇴, 휴가등을 관리 했을 경우에 부당노동행위로 간주하고 있는 추세에 있다. 이것을 이용하는 것이지.

정리를 하면 법이 정한 프리랜서처럼 일을 하면 못하겠다고 하고 그렇다고 정규직 처럼 일을 시키면 그것도 못하겠다고 하고 하는 인간들이 한국 IT 프리랜서들이란 거다.

하나만 주장해라.. 하나만… 좋은것만 골라서 적용받기를 원하는게 인간이 할 짓이냐?

9~18시까지 일을 시키고 그 외에 긴급한 사정이 없는한 일을 안시키겠다, 휴가를 주도록 하겠다등은 프리랜서들에게 특혜를 주고 있다고 생각은 전혀 생각은 못한다. 심지여 인사평가를 받는 것도 아닌 상태인데, 이런 것을 해주는 것 자체가 특혜다.

더군다나 특정 장소를 제공까지 해주는 것도 특혜라고 생각하지 못한다. 애시당초 프리랜서는 준 사업자에 속한다. 사업자는 별도의 사업장이 있어야 한다.

프리랜서는 몸만 있으면 되는거다?

또 다른 주장은 프리랜서는 몸만 있으면 되는 논리다. 보통 프리랜서들은 노트북을 지참해 프로젝트에 투입되곤 한다. 이게 불만이라는 거다.

용역을 제공하는 사람이라 모든 장비는 업체가 제공해야 한다는 논리… 하지만 용역법 어디에도 모든 장비를 업체가 제공하라는 조문은 없다. 그야말로 민법 개념이라 계약을 어떻게 하느냐에 따라 달라지는 것이다.

업체에게 장비 제공을 요청했는데 업체가 거절했다면 계약을 하지 않으면 그만인 것이다. 그것을 장비를 제공하지 않았다고 개념없는 업체라고 까대는 인간들이 아주 많은 곳이 IT 프리랜서들이다.

그렇게 투덜대면서도 노트북 좋은게 뭐냐 문의를 또 많이 하지만, 더 웃긴건 그 좋은 노트북에 깔리는 OS, MS Office 모두 불법으로 설치된다는데 있다. 단가 500은 받아야 겠다는 사람들이 OS, MS Office 구입 비용이 아깝다는 사람들이다.

IT 에 종사하면서도 그 IT 종사자들의 피땀으로 일궈낸 결과물을 돈주고 못사겠고 불법 복제품 쓰겠다고 자랑스럽게 이야기하는 사람이 IT 프리랜서들이다. 그러면 그들은 업체가 노트북과 OS, MS Office 등을 제공해 줘야 한다고 주장한다. 바보냐..

데이터베이스를 위한 시스템 설정 – HugePage Size

Oracle, MariadB, MySQL 등과 같은 관계형 데이터베이스를 다루다보면 시스템 튜닝에 대해서 많이 접하게 된다. 특히나 리눅스 시스템에서 이들 데이터베이스 시스템이 제대로 작동하기 위한 운영체제 차원에서 필요한 작업을 많이 하게 된다.

이러한 운영체제 차원에서 작업은 여러가지가 있어서 알아야 하는 내용도 많고 세팅해야 하는 것도 많다. 대부분 인터넷이나 가이드 북을 이용해 어찌어찌 설정을 한다고 하지만 많은 사람들이 그것이 왜 필요한지 깊게 이해하는 사람들은 드물다.

그래서 아주 간단하게 데이터베이스 시스템을 다루는데 있어 리눅스 운영체제에서 필요로 하는 작업에 필요한 배경지식에 대해서 다루어 보고자 한다.

가상 메모리 관리(Virtual Memory Management)

모든 운영체제는 가상 메모리 관리 기법을 사용한다. 가상이라는 말에서 보이듯이 메모리를 가상화 한다는 이야기인데, 정확하게 말하면 실제로 물리적 메모리의 양이 정해져 있는데도 불구하고 그보다 많은 메모리를 필요로하는 애플리케이션을 구동할 수 있게 해주는 기법이다.

가상 메모리 관리 기법이 존재하기 전에는 실제 물리적 메모리 보다 많은 애플리케이션을 실행할 수 없었다. 더군다나 현대의 운영체제는 멀티 태스킹(Multi Tasking) 으로 운영되기 때문에 이들 애플리케이션 모두가 사용하는 메모리 양을 계산해보면 실제 물리적 메모리보다 많다. 그런데도 신기하게도 아무런 문제 없이 작동되는데 가상 메모리 기법 때문이다.

가상 메모리 관리에서 운영체제는 실제 주소가 아닌 가상 메모리 주소에 접근하게 된다. 하지만 실제 데이터는 물리적 메모리에 존재하기 때문에 가상 메모리 주소를 물리적 메모리로 변환해줘야 할 필요가 있다. 이렇게 가상 메모리 주소를 물리적 메모리 주소로 변환해주는 것이 MMU(Memory Management Unit) 이다.

이 MMU 는 물리적으로 CPU 내부에 존재한다. 현대의 거의 대부분의 CPU 에는 이런 MMU 가 다 있다.

MMU(Memory Management Unit)

MMU 는 가상 메모리 주소를 실제 물리적 주소로 변환해주는 것인데, 내부적으로 가상 메모리 주소와 물리적 주소를 매핑 시켜놓는 테이블이 존재한다.

일종의 매핑 테이블(Mapping Table) 인데 매핑 테이블은 가상 메모리 주소와 물리 메모리를 페이지(Page) 단위로 관리하도록 되어 있다. 쉽게 말하면 가상 메모리 주소 공간을 특정 크기 단위로 쪼갠 페이지, 실제 물리 메모리 주소를 특정 크기 단위로 쪼갠 페이지를 서로 매핑 시켜 논 것이다.

위 그림을 보면 가상 메모리, 물리 메모리가 양 옆에 있고 중간에 주소변환을 위한 페이지 맵(PAGE MAP) 혹은 테이블 이 존재한다.

MMU 느린 속도

MMU 내에 페이지 테이블이 존재는 가상 메모리를 물리 메모리로 빠르게 변환 시켜준다. MMU가 CPU 내부, 반도체 내부에 유닛으로 존재하다보니 소프트웨어에 비하면 속도가 매우 빠르다.

그런데, CPU 에서 가상 메모리에 접근할때 마다 페이지 테이블 전체를 스캔해야 한다. 그래야만 실제 데이터를 가지고 올 수 있을 테니까. 아무리 반도체 칩으로 구현되어 있어도 이렇게 데이터 접근시마다 페이지 테이블 전체를 스캔하면 아무해도 속도가 나질 않는다.

만일 페이지 테이블이 엄청나게 크다면 이 또한 속도에 영향을 준다.

느린 속도… 캐쉬가 답이다.

그래서 MMU 에 페이지 테이블 검색 속도를 높이기 위해서 중간에 캐쉬를 놓게 되었는데 이것이 바로 TLB(Translation Lookaside  Buffer) 이다.

위 그림은 가상 메모리 접근에 MMU 내부의 페이지 테이블과 TLB 가 작동하는지를 보여주는 그림이다. 간단하게 설명하면 CPU 는 무조건 TLB 를 먼저 찾는다. 캐쉬이다 보니까 필요로하는 데이터가 TLB 에 접근하면 찾을 수 있는지 검색을 하는 것이다. 만일 있다면 TLB 를 이용해서 물리 메모리에 접근하게 된다.

하지만 TLB 에 없다면 그때는 페이지 테이블을 전부 스캔하게 된다. 이렇게 페이지 테이블 스캔은 전체적으로 메모리 접근 속도에 영향을 주게 되고 전체적인 운영체제 성능에 영향을 미치게 된다.

4kb 크기의 페이지 문제

리눅스 운영체제에서 한 페이지 단위는 4kb 크기다. 만일 128GB 의 물리 메모리를 장착할 경우에 32M(약 3천 2백만) 개 정도의 페이지가 존재하게 된다. 이 많은 페이지를 페이지 테이블에 쑤셔 넣고 전체 스캔을 하게 되면 아무리 빠른 CPU라도 느릴 수밖에 없게 된다.

또한, 많은 양의 페이지는 TLB 에도 영향을 주게 된다. 너무나 많은 페이지가 존재 하다보니 캐쉬를 했던 페이지의 hit 율이 떨어져 자꾸 페이지 테이블 스캔을 하게 되는 것이다.

페이지 테이블이 페이지가 적고 캐쉬해야하는 양이 많으면 페이지 테이블를 스캔해야하는 일이 줄어든다.

HugePage 는 TLB 의 Hit 를 높여준다

Huge Page 는 기본 페이지 크기 4kb 를 크게 하는 기법이다. 이 기법을 사용하면 페이지 갯수가 줄어든다.

그런데, 많은 사람들이 페이지 크기를 늘리게 될 경우에 그 페이지가 가지는 데이터의 양을 한꺼번에 접근할 수 있어서 효율이 높아진다고 생각하는 경우가 많다. 물론 그런 영향이 없지는 않지만 Huge Page 를 하는 이유는 TLB 의 Hit 를 높여주는, 반대로 TLB 의 Miss 를 낮춰주는데 있다.

TLB 의 Hit 를 높여주면, 캐쉬 사용을 높여주면 데이터 접근이 빨라진다. 이것은 전체적인 운영체제의 메모리 성능을 높여주는 효과를 보여주게 된다. TLB Hit 를 위해서 간단한 방법이 바로 페이지 크기를 늘려주는 것이다. 4kb 마다 한 페이지가 아닌 2MB 마다 한 페이지라면 페이지 테이블 크기도 줄어들고 TLB 에 캐쉬된 페이지의 Hit 가 높아지게 된다.

Huge Page 사용 전략

HugePage 를 무턱대고 설정해서는 안된다. 일종의 전략이 반드시 필요하다.

  • OS 에서 지원해 줘야 한다.
  • 애플리케이션에서 지원해 줘야 한다.
  • 공유 메모리 설정과 연계되어 있다.

HugePage 를 사용하면 무조건 OS 상에 성능이 개선되는게 아니다. OS 에서는 당연히 사용을 하겠지만 애플리케이션에서도 HugePage 사용이 가능해야 한다.

HugePage 가 사용 가능한 애플리케이션으로 데이터베이스 시스템이 있다. PHP 와 같은 경우에도 사용이 가능하다고 한다.

무엇보다 중요한 것은 HugePage 설정은 단일 애플리케이션 시스템에 적합하다. Oracle 데이터베이스 하나만 작동하는 시스템이나 MySQL 하나만 작동하는 시스템등 여러 애플리케이션이 아니라 단일 애플리케이션만 구동하는 환경이라야 한다.

리눅스에서 HugePage 설정

MariaDB 를 위해 설정을 진행 해보자. 환경은 다음과 같다.

  • CentOS 8 64bit
  • RAM 4G
  • MariaDB 10.5.8

가장 먼저 해야할 것은 Transparent Huge Pages (THP) 설정을 never 로 바꾸는 것이다. THP 는 HugePage 를 자동으로 맞춰주는 기능인데, 성능 하락을 가져오기도 한다.

커널 파라메터를 수정하는 방법도 있지만 grub 에 부팅 옵션을 추가하는 것이 가장 간단하다.

위와같이 한 다음 재부팅을 한번 해주면 적용 된다.

현재 상태를 살펴보자. /proc/meminfo 를 보면 알 수 있다.

내용을 보면 아직 HugPage 를 사용하고 있지 않다고 나온다. 여기서 이제 계산이 필요하다. 얼마만큼 사용할 것인가, 누가 사용할 것인가 결정해야 하는 것이다.

MariaDB 를 사용할 것인데, MariaDB 를 사용하는데 있어서 InnoDB 를 사용할 것이다. InnoDB 는 Innodb pool 이 주로 메모리를 사용할 것인데, MariaDB 의 경우 물리 메모리에 약 70% 를 Inndb Pool 로 할달할 것을 권고 하고 있다. 나머지 10%는 MariaDB 자체 운영을 위해서 필요 하다. 전체 물리메모리에 약 80%에 해당한다.

df -k 했을때 나오는 전체 메모리 양이 3825740 kb(약 3.8GB) 인데, 이것에 80% 이면 3060592 kb 이다. 이것을 다시 2048 kb (한 페이지 크기) 로 나누면 1494.4296875 인데, 대략 1500 정도로 해두면 될 듯 하다.

이것을 이제 커널 파라메터로 넘겨 준다. sysctl.d 디렉토리에 파일을 만들어 별도로 관리해준다.

vm.hugetlb_shm_group 은 hugetlb 를 사용할 리눅스 시스템 그룹을 지정한 것이다.

MariaDB 에서 설정하기

시스템에서 HugePage 사용을 설정했다고 MariaDB 가 알아서 사용하지 않는다. my.cnf 서버 설정 파일에서 사용하도록 지정해 줘야 한다.

MariaDB 10.5.8 컴파일 설치

MariaDB 10.5.8 컴파일 설치를 해보도록 한다. 컴파일 설치를 위한 환경은 다음과 같다.

  • CentOS 8(x86_64) Latest version
  • 최소 설치(Minimal Installation) 환경

CentOS 8 에 최소 설치 환경이 매우 중요 하다. 최소 설치 환경이 아니라면 이 문서 내용 그대로 할 수는 없을 수도 있다.

컴파일 환경 구축

CentOS 8 을 최소설치하게 되면 패키지 저장소 또한 최소한으로 활성화가 된다. CentOS 8 은 패키지를 위한 저장소를 많이 분할해 놨는데 다음과 같다.

최소설치한 후 활성화된 저장소는 다음과 같다.

RedHat 배포판의 경우 프로그래밍 라이브러리들은 devel 패키지로 불린다. 이런 devel 패키지는 powertools 저장소에 존재한다. 따라서 이 저장소를 다음과 같이 활성화 시켜준다.

이제 컴파일을 위한 컴파일러와 라이브러리를 다음과 같이 설치 한다.

설치 작업시에 필요한 유틸리티 프로그램도 함께 설치해 준다.

Configure, Make, Install

컴파일을 위해 Configure 를 해준다. Configure 를 하기전에 소스 압축을 해제한 디렉토리에 build_target 디렉토리를 만들고 그 안에 다음의 내용을 기반으로 하는 build.sh 스크립트 파일을 작성해 준다.

build.sh 파일을 작성한 후에 다음과 같이 실행 퍼미션을 주고 실행해 준다.

아무런 오류 없이 실행이 됐다면 컴파일과 설치를 해준다.

이상 없이 컴파일과 정상적으로 설치가 되었다면 설치후 작업을 진행한다.

설치 후 작업

Mariadb 는 정상적으로 작동하기 위해서는 시스템 계정이 반드시 필요하다. 다음과 같이 시스템 계정을 생성해 준다.

계정 생성이 되었다면 이제 데이터베이스가 사용할 데이터 디렉토리를 생성해 준다.

MariaDB 의 라이브러리를 인식시켜준다.

이제 간단하게 데이터베이스를 초기화 해야 하는데, 그러기 위해서 my.cnf 파일을 다음과 같이 생성.

이제 시스템 데이터베이스를 생성해준다.

galera_recovery 파일 수정

galera_recovery 라는 명령어가 있다. 이 파일을 쉘 스크립트 파일인데, mariadb.service 파일에도 이 명령어가 사용되고 있다. 그런데, 이 파일에는 사용지로 mysql 로 하드코딩되어 있어서 오류를 낸다. 바꿔준다.

systemd 등록

Mariadb 에서는 systemd 등록을 위한 서비스 유닛 파일을 제공한다. 이 파일은 설치 디렉토리에 support-files/systemd 에 mariadb.service 파일로 존재한다. 이 파일을 열어서 mariadb 실행 계정과 그룹을 다음과 같이 바꿔 준다.

systemd 를 사용할 경우에 Max file open 갯수를 mariadb.service 에서 바꿔줄 수 있다. 물론 /etc/security/limits.conf 파일을 수정해야하는 경우도 있다.

이제 systemd 에 등록하고 활성화 해준다.

Mariadb 시작/중지

이제 제대로 설치가 되었는지 Mariadb 를 시작/중지 해보자.

아무런 에러가 없다면 정상적으로 작동하는 것이다.

Yum 패키지 충돌 발생시 쓸 수 있는 명령어

최근에 CentOS 8 에서 Kubernetes 를 테스트하던 중에 패키지 업데이트가 되지 않는 일이 발생 했다. 아직 Kubernetes 는 CentOS 8 배포판을 정식으로 지원하지 않아 CentOS 7 배포판의 패키지를 사용해야 하는 상황이다.

그런데, yum 명령어로 업데이트를 할려고 보니 오류가 발생 했다. 이럴 경우에 다음과 같은 명령어를 사용해서 의존성을 체크해 볼 수 있다.

위와같은 명령어를 이용하면 패키지 의존성에 대한 내용을 풀어서 볼 수 있다.

참고: kubeadm and kubelet 1.15 fail to install on centos 7 after patches released today#92242