본문 바로가기

서버운영 (TA, ADMIN)/미들웨어

[버전관리] CentOS에서 Git 설치

CentOS7에서 Git서버 구축하기


버전관리를 위해 깃서버를 구축해보려고 합니다. GitHub 등 깃저장소를 호스팅해주는 사이트들도 많이 있지만, 회사 상용서비스 소스는 회사 자체 서버에서 관리하는 것이 보안상 가장 안전합니다. Private repository의 경우, 요금을 추가로 내야하기도 하고요.




본포스팅은 Git Dcoumentation (https://git-scm.com/book/ko/v2) 사이트를 참고하여 작성하였습니다.


팀 프로젝트시 공동으로 사용할 수 있는 저장소를 만들고 모두 이 저장소에서 Push, Pull 작업을 수행할 수 있어야 합니다. 여기서 공동 저장소가 Git 서버가 됩니다. Git 저장소를 운영하는데 많은 자원이 필요하지 않아 별도의 Git 서버를 준비하지 않아도 됩니다.


1) 사용할 전송 프로토콜을 정합니다.

- Git 서버에서는 Local, SSG, Git, HTTP 이렇게 네가지의 네트워크 프로토콜을 사용할 수 있습니다.

2) 각 프로토콜에 맞게 서버를 구성합니다.


리모트 저장소의 경우 Working Directory가 없는 Bare 저장소 입니다. 이 저장소는 협업용으로 체크아웃이 필요 없고, Git 데이터만 있으면 됩니다. 다시 말해서 Bare 저장소는 일반 프로젝트에서 .git 디렉토리만 있는 저장소입니다.



프로토콜

Git은 Local, SSH, Git, HTTP 이렇게 네가지의 프로토콜을 지원합니다.

HTTP 프로토콜을 제외한 나머지 프로토콜에서는 모두 Git이 서버에 설치돼있어야 합니다.



1) 로컬 프로토콜

가장 기본적인 것이 로컬 프로토콜입니다. 리모트 저장소가 단순히 디스크의 다른 디렉토리에 있을때 사용하게 되는데요. 팀원들이 전부 한 시스템에 로그인하여 개발하거나 아니면 NFS같은 것으로 파일시스템을 공유하고 있을때 사용합니다. 전자는 문제가 될수 있습니다.모든 저장소가 한시스템에 있다는 것은 프로젝트 관리에 위험요소가 증가하게된다는 말이기도 합니다.


공유 파일시스템을 마운트했을때는 로컬 저장소를 사용하는 것처럼 Clone, Push, Pull을 이용하면 됩니다. 저장소를 clone하거나 프로젝트에 리모트 저장소로 추가합니다. 추가할때 URL 자리에 저장소의 경로를 이용합니다. 


$git clone /opt/git/project.git

$git clone file:///opt/git/project.git


Git은 파일 경로를 직접 쓸 때와 file://로 시작하는 URL을 사용할 때에 약간 다르게 처리합니다. 디렉토리 경로를 그대로 사용하면 Git은 필요한 파일을 직접 복사하거나 하드 링크를 사용합니다. 하지만 file:// 로 시작하면 Git은 네트워크를 통해서 데이터를 전송할 때처럼 프로세를 별도로 생성하여 처리하게 됩니다. 이 프로세스로 데이터를 전송하는 것은 효율이 좀 떨어지지만 그래도 file://을 사용하는 이유는 외부 레퍼런스나 개체들이 포함된 저장소의 복사본을 깔끔하게 보존하기 위해서이다. 보통 다른 버전 관리 시스템들에서 임포트한 후에 사용됩니다.


이미 가진 Git 프로젝트에는 다음과 같이 로컬 저장소를 추가합니다.

$ git remote add local_proj /opt/git/project.git


위 설정을 통해 네트워크에 있는 리모트 저장소처럼 Push하거나 Pull이 가능해집니다.


로컬 프로토콜 이용 장점

1) 파일기반 저장소의 장점은 간단합니다.

2) 기존에 있던 네트워크나 파일의 권한을 그대로 사용하기 때문에 설정하기가 쉽습니다.

3) 이미 팀 전체가 접근할 수 있는 파일 시스템을 가지고 있다면 저장소를 아주 쉽게 구성이 가능합니다.

4) 다른 디렉토리에 공유할 때처럼 모든 동료가 읽고 쓸 수 있는 공유 디렉토리에 Bare 저장소를 만들면 됩니다.


동료가 작업하는 저장소에서 바로 가져오는게 편리합니다. 만약 함께 프로젝트를 하는 동료가 자신이 한 일을 당신이 확인해주기를 원한다면, 동료가 서버에 Push하고 받는사람이 다시 Pull할 필요없이 git pull /home/john/project 명령어를 실행시켜 쉽게 동료의 코드를 가져올 수 있습니다.


로컬 프로토콜 이용 단점

1) 다양한 상황에서 접근할 수 있도록 디렉토리를 공유하는것 자체가 일반적으로 어렵습니다.

2) 리모트 저장소가 있는 디스크를 마운트해야하는데 이것은 다른 프로토콜을 이용하는 방법보다 느리고 어렵습니다.

3) 파일시스템을 마운트해서 사용하는 중이라면, 별로 빠르지도 않습니다. 로컬 저장소는 데이터를 빠르게 읽을 수 있을때만 빠릅니다.

4) NFS에 있는 저장소에 Git을 사용하는 것은 보통 같은 서버에 SSH로 접근하는 것보다 느립니다.



2) SSH 프로토콜

Git의 대표적인 프로토콜은 SSH입니다. 대부분 서버는 SSH로 접근할 수 있도록 설정돼있습니다. 설정되어 있지 않더라도 설정이 쉽습니다. 그리고 SSH는 읽기/쓰기 접근을 쉽게 할 수 있는 유일한 네트워크 프로토콜입니다. 다른 네트워크 프로토콜인 HTTP와 Git은 일반적으로 읽기만 가능합니다. 그래서 초보자라고 해도 쓰기 명령을 이용하려면 SSH가 필요합니다. SSH는 또한 인증도 지원합니다. SSH는 보통 유비쿼터스적이면서도, 사용 및 설치가 쉽습니다.


SSH를 통해 Git 저장소를 Clone하려면 ssh://로 시작하는 URL을 사용합니다.


$ git clone ssh://user@server:project.git


다음과 같이 프로토콜 이름을 명시하지 않고도 SSH를 사용할 수 있습니다.


$ git clone user@server:project.git


사용자 계정을 생략할 수도 있는데 계정을 생략하면 Git은 현재 로그인한 사용자의 계정을 사용합니다.


SSH프로토콜 이용시 장점

1) 누가 리모트에서 저장소에 접근했는지 알 수있습니다.

2) SSH는 상대적으로 설정하기 쉽습니다. SSH 데몬이 흔하기 때문입니다.

   네트워크 관리자들은 SSH 데몬을 다루어본 경험이 있고 대부분의 OS 배포판에는 SSH 데몬과 관리도구들이 모두 들어 있습니다.

3) SSH를 통해 접근하면 보안에 안전합니다. 모든 데이터들이 암호화되어 인증된 상태로 전송되게 합니다.

4) SSH는 전송시 데이터를 가능한 압축하여 전송하므로 효율적입니다.


SSH프로토콜 이용시 단점

1) 익명으로 접근이 불가능합니다. 심지어 읽기 전용인 경우에도 시스템에 접근할 수 없습니다.

2) 회사에서만 사용할 것이라면 SSH가 가장 적합한 프로토콜이지만, 오픈소스 프로젝트는 SSH만으로 부족합니다.

만약, 사람들이 프로젝트에 익명으로 접근할 수 있게 하려면, 자신이 PUSH할 때 사용할 SSH를 설치하는 것과 별개로 다른 사람들이 PULL할때 사용할 다른 프로토콜을 추가해야 합니다.



3) Git 프로토콜

Git 프로토콜은 Git에 포함된 데몬을 사용하는 것입니다. 포트는 9418로 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없습니다. 저장소에 git-export-daemon-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없습니다. 이 파일이 없는 저장소는 서비스되지 않습니다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중 하나만 선택할 수 있습니다. 그래서 이 프로토콜로는 Push하게 할 수 없습니다. 엄밀히 말하자면 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수는 없습니다. Push할 수 있을 경우, 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있게 됩니다. 이러한 이유로 잘 쓰지 않는 프로토콜입니다.


Git 프로토콜 이용시 장점

1) Git 프로토콜은 전송속도가 가장 빠릅니다.

  전송량이 많은 공개 프로젝트나 별도의 인증필요없이 읽기만 허용하는 프로젝트 서비스시 유용

2) 암호화와 인증을 빼면 SSH 프로토콜과 전송 메커니즘이 별반 다르지 않습니다.


Git 프로토콜 이용시 단점

1) 인증 메커니즘이 없습니다. Git 프로토콜만으로 접근할 수 있는 프로젝트는 바람직하지 못합니다.

   따라서 일반적으로 SSH 프로토콜과 함께 사용합니다.

   소수의 개발자만 Push할 수 있고 대다수의 사람은 git://을 사용하여 읽을 수만 있게 적용합니다.

   어쩌면 가장 설치하기 어려운 방법일 수도 있습니다.

2) 별도의 데몬이 필요하고 프로젝트에 맞게 설정해야 합니다.

   Gitosis 절에서 설정하는 법을 살펴볼수 있습니다. 자원을 아낄 수 있도록 xinetd도 설정해야하고 방화벽을 통과할 수 있도록 9418 포트도 열어야합니다. 이 포트는 일반적으로 회사들이 허용하는 표준 포트가 아니며, 규모가 큰 회사의 방화벽이라면 당연히 이 포트를 막아 둡니다.



4) HTTP/S 프로토콜

마지막으로, HTTP 프로토콜이 있습니다. HTTP와 HTTPS 프로토콜은 설정이 간단하다는 강력한 장점이 있습니다. HTTP 도큐먼트 루트 밑에 Bare 저장소를 두고 post-update 훅을 설정하는 것이 기본적으로 해야하는 일의 전부입니다. 저장소가 있는 웹서버에 접근할 수 있다면 그 저장소를 Clone할 수도 있습니다. HTTP를 통해서 저장소를 읽을 수 있게 하려면 다음과 같이 하면 됩니다.


$ cd /var/www/htdocs/

$ git clone --bare /path/to/git_project gitproject.git

$ cd gitproject.git

$ mv hooks/post-update.sample hooks/post-update

$ chmod a+x hooks/post-update


post-update 훅은 Git에 포함되어 있으며 git update-server-info라는 명령어를 실행시킵니다. 이 명령어는 HTTP로 Fetch와 Clone 명령이 잘 동작하게 합니다. SSH를 통해서 저장소에 Push할 때 실행되며, 사용자는 다음과 같이 Clone합니다.


$ git clone http://example.com/gitproject.git


여기서는 Apache 서버가 기본으로 사용하는 /var/www/htdocs를 루트 디렉토리로 사용하지만 다른 웹서버를 사용해도 됩니다. 단순히 Bare 저장소를 http 문서 루트에 넣으면 됩니다. Git 데이터는 일반적인 정적 파일처럼 취급됩니다.


HTTP를 통해서 Push하는 것도 가능합니다. 단지 이 방법을 잘사용하지 않는 WebDAV 환경을 완벽하게 구축해야 합니다. 잘 사용하지않는 프로토콜입니다. HTTP 프로토콜로 Push를 하고 싶을 경우 http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt 읽고 저장소를 만들면 됩니다. HTTP를 통해서 Push하는 방법의 좋은 점은 WebDAV 서버를 아무거나 골라 쓸 수 있다는 점입니다. 그래서 WebDAV를 지원하는 웹 호스팅 업체를 이용하면 이 기능을 사용할 수 있습니다.


HTTP/S 프로토콜 이용시, 장점

1) HTTP 프로토콜은 설정하기 쉽다는 것이 장점입니다. 몇개의 필수 명령어만 실행하면 어디에서나 저장소에 접근하게 만들 수 있습니다. 단 몇분만에.

2) HTTP 프로콜은 서버의 리소스를 많이 사용하지도 않습니다. 보통은 정적 HTTP 서버만으로도 충분하기 때문에 흔한 Apache 서버로 초당 수천 개의 파일을 처리할 수 있습니다. 따라서 작은 서버로도 충분히 감당할 수 있습니다.

3) HTTPS를 사용해서 서비스할 수도 있으므로 전송하는 데이터를 암호화할 수도 있습니다. 클라이언트가 서명된 SSL 인증서를 사용하게 할 수도 있습니다. SSH 공개키를 사용하는 방식보다 쉽습니다. SSL 인증서를 사용하는게 나을 때도 있고, 단순히 HTTPS위에서 HTTP기반 인증을 사용하는게 나을때도 있습니다.

4) HTTP는 매우 보편적인 프로토콜이라서 거의 모든 회사가 트래픽이 방화벽을 통과하도록 허용한다는 장점도 지니고 있습니다.


HTTP/S 프로토콜 이용시, 단점

1) 클라이언트에서 HTTP가 비효율적입니다.

2) 저장소에서 Fetch하거나 Clone할때 오래 걸릴 수있습니다.

3) 다른 프로토콜의 네트워크 오버헤드보다 HTTP의 오버헤드가 조금더 큽니다.

  지능적으로 정말 필요한 데이터만 전송하지 않기때문에 HTTP 프로토콜은 Dumb Protocol이라고 부르기도 합니다. 효율적으로 전송하고자 서버는 아무것도 하지 않습니다. 이러한 이유로, HTTP와 다른 프로토콜의 성능 차이가 발생하기도합니다.



최초 Git 저장소 생성

어떤 서버를 설치하더라도 일단 저장소를 Bare 저장소로 만들어야 합니다. 다시 말하자면, Bare 저장소는 Working Directory가 없는 저장소입니다. --bare 옵션을 주고 Clone하면 새로운 Bare 저장소가 만들어집니다. 디렉토리는 관례에 따라 .git 확장자로 끝나게 됩니다.



기존 디렉토리를 Git 저장소로 만들기

기존 디렉토리를 Git으로 관리하고 싶을 때, 프로젝트의 디렉토리로 이동해서 아래와 같은 명령을 실행합니다.


$ git init


이 명령은 .git 이라는 하위 디렉토리를 만듭니다. .git 디렉토리에는 저장소에 필요한 뼈대 파일(Skeleton)이 들어 있습니다. (.git 디렉토리가 막 만들어진 직후에 어떤 파일이 있느지에 대한 내용은 이후에 다루게 됩니다) 이 명령만으로는 아직 프로젝트의 어떤 파일도 관리하지 않습니다.


Git이 파일을 관리하게 하려면 저장소에 파일을 추가하고 커밋해야 합니다. git add 명령으로 파일을 추가하고 커밋할 수 있습니다.


$ git add *.c

$ git add README

$ git commit -m 'initial project version'


매우 짧은 시간에 명령어를 몇개 실행해서 Git 저장소를 만들고 파일이 관리되게 했습니다.



기존 저장소를 Clone하기

다른 프로젝트에 참여하거나(Contribute) Git 저장소를 복사하고 싶을 때 git clone 명령을 사용합니다. 이미 Subversion같은 VCS에 익숙한 사용자에게는 checkout이 아니라 clone이라는 점이 도드라져 보일 수도 있습니다. Git이 Subversion과 다른 가장 큰 차이점은 서버에 있는 모든 데이터를 복사한다는 것입니다. git clone을 실행하면 프로젝트 히스토리를 전부 받아옵니다. 실제로 서버의 디스크가 망가져도 클라이언트 저장소 중에서 아무거나 하나 가져다가 복구하면됩니다. (서버에만 적용했던 설정은 복구하지 못하지만 모든 데이터는 복구됩니다)


git clone [url] 명령으로 저장소를 Clone합니다.


$ git clone git://github.com/schacon/grit.git


이 명령은 "grit"이라는 디렉토리를 만들고 그 안에 .git 디렉토리를 만듭니다. 그리고 저장소의 데이터를 모두 가져와서 자동으로 최신 버전을 Checkout해 놓습니다. grit 디렉토리로 이동하면 Checkout으로 생성한 파일을 볼 수 있고 당장 하고자 하는 일을 시작할 수 있습니다. 아래와 같은 명령을 사용하여 저장소를 Clone하면 "grit"이 아니라 다른 디렉토리 이름으로 Clone할 수 있습니다.


$ git clone git://github.com/schacon/grit.git mygrit


디렉토리 이름이 mygrit이라는 것만 빼면 이 명령의 결과와 앞선 명령의 결과는 같습니다.


앞서 말했듯이 Git은 다양한 프로토콜을 지원합니다. git, https(s)를 사용할 수도 있고 ssh프로토콜을 사용할 수도 있습니다.



만약 창업을 준비하고 있거나 회사에서 Git을 막 도입하려고 할 때는 개발자의 수가 많지 않아서 설정할 것이 벼로 없습니다. 자용자를 관리하는 것이 Git 서버를 설장할 때 가장 골치 아픈 것 중 하나입니다. 사람이 많으면 어떤 사용자는 읽기만 가능하게 하고 어떤 사용자는 읽고 쓰기 둘 다 가능하게 해야합니다. 이렇게 설정하는 것은 조금 더 까다롭습니다.


SSH 접속

만약 모든 개발자가 SSH로 접속할 수 있는 서버가 있으면 너무 쉽게 저장소를 만들 수 있습니다. 앞서 말했듯이 정말 할 일이 별로 없습니다. 그리고 저장소의 권한을 꼼곰하게 관리해야 하면 운영체제의 파일시스템 권한 관리를 이용할 수 있습니다.


동료가 저장소에 쓰기 접근을 해야하는데 아직 SSH로 접근할 수 있는 서버가 없으면 하나 마련해야 합니다. 아마 서버가 하나 있다면 그 서버에는 이미 SSH 서버가 설치되어 있고 SSH로 접속하여 사용하고 있을 것입니다.


팀원들이 접속할 수 있도록 하는 방법은 몇가지가 있습니다. 첫째로 모두에게 계정을 만들어주느 방법이 있습니다. 이 방법이 제일 단순하지만 귀찮습니다. 팀원마다 'adduser'를 실행시키고 임시 암호를 부여해야 하기 때문에 보통 이 방법을 쓰고 싶어하지 않습니다.


둘째로 서버마다 git이라는 계정을 하나씩 만드는 방법이 있습니다. 쓰기 권한이 필요한 사용자의 SSH 공개키를 모두 모아서 git 계정의 ~/.ssh/authorized_keys 파일에 모든 키를 입력합니다. 그러면 모두 git 계정으로 그 서버에 접속할 수 있게 됩니다. 이 git 계정은 커밋 데이터에는 아무런 영향을 끼치지 않습니다. 다시 말해서 접속하는데 사용하는 SSH 계정과 커밋에 저장되는 사용자는 아무 상관이 없습니다.


SSH 서버 인증을 LDAP 서버를 이용할 수도 있습니다. 이미 사용하고 있는 중앙집중식 인증 소스가 있으면 해당 인증을 이용하여 SSH 서버에 인증하도록 할 수도 있습니다. SSH 인증 메커니즘 중 아무거나 하나 이용할 수 있으면 사용자는 그 서버에 접근할 수 있습니다.




Git 서버 - SSH 공개키 만들기


SSH 공개키 만들기


많은 Git 서버들은 SSH 공개키로 인증합니다. 공개키를 사용하려면 일단 공개키를 만들어야합니다. 공개키를 만드는 방법은 모든 운영체제가 비슷합니다. 먼저 키가 있는지부터 확인합니다. 사용자의 SSH 키들은 기본적으로 사용자의 ~/.ssh 디렉토리에 저장합니다. 그래서 만약 디렉토리의 파일을 살펴보면 이미 공개키가 있는지 확인할 수 있습니다.


$ cd ~/.ssh

$ ls

authorized_key2       id_dsa        know_hosts

config                id_dsa.pub   


id_dsa나 id_rsa라는 파일이름이 보일것이고 이에 같은 파일명의 .pub이라는 확장자가 붙은 파일이 하나 더 있을 것입니다. 그중 .pub 파일이 공개키이고 다른 파일은 개인키입니다. 만약 이 파일들이 없거나 .ssh 디렉토리도 없으면 ssh-keygen 이라는 프로그램으로 키를 생성해야합니다. ssh-keygen 프로그램은 Linux나 Mac의 SSH 패키지에 포함돼 있고 Windows는 Git for Windows 안에 들어 있습니다.


$ ssh-keygen

Generating public/private rsa key pair.

Enter file in which to save the key (/home/schacon/.ssh/id_rsa):

create directory '/home/schacon/.ssh'

Enter passphrase (empty for no passphrase)"

Enter same passphrase again:

Your identification has been saved in /home/schacon/.ssh/id_rsa.

Your public key has been saved in /home/schacon/.ssh/id_rsa.pub.

The key fingerprint is:

d0:82:24:8e:d7:f1:bb:9b:33:53:96:93:49:da:9b:e3 chacon@mylaptop.local


ssh/id_rsa 키를 저장하고 싶은 디렉토리를 입력하고 암호를 두번 입력합니다. 이 때 암호를 비워두면 키를 사용할때 암호를 묻지 않습니다.


다음은 사용자가 자신의 공개키를 Git 서버 관리자에게 보내야 합니다. 사용자는 .pub 파일의 내용을 복사하여 이메일을 보내기만 하면 됩니다. 공개키는 아래와 같이 생겼습니다.


$ cat ~/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU

GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3

Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA

t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En

mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx

NrRFi9wrf+M7Q== schacon@mylaptop.local