아이패드에서 프로그래밍 공부를 해보고자 여러 어플을 찾아봤습니다. 파이썬 같은 경우는 적당한 유료 어플이 있었지만 VSCode와 같은 무료면서 강력한 기능을 가진 어플은 없었습니다.
다양한 방면으로 찾아보던 중 Code Server라는 기능을 사용하면 웹 브라우저에서 VSCode의 기능을 이용할 수 있다고 하여 사용하는 방법에 대해 포스팅합니다.
1. Code server란?
Run VS Code on any machine anywhere and access it in the browser.
* Code on any device with a consistent development environment * Use cloud servers to speed up tests, compilations, downloads, and more * Preserve battery life when you're on the go; all intensive tasks run on your server
🔔 code-server is a free browser-based IDE while Coder, is our enterprise developer workspace platform. For more information, visit Coder.com
Ubuntu Jenkins에서 docker build시 Docker permission denied 문제를 수정하는 방법에 대해 알아봅니다.
1. 문제
Ubunto 20.04에 설치된 Jenkins 2.317 버전에서 docker build시 다음 에러 메시지와 함께 permission denied 에러가 발생합니다.
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/build?buildargs=%7B%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&shmsize=0&t=my-app%3Alatest&target=&ulimits=null&version=1": dial unix /var/run/docker.sock: connect: permission denied
2. 원인 및 수정
jenkins 유저가 docker에 접근할 권한을 설정해야 합니다. 다음 명령을 통해 docker에 권한을 부여합니다
그리고 다시 push를 해봅니다. 사실 이 방법으로 해결되면 이 글을 읽고 있지 않을 겁니다. 다른 원인에 대해 생각해 봅시다.
3. Nginx 문제
제 경우에 해당하는 원인이었습니다. 전 Harbor를 Private registy로 사용하고 있으며 해당 서버에 Nginx를 이용해 proxy_pass를 설정해 둔 상태입니다.
또한 push명령을 직접 치기 귀찮아서 Harbor의 Repository에서 알려주는 Push Command를 복사해서 사용했습니다. 문제는 여기서 발생했습니다.
예를 들어 Harbor의 HTTPS 기본 포트를 변경해 사용하고 있다고 가정합시다. 443에서 1443으로 변경한 뒤 prepare를 통해 harbor.yml을 생성하게 되면 docker-compose.yml은 자동적으로 포트를 1443:8443으로 설정하게 됩니다. 또한 이런 식으로 설치된 Harbor는 Push command에 default port가 변경되었으므로 자동으로 1443 포트를 추가하게 됩니다.
Fluentd를 설치할 우분투 환경을 미리 준비합니다. 해당 글에선 우분투 20.04 버전을 기준으로 설명합니다.
1. 설치 전 설정.
Fluentd를 설치하기 전에 이후 단계에서 문제가 발생하지 않도록 환경을 올바르게 설정할 것을 권장합니다. 공식 문서에 따르면 NTP설정, 최대 File Descriptors 숫자 설정, 네트워크 커널 매개 변수 최적화를 먼저 수행할 것을 권고합니다.
먼저 NTP를 설정해줍니다. 정확한 현재 타임 스탬프를 갖도록 노드에 chrony, ntpd 등과 같은 NTP 데몬을 설정하는 것이 좋습니다. 이는 모든 프로덕션 등급 로깅 서비스에 중요합니다. Amazon Web Services 사용자의 경우 AWS에서 호스팅 하는 NTP 서버를 사용하는 것이 좋습니다.
다음은 File Descriptors의 최대치를 늘려줘야 합니다. 만약 td-agent 패키지를 사용하는 경우이 값은 기본적으로 설정되므로 스킵하셔도 됩니다. 이 글은 td-agent를 이용할 것이므로 변경 방법만 설명한 뒤 넘어가도록 하겠습니다. 저와 동일한 방법으로 설치를 원하시는 분은 NTP 설정만 하시고 넘겨주시면 됩니다.
다음 명령어를 통해 현재 시스템의 File Descriptors의 최댓값을 확인해 줍시다. 만약 해당 값이 1024라면 수정이 필요합니다.
$ ulimit -n
/etc/security/limits.conf 파일을 열고 다음 내용을 추가해 주세요.
$ sudo /etc/security/limits.conf
root soft nofile 65536 root hard nofile 65536 * soft nofile 65536 * hard nofile 65536
저장 후 시스템을 리부팅 시켜줍니다. 만약 systemd에서 fluentd를 실행한다면 LimitNOFILE = 65536 옵션도 사용할 수 있습니다.
Fluentd 인스턴스가 많은 고부하의 환경이라면 네트워크 커널 매개 변수 최적화가 필요합니다. 다음 구성을 /etc/sysctl.conf에 추가합니다.
전 개발용으로 사용할 예정이기 때문에 네트워크 커널 매개 변수 최적화 과정도 생략하였습니다. 만약 변경사항을 적용했다면 sysctl -p 명령을 사용하거나 노드를 재부팅해야 합니다.
2. td-agent를 이용한 fluentd 설치.
td-agent는 Treasure Data, Inc.에서 관리하는 안정적인 Fluentd 배포 패키지입니다. Fluentd에서는 설치 프로세스를 자동화하기 위해 쉘 스크립트를 제공해 줍니다. /etc/apt/source.list.d/treasure-data.list에 새 apt 저장소를 등록하고 td-agent deb 설치를 시작해 봅시다.
$ curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-focal-td-agnet4.sh | sh
뭔가 자동으로 쭉 진행 되고 위처럼 맨 마지막에 Installation complete. Happy Logging!이 찍혔다면 정상적으로 설치가 된 겁니다. 이제 데몬을 실행시켜줍시다.
$ sudo service td-agent start $ sudo service td-agent status
3. HTTP를 통해 샘플 로그 업로드 해보기.
이제 샘플 로그를 한번 올려보겠습니다. 엔드포인트의 기본 포트는 8888입니다. 다음 명령어를 통해 설정값을 조회할 수 있으며 원하시면 여기서 변경할 수 있습니다.
$ vim /etc/td-agent/td-agent.conf
이제 HTTP 엔드포인트에서 로그를 수신해 stdout으로 라우팅 해보도록 하겠습니다. 다음 명령어를 확인해 주세요. td-agent 로그의 경우 /var/log/td-agent/td-agnet.log를 참고하시면 됩니다.
요즘 개발 후 배포할 때 빠지지 않고 등장하는 주제 중 하나가 도커입니다. 도커 하면 뒤이어 따라 나오는 것이 쿠버네티스입니다. 이 글에선 쿠버네티스가 대체 무엇인지, 왜 필요한지 그리고 무엇을 할 수 있는지에 대해 알아보도록 하겠습니다.
1. Kubernetes. 쿠버네티스.
Kubernetes, 또는 쿠버네티스, 또는 간단히 "큐브(kube)"는 Linux 컨테이너 작업을 자동화하는 오픈소스 플랫폼입니다.
쿠버네티스는 컨테이너화 된 워크로드와 서비스를 관리하기 위한 이식할 수 있고, 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 지원합니다. 즉, Linux 컨테이너를 실행하는 호스트 그룹을 함께 클러스터링 할 수 있으며 쿠버네티스를 통해 이러한 클러스터를 쉽고 효율적으로 관리할 수 있습니다. 이 클러스터는 퍼블릭 클라우드, 프라이빗 클라우드 또는 하이브리드 클라우드 전체로 호스트를 확장할 수 있습니다.
이러한 이유로 쿠버네티스는 실시간 데이터 스트리밍과 같이 신속한 확장을 요하는 클라우드 네이티브 애플리케이션을 호스팅 하는 데 이상적인 플랫폼입니다.
쿠버네티스는 원래 Google 엔지니어들이 개발하고 설계한 플랫폼입니다. Google은 초창기에 Linux 컨테이너 기술에 기여(cgroups)하였으며 Google 제품이 컨테이너에서 어떻게 작동하는지 대중에게 공개하였습니다. 이는 Google의 클라우드 서비스를 구동하는 기술이기도 합니다. Google은 내부 플랫폼인 Borg를 통해 일주일에 20억 개 이상의 컨테이너 배포를 생성하고 있습니다. Borg는 쿠버네티스의 전신이었으며 수년 동안 Borg를 개발하는 과정에서 축적된 경험은 쿠버네티스 기술의 주요 원동력이 되었습니다.
2. 기술의 변화.
사실 컨테이너 기술은 최신 기술이 아닙니다. 이전부터 존재해왔었지만 불과 몇 년 전부터 도커와 함께 핫해진 개념입니다. 이와 함께 쿠버네티스도 시간이 지나면서 유용하게 되었는데 어떻게 변해왔길래 유용해졌는지 알아봅시다.
전통적인 배포 방식은 애플리케이션을 물리 서버에서 실행되는 방식입니다. 한 물리 서버에서 여러 애플리케이션의 리소스 한계를 정의할 방법이 없었으므로 리소스 할당의 문제가 발생했습니다. 예를 들어 물리 서버 하나에서 여러 애플리케이션을 실행하면 리소스 전부를 차지하는 애플리케이션 인스턴스가 있을 수 있고, 결과적으로는 다른 애플리케이션의 성능이 저하될 수 있었습니다. 이에 대한 해결책은 서로 다른 여러 물리 서버에서 각 애플리케이션을 실행하는 방법이 있었습니다. 그러나 이는 리소스가 충분히 활용되지 않는다는 점에서 확장 가능하지 않았으므로, 물리 서버를 많이 유지하기 위해서 많은 비용이 들어가는 단점이 있습니다.
그 해결책으로 가상화가 도입되었습니다. 이는 단일 물리 서버의 CPU에서 여러 가상 시스템 (VM)을 실행하는 방법입니다. 가상화를 사용하면 VM 간에 애플리케이션을 격리하고 애플리케이션의 정보를 다른 애플리케이션에서 자유롭게 액세스 할 수 없으므로, 일정 수준의 보안성을 제공할 수도 있습니다. 가상화를 사용하면 물리 서버에서 리소스를 보다 효율적으로 활용할 수 있으며, 쉽게 애플리케이션을 추가하거나 업데이트할 수 있고 하드웨어 비용을 절감할 수 있어 더 나은 확장성을 제공합니다. 가상화를 통해 일련의 물리적 리소스를 폐기 가능한(disposable) 가상 머신으로 구성된 클러스터로 만들 수도 있습니다. 각 VM은 가상화된 하드웨어 상에서 자체 운영체제를 포함한 하나의 완전한 머신으로 존재합니다.
이후 좀 더 나아가 가상화에서 격리성을 완화시킨 컨테이너 배포 방식이 도입되었습니다. 컨테이너 방식은 VM과 유사하지만 애플리케이션 간에 운영체제(OS)를 공유합니다. 그러므로 컨테이너는 가볍다고 여겨집니다. VM과 마찬가지로 컨테이너에는 자체 파일 시스템, CPU, 메모리, 프로세스 공간 등이 있습니다. 기본 인프라와의 종속성을 끊었기 때문에, 클라우드나 OS 배포본에 모두 이식할 수 있다는 장점이 있습니다.
일반적으로 컨테이너 방식의 배포는 다음과 같은 추가적인 장점을 제공해 인기가 있다고 알려져 있습니다.
빠른 생성과 배포: VM 이미지를 사용하는 것에 비해 컨테이너 이미지 생성이 보다 쉽고 효율적입니다.
CI&CD: 안정적이고 주기적으로 컨테이너 이미지를 빌드해서 배포할 수 있고 빠르고 쉽게 롤백할 수 있습니다.
개발과 운영의 관심사 분리: 배포 시점이 아닌 빌드/릴리스 시점에 애플리케이션 컨테이너 이미지를 만들기 때문에, 애플리케이션이 인프라에서 분리됩니다.
가시성은 OS 수준의 정보와 메트릭에 머무르지 않고, 애플리케이션의 헬스체크 및 그 밖의 시그널을 볼 수 있습니다.
개발, 테스팅 및 운영 환경에 걸친 일관성: 랩탑에서도 클라우드에서와 동일하게 구동됩니다.
클라우드 및 OS 배포판 간 이식성: Ubuntu, RHEL, CoreOS, 온-프레미스, 주요 퍼블릭 클라우드와 어디에서든 구동 가능합니다.
애플리케이션 중심 관리: 추상화 수준이 가상 하드웨어 상에서 OS를 실행하는 수준에서 논리적인 리소스를 사용하는 OS 상에서 애플리케이션을 실행하는 수준으로 높아집니다.
느슨하게 결합, 분산, 유연하고 자유로운 마이크로 서비스: 애플리케이션은 단일 목적의 머신에서 모놀리식 스택으로 구동되지 않고 보다 작고 독립적인 단위로 쪼개져서 동적으로 배포되고 관리됩니다.
리소스 격리: 애플리케이션 성능을 예측할 수 있습니다.
자원 사용량: 리소스 사용의 효율이 높습니다.
3. 쿠버네티스는 왜 필요할까?
컨테이너는 애플리케이션을 포장하고 실행하는 좋은 방법입니다. 프로덕션 환경에서는 애플리케이션을 실행하는 컨테이너를 관리하고 가동 중지 시간이 없는지 확인해야 합니다. 예를 들어 컨테이너가 다운되면 다른 컨테이너를 다시 시작해야 합니다. 이 문제를 시스템에 의해 처리한다면 더 쉽지 않을까요? 이게 쿠버네티스가 필요한 이유입니다. 쿠버네티스는 분산 시스템을 탄력적으로 실행하기 위한 프레임 워크를 제공합니다. 애플리케이션의 확장과 장애 조치를 처리하고, 배포 패턴 등을 제공해줍니다.
고 가용성 외에도 다른 포인트도 있습니다. 실제 프로덕션 애플리케이션은 여러 컨테이너에 걸쳐 있으며 이러한 컨테이너는 여러 서버 호스트에 배포되어야 합니다. 컨테이너를 위한 보안은 멀티레이어 구조이며 복잡할 수 있습니다. 바로 여기에 다시 쿠버네티스가 사용됩니다.
쿠버네티스는 이러한 워크로드를 위해 규모에 맞는 컨테이너를 배포하는 데 필요한 오케스트레이션 및 관리 기능을 제공합니다. 쿠버네티스 오케스트레이션을 사용하면 여러 컨테이너에 걸쳐 애플리케이션 서비스를 구축하고 클러스터 전체에서 컨테이너의 일정을 계획하고 이러한 컨테이너를 확장하여 컨테이너의 상태를 지속적으로 관리할 수 있습니다. 쿠버네티스를 활용하면 IT 보안을 한층 강화할 수 있습니다.
물론 이는 실제 환경에서 컨테이너를 사용하는 방식에 따라 달라집니다. Linux 컨테이너를 사용하는 가장 기본적인 방식은 컨테이너를 효율적이고 빠른 가상 머신으로 다루는 것입니다. 이를 프로덕션 환경과 여러 애플리케이션으로 확장하고 나면 개별 서비스를 제공하기 위해 같은 위치에 배치된 여러 개의 컨테이너를 함께 사용해야 한다는 것을 분명히 알 수 있습니다. 따라서 환경에서 컨테이너 수가 크게 증가하며 컨테이너가 누적됨에 따라 복잡성도 증가합니다.
쿠버네티스는 컨테이너를 "포드(pod)"로 분류하여 컨테이너 급증과 관련된 여러 가지 문제를 해결합니다. 포드는 그룹화된 컨테이너에 추상화 계층을 추가하므로 사용자가 워크로드를 예약하고 네트워킹 및 저장소와 같은 필수 서비스를 컨테이너에 제공할 수 있습니다. 쿠버네티스의 또 다른 부분을 사용해 이러한 포드 전체에서 부하를 분산하고 적합한 수의 컨테이너를 실행하여 워크로드를 지원할 수 있습니다.
4. 쿠버네티스는 무엇을 할 수 있나요?
사용자의 환경에서 쿠버네티스를 사용할 경우 얻을 수 있는 주요 이점은 쿠버네티스를 통해 물리 또는 가상 머신의 클러스트에서 컨테이너를 예약하고 실행할 수 있는 플랫폼이 확보된다는 것입니다. 더 넓게 보면, 프로덕션 환경에 컨테이너 기반 인프라를 완전히 구현해서 사용할 수 있습니다. 또한 쿠버네티스는 운영 작업 자동화와 관련이 있으므로 다른 애플리케이션 플랫폼 또는 관리 시스템에서 가능한 작업의 상당수를 컨테이너를 사용해 수행할 수 있습니다.
쿠버네티스를 사용하여 수행할 수 있는 작업은 다음과 같습니다.
여러 호스트에 걸쳐 컨테이너를 오케스트레이션 합니다.
하드웨어를 최대한 활용하여 엔터프라이즈 애플리케이션을 실행하는 데 필요한 리소스를 극대화합니다.
애플리케이션 배포 및 업데이트를 제어하고 자동화합니다.
스토리지를 장착 및 추가해 스테이트풀(stateful) 애플리케이션을 실행합니다.
컨테이너화 된 애플리케이션과 해당 리소스를 즉시 확장합니다.
선언적으로(Declaratively) 서비스를 관리함으로써, 배포한 애플리케이션이 항상 배포 목적대로 실행되도록 합니다.
자동 배치, 자동 재시작, 자동 복제, 자동 확장을 사용해 애플리케이션 상태 확인과 셀프 복구를 수행합니다.
DNS 이름을 사용하거나 자체 IP주소를 사용해 컨테이너를 노출시킬 수 있습니다.
컨테이너에 대한 트래픽이 많으면 네트워크 트래픽을 로드밸런싱 해 안정적인 배포가 이루어지게 합니다.
자동화된 롤아웃과 롤백을 지원합니다.
실패한 컨테이너를 다시 시작하고 교체하며 응답하지 않는 컨테이너를 죽이고 서비스를 새로 준비합니다.