PORCH Installation Manual
이 문서는 인프라 자동화 관리툴인 PORCH의 설치 매뉴얼입니다.
PORCH 소개
이 프로젝트의 핵심 기술을 “Immutable Infrastructure Automation” (IIA) and “Continuous Deployment PIpeline”(CDP) 굳이 번역하자면 “불변 인프라 자동화” 와 “연속 배치관(?)” 기술
각 용어의 정의
- Immutable : 생성 후 변경되지 않는
- Infrastructure: 물리/가상 자원(물리 자원, 가상 자원, 소프트웨어 스택 등)의 총체
- Automation: 서비스에 필요한 물리/가상 자원의 생성, 설정을 자동화
필수 기능
- 운영자의 간섭없는 시스템 설치, 설정 (non-interactive system install and configuration)
- 각 요소 별 설정 메타데이터 형상관리 시스템 (version control system for configuration metadata of each component)
- 구성요소 업그레이드는 기존 자원 업그레이드가 아닌 새 메타데이터 업데이트 후 새 자원으로 교체
- 개발자의 코드가 형상관리시스템에 push되면 빌드, 시험 컨테이너가 바로 만들어져 개발 라이프사이클 자동화
- 전통적 “Mutable and Manual” 인프라 관리기술의 문제점
- 인프라 규모가 커짐에 따라 운영 관리 복잡성은 기하급수적으로 증가
- 대규모 시스템 배치가 필요할 때 느리고 배치 중 오류 확률 증가
- 보안 위협으로부터 보호하는 절차가 복잡하고 오류 확률이 높아짐
기대효과
- 서버 시스템 완전 자동화 구현으로 운영 유지 관리 편의성 증대
- 소스코드 형상관리와 같이 인프라 설정 형상관리를 통해 연속 통합(Continuous Integration), 연속 배치(Continuous Deployment) 구현
- 시스템 오류와 보안 위협 감소 : 시스템 설정을 개별 서버에서 하게 되면, 업그레이드/패치 시 충돌로 인한 오류 발생 가능성 높음 ᅟ
PORCH 설치
ᅟporch 를 물리서버에 설치 할 수 있지만 가상머신에 설치하여 운영 할 수 있습니다. 해당 매뉴얼은 PORCH를 가상머신에 설치한 과정을 기술하였습니다. kvm, xen hypervisor 설치되어진 환경에서 가상머신 생성하는 과정부터 설치를 진행합니다.
서버 생성
PORCH 에 OS는 debian 입니다. debian jessie 가상머신을 생성하고 PORCH 를 설치합니다.
porch on kvm
ᅟvirt-install 을 이용하여 아래와 같이 가상머신을 구동하고 debian jessie를 설치합니다.
# mkdir -p /vm/{iso,img}
# curl -o /vm/iso/debian8.iso http://ftp.daumkakao.com/debian-cd/8.7.1/amd64/iso-cd/debian-8.7.1-amd64-netinst.iso
# vi /vm/porch.sh
#!/bin/sh
virt-install --virt-type kvm --name ᅟporch \
--cdrom /vm/iso/debian8.iso --hvm \
--os-variant debian8 \
--disk path=/vm/img/ᅟporch,size=80,format=qcow2 \
--vcpus 6 --memory 4096 \
--network bridge=br0,model=virtio \
--network bridge=br1,model=virtio \
--boot cdrom,hd \
--graphics vnc,listen=0.0.0.0,password=porchadmin
가상머신에 vnc 포트는 virsh vncdisplay 옵션으로 확인 할 수 있습니다. vnc 접속하여 설치를 진행합니다.
# virsh vncdisplay porch
:0
ᅟporch on pengxcloud
debiab jessie template이 존재한다면 pengxcli 를 이용하여 porch 가상머신을 생성합니다.
# pengxcli vm-add porch ec0edcbc-2dd0-40b4-a058-ec371fc30f6b 2 1 1024 1024 porch xenbr0 xenbr1
template이 없다면 config 파일을 만들어 신규 debian jessie를 설치합니다.
# mkdir -p /vm/{iso,img}
# curl -o /vm/iso/debian8.iso http://ftp.daumkakao.com/debian-cd/8.7.1/amd64/iso-cd/debian-8.7.1-amd64-netinst.iso
# qemu-img create -f qcow2 /vm/img/porch.qcow2 10G
# vi /vm/porch.cfg
name = "porch"
builder = "hvm"
maxmem = 1024
memory = 1024
maxvcpus = 4
vcpus = 1
boot = "c"
disk = ["format=qcow2,vdev=xvda,access=rw,target=/vms/img/porch.qcow2"]
vif = ["bridge=xenbr0,type=vif,model=e1000", "bridge=xenbr1,type=vif,model=e1000"]
vnc = 1
vnclisten = "0.0.0.0"
vncunused = 1
vncpasswd = "porchadmin"
hap = 1
pae = 1
acpi = 1
apic = 1
nx = 1
hpet = 1
nestedhvm = 0
localtime = 1
xen_platform_pci = 1
viridian = 0
stdvga = 0
videoram = 8
#usb = 1
#usbdevice = "tablet"
bios = "seabios"
device_model_version = "qemu-xen"
device_model_override = "/usr/bin/qemu-system-i386"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "coredump-destroy"
# xl create /vm/porch.cfg
가상머신에 vnc 포트는 virsh vncdisplay 옵션으로 확인 할 수 있습니다.
# xenstore-ls /local/domain/{dom_id} | grep vnc
vnc-pass = "porchadmin"
vnc-listen = "0.0.0.0"
vnc-port = "5905"
OS 설치 과정은 생략하도록 하겠습니다. 설치 중 일반 사용자 생성시 계정명은 porch 로 생성하였습니다.
기본 설정
가상머신에 접속하여 네트워크 설정을 진행합니다. 해당 문서는 배포망, 서비스망 2개에 네트워크로 구성된 환경으로 진행하였습니다. porch 의 네트워크 구성은 아래와 같이 배포망은 eth0, 서비스망 인터페이스는 eth1 로 구성하는 구조를 권장합니다.
- 배포망(eth0) : 10.0.0.150
- 서비스망(eth1) : 192.168.0.150
sudo 설치 및 설정
# apt update
# apt install sudo
# vi /etc/sudoers
...
ᅟporch ALL=(ALL:ALL) NOPASSWD:ALL
NTP 설치 및 설정
$ sudo apt install -y ntp
$ sudo systemctl start ntpd
$ sudo systemctl enable ntpd
docker 설치
$ sudo apt install -y apt-transport-https ca-certificates curl \
software-properties-common
$ sudo curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
$ sudo apt-key finger |grep 9DC8
(key should be 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88)
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
$ sudo apt update
$ sudo apt install -y docker-ce
$ sudo gpasswd -a porch docker (udam 사용자에게 docker 그룹 권한을 부여)
$ sudo systemctl status docker (docker가 시작되었는 지 확인)
porch 사용자 계정으로 컨테이너를 구동하여 설치 검증을 합니다.
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
시험한 컨테이너를 삭제합니다.
$ docker ps -a (컨테이너 이름 확인)
$ docker rm eloquent_austin
eloquent_austin
$ docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Deleted: sha256:48b5124b2768d2b917edcb640435044a97967015485e812545546cbed5cf0233
Deleted: sha256:98c944e98de8d35097100ff70a31083ec57704be0991a92c51700465e4544d08
etcd cluster 설치 및 설정
porch 에 etcd를 docker container로 구동합니다.
TLS certificate 생성
etcd git repo에 tls를 쉽게 생성할 수 있는 도구를 제공한다. 컨테이너를 구동하여 그 안에서 TLS 인증서를 생성한다.
$ docker run -ti --rm -v /tmp:/out golang /bin/bash
root@ae3ff554c914:/go# git clone https://github.com/coreos/etcd
root@ae3ff554c914:/go# cd etcd/hack/tls-setup
root@ae3ff554c914:/go/etcd/hack/tls-setup# mkdir /out/etcd-cert
root@ae3ff554c914:/go/etcd/hack/tls-setup# apt update
root@ae3ff554c914:/go/etcd/hack/tls-setup# apt install -y vim
root@ae3ff554c914:/go/etcd/hack/tls-setup# vi config/ca-config.json
{
"signing": {
"default": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "87600h"
}
}
}
87600h == 10 years (should be enough.)
root@ae3ff554c914:/go/etcd/hack/tls-setup# vi config/ca-csr.json
{
"CN": "ETCD CA",
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
"O": "iOrchard",
"OU": "Service Technology Team",
"L": "Gangnam-gu",
"ST": "Seoul",
"C": "KR"
}
]
}
root@ae3ff554c914:/go/etcd/hack/tls-setup# vi config/etcd0.json
{
"CN": "etcd0",
"hosts": [
"10.0.0.150",
"porch",
"127.0.0.1",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
"O": "iOrchard",
"OU": "Service Technology Team",
"L": "Gangnam-gu"
}
]
}
클라이언트 인증서를 설정합니다.
root@ae3ff554c914:/go/etcd/hack/tls-setup# vi config/client.json
{
"CN": "etcd-client",
"hosts": [
"127.0.0.1",
"localhost"
],
"key": {
"algo": "ecdsa",
"size": 384
},
"names": [
{
"O": "iOrchard",
"OU": "Service Technology Team",
"L": "Gangnam-gu"
}
]
}
root@ae3ff554c914:/go/etcd/hack/tls-setup# vi Makefile
: set paste
...
req:
$(CFSSL) gencert \
-ca certs/ca.pem \
-ca-key certs/ca-key.pem \
-config config/ca-config.json \
config/etcd0.json | $(JSON) -bare certs/etcd0
$(CFSSL) gencert \
-ca certs/ca.pem \
-ca-key certs/ca-key.pem \
-config config/ca-config.json \
config/client.json | $(JSON) -bare certs/client
...
Makefile의 req 부분에서 etcd0, client 생성을 위와 같이 설정합니다. 위 req 부분에서 etcd0과 client 부분만 변경하고 나머지 엔트리들을 삭제합니다.
Makefile은 indentation으로 TAB을 사용하므로 에러가 발생하기에 위 내용을 copy & paste 할 경우 vi 에 pate mode로 전환하여 붙여넣습니다.
TLS certs 를 생성합니다.
cfssl 바이너리를 가져와 `/go/bin/`에 저장합니다.
root@ae3ff554c914:/go/etcd/hack/tls-setup# make cfssl
go get -u -tags nopkcs11 github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson
go get -u github.com/mattn/goreman
CA 인증서를 생성합니다.
root@ae3ff554c914:/go/etcd/hack/tls-setup# make ca
mkdir -p certs
2017/06/07 17:16:07 [INFO] generating a new CA key and certificate from CSR
2017/06/07 17:16:07 [INFO] generate received request
2017/06/07 17:16:07 [INFO] received CSR
2017/06/07 17:16:07 [INFO] generating key: ecdsa-384
2017/06/07 17:16:07 [INFO] encoded CSR
2017/06/07 17:16:07 [INFO] signed certificate with serial number 125782362072859064781008653288266758237889669094
생성된 CA 인증서로 각 etcd 서버/클라이언트 인증서를 생성합니다.
root@ae3ff554c914:/go/etcd/hack/tls-setup# make req
2017/06/07 17:21:19 [INFO] generate received request
2017/06/07 17:21:19 [INFO] received CSR
2017/06/07 17:21:19 [INFO] generating key: ecdsa-384
2017/06/07 17:21:19 [INFO] encoded CSR
2017/06/07 17:21:19 [INFO] signed certificate with serial number 715595833875702950179628632233744324477815970137
2017/06/07 17:21:19 [INFO] generate received request
2017/06/07 17:21:19 [INFO] received CSR
2017/06/07 17:21:19 [INFO] generating key: ecdsa-384
2017/06/07 17:21:19 [INFO] encoded CSR
2017/06/07 17:21:19 [INFO] signed certificate with serial number 169717375321772320384205510672357633574611121108
certs 파일에 있는 모든 인증서를 /out/etcd-cert/ 로 복사합니다.
root@ae3ff554c914:/go/etcd/hack/tls-setup# cp certs/* /out/etcd-cert/
이제 porch 서버에 /tmp/etcd-cert/ 경로를 확인해보면 위 복사한 인증서를 확인 할 수 있습니다.
해당 인증서를 이용하여 etcd 컨테이너를 구동합니다. /tmp/etcd-cert/ 로부터 /etc/ssl/etcd/ 로 파일들을 복사합니다.
$ sudo mkdir /etc/ssl/etcd
$ sudo cp /tmp/etcd-cert/{ca*.pem,etcd0*.pem} /etc/ssl/etcd/
클라이언트 인증서를 /etc/ssl/etcd/ 에 놓고 porch 사용자가 key 파일을 읽을 수 있도록 권한을 변경합니다.
$ sudo cp /tmp/etcd-cert/client{-key,}.pem /etc/ssl/etcd/
$ sudo chmod 644 /etc/ssl/etcd/client-key.pem
인증서 내용을 확인하려면 아래 명령으로 확인 할 수 있습니다.
$ openssl x509 -noout -text -in /etc/ssl/etcd/etcd0.pem
아래 etcd.sh 스크립트 파일을 생성합니다.
$ vi etcd.sh
HostIP=$(ip addr show dev eth0 |grep 'inet ' |awk '{print $2}' |cut -d'/' -f1)
docker run -d \
-v /etc/ssl/etcd:/etc/ssl/certs \
-v /var/lib/etcd:/etcd0.etcd \
-p 4001:4001 -p 2380:2380 -p 2379:2379 \
--name etcd0 quay.io/coreos/etcd \
etcd \
-name etcd0 \
-trusted-ca-file=/etc/ssl/certs/ca.pem \
-cert-file=/etc/ssl/certs/etcd0.pem \
-key-file=/etc/ssl/certs/etcd0-key.pem \
-client-cert-auth=1 \
-peer-trusted-ca-file=/etc/ssl/certs/ca.pem \
-peer-cert-file=/etc/ssl/certs/etcd0.pem \
-peer-key-file=/etc/ssl/certs/etcd0-key.pem \
-peer-client-cert-auth=1 \
-advertise-client-urls https://${HostIP}:2379,https://${HostIP}:4001 \
-listen-client-urls https://0.0.0.0:2379,https://0.0.0.0:4001 \
-initial-advertise-peer-urls https://${HostIP}:2380 \
-listen-peer-urls https://0.0.0.0:2380 \
-initial-cluster-token etcd-cluster \
-initial-cluster etcd0=https://${HostIP}:2380 \
-initial-cluster-state new
etcd 를 구동한 뒤 구동상태를 확인합니다.
$ sh etcd.sh
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8b096a81df06 quay.io/coreos/etcd "etcd -name etcd0 ..." 9 minutes ago Up 9 minutes 0.0.0.0:2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp etcd0
위 컨테이너로부터 etcdctl 바이너리를 PORCH 서버로 복사합니다.
$ docker cp etcd0:/usr/local/bin/etcdctl .
이제 클라이언트에서 클라이언트 인증서를 이용하여 접속을 시도합니다. PORCH 에 배포망 ip를 hosts 파일에 등록합니다.
$ sudo echo "10.0.0.150 etcd0" >> /etc/hosts
$ ./etcdctl --endpoints https://etcd0:2379 \
--cert-file /etc/ssl/etcd/client.pem \
--key-file /etc/ssl/etcd/client-key.pem \
--ca-file /etc/ssl/etcd/ca.pem member list
4ec2422565450a13: name=etcd0 peerURLs=https://10.0.0.150:2380 clientURLs=https://10.0.0.150:2379,https://10.0.0.150:4001 isLeader=true
소프트웨어 설치 및 설정
porch 사용자 계정으로 porch 소프트웨어를 설치합니다.
python3 관련 필수 패키지 설치
- python3-venv (for virtual env.)
- gcc (for cryptography compile)
- python3-dev (for cryptography compile)
- libssl-dev (for cryptography compile)
$ sudo apt install -y python3-venv gcc python3-dev libssl-dev
python 가상환경 설정
$ mkdir .envs
$ pyvenv .envs/porch
$ vi .bashrc
...
# porch virtualenv
source .envs/porch/bin/activate
$ source .envs/porch/bin/activate
(porch) $
flask webframework 설치 및 설정
porch 는 Web backend API 서버로 Flask를 사용합니다.
(porch) $ pip install -U pip
(porch) $ pip install
flask-restplus (rest api)
python-etcd (etcd python client)
requests (http python client)
flask-jwt-extended (json web token)
bcrypt (salt-key based hash password generator)
flask-cors (cross origin resource sharing support)
cryptography (ssh pub/private key generator)
GitPython (git python library)
ansible==2.2.1.0 (automation tool)
ansible 2.3.0은 python 3.4와 호환되지 않습니다. 참조 :
https://github.com/ansible/ansible/issues/24180
cliff cli framework 설치 및 설정
Cliff는 CLI framework 로 ud 명령어를 사용하기 위해 설치합니다.
(porch) $ pip install -U setuptools
(porch) $ pip install cliff
nfs 서비스 중지
porch 는 nfs를 사용하지 않으므로 nfs 서비스를 사용 중이라면 다음과 같이 nfs 서비스를 중지합니다.
(porch) $ sudo systemctl stop nfs-kernel-server nfs-common rpcbind
(porch) $ sudo systemctl mask nfs-kernel-server nfs-common rpcbind
porch 소스 파일 가져오기
(ᅟporch) $ git clone https://git.iorchard.co.kr/jijisa/porch.git
fai 설치 및 설정
(porch) $ sudo su
# wget -O - http://fai-project.org/download/074BCDE4.asc | apt-key add -
# echo "deb http://fai-project.org/download jessie koeln" > \
/etc/apt/sources.list.d/fai.list
# apt update
# apt install -y fai-quickstart pxelinux rinse aptitude xz-utils \
ipmitool freeipmi-tools
# sed -i -e 's/^#deb/deb/' /etc/fai/apt/sources.list
# sed -i -e 's/#LOGUSER/LOGUSER/' /etc/fai/fai.conf
# fai-setup -v
(It takes a long time)
...
FAI setup finished.
Log file written to /var/log/fai/fai-setup.log
copy porch/srv/tftp/fai/* /srv/tftp/fai/
(ᅟporch) $ sudo chown -R porch:porchard /srv/tftp/fai
(ᅟporch) $ cp -a porch/srv/tftp/fai/* /srv/tftp/fai/
copy fai config files
(ᅟporch) $ sudo chown -R porch:porch /srv/fai
(ᅟporch) $ cp -a porch/srv/fai/config/* /srv/fai/config/
(ᅟporch) $ mkdir /srv/fai/{pub,pri}keys
$ mkdir /srv/fai/config/pubkeys
copy /usr/lib/PXELINUX/lpxelinux.0 to /srv/tftp/fai
(ᅟporch) $ cp /usr/lib/PXELINUX/lpxelinux.0 /srv/tftp/fai
create and copy public/private keys to /srv/fai/{pub,pri}keys/
(ᅟporch) $ ssh-keygen -N ''
(ᅟporch) $ cp .ssh/id_rsa.pub /srv/fai/config/pubkeys/authorized_keys
(ᅟporch) $ cp .ssh/id_rsa /srv/fai/prikeys/prikey
copy and edit boot.ipxe (IP address)
IP 주소를 porch에 배포망 IP 주소로 바꾼다.
(ᅟporch) $ cd /srv/tftp/fai
(ᅟporch) $ cp boot.ipxe.dev boot.ipxe
(ᅟporch) $ vi boot.ipxe
#!ipxe
echo ${net1/mac}
chain http://10.0.0.150/api/fai/pxe/${net1/mac}
get undionly.kpxe
$ wget -O /srv/tftp/fai/undionly.kpxe http://boot.ipxe.org/undionly.kpxe
create squash image
$ sudo fai-cd -d "" -SMeJ /srv/tftp/fai/squash.img
create basefiles
$ cd /srv/fai/config/basefiles
$ sudo ./mk-basefile CENTOS7_64
$ sudo ./mk-basefile JESSIE64
$ sudo ln -s /usr/share/debootstrap/scripts/gutsy \
/usr/share/debootstrap/scripts/xenial
$ sudo ./mk-basefile XENIAL64
$ xz CENTOS7_64.tar
$ xz JESSIE64.tar
$ xz XENIAL64.tar
$ cd /srv/fai/config
$ mkdir pubkeys saltkey
$ sh config_tarball.sh
$ mv fai-*.tar /srv/tftp/fai/
configuration package
ᅟ추가 설치가 필요한 패키지가 있다면 package_config/{class} 설정 파일에 패키지명을 추가합니다. ᅟ 패키지 명령은 PACKAGES 단어 다음에 ᅟ수행할 명령 이름으로 정의합니다. 명령 이름은 apt-get, aptitude 또는 yum 과 같은 패키지 도구에 매핑됩니다.
추가로 명령 이름의 목록을 install_packages 를 사용하여 확인 할 수 있습니다.
$ sudo install_packages -H
List of known commands for package_config files
Short list:
apt
aptitude
aptitude-r
cupt
cupt-r
dnfgroup
dnfi
dnfr
dselect-upgrade
hold
install
install-norec
remove
rpmr
smarti
smartr
taskinst
taskrm
unpack
urpme
urpmi
y2i
y2r
yast
yumgroup
yumi
yumr
zypper
zypper-rm
Long list:
apt apt -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install
aptitude aptitude -R -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install
aptitude-r aptitude -r -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install
cupt cupt -R -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install
cupt-r cupt -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew install
dnfgroup dnf -y group install
dnfi dnf -y install
dnfr dnf -y remove
dselect-upgrade apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew dselect-upgrade
hold dpkg --set-selections
install apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew --fix-missing install
install-norec apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew --fix-missing install --no-install-recommends
remove apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confnew --purge remove
rpmr rpm -e
smarti smart install -y
smartr smart remove -y
taskinst tasksel install
taskrm tasksel remove
unpack cd /var/cache/apt/archives/partial/; aptitude download
urpme urpme --auto --foce --allow-force --keep
urpmi urpmi --auto --foce --allow-force --keep
y2i y2pmsh isc
y2r y2pmsh remove
yast yast -i
yumgroup yum -y groupinstall
yumi yum -y install
yumr yum -y remove
zypper zypper -n install
zypper-rm zypper -n remove
예로 debian class 에 dig, nslookup 을 사용하기 위하여 dnsutils 패키지를 추가하였습니다. install 명령 이름은 install 뒤에 지정된 모든 패키지를 설치합니다. 패키지 이름에 ᅟ하이픈이 추가되면 패키지를 제고하고 설치하지 않습니다.
아래와 같이 package_config 디렉토리로 이동하여 DEBIAN class package 설정 파일을 열어 dnsutils 패키지명을 추가하였습니다.
$ cd /srv/fai/config/package_config
$ vi DEBIAN
...
PACKAGES install I386
linux-image-686-pae initramfs-tools
memtest86+
PACKAGES install CHROOT
linux-image-686-pae-
linux-image-amd64-
PACKAGES install AMD64
linux-image-amd64 initramfs-tools
memtest86+
PACKAGES install DHCPC
isc-dhcp-client
PACKAGES install GRUB_PC
grub-pc grub-legacy- lilo-
PACKAGES install LVM
lvm2
PACKAGES install PORCH
nano-
curl
PACKAGES install
dnsutils
수정이 완료되었다면 위 create basefiles 작업에서 수행하였던 config tarball 을 다시 생성하고 이동하는 작업을 다시 진행합니다.
$ cd /srv/fai/config
$ sh config_tarball.sh
$ mv fai-*.tar /srv/tftp/fai/
porch 포털 페이지에서 os 자동 배포할 서버를 Provisioned 준비 상태로 변경 후 os 를 배포하여 정상적으로 패키지가 설치되었는지 점검합니다.
dhcp 설정
$ sudo cp porch/conf/dhcpd.conf.dev /etc/dhcp/dhcpd.conf
$ sudo vi /etc/dhcp/dhcpd.conf
subnet 10.0.0.0 netmask 255.255.0.0 {
option routers 10.0.0.23;
...
filename "http://10.0.0.150/api/fai/boot/";
...
$ sudo systemctl restart isc-dhcp-server
ᅟpxeboot 를 위한 설정
porch 로 자동설치하는 머신들은 porch 에 배포망 IP를 gateway로 설정하여 인터넷 연결이 되어야 합니다. 따라서 porch 에 IP Masquerade 설정을 합니다. 해당 매뉴얼과 같이 porch 가 가상머신으로 구동 중이라면, porch 가 구동 중인 물리머신에 배포망 IP를 gateway 로 설정합니다.
아래는 porch(debian) 에서의 설정 방법입니다.
$ sudo iptables-save > /etc/iptables.up.rules
$ vi /etc/iptables.up.rules
...
:POSTROUTING ACCEPT [6311:437650]
-A POSTROUTING -o eth0 -j MASQUERADE
...
CLI에서 수동 입력시 아래 명령으로 수행합니다.
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$ sudo vi /etc/sysctl.conf
...
net.ipv4.ip_forward=1
...
$ sudo sysctl -p
flask backend 설정
$ cp porch/porch/config.py.dev porch/porch/config.py
$ cp porch/porch/settings.py.dev porch/porch/settings.py
초기 관리자 salt/password를 먼저 생성한다.
$ python porch/scripts/create_adminpw.py
출력된 salt과 adminpw 를 config.py에 기입한다.
$ python porch/scripts/create_jwt_key.py
출력된 jwt key 를 config.py에 기입한다. Do not Edit Below!! 라인 전까지 udam 서버에 맞게 설정을 수정한다.
$ vi porch/porch/config.py
...
## URL
PORCH_URL = 'http://10.0.0.150/api/fai' # Put PORCH's pxe network ip address.
# ADMIN_* is used when there is no admin entry in etcd.
# ADMIN_SALT = bcrypt.gensalt()
# ADMIN_PW = bcrypt.hashpw(b"plaintext_password", ADMIN_SALT)
ADMIN_ID = 'admin'
ADMIN_SALT = '$2b$12$cQBcbldPwh.o5uH52J1TGO'
ADMIN_PW = '$2b$12$cQBcbldPwh.o5uH52J1TGOkc5FRxfHwfZ2oPktk4L/fDNUNOfHaue'
# JWT secret key
# Create random key: binascii.hexlify(os.urandom(24)).decode()
JWT_SECRET_KEY = '8e2edbd163909f711be60ec7ca07d0e1f8a2b540b6fef2cc'
JWT_ACCESS_TOKEN_EXPIRES = timedelta(minutes=60)
#JWT_ACCESS_TOKEN_EXPIRES is 15 minutes default.
#JWT_REFRESH_TOKEN_EXPIRES is 1 month default.
# ipmi
IPMIUSER = 'root'
IPMIPASS = 'xxxx'
# Terminal
PORCH_USER = 'porch'
PORCHSHELL = 'myshell'
TERM_PORT_BEGIN = 40000
TERM_PORT_END = 41000
MY_IP = '192.168.0.150'
# PROXY
PROXY_URL = '10.0.0.150'
PROXY_PORT = 3128
...
settings.py도 udam 서버에 맞게 설정을 수정합니다. etcd cert 경로를 지정합니다.
$ vi porch/porch/settings.py
...
# Flask settings
FLASK_HOST = '0.0.0.0'
FLASK_PORT = 8000
FLASK_DEBUG = True # Do not use debug mode in production
# Flask-Restplus settings
RESTPLUS_SWAGGER_UI_DOC_EXPANSION = 'list'
RESTPLUS_VALIDATE = True
RESTPLUS_MASK_SWAGGER = False
RESTPLUS_ERROR_404_HELP = False
# ETCD settings
ETCD_HOST = '10.0.0.150'
ETCD_PORT = 2379
ETCD_PROTO = 'https' # 'http' or 'https'
ETCD_PREFIX = '/porch'
ETCD_CERT = ('/etc/ssl/etcd/client.pem',
'/etc/ssl/etcd/client-key.pem')
ETCD_CA_CERT = '/etc/ssl/etcd/ca.pem'
기본 docker image 저장
porch에서 사용하는 기본 docker 이미지로는 myshell 이 있습니다. 해당 이미지를 이용하여 파일 배포 관리 콘솔을 사용합니다.
$ mkdir docker
$ cd docker
$ vi Dockerfile
FROM debian:jessie
MAINTAINER Heechul Kim <jijisa@iorchard.net>
LABEL version="1.0"
LABEL description="This is an image for common shell."
USER root
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y openssh-client vim dnsutils && \
apt-get clean && \
rm -fr /var/lib/apt/lists/*
$ docker build -t myshell .
이미지가 정상적으로 생성되었는지 확인합니다.
$ docker images
myshell latest a9aea684cc9f 38 seconds ago
shellinabox 설치
$ cd ~
$ sudo apt install -y git libssl-dev libpam0g-dev zlib1g-dev dh-autoreconf
$ git clone https://github.com/shellinabox/shellinabox.git
$ cd shellinabox
$ autoreconf -i
$ ./configure && make
$ sudo cp shellinaboxd /usr/local/bin/
$ cd ..
$ rm -fr shellinabox
필수 디렉토리 생성
$ mkdir porch/porch/{git,log,play}
$ mkdir porch/porch/log/{os,app,file}
symlink ansible-playbook
ansible-playbook 바이너리는 virtualenv에 저장되어 있습니다. /usr/local/bin/ 경로에 symlink 작업을 진행합니다.
$ sudo ln -s /home/udam/.envs/porch/bin/ansible-playbook /usr/local/bin/ansible-playbook
uwsgi 설치 및 설정
$ sudo apt install -y uwsgi uwsgi-plugin-python3
$ sudo cp porch/conf/uwsgi.ini /etc/uwsgi/apps-available/porch.ini
$ sudo ln -s /etc/uwsgi/apps-available/porch.ini /etc/uwsgi/apps-enabled/porch.ini
$ sudo cp /usr/share/uwsgi/conf/default.ini /etc/default/uwsgi_default.ini
$ sudo vi /etc/default/uwsgi_default.ini
chmod-socket = 666 (nginx는 www-data, 그러므로 666필요)
uid = porch
gid = porch
$ sudo vi /etc/default/uwsgi
INHERITED_CONFIG=/etc/default/uwsgi_default.ini
$ sudo systemctl restart uwsgi
nginx 설치 및 설정
$ sudo apt install -y nginx
$ sudo cp porch/conf/nginx_porch /etc/nginx/sites-available/porch
$ sudo vi /etc/nginx/sites-available/porch
- root /home/jijisa/porch/web;
+ root /home/porch/porch/web;
- uwsgi_pass unix:/home/jijisa/porch/porch.sock;
+ uwsgi_pass unix:/run/uwsgi/app/porch/socket;
$ sudo ln -sf /etc/nginx/sites-available/porch /etc/nginx/sites-enabled/default
$ sudo systemctl restart nginx
nodeenv 설치 및 설정
(porch) $ pip install nodeenv
(porch) $ nodeenv -p
quasar 설치 및 설정
(porch) $ cd porch/quasar
(porch) $ npm install -g quasar-cli
(porch) $ quasar init porch
(porch) $ cp -a src porch/
(porch) $ cp config.js porch/src/
(porch) $ cd porch
(porch) $ npm install
(porch) $ npm install vue-cookie vue-resource vuelidate vuex --save
(porch) $ vi src/config.js
export const API_URL = 'http://192.168.0.150/api'
위 IP를 porch 에 서비스 IP로 수정합니다.
(porch) $ quasar build
(porch) $ cp -a dist ~/porch/web
cli 설치 및 설정
(porch) $ cd porch/cliff
(porch) $ python setup.py build
(porch) $ cp po/config.py.dev po/config.py
(porch) $ vi po/config.py
API_ENDPOINT = 'http://localhost:80/api'
이제 웹브라우저를 열고 http://{서비스망 IP} 에 접속하여 페이지를 확인하고 관리자 계정(admin)으로 로그인 합니다. 로그인이 성공하였다면 PORCH 관리자 매뉴얼을 참조하여 인프라 자동화 서비스를 시작하도록 하겠습니다.