Linux

Basic-Docker

오랜만의 블로깅이다.

오랜만에 글을 쓰는것은 Docker 다.

간단히 도커 설치부터 이야기를 해보겠다. 나는 Redhat 계열의 리눅스를 좋아하므로 Centos7 로 진행하려 한다.

yum 으로 도커를 설치할건데, 몇가지를 선택해야 한다.

도커를 제공하는 레포는 여러가지가 있는데, 나는 Centos 의 Extra repo를 좋아한다. 다른레포를 사용하지 않고 그냥 바로 설치 할수 있기 때문이다.

https://docs.docker.com/engine/install/centos/

다음 URL을 참고하자.

물론 최신버전과는 거리가 좀 많다. Extra repo 는 1.13버전을 제공하며, 현재 Docker-ce repo에서 제공하는 버전은 1.20다.

Docker를 사용하기 위해선 6개의 패키지가 필요하다.

[root@linuxer ~ ]# yum install -y docker

(1/6): container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm                     
|  40 kB  00:00:00     
(2/6): container-storage-setup-0.11.0-2.git5eaf76c.el7.noarch.rpm               
|  35 kB  00:00:00     
(3/6): containers-common-0.1.40-11.el7_8.x86_64.rpm                             
|  43 kB  00:00:00     
(4/6): docker-client-1.13.1-162.git64e9980.el7.centos.x86_64.rpm                
| 3.9 MB  00:00:00     
(5/6): docker-common-1.13.1-162.git64e9980.el7.centos.x86_64.rpm                
|  99 kB  00:00:00     
(6/6): docker-1.13.1-162.git64e9980.el7.centos.x86_64.rpm                       
|  18 MB  00:00:00 

docker 만 설치해도 의존성으로 도커를 사용하기위한 패키지를 설치해준다.
아이러니 하게 yum remove docker 로 삭제하면 docker는 그냥혼자 지워진다. 설치할땐 패거리로 오고 갈땐 혼자간다. 구버전이라 패키지 네이밍도 좀 올드 하다.

docker-ce repo 에서 지원하는 패키지를 확인해보면 이렇다.

[root@linuxer ~ ]# yum install -y docker-ce

(1/6): container-selinux-2.119.2-1.911c772.el7_8.noarch.rpm                      
|  40 kB  00:00:00     
(2/6): docker-ce-20.10.7-3.el7.x86_64.rpm                                       
|  27 MB  00:00:00     
(3/6): containerd.io-1.4.6-3.1.el7.x86_64.rpm                                  
|  34 MB  00:00:00     
(4/6): docker-ce-rootless-extras-20.10.7-3.el7.x86_64.rpm                      
| 9.2 MB  00:00:00     
(5/6): docker-scan-plugin-0.8.0-3.el7.x86_64.rpm                                
| 4.2 MB  00:00:00     
(6/6): docker-ce-cli-20.10.7-3.el7.x86_64.rpm                                   
|  33 MB  00:00:02     

패키지의 역할을 각각 설명하자면, docker 의 데몬을 실행하기 위한 패키지 그리고 우리가 흔히 쓰는 docker 명령어를 포함한 docker-cli, 그리고 containerd는 컨테이너를 실행하고 노드에서 이미지를 관리하는데 필요한 기능을 제공하는 OCI다. OCI는 Open Container initiative 라고 하는데 업계 표준이라 생각하면 간단하다.

패키지의 이름과 역할 분류가 조금씩 변한거다.

그럼 이제 좀 원론적인 이야기를 한번 해야겠다.

도커는 격리된 프로세스다. 도커를 실행중인 리눅스 시스템에서 아주 쉽게 알수있다.

docker run -d -p 8080:80 ngnix 명령어로 도커를 실행했다.

그리고 도커를 실행중인 호스트에서 ps 명령어를 쳤다.

[root@linuxer ~ ]# ps afxuwww

/usr/bin/containerd-shim-runc-v2 -namespace moby -id 
\_ nginx: master process nginx -g daemon off;
\_ nginx: worker process
\_ nginx: worker process

ps afxuwww 명령어에서 보기쉽게 트리만 떼온 상태다. containerd-shim-runc 데몬이 nginx를 실행중인것을 알 수 있다. 이것만으로도 컨테이너는 프로세스다. 라는것을 알수있다.

이렇기에 컨테이너는 불 안정함을 띄고 있고, 취약한 부분이 있다.

이제 도커 파일을 이야기해보려한다.

근래엔 도커파일의 사용법을 다들 잘아는 터라 Docs 로 대체한다.

https://docs.docker.com/engine/reference/builder/

근래에 내가 만든 도커파일은 이렇다.

FROM centos:7
LABEL maintainer "linuxer<linuxer@linuxer.name>"
LABEL "purpose"="practice"
ENV PATH /opt/remi/php80/root/usr/sbin:$PATH
RUN yum -y update
RUN yum -y install epel-release
RUN yum -y install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
RUN yum -y install nginx php80-php-fpm
RUN mkdir /var/run/php
RUN mkdir /root/bin
ADD www.conf /etc/opt/remi/php80/php-fpm.d/
ADD php.ini /etc/opt/remi/php80/
ADD nginx.conf /etc/nginx/
ADD index.php /usr/share/nginx/html/
ADD start.sh /root/bin/
RUN chmod 755 /root/bin/start.sh
WORKDIR /usr/share/nginx/html/
EXPOSE 80
CMD ["/bin/bash", "-c", "/root/bin/start.sh"]

ngnix와 php80 버전을 합친 Dockerfile이다.

ADD한 파일들은 직접 파라미터를 수정한터라 스킵하고 start.sh에 대해서 이야기하려한다. 일반적으로 컨테이너는 포그라운드에서 동작한다. 백그라운드에서 동착한다면 작업을 마친 프로세스는 스스로 종료된다. 여기에서 문제가 발생한다. 도커는 CMD로 시작되는 프로세스는 아무리 많이 입력 되어도 마지막 줄만 실행된다. 그렇기에 두개의 프로세스를 한번에 실행할수 없었다. 이게바로..포그라운드의 문제점이었다.

이문제점을 회피하기위해서 수십가지의 테스트를 하였다.

CMD ["php-fpm", "-f", "&", "nginx", "-g", "daemon", "off"]

이런짓까지.. 하지만 실패했고 결국 스크립트를 작성하여 실행하도록 하고 fg %1 과같은 명령어를 썼다.

[root@linuxer ~ ]# cat start.sh

#!/bin/bash
set -m
/opt/remi/php80/root/usr/sbin/php-fpm --nodaemonize \
--fpm-config /etc/opt/remi/php80/php-fpm.conf & \
/usr/sbin/nginx
fg %1

다른사람들에게 팁을 얻으려고 했으나, 안티 패턴인지 딱히 다들 말이없었다. 컨테이너이므로 쪼개 라는 대답을 얻었다. 나도 알고있는 부분인지라 사실 쪼갤까 했지만 일단 스크립트를 써서 완성을 했다.

이렇게 완성한 컨테이너 를 실행해 보면

[root@linuxer ~ ]# ps afxuwww
/usr/bin/containerd-shim-runc-v2 -namespace moby -id 4
      \_ php-fpm: master process (/etc/opt/remi/php80/php-fpm.conf)
      |   \_ php-fpm: pool www
      |   \_ php-fpm: pool www
      |   \_ php-fpm: pool www
      |   \_ php-fpm: pool www
      |   \_ php-fpm: pool www
      \_ nginx: master process /usr/sbin/nginx
          \_ nginx: worker process
          \_ nginx: worker process

두개의 부모프로세스를 가진 컨테이너를 확인할수 있다.

사실 이건 테스트 하느라 만든 방법이고 실제로는 nginx 를 lb로 이용하여 php-fpm 으로 라우팅 하는 구조를 만들꺼다. 그전에 손풀기로 만들어본 이미지 이나, 나름 재미있어서 포스팅까지 진행했다.

좋은밤되시라!

Linux-one-line-Challenge

리눅서들은 이상한 것에 집착하곤 한다.

한줄 명령어가 그 중 하나이다.

보통 그렇다. 이런 아무렇지 않은 질문으로 시작한다.

질문은 곧 챌린지가 되고 도전이 시작된다.

적당히 조언했던것이..

다른 분의 참전으로 새로운 측면을 맞이한다.

ls -lt 는 시간순 정렬이다.

대충이라고 하셨지만 골자는 이렇다. ls -ptl 은 파일의 최신순서대로 정렬해서 보여준다. 거기에 / 디렉토리를 빼고 토탈을 빼는 방식이다.

물론 이런것들이 한방에 되진 않는다.

여러 가지 조언을했지만 사실 말처럼 쉽게 되지 않는다. 그저 제한사항 들을 확인하는 것이다.

위에 내가 쓴 명령어는 안됬다.

하얀색 프로필을쓰시는 분은 초굇수다.

이제 거의 정답이 나왔다. 여기서 디렉토리만 제외하면 정답이다.

맞다 나눠서 하는것도 정답이다. 하지만, 챌린지는 그렇게 쉽지 않다. 한줄로 해야한다.

find . -type d -exec bash -c 'echo "next dir: ${1}" ; ls -lt "$1" |
    grep ^- |
    head -n 5' bash {} \;

정답이다. 그러나 더깔끔하게 하고싶었다 나는...ㅠㅠ

find /root -type d -exec sh -c "ls -lpt {} | egrep -v '^d|합계' | head -n 1" \;

나는 grep -v 로 ^d 옵션을 줘서 첫글자가 d 그러니까 디렉토리 속성일경우 제외하여 결과를 만들었다.

sh -c "find /root -type d -exec bash -c \"ls -lpt {} | egrep -v '/|total' | head -n 1 \" \;" | awk '{print $9}'

리눅스는 각자의 방법이 있다.

그런 방법들이 너무 사랑스럽다.

오랜만에 즐거운 one line Challenge 였다.

좋은하루되시라!

Linux-bashtop

bashtop&bpytop 이 핫해서 centos 7 에서 설치했습니다.

bashtop 은 bash 4.4 이상 bpytop는 python3이상입니다.
오늘 저는 bashtop를 사용해볼까 합니다.

먼저 bash 5.0을 설치 하려 합니다.

 cd /usr/local/src/
 wget http://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz
 tar zxvf bash-5.0.tar.gz
 cd bash-5.0/
 ./configure && make && make install
 mv /bin/bash /bin/bash.bak
 ln -s /usr/local/bin/bash /bin/bash
 
[root@linuxer src]# bash -version
GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)

그래서 bash 를 다운받고 컴파일 해줬습니다. 기존 bash 는 4.2 버전이라 bash.bak 으로 변경해 문제가 생기면 언제든 사용할수 있도록 만들었습니다.

yum install git
git clone https://github.com/aristocratos/bashtop.git
cd bashtop/
make install

이제 완성됬습니다.

Bashtop 의 컴파일 까지 끝났으므로 실행만 하면 됩니다.

./bashtop

레트로 게임같은 비주얼에서 매우 만족스럽습니다.

한번써보시는걸 추천해 드립니다.

감사합니다.

grep-return-NULL

if 돌려야할거 같았는데.. 아니었다.

[root@linuxer log]# grep "11111" /var/log/messages 2>&- || echo "NULL"
Dec 21 02:51:18 linuxer dhclient[3934]: XMT: Solicit on eth0, interval 111110ms.
[root@linuxer log]# grep "111111" /var/log/messages 2>&- || echo "NULL"
NULL

핵심은 오류출력을 리디렉션하여 클로즈..

2>&-

https://tldp.org/LDP/abs/html/io-redirection.html
홀스님께서 알려주신 URL이다 표준출력에서 -가 뭔지 몰랐다.

[root@linuxer log]# grep "11111" /var/log/messages 2>&- || echo "NULL"
Dec 21 02:51:18 linuxer dhclient[3934]: XMT: Solicit on eth0, interval 111110ms.
[root@linuxer log]# grep "111111" /var/log/messages 2>&- || echo "NULL"
NULL

오랜만의 리눅스 포스팅...역시 shell은 끝이없다.

terraform-provider-ncloud-review

오늘 하시코프x네이버클라우드 웨비나에서 terraform 과 Vault 에 대한 웨비나를 청취했습니다.

https://github.com/NaverCloudPlatform/terraform-provider-ncloud

이전에 방과후(?) meetup에서 네이버클라우드가 테라폼의 프로바이더로 있다는것을 알았습니다. 그 덕분에 네이버클라우드에서 terraform은 이미 경험이 있는 상태고, Vault도 경험이 있었습니다. 오늘의 주제 중 Secrets Engines이 궁금했습니다.

https://www.vaultproject.io/docs/secrets

Secrets engines are components which store, generate, or encrypt data.

시크릿엔진은 데이터를 저장또는 생성하고 암호화하는 구성요소.

AWS 의 Parameter Store / Secrets Manager 와 비슷한 기능을 한다고 생각이 들었습니다. 다른 벤더에서도 비슷한 서비스들이 있습니다.

https://hackernoon.com/aws-secrets-manager-vs-hashicorp-vault-vs-aws-parameter-store-bcbf60b0c0d1

https://www.cloudjourney.io/articles/security/aws_secrets_manager_vs_hashi_vault-su/

가장 일반적인 사용예라 생각되는것은, access key의 암호화라 생각됩니다. 일반적으로 aws-vault 같은 명령어로 지원합니다.

아직 ncp-vault 가 만들어진게 아니라, ncp 내에서 사용하기엔 좀 불편한 부분이 있으리라 생각됩니다. 현재 npc 는 provider로 등록된 상태고 cli 를 지원하므로 차차 지원하리라 생각됩니다.

https://www.44bits.io/ko/post/securing-aws-credentials-with-aws-vault#%ED%85%8C%EB%9D%BC%ED%8F%BCterraform%EC%97%90%EC%84%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

aws 에서의 vault 사용예입니다.

https://www.vaultproject.io/docs/secrets/databases/mysql-maria

mysql-maria db의 user 암호화입니다.

이런 방법이 필요한 이유는 결국 어플리케이션 소스의 탈취로 문제를 방지하기 위함입니다. key의 자동로테이션이나, expire time 을가진 key 발급등을 할 수 있습니다.

Vault 는 근래에 들어서 굉장히 핫한 오픈소스라 테스트 해보시는게 좋을것 같습니다.

마무리를 하자면..

템플릿 소스들이 점점 쌓이고 사용예가 늘면 IaC는 점점 더 일반화 될것입니다.

미리미리 IaC를 준비하고 사용방법을 익히는것도 좋을것 같습니다.

조만간 Secrets Engines 사용하기 위해 자동화 스크립트를 적용하는 고민을 한번 해보려 합니다. 시간이 나면 한번 테스트 해봐야겠습니다.

읽어주셔서 감사합니다!