Named Pipe(네임드 파이프) 를 활용한 다른 서버로 파일전송(압축/해제)

Last Updated on 11월 21, 2020 by 태랑(정현호)

named pipe 는 유닉스 계열의 일반 파이프를 확장 한 것


pipe는 익명의 pipe 와 명명된 파이프 인 named pipe 2가지로 분류 할 수 있습니다.

둘다 방식은 First In First Out( FIFO ), 즉 선입/선출의 데이터 구조를 의미합니다

일반 pipe(익명의 pipe) 는 송수신할 프로세스가 명확히 알수 있을때 사용하게 됩니다.
즉 송수신할 프로세스가 명확하게 선언되거나 알고 있는 상태에서 사용 되고 이런 관계성에 의해서 이름을 알지 않아도 통신할 수 있습니다.

프로세스 관계상 부모-자식 관계를 가지는 프로세스의 통신등에서 사용됩니다


부모-자식 프로세스 같이 관계성이 있는 프로세스 간의 통신이 아닌, 즉 정의 되지 않은 별개의 프로세스 간의 pipe 통신을 사용하려면 미리 선언된 혹은 이름이 있는 pipe 을 통해 별개의 프로세스간의 pipe 를 통해 통신할 수 있습니다.

그래서 이와 같이 별개의 프로세스 간의 통신을 하기위해 named Pipe 를 사용 하게 됩니다.


사실 named pipe에 대해서 알게 된거는 아주 예전이긴 합니다.
예전에 Oracle DB의 exp/imp 를 사용하는데 있어서 추출과 입력을 동시에 수행하면서 빠른 처리나 작업 속도 단축을 위해 사용하는 use case로 named pipe를 알게 되었습니다

얼마전에 커뮤니티에서 서버간의 파일을 묶고/압축 하고 외부의 다른 서버로 전송하고 다시 압축을 해제 하는 이런 일련의 작업을 조금더 빨리 할 수 있는 방법이 있는가의 질문에서 갑자기 named pipe가 생각나서 다시 한번  정리하게 되었습니다.

named pipe 생성


named pipe 를 사용한 예제는 여러 사이트에 여러 방법이 소개 되고 있으며 wiki 에서도 몇가지 예제로 소개 되고 있습니다.
추가로 내용을 더 확인 해보셔도 좋을 것 같습니다.


시나리오는 A 서버 에서 tar로 파일을 묶으면서 압축(zcvf) 하면서 원격지로 전송을 하고 , 원격지 서버에서는 전송되는 데이터를 바로바로 압축을 해제(zxvf) 하는 과정으로 진행할 것 입니다.

named pipe 는 아래와 같이 쉽게 만들수 있습니다.


# 각 서버별 named pipe 생성
source서버에서 실행 : mknod /tmp/source_pipe p
target 서버에서 실행 : mknod /tmp/target_pipe p

생성후 조회하면 아래와 같은 permission 과 속성을 가지고 있습니다.
$ ls -al /tmp/target_pipe
prw-rw-r-- 1 ubuntu ubuntu 0 Nov 4 12:19 /tmp/target_pipe




ssh 키 생성 및 config 설정


telnet 을 사용하던 환경에서는 rsh 로 인증된 접속을 통해 파일을 전송하여 사용 사용 할 수 있었습니다
지금은 보통 ssh 를 사용하기 때문에 비밀번호를 입력하지 않고 사전에 인증 설정을 먼저 하고 전송 명령어를 수행하도록 하겠습니다.
(백그라운드로 수행하기 위하여 혹은 스크립트 내에서 수행하기 위하여)



접속을 받는 target 에서 아래와 같이 rsa 키 생성을 진행 합니다.

$ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ubuntu/.ssh/id_rsa): [엔터]
Enter passphrase (empty for no passphrase): [엔터]
Enter same passphrase again: [엔터]
Your identification has been saved in /home/ubuntu/.ssh/id_rsa.
Your public key has been saved in /home/ubuntu/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
The key's randomart image is:
+---[RSA 4096]----+
|+=========.o |
|.B.*o+++B . |
| Eo+==+o |
| +.=*. . |
| . ..+S. |
| . = o |
| . . + . |
| . . |
| … |
+----[SHA256]-----+


키가 생성 하였다면 id_rsa.pub 의 내용을 authorized_keys 에 넣어 줍니다
$ cd .ssh
$ cat id_rsa.pub  >> authorized_keys
$ chmod 600 authorized_keys
   ==> permission은 600 이나 400 이어야 합니다.

그다음 sftp 를 통해 .ssh 디렉토리 안에 있는 id_rsa 파일을 Source 에 전송합니다.



# target 에서는 전송받은 비밀키(개인키) 를 통해 설정 및 접속 합니다.

일단 전송받은 키를 .ssh 디렉토리에 옴겨 놓도록 하겠습니다.
$ mv  id_rsa  .ssh


config 파일에 아래와 같이 내용을 입력 합니다. 파일이 없다면 vi 로 내용을 입력하면서 생성 하면 됩니다.
$ vi config
Host test_target     <-- ssh 접속시 식별자(alias)
HostName 192.168.56.xx  <-- target ip 를 입력
User ubuntu       <-- 접속 유저명
IdentityFile ~/.ssh/id_rsa    <-- 비밀키 파일명


파일을 생성하였다면 아래와 같이 접속하면 됩니다.
# ssh test_target



named pipe 사용 예제


/usr/local/source_pipe mysql-5.7.31-linux-glibc2.12-x86_64 디렉토리를 압축하여 전송하고 동시에 압축을 해제까지 named pipe 를 활용해서 진행하겠습니다.

절차는 크게 복잡 하지 않고, 간단 합니다
아래의 단계에서 각각 창을 별도로 열고 수행을 진행합니다
즉 터미널을 3개를 사용하도록 합니다.



1) source 서버 실행
$ cd /usr/local
$ sudo tar zcvf /tmp/source_pipe mysql-5.7.31-linux-glibc2.12-x86_64

2) source 서버 실행
$ sudo dd if=/tmp/source_pipe | ssh test_target dd of=/tmp/target_pipe &

3) target 서버에서 실행
$ cd /usr/local
$ sudo tar zxvf /tmp/target_pipe &




tar zcvf  를 실행하면 아래와 같이 진행하다가 파이프라인에서 끝까지 만큼 진행되고 output 에 대해서 기다리게 됩니다.




두번째 터미널에서 dd 와 ssh 를 통해서 remote server 의 pipe 로 연결 합니다.





target server 의 pipe 용량만큼 추가로 진행되고 다시 output 기다립니다.




target(remote) server 에서 output 을 하게 되는 tar zxvf 를 실행하게 되면 아래와 같이 pipe 에서 output 을 기다리던 파일이 압축이 해제되게 되고 source 서버에서는 다시 tar zcvf 작업이 이어서 실행되게 됩니다.



Ref link
https://ko.wikipedia.org/wiki/명명된_파이프
https://skywaves84.tistory.com/entry/Named-PipeFIFO

답글 남기기