Welcome to taco documentation!¶
TACO 2.0 AIO 설치 가이드 (Kubernetes & Ceph Deployment)¶
이 매뉴얼은 AWS에서 생성한 EC2 환경을 기준으로 작성되었으며, Kubernetes, Ceph을 하나의 VM에 모두 설치하는 AIO (All-In-One) 가이드이다.
설치 환경¶
Single Host 사양¶
- Instance : AWS EC2
- OS : CentOS Linux 7.7.1908
- Flavor : m5.2xlarge
- vCPU : 8
- MEM : 32G <–24G 이상 권장
Installing Guide¶
계정 설정¶
이 매뉴얼에서 사용하는 계정은 centos 이며, 〈$〉로 시작하는 커맨드는 centos 계정에서 수행함을 의미한다.
- sudo 권한 부여
centos 계정에서 패스워드 없이 sudo를 사용할 수 있도록 아래와 같이 설정한다.
$ sudo visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
centos ALL=(ALL:ALL) NOPASSWD: ALL
- ssh 패스워드 설정
패스워드를 통해 ssh 로그인을 할 수 있도록 아래 변수를 yes로 바꿔준다.
$ sudo vi /etc/ssh/sshd_config
PasswordAuthentication yes
패스워드를 설정하고 변경된 sshd 설정을 반영시킨다.
$ sudo passwd centos
$ sudo systemctl restart sshd
Pre-installation¶
TACO 설치에 필요한 패키지와 소스 코드를 다운로드한다.
- 패키지 업데이트 및 다운로드
$ sudo yum update -y
$ sudo yum install -y epel-release git
$ sudo yum install -y python-pip
$ sudo yum update -y
- tacoplay 다운로드
tacoplay는 ansible playbook 모음을 이용하여 TACO를 자동으로 설치하는 프로그램이다.
$ git clone -b taco-v20.05 --single-branch https://github.com/openinfradev/tacoplay.git ~/tacoplay
$ cd $_
tacoplay에 필요한 패키지와 소스 코드를 다운로드한다.
$ sudo pip install --upgrade pip
$ sudo pip install -r requirements.txt --upgrade --ignore-installed
$ ./fetch-sub-projects.sh
인벤토리 수정¶
인벤토리 설정을 위해 필요한 로컬 정보를 아래의 방법으로 확인한다.
- { Additional_Empty_Volume } : nvme1n1 <–추가한 50G 빈 볼륨
$ lsblk
##(example)
nvme0n1 259:0 0 200G 0 disk
└─nvme0n1p1 259:1 0 200G 0 part /
nvme1n1 259:2 0 50G 0 disk
- { host_ip } : 172.32.0.81 <– 아래 출력된 결과의 9번째 줄에서 확인 가능.
- { network_cidr } : 172.32.0.0/24 <–아래에서 출력된 9번째 줄에서 확인 가능한 172.32.0.81/24의 네 번째 옥텟을 0으로 바꾼 값.
$ ip a
##(example)
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:ae:fa:f2:88:84 brd ff:ff:ff:ff:ff:ff
inet 172.32.0.81/24 brd 172.32.0.255 scope global dynamic ens5
valid_lft 3520sec preferred_lft 3520sec
inet6 fe80::ae:faff:fef2:8884/64 scope link
valid_lft forever preferred_lft forever
- 인벤토리 설정
제공된 샘플 extra-vars.yml 에서 아래와 같이 5가지 항목의 value를 수정한다.
##{ } 안에 알맞은 값을 대입하여 아래 설정을 extra-vars.yml에 저장한다.
$ vi ~/tacoplay/inventory/sample/aio/extra-vars.yml
taco_apps: [""]
monitor_interface: { ethernet_interface } ##should be edited
public_network: { network_cidr } ##should be edited
cluster_network: { network_cidr } ##should be edited
lvm_volumes:
- data: /dev/{ Addtional_Empty_Volume } ##should be edited
- (optional) LMA (Logging, Monitoring, Alerting) 설치를 위한 인벤토리 설정
LMA를 설치하면 TACO가 관리하는 리소스의 로그와 사용 현황을 확인할 수 있는 대쉬보드가 제공된다.
제공된 샘플 extra-vars.yml 에서 아래와 같이 1가지 항목의 value를 수정한다.
##taco_apps의 value에 "lma"를 추가하면 자동으로 LMA를 설치한다.
$ vi ~/tacoplay/inventory/sample/aio/extra-vars.yml
taco_apps: ["lma"]
tacoplay 실행¶
위의 설정을 모두 마쳤다면 tacoplay를 실행한다.
$ cd ~/tacoplay/
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml
테스트 환경 사양에 따라 배포 완료 시간이 30분 정도에서 1시간 정도까지 달라질 수 있다.
Taco apps 설치¶
- LMA 설치
Tacoplay를 통한 LMA 등의 taco_apps는 [Decapod](https://github.com/openinfradev/decapod-flow.git)을 사용한다. 아래 메뉴얼은 Argo CLI를 사용하는 방법이다. Argo UI(http://{ host_ip }:30004/)를 통해서도 실행할 수 있다. .. code-block:: bash
$ git clone https://github.com/openinfradev/decapod-flow.git $ cd decapod-flow/workflows $ argo submit –from wftmpl/prepare-manifest -n argo $ argo list -n argo // prepare-manifest-XXX workflow가 완료될 때 까지 기다린다.
$ argo submit lma-federation-wf.yaml
- (Optional) LMA 커스터마이징
위에서 설치한 LMA에 대한 configuration을 보거나 수정하고 싶다면, [decapod-base-yaml](https://github.com/openinfradev/decapod-base-yaml.git)과 [decapod-site-yaml](https://github.com/openinfradev/decapod-site-yaml.git)을 참조하여 자신의 site-yaml을 만들어야 한다.
- [decapod-site-yaml](https://github.com/openinfradev/decapod-site-yaml.git)을 fork한다.
- decapod-site-yaml/lma/site/hanu-deploy-apps/site-values.yaml 의 값들을 바꾸고 commit한다.
3. Argo CLI로 prepare-manifest를 다시 실행한다. .. code-block:: bash
$ argo submit –from wftmpl/prepare-manifest -p site_yaml_url=https://github.com/{ your_repo }/decapod-site-yaml.git
4. LMA를 재 배포한다. .. code-block:: bash
$ argo submit lma-federation-wf.yaml
- LMA 접속
LMA를 설치한 경우 아래 접속 정보를 참고하여 웹 브라우저로 접속해본다.
Trouble Shooting¶
- ansible 로그 확인 방법
- 디폴트로 생성되는 로그는 /tmp/ansible.log를 확인한다. 로그를 별도로 관리하고자 한다면 〈> example_file.log_0〉 옵션을 붙여 로그를 원하는 파일에 생성할 수 있다.
- ansible-playbook 명령 시 -vvvv 옵션을 추가하면 더 구체적인 로그가 기록된다.
- ansible 설치 중에 문제가 발생하여 재설치할 때 tag를 이용하여 일부 role만 수행하는 방법
tacoplay 실행 시 tacoplay/site.yml에 작성되어 있는 role의 순서대로 설치가 진행된다. 설치는 크게 보았을 때 ceph - K8s - taco_app(LMA) 순으로 진행된다. 이를 부분적으로 설치하고 싶다면 아래 명령을 수행하면 된다.
##1. 초기 세팅 및 ceph의 설치를 진행하는 커맨드(ceph이 이미 설치된 경우 에러가 발생할 수 있으니 주의한다.)
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --tags setup-os,ceph,ceph-post-install --skip-tags k8s
##2. ceph이 정상적으로 설치되었을 때, K8s를 설치하는 커맨드(ceph을 중복으로 설치하게 되면 문제가 발생하여 스킵해준다)
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --tags ceph-post-install,k8s,taco-clients --skip-tags ceph
##3. K8s까지 정상적으로 설치되었을 때, taco_app(LMA)의 배포 혹은 남은 role을 수행하는 커맨드
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --skip-tags ceph,k8s
- K8s 설치 관련 문제 발생 시
- kube-system 네임스페이스를 갖는 K8s 리소스들이 잘 작동 중인지 확인한다.
$ kubectl get pods -n kube-system
$ kubectl get services -n kube-system
$ kubectl get deployments -n kube-system
- 《The connection to the server localhost:8080 was refused - did you specify the right host or port?》와 같은 문구가 발생한다면
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
위 명령을 순차적으로 수행한다. root 계정에서는 K8s 클러스터에 접근할 수 있으나 centos와 같은 user 계정에서 접근하지 못할 때 발생한다.(참고: https://snowdeer.github.io/kubernetes/2018/02/13/kubernetes-can-not-use-kubectl/)
TACO 2.0 AIO 설치 가이드 (Kubernetes & Ceph & OpenStack Deployment)¶
이 매뉴얼은 AWS에서 생성한 EC2 환경을 기준으로 작성되었으며, Kubernetes, Ceph, OpenStack을 하나의 VM에 모두 설치하는 AIO (All-In-One) 가이드이다.
설치 환경¶
Single Host 사양¶
- Instance : AWS EC2
- OS : CentOS Linux 7.7.1908
- Flavor : m5.2xlarge
- vCPU : 8
- MEM : 32G <–24G 이상 권장
Installing Guide¶
계정 설정¶
이 매뉴얼에서 사용하는 계정은 centos 이며, 〈$〉로 시작하는 커맨드는 centos 계정에서 수행함을 의미한다.
- sudo 권한 부여
centos 계정에서 패스워드 없이 sudo를 사용할 수 있도록 아래와 같이 설정한다.
$ sudo visudo
## Allow root to run any commands anywhere
root ALL=(ALL) ALL
centos ALL=(ALL:ALL) NOPASSWD: ALL
- ssh 패스워드 설정
패스워드를 통해 ssh 로그인을 할 수 있도록 아래 변수를 yes로 바꿔준다.
$ sudo vi /etc/ssh/sshd_config
PasswordAuthentication yes
패스워드를 설정하고 변경된 sshd 설정을 반영시킨다.
$ sudo passwd centos
$ sudo systemctl restart sshd
Pre-installation¶
TACO 설치에 필요한 패키지와 소스 코드를 다운로드한다.
- 패키지 업데이트 및 다운로드
$ sudo yum update -y
$ sudo yum install -y bridge-utils epel-release git
$ sudo yum install -y python-pip
$ sudo yum update -y
- tacoplay 다운로드
tacoplay는 ansible playbook 모음을 이용하여 TACO를 자동으로 설치하는 프로그램이다.
$ git clone -b taco-v20.05 --single-branch https://github.com/openinfradev/tacoplay.git ~/tacoplay
$ cd $_
tacoplay에 필요한 패키지와 소스 코드를 다운로드한다.
$ sudo pip install --upgrade pip
$ sudo pip install -r requirements.txt --upgrade --ignore-installed
$ ./fetch-sub-projects.sh
브릿지 네트워크 구성¶
AIO node가 보유한 IP 자원을 오픈스택 위에 생성될 VM에게 할당해주기 위해서 브릿지 네트워크를 구성해야 한다. 이를 위해 필요한 로컬 정보를 아래의 방법으로 확인한다.
- { ethernet_interface }, { interface_MAC }, { host_ip }
{ ethernet_interface } : ens5 <–아래 출력된 결과의 7번째 줄, AWS에서 생성한 인스턴스가 아닌 경우 eth0 등의 이름으로 출력될 수 있다.
{ interface_MAC } : 02:ae:fa:f2:88:84 <–아래 출력된 결과의 8번째 줄
{ host_ip } : 172.32.0.81 <–아래 출력된 결과의 9번째 줄
$ ip a
##(example)
1 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
2 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
3 inet 127.0.0.1/8 scope host lo
4 valid_lft forever preferred_lft forever
5 inet6 ::1/128 scope host
6 valid_lft forever preferred_lft forever
7 2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
8 link/ether 02:ae:fa:f2:88:84 brd ff:ff:ff:ff:ff:ff
9 inet 172.32.0.81/24 brd 172.32.0.255 scope global dynamic ens5
10 valid_lft 3520sec preferred_lft 3520sec
11 inet6 fe80::ae:faff:fef2:8884/64 scope link
12 valid_lft forever preferred_lft forever
- { gateway } : 172.32.0.1 <–아래 《ip route》을 통해 알 수 있다.
$ ip route
##(example)
default via 172.32.0.1 dev ens5
172.32.0.0/24 dev ens5 proto kernel scope link src 172.32.0.81
- 브릿지 네트워크 생성
위에서 확인한 값을 바탕으로 br-data라는 이름의 브릿지 네트워크 생성을 시작한다. 사용되는 계정은 root 이며, 〈#〉로 시작하는 커맨드는 root 계정에서 수행함을 의미한다. 〈##〉로 시작하는 것은 주석을 의미한다.
$ sudo su -
# cd /etc/sysconfig/network-scripts/
##{ } 안에 알맞은 값을 대입하여 아래 설정을 ifcfg-{ ethernet_interface }에 저장한다
# vi ifcfg-{ ethernet_interface } ##should be edited
DEVICE={ ethernet_interface } ##should be edited
ONBOOT=yes
TYPE=Ethernet
BRIDGE=br-data
BOOTPROTO=none
NM_CONTROLLED=no
##{ } 안에 알맞은 값을 대입하여 아래 설정을 ifcfg-br-data에 저장한다
# vi ifcfg-br-data
BOOTPROTO=none
DEFROUTE=yes
DEVICE=br-data
GATEWAY={ gateway } ##should be edited
IPADDR={ host_ip } ##should be edited
NETMASK=255.255.255.0
ONBOOT=yes
TYPE=Bridge
STP=no
NM_CONTROLLED=no
위에서 확인한 값을 바탕으로 설정한 내용을 반영한다.
# systemctl restart network
# ip link add veth0 type veth peer name veth1
# ip link set veth0 up
# ip link set veth1 up
##{ } 안에 알맞은 값을 대입하여 아래 명령을 수행한다. 두 명령을 ';'을 통해 연속적으로 수행하지 않으면 ssh 접속이 끊길 수 있으니 주의한다.
# brctl addif br-data veth1;ifconfig br-data hw ether { interface_MAC } ##should be edited
브릿지 네트워크 구성을 마쳤다면 centos 계정으로 전환한다.
# su - centos
인벤토리 수정¶
인벤토리 설정을 위해 필요한 로컬 정보를 아래의 방법으로 확인한다.
- { Additional_Empty_Volume } : nvme1n1 <–추가한 50G 빈 볼륨
$ lsblk
##(example)
nvme0n1 259:0 0 200G 0 disk
└─nvme0n1p1 259:1 0 200G 0 part /
nvme1n1 259:2 0 50G 0 disk
- { host_ip } : 172.32.0.81 <– 아래 출력된 결과의 9번째 줄에서 확인 가능. 브릿지 네트워크를 구성한 경우에는 네트워크 구성 단계에서 확인한 { host_ip }(혹은 br-data가 갖고 있는 ip)를 사용한다.
- { network_cidr } : 172.32.0.0/24 <–아래에서 출력된 9번째 줄에서 확인 가능한 172.32.0.81/24의 네 번째 옥텟을 0으로 바꾼 값. 브릿지 네트워크를 구성한 경우에는 네트워크 구성 단계에서 확인한 { host_ip }(혹은 br-data가 갖고 있는 ip)를 통해 구한다.
$ ip a
##(example)br-data 구성하기 전
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 02:ae:fa:f2:88:84 brd ff:ff:ff:ff:ff:ff
inet 172.32.0.81/24 brd 172.32.0.255 scope global dynamic ens5
valid_lft 3520sec preferred_lft 3520sec
inet6 fe80::ae:faff:fef2:8884/64 scope link
valid_lft forever preferred_lft forever
브릿지 네트워크를 구성하였다면 아래와 비슷한 결과가 출력될 것이다. 이때 { host_ip }와 { network_cidr }은 br-data의 것을 참고한다.
$ ip a
##(example)br-data 구성한 후
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever.
2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq master br-data state UP group default qlen 1000
link/ether 02:ae:fa:f2:88:84 brd ff:ff:ff:ff:ff:ff
inet6 fe80::ae:faff:fef2:8884/64 scope link
valid_lft forever preferred_lft forever
3: br-data: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 02:ae:fa:f2:88:84 brd ff:ff:ff:ff:ff:ff
inet 172.32.0.81/24 brd 172.32.0.255 scope global br-data
valid_lft forever preferred_lft forever
inet6 fe80::ae:faff:fef2:8884/64 scope link
valid_lft forever preferred_lft forever
4: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br-data state UP group default qlen 1000
link/ether 1e:88:df:ce:3a:43 brd ff:ff:ff:ff:ff:ff
inet6 fe80::1c88:dfff:fece:3a43/64 scope link
valid_lft forever preferred_lft forever
5: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 06:12:1a:0a:65:25 brd ff:ff:ff:ff:ff:ff
inet6 fe80::412:1aff:fe0a:6525/64 scope link
valid_lft forever preferred_lft forever
- 인벤토리 설정
제공된 sample extra-vars.yml 파일에서 아래와 같이 5가지 항목의 value를 수정한다.
##{ } 안에 알맞은 값을 대입하여 아래 설정을 extra-vars.yml에 저장한다.
$ vi ~/tacoplay/inventory/sample/aio/extra-vars.yml
taco_apps: ["openstack"]
monitor_interface: br-data
public_network: { network_cidr } ##should be edited
cluster_network: { network_cidr } ##should be edited
lvm_volumes:
- data: /dev/{ Additional_Empty_Volume } ##should be edited
- (optional) LMA (Logging, Monitoring, Alerting) 설치를 위한 인벤토리 설정
LMA를 설치하면 TACO가 관리하는 리소스의 로그와 사용 현황을 확인할 수 있는 대쉬보드가 제공 된다.
제공된 샘플 extra-vars.yml 에서 아래와 같이 1가지 항목의 value를 수정한다.
##taco_apps의 value에 "lma"를 추가하면 자동으로 LMA를 설치한다.
$ vi ~/tacoplay/inventory/sample/aio/extra-vars.yml
taco_apps: ["openstack","lma"]
tacoplay 실행¶
위의 설정을 모두 마쳤다면 tacoplay를 실행한다.
$ cd ~/tacoplay/
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml
테스트 환경 사양에 따라 배포 완료 시간이 40분에서 2시간까지 달라질 수 있다.
Taco apps 설치¶
- OpenStack 설치
Tacoplay를 통한 OpenStack 등의 taco_apps는 [Decapod](https://github.com/openinfradev/decapod-flow.git)을 사용한다. 아래 메뉴얼은 Argo CLI를 사용하는 방법이다. Argo UI(http://{ host_ip }:30004/)를 통해서도 실행할 수 있다. .. code-block:: bash
$ git clone https://github.com/openinfradev/decapod-flow.git $ cd decapod-flow/workflows $ argo submit –from wftmpl/prepare-manifest -n argo $ argo list -n argo // prepare-manifest-XXX workflow가 완료될 때까지 기다린다.
$ argo submit openstack-infra-wf.yaml // openstack-infra-XXX workflow 가 완료될 때까지 기다린다. $ argo submit openstack-components-wf.yaml
- (Optional) OpenStack 커스터마이징
위에서 설치한 OpenStack 대한 configuration을 보거나 수정하고 싶다면, [decapod-base-yaml](https://github.com/openinfradev/decapod-base-yaml.git)과 [decapod-site-yaml](https://github.com/openinfradev/decapod-site-yaml.git)을 참조하여 자신의 site-yaml을 만들어야 한다.
- [decapod-site-yaml](https://github.com/openinfradev/decapod-site-yaml.git)을 fork한다.
- decapod-site-yaml/openstack/site/hanu-deploy-apps/site-values.yaml 의 값들을 바꾸고 commit한다.
3. Argo CLI로 prepare-manifest를 다시 실행한다. .. code-block:: bash
$ argo submit –from wftmpl/prepare-manifest -p site_yaml_url=https://github.com/{ your_repo }/decapod-site-yaml.git
4. OpenStack 재 배포한다. .. code-block:: bash
$ argo submit openstack-infra-wf.yaml // openstack-infra-XXX workflow 가 완료될 때까지 기다린다. $ argo submit openstack-components-wf.yaml
$ watch 'kubectl get pods -n openstack' ##openstack을 구성하는 모든 파드를 모니터링
$ watch 'kubectl get pods -n openstack | grep -v Comp' ##Completed 상태인 파드를 제외하고 모니터링
$ watch 'kubectl get pods -n openstack | grep -v Comp | grep -v Runn' ##Completed 혹은 Running 상태인 파드를 제외하고 모니터링
$ watch 'kubectl get pods -n lma' ##lma를 구성하는 모든 파드를 모니터링
$ watch 'kubectl get pods -n fed' ##fed(fedaration) 관련 파드를 모니터링
$ watch 'kubectl get pods -A' ##모든 K8s 파드를 모니터링(kube-system, openstack, lma, fed)
- 오픈스택 설치 확인
웹 브라우저를 통해 { host_ip }:31000 접속하여 openstack 웹 콘솔이 나타나는지 확인한다.

- LMA 접속
LMA를 설치한 경우 아래 접속 정보를 참고하여 웹 브라우저로 접속해본다.
- 오픈스택 VM 생성을 위한 네트워크 토폴로지 구성
네트워크를 구성해주어야 오픈스택에서 인스턴스를 생성할 수 있다. 다음은 centos 계정에 생성된 os_client를 통해 예시 네트워크를 구성하는 절차이다.
$ sh /home/centos/os_client.sh
~$ openstack network create private-net
~$ openstack subnet create --network private-net --subnet-range 172.30.1.0/24 --dns-nameserver 8.8.8.8 private-subnet
~$ openstack network create --external --share --provider-network-type flat --provider-physical-network provider provider-net
~$ openstack subnet create --network provider-net --subnet-range 192.168.97.0/24 --dns-nameserver 8.8.8.8 provider-subnet --allocation-pool 192.168.97.122=192.168.97.122,192.168.97.46=192.168.97.46,192.168.97.231=192.168.97.231,192.168.97.115=192.168.97.115
~$ openstack network create --external --share --provider-network-type flat --provider-physical-network provider provider-net
~$ openstack subnet create --network provider-net --subnet-range 192.168.97.0/24 --dns-nameserver 8.8.8.8 provider-subnet--allocation-pool 192.168.97.91=192.168.97.91,192.168.97.70=192.168.97.70,192.168.97.31=192.168.97.31,192.168.97.182=192.168.97.182
~$ openstack network create --external --share --provider-network-type flat --provider-physical-network provider provider-net
~$ openstack subnet create --network provider-net --subnet-range 192.168.97.0/24 --dns-nameserver 8.8.8.8 provider-subnet--allocation-pool 192.168.97.52=192.168.97.52,192.168.97.206=192.168.97.206,192.168.97.192=192.168.97.192,192.168.97.13=192.168.97.13
~$ openstack router create admin-router
~$ openstack router add subnet admin-router private-subnet
~$ openstack router set --external-gateway provider-net admin-router
~$ openstack router show admin-router
~$ openstack security group list --project admin | grep default | awk '{print $2}'
##출력되는 값을 { security_group } 이라고 하자
##{ }안에 알맞은 값을 대입하여 명령을 실행한다.
~$ openstack security group rule create --proto tcp --remote-ip 0.0.0.0/0 --dst-port 1:65535 --ingress { security_group }
~$ openstack security group rule create --protocol icmp --remote-ip 0.0.0.0/0 { security_group }
~$ openstack security group rule create --protocol icmp --remote-ip 0.0.0.0/0 --egress { security_group }
네트워크를 구성했다면 { host_ip }:31000 으로 접속하여 Compute > 인스턴스 탭에서 인스턴스를 추가할 수 있다. 제공되는 cirros 이미지를 사용하여 인스턴스를 생성했다면, 인스턴스명을 클릭하여 콘솔탭으로 접근한다. cirros의 default 로그인 정보는 cirros / gocubsgo 이다.(콘솔이 정상적으로 열리지 않는다면 웹페이지 새로고침을 반복한다.)
Trouble Shooting¶
- ansible 로그 확인 방법
- 디폴트로 생성되는 로그는 /tmp/ansible.log를 확인한다. 로그를 별도로 관리하고자 한다면 〈> example_file.log_0〉 옵션을 붙여 로그를 원하는 파일에 생성할 수 있다.
- ansible-playbook 명령 시 -vvvv 옵션을 추가하면 더 구체적인 로그가 기록된다.
- ansible 설치 중에 문제가 발생하여 재설치할 때 tag를 이용하여 일부 role만 수행하는 방법
tacoplay 실행 시 tacoplay/site.yml에 작성되어 있는 role의 순서대로 설치가 진행된다. 설치는 크게 보았을 때 ceph - K8s - taco_app(오픈스택 및 LMA) 순으로 진행된다. 이를 부분적으로 설치하고 싶다면 아래 명령을 수행하면 된다.
##1. 초기 세팅 및 ceph의 설치를 진행하는 커맨드(ceph이 이미 설치된 경우 에러가 발생할 수 있으니 주의한다.)
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --tags setup-os,ceph,ceph-post-install --skip-tags k8s
##2. ceph이 정상적으로 설치되었을 때, K8s를 설치하는 커맨드(ceph을 중복으로 설치하게 되면 문제가 발생하여 스킵해준다)
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --tags ceph-post-install,k8s,taco-clients --skip-tags ceph
##3. K8s까지 정상적으로 설치되었을 때, taco_app(오픈스택 및 LMA)의 배포 혹은 남은 role을 수행하는 커맨드
$ ansible-playbook -b -i inventory/sample/aio/hosts.ini -e @inventory/sample/aio/extra-vars.yml site.yml --skip-tags ceph,k8s
- K8s 설치 관련 문제 발생 시
- kube-system 네임스페이스를 갖는 K8s 리소스들이 잘 작동 중인지 확인한다.
$ kubectl get pods -n kube-system
$ kubectl get services -n kube-system
$ kubectl get deployments -n kube-system
- 《The connection to the server localhost:8080 was refused - did you specify the right host or port?》와 같은 문구가 발생한다면
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
위 명령을 순차적으로 수행한다. root 계정에서는 K8s 클러스터에 접근할 수 있으나 centos와 같은 user 계정에서 접근하지 못할 때 발생한다.(참고: https://snowdeer.github.io/kubernetes/2018/02/13/kubernetes-can-not-use-kubectl/)
- 오픈스택 설치 관련 문제 발생 시
- 설치 로그는 /tmp/openstack-deployment.log를 확인한다.
- openstack 네임스페이스를 갖는 K8s 리소스들이 잘 작동 중인지 확인한다.
$ kubectl get pods -n openstack
- 문제가 생긴 파드가 있다면 events 및 log를 살핀다.
$ kubectl get pods -n openstack ##문제가 생긴 pod의 이름을 확인한다.
$ kubectl describe pods -n openstack example_pod_name
$ kubectl logs -n openstack example_pod_name
- helm 설치가 정상적인지 확인한다. helm의 설치는 tacoplay/kubespray/roles/kubernetes-apps/helm/tasks/main.yml 에서 진행된다.
$ helm version
Client: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.16.1", GitCommit:"bbdfe5e7803a12bbdf97e94cd847859890cf4050", GitTreeState:"clean"}
- helm chart가 정상적으로 배포되었는지 확인한다.
$ helm list -a
- horizon 파드가 ready 상태가 되지 못하고 restart가 반복될 때
사용된 single host 인스턴스의 사양이 낮은 경우 horizon 파드 내 compress 관련 role이 늦게 처리되어 문제가 발생할 수 있다. 아래 명령을 통해 horizon deployment 설정에 접근하여 〈initialDelaySeconds〉 항목 2개를 찾아 value를 180으로, 〈periodSeconds〉 항목 2개를 찾아 value를 600으로 변경해준다.
$ kubectl edit deployment -n openstack horizon
86 livenessProbe:
87 failureThreshold: 3
88 httpGet:
89 path: /
90 port: 80
91 scheme: HTTP
92 initialDelaySeconds: 180 ##HERE
93 periodSeconds: 600 ##HERE
94 successThreshold: 1
95 timeoutSeconds: 5
101 readinessProbe:
102 failureThreshold: 3
103 httpGet:
104 path: /
105 port: 80
106 scheme: HTTP
107 initialDelaySeconds: 180 ##HERE
108 periodSeconds: 600 ##HERE
109 successThreshold: 1
110 timeoutSeconds: 1
TACOPLAY¶
Introduction¶
tacoplay는 TACO를 구성하고 있는 다양한 서비스를 쉽게 설치하고 설정할 수 있게 해 주는 ansible playbook의 모음으로, 오픈 소스 프로젝트들과 자체 개발한 playbook들로 이뤄져 있다. 다음은 TACO에서 사용하는 오픈소스 프로젝트로 괄호 안은 해당 소프트웨어를 설치하는 데 사용하고 있는 주요 오픈 소스 프로젝트다.
- Docker registry
- Ceph
- Kubernetes (Kubespray)
- Airship-armada
- OpenStack (Helm / openstack-helm)
- Logging, Monitoring, Alarm (openstack-helm-infra)
주요 기능은 다음과 같다.
- 필요한 소프트웨어들을 한 번에 설치, 제거, 확장할 수 있는 통합 playbook 제공
- 각 소프트웨어의 정상 동작에 필요한 OS 설정 자동화
- 각 소프트웨어들 간의 통합 연동 설정
- 인터넷 접근이 불가능한 환경에서의 구축을 위한 설정 간소화
tacoplay 구성¶
서브 프로젝트¶
- armada: armada 설치에 필요한 소스
- ceph-ansible: ceph 설치 자동화를 위한 ansible playbook
- kubespray: kubernetes 설치 자동화를 위한 ansible playbook
- charts: kubernetes위에 openstack을 배포하기 위한 helm chart
playbooks¶
site-prepare.yml
: 설치에 필요한 모든 리소스를 tar로 묶어줌(단, OS 패키지 및 python 패키지 제외)site-assert.yml
: 설정 검증site.yml
: 클러스터 설치armada-apply.yml
: 설치 후, armada manifest 설정만 변경/적용하고 싶은 경우에 사용scale.yml
: 클러스터 확장reset.yml
: 클러스터 삭제
roles¶
setup-os
: TACO 실행에 필요한 부가적인 OS 설정을 제공(local repo 설정, NAT/TC 룰 설정)docker
: docker 설치docker-registry
: TACO 설치에 필요한 docker 이미지들을 서비스 할 docker registry 컨테이너를 실행rbd_provisioner
: rbd 기반의 PV를 사용할 때 필요한 provisioner와 storage class를 생성admin-node
: ceph, kubectl, helm, openstack 등의 admin operation이 가능하도록 클라이언트 툴 설치 및 설정openstack/client
: openstack client 패키지를 설치하고, ingress를 통해 openstack 서비스 endpoint에 접근 가능하도록 호스트 파일 설정 추가openstack/setup-os
: openstack 실행에 필요한 커널 모듈 로드 및 부가적인 OS 설정openstack/preinstall
: openstack 배포 전에 k8s에 openstack namespace 및 cluster role binding 리소스 생성openstack/openstack-defaults
: taco에서 사용하는 openstack 기본 설정값 정의armada/install
: armada 설치armada/apply
: manifest template으로부터 armada-manifest.yml 파일 생성, 실제로 openstack을 배포하는 액션인 armada apply 명령을 실행
vars¶
- taco에서 사용하고 있는 기본 설정 값을 정의해 둔 것으로, 사이트 별 설정 적용은 vars 아래의 파일을 직접 수정하지 않고 extra-vars 파일을 통해 override 하도록 한다
global_
: 모든 사이트에 공통 적으로 적용해야 하는 설정global_ceph.yml
: ceph-ansible 실행 시 적용할 기본 설정global_docker.yml
: role/docker와 kubespray/roles/container-enbine/docker 실행 시 적용할 기본 설정global_k8s-cluster.yml
: kubespray 실행 시 적용할 기본 설정global_k8s-images.yml
: kubespray로 k8s 설치 시에 필요한 컨테이너 이미지 다운로드 URL 설정, local registry가 있는 경우에만 선택적으로 사용함global_taco.yml
: taco playbook 및 role에서 정의하고 있는 value들의 모음
site_specific.yml
: 사이트 별로 꼭 확인/적용해야 하는 value들의 모음
tests¶
adminrc
cirros-0.4.0-x86_64-disk.img
taco-test.sh
인벤토리 구성 방법¶
새로운 사이트 구축을 위한 인벤토리를 구성할 때는 기본적으로 아래의 세 가지 파일을 생성해 줘야 하며, 경우에 따라서는 group_vars나 hosts_vars를 추가해 주기도 한다.
hosts.ini
extra-vars.yml
armada-manifest.yml
hosts.ini 구성 방법¶
호스트파일을 생성하기 위해서는 우선 클러스터를 구성하는 물리 노드들의 역할을 정해줘야 한다.
구축 형상 예시)

tacoplay에서는 크게 다음의 노드 그룹(역할)을 정의하고 있다. 여건에 따라 하나의 노드가 여러개의 역할을 수행해도 관계 없다.
- tacoplay
- admin-node
- registry
- controller-node
- compute-node
- ceph-ansible
- mons
- osds
- mgrs
- clients
- kubespray
- etcd
- kube-master
- kube-node
- kube-cluster
TACO 클러스터를 구성하는 노드들의 역할을 먼저 정한 다음 그에 맞게 위에서 설명한 노드 그룹에 배치하면 된다. 부가적으로 k8s 설치 후 적용할 노드 라벨에 한해서만 설정 값을 hosts.ini에 정의해 주고 있다. 유의 할 점은, 그룹 별 라벨 설정 값은 자동으로 merge가 되지 않는다.
[controller-node]
ctrl01-prd
ctrl02-prd
ctrl03-prd
[compute-node]
com01-prd
com02-prd
[controller-node:vars]
node_labels={"fluent-logging":"enabled", "node-exporter":"enabled", "openstack-control-plane":"enabled", "linuxbridge":"enabled"}
[compute-node-r06:vars]
node_labels={"fluent-logging":"enabled", "node-exporter":"enabled", "openstack-compute-node":"enabled", "linuxbridge":"enabled"}
[controller-node]
node01
node02
node03
[compute-node]
node01
node02
node03
[controller-node:vars]
node_labels={"fluent-logging":"enabled", "node-exporter":"enabled", "openstack-control-plane":"enabled", "openstack-compute-node":"enabled", "linuxbridge":"enabled"}
인벤토리를 구성하는 호스트의 그룹 별로 특정 설정 값을 다르게 적용해야 하는 경우 혹은 새로운 호스트 그룹을 추가해야 하는 경우 인벤토리 파일에 새로운 그룹을 정의해 주면 편하다. 아래는 rack04와 rack06 두 개의 랙으로 구성된 클러스터의 인벤토리 파일 구성 예시다.
(생략)
# Kubernetes cluster
[kube-master]
master01-prd
master02-prd
master03-prd
[etcd]
master01-prd
master02-prd
master03-prd
[kube-node]
ctrl01-prd
ctrl02-prd
ctrl03-prd
com01-prd-r06
com02-prd-r06
com11-prd-r04
com12-prd-r04
[rack06]
master01-prd
master02-prd
master03-prd
ctrl01-prd
ctrl02-prd
ctrl03-prd
com01-prd-r06
com02-prd-r06
[rack04]
com11-prd-r04
com12-prd-r04
(생략)
이렇게 정의 해 두면 rack04를 확장할 때 다음처럼 그룹 이름만 넘겨주는 것이 가능하다.
$ ansible-playbook -b -i inventory/product-vm/hosts.ini scale.yml --limit etcd,rack04
extra-vars.yml 설정 방법¶
extra-vars.yml
에는 기본적으로 vars/site_specific.yml
에 정의해 둔 설정 값을 사이트에 맞게 적어주면 된다. 특정 설정 값에 의존성이 있는 설정 값들도 있으므로 vars/site_specific.yml
을 잘 읽어보기를 권장한다.
설정 값 | 관련 playbook | description |
---|---|---|
cicd_registry_enabled | tacoplay | VS lab 내부 registry 사용 여부, 외부에서는 항상 false |
localrepo_enabled | tacoplay | Local repo 사용 여부 |
localrepo_yum | tacoplay | Local yum repo URL |
localrepo_k8s | tacoplay | Local k8s 바이너리 repo URL |
localrepo_pypi | tacoplay | Local pypi 서버 |
taco_storage | tacoplay | PV 생성에 사용할 backend storage 타입(기본값: rbd) |
ceph_monitors | tacoplay | Ceph monitor 주소, tacoplay로 ceph을 설치하지 않고 연동만 하는 경우에만 설정 |
ceph_admin_keyring | tacoplay | Ceph admin keyring 값, tacoplay로 ceph을 설치하지 않고 연동만 하는 경우에만 설정 |
monitor_interface | ceph-ansible | Ceph monitor 주소가 할당된 인터페이스 이름, tacoplay로 ceph을 설치하는 경우에만 설정 |
public_network | ceph-ansible | Ceph public network 대역, tacoplay로 ceph을 설치하는 경우에만 설정 |
cluster_network | ceph-ansible | Ceph cluster network 대역, tacoplay로 ceph을 설치하는 경우에만 설정 |
osd_objectstore | ceph-ansible | Ceph object store 타입, tacoplay로 ceph을 설치하는 경우에만 설정 |
lvm_volumes | ceph-ansible | Ceph에서 사용할 lvm volume 목록, tacoplay로 ceph을 설치하는 경우에만 설정 |
kube_pods_subnet | kubespray | K8S pod에 할당할 IP 대역 |
kube_service_addresses | kubespray | K8S service IP로 사용할 대역 |
ipip_mode | kubespray | Pod 간 통신 시에 ipip 터널링 사용 여부, 클라우드 환경에서 보통 true, 베어메탈 구축 시 보통 false |
peer_with_router | kubespray | 인프라 router에 pod 대역을 광고할 지 여부, 클러스터 스케일을 고려해 결정 |
group_vars 설정 방법¶
노드 그룹 별로 설정 값을 다르게 줘야 하는 경우 인벤토리 디렉토리 아래에 group_vars 디렉토리를 만들고 group_name.yml
파일을 만들어 각 그룹에 적용할 설정 값을 추가하면 된다. 참고로 group_vars의 우선순위는 extra_vars 보다 낮기 때문에 group_vars에 정의한 값은 extra_vars에 존재하지 않도록 유의한다. 아래는 rack06과 rack04에 각각 다른 설정을 적용한 예시다.
[taco@admin-prd tacoplay]$ ls -l inventory/lab-prd/group_vars/
total 8
-rw-rw-r--. 1 taco taco 79 Feb 20 16:21 rack04.yml
-rw-rw-r--. 1 taco taco 121 Feb 20 16:21 rack06.yml
[taco@admin-prd tacoplay]$ cat inventory/lab-prd/group_vars/rack06.yml
# calico
local_as: 64517
peers:
- as: 64517
router_id: 192.168.95.2
- as: 64517
router_id: 192.168.95.3
[taco@admin-prd tacoplay]$ cat inventory/lab-prd/group_vars/rack04.yml
# calico
local_as: 64518
peers:
- as: 64518
router_id: 192.168.96.1
host_vars 설정 방법¶
호스트 별로 설정 값을 다르게 줘야 하는 경우 인벤토리 디렉토리 아래에 host_vars 디렉토리를 만들고 host_name.yml
파일을 만들어 각 호스트에 적용할 값을 추가하면 된다. 마찬가지로 host_vars의 우선순위는 extra_vars 보다 낮기 때문에 host_vars에 정의한 값은 extra_vars에 존재하지 않도록 유의한다. 아래는 호스트 별로 다른 설정을 적용한 예시다.
[taco@admin-prd tacoplay]$ cat inventory/dev/hosts.ini
(생략)
taco-ceph01 ip=90.90.230.26
taco-ceph02 ip=90.90.230.27
taco-ceph03 ip=90.90.230.28
[taco@admin-prd tacoplay]$ ls -l inventory/dev/host_vars/
total 12
-rw-rw-r--. 1 taco taco 140 Feb 21 10:11 taco-ceph01.yml
-rw-rw-r--. 1 taco taco 193 Feb 21 10:11 taco-ceph02.yml
-rw-rw-r--. 1 taco taco 192 Feb 21 10:11 taco-ceph03.yml
[taco@admin-prd tacoplay]$ cat inventory/dev/host_vars/taco-ceph01.yml
# 1.92TB x 6
lvm_volumes:
- data: /dev/sdb
- data: /dev/sdc
- data: /dev/sdd
- data: /dev/sde
- data: /dev/sdf
- data: /dev/sdg
[taco@admin-prd tacoplay]$ cat inventory/dev/host_vars/taco-ceph02.yml
# 1.92TB x 7 and 960GB x 1
lvm_volumes:
- data: /dev/sda
- data: /dev/sdb
- data: /dev/sdd
- data: /dev/sde
- data: /dev/sdf
- data: /dev/sdg
- data: /dev/sdh
- data: /dev/sdi
[taco@admin-prd tacoplay]$ cat inventory/dev/host_vars/taco-ceph03.yml
# 1.92TB x 7 and 960GB x 1
lvm_volumes:
- data: /dev/sda
- data: /dev/sdb
- data: /dev/sdd
- data: /dev/sde
- data: /dev/sdf
- data: /dev/sdg
- data: /dev/sdh
- data: /dev/sdi
Playbook Details¶
site-prepare.yml¶
site-prepare.yml
은 taco 설치에 필요한 모든 컨테이너 이미지와 파일들을 tar로 묶어주는 기능을 한다.
인터넷이 없는 환경에서는 OS 패키지와 python 패키지 미러를 따로 구축하여야한다.
site.yml¶
site assert¶
인벤토리를 검증하는 단계로, 빠진 설정이 없는지 확인하는 로직이 들어있다. 구축 담당자의 편의를 위해 사이트마다 꼭 확인해야 할 설정들은 vars/site_specific.yml
에서 《TACOFIXME》라는 값으로 오버라이드하고 있는데, 이런 값들은 사이트 인벤토리의 extra-vars.yml
파일에서 알맞은 값으로 꼭 오버라이드 해서 ansible-playbook 실행 시에 《-e》 옵션으로 넘겨 줘야 한다. 그렇지 않으면 site assert 단계에서 오류를 발생시켜 더 이상 진행되지 않는다.
# Assert inventory
- import_playbook: site-assert.yml
tags: assert
# set localrepo_yum, k8s, pypi as well when localrepo is enabled
localrepo_enabled: TACOFIXME
localrepo_yum: TACOFIXME
localrepo_k8s: TACOFIXME
localrepo_pypi: TACOFIXME
localrepo_enabled: true
localrepo_yum: 192.168.95.11
localrepo_k8s: 192.168.95.11
localrepo_pypi: 192.168.95.11
- name: Assert localrepo urls are set properly
assert:
that: "{{ item }} != 'TACOFIXME'"
with_items:
- localrepo_pypi
- localrepo_yum
- localrepo_k8s
when: localrepo_enabled
tags: always
variable include¶
Global 및 site specific variable을 적용한다. extra-vars.yml
은 ansible-playbook 실행 명령을 통해 적용하게 된다. 참고로 extra vars의 우선순위가 가장 높으며, 사이트 특수하게 적용하고 싶은 값은 extra-vars.yml이나 필요시 인벤토리 아래에 group_vars나 host_vars 디렉토리를 만들어 해당 그룹이나 호스트에만 설정 값을 적용하는 것이 가능하므로, tacoplay/vars 아래의 파일들은 가급적 수정하지 않도록 한다.
- hosts: localhost:all
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
tasks:
- name: include global override files
include_vars: "{{ item }}"
loop:
- "{{ playbook_dir }}/vars/global_taco.yml"
- "{{ playbook_dir }}/vars/global_docker.yml"
- "{{ playbook_dir }}/vars/global_ceph.yml"
- "{{ playbook_dir }}/vars/global_k8s-cluster.yml"
- "{{ playbook_dir }}/vars/site_specific.yml"
- name: include global override files
include_vars: "{{ item }}"
loop:
- "{{ playbook_dir }}/vars/global_k8s-images.yml"
when: groups['registry'] is defined and (groups['registry'] | length > 0)
tags: always
populate hostname in hostfile¶
/etc/hosts 파일에 각 노드의 hostname을 추가한다. OpenStack nova-compute 실행에 필요한 설정 값으로 향후 role/openstack/setup-os로 옮기는 것이 맞다.
# Populate hostname to hosts file
- hosts: taco
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
tasks:
- name: make sure hostname is in hosts file
replace:
dest: /etc/hosts
regexp: '^(127\.0\.0\.1(?!.*\b{{ inventory_hostname }}\b).*)$'
replace: '\1 {{ inventory_hostname }}'
tags: always
Prepare OS¶
설정에 따라 OS에 TC, NAT 룰을 설정하고, firewalld 서비스를 disable 시키고(향후 선택적으로 활성화시키는 방법을 고려하는 것이 좋을 것 같다), local repo를 사용하는 경우 localrepo.repo 파일을 만들어 모든 노드의 /etc/yum.repo.d/ 아래에 복사한다.
- hosts: taco
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: taco-defaults }
- { role: setup-os }
tags: setup-os
Docker registry¶
kubespray와 openstack 배포에 필요한 docker 이미지를 서비스하기 위한 작업이다. docker registry 서비스에 필요한 이미지는 tacoplay/docker_registry 아래에 포함되어 있다.
# Run docker registry
- hosts: registry
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: taco-defaults }
- { role: docker }
- { role: docker-registry }
tags: registry
Install Ceph¶
taco storage로 ceph을 사용하는 경우에 한해 ceph을 설치한다. 인벤토리 구성에 따라 ceph 클러스터를 새로 구축하기도 하고, 이미 구축된 ceph을 연동만 하는 경우 ceph client만 설치하기도 한다.
# Install Ceph
- import_playbook: ceph-ansible/site.yml
tags: ceph
when: taco_storage == 'ceph'
Install K8S¶
Kubernetes를 설치하고, admin 노드에 kubeconfig와 kubectl, helm 바이너리를 복사한다(참고로, 이후의 모든 k8s 리소스 생성은 admin-node에서 수행한다). 더불어 ceph을 사용하는 경우 rbd_provisioner를 생성하고, rbd 기반의 PV를 사용할 수 있도록 설정한다.
# Install K8S
- import_playbook: kubespray/cluster.yml
tags: k8s
- hosts: taco
roles:
- { role: taco-defaults }
- { role: admin-node }
tags: k8s
- hosts: admin-node
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: taco-defaults }
- { role: rbd_provisioner, when: rbd_provisioner_enabled }
tags: k8s
OpenStack 배포 준비 및 배포¶
먼저 openstack 클러스터에 포함된 모든 노드를 대상으로 openstack 서비스에 필요한 OS 설정 작업을 한다. 즉, 필요한 kernel 모듈을 올리거나 /dev/kvm의 권한을 확인하는 등의 작업이 이뤄진다. 그리고 openstack 배포 툴로 사용하고 있는 armada를 admin 노드의 virtual env에 설치하고 armada/apply 과정에서 실제 배포 작업을 수행한다.
armada 설치가 완료되면, inventory 아래에 armada-manifest.yaml
이 존재하지 않는 경우 template으로부터 armada-manifest.yaml
을 생성해서 배포 명령을 실행한다. armada-manifest.yaml
이 존재한다면 template 작업은 생략한다. armada apply 명령을 실행한 후에는 openstack client 설정에 필요한 리소스(ingress controller pod)가 올라올 때 까지만 기다렸다가 openstack client 설치 및 openstack 서비스 접근을 위한 호스트파일 설정을 하고 site.yml playbook은 끝난다.
# Tune system for OpenStack
- hosts: controller-node:compute-node
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: openstack/setup-os }
tags: openstack
# Prepare armada-manifests and then run armada apply
- hosts: admin-node
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: armada/install, tags: armada }
- { role: openstack/pre-install, tags: openstack }
- { role: openstack/openstack-defaults, tags: openstack }
- { role: armada/apply, tags: armada }
- hosts: admin-node:controller-node
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
roles:
- { role: openstack/openstack-defaults }
- { role: openstack/client }
tags: openstack
armada-apply.yml¶
site.yml playbook을 적어도 한번 성공적으로 수행한 후(최소한 armada 설치까지), armada-manifest.yml만 수정해서 적용하고 싶은 경우 사용한다.
$ ansible-playbook -v -b -i inventory/sample.ini armada-apply.yml
scale.yml¶
taco 구축 후 노드를 확장하고 싶은 경우 사용한다. 노드 확장 절차와 playbook 실행 명령은 Adding nodes with Kubespray 를 참고한다.
Adding nodes with Kubespray¶
새로운 노드 추가 절차¶
/etc/hosts 업데이트¶
Ansible 호스트의 /etc/hosts에 새로운 노드의 ansible SSH 접속 IP를 추가한다. 보통 매니지먼트 네트워크와 동일하다. 아래는 com-3, com-4, com-5 노드를 추가하는 예시다.
[centos@deployer tacoplay]$ sudo sed -i -e "\$a 172.80.0.17 com-3" /etc/hosts
[centos@deployer tacoplay]$ sudo sed -i -e "\$a 172.80.0.18 com-4" /etc/hosts
[centos@deployer tacoplay]$ sudo sed -i -e "\$a 172.80.0.19 com-5" /etc/hosts
SSH key 복사¶
Ansible 호스트에서 새로 추가된 노드로 password 없이 ssh 접근이 가능하도록 설정한다.
[centos@deployer tacoplay]$ ssh-copy-id com-3
[centos@deployer tacoplay]$ ssh-copy-id com-4
[centos@deployer tacoplay]$ ssh-copy-id com-5
인벤토리 파일 업데이트¶
인벤토리 파일에 새로 추가된 노드 정보를 넣어 준다.
[centos@deployer tacoplay]$ vi inventory/sample/hosts.ini
# ## Configure 'ip' variable to bind kubernetes services on a
# ## different ip than the default iface
master-1 ip=172.80.0.9
master-2 ip=172.80.0.11
master-3 ip=172.80.0.6
ctrl-1 ip=172.80.0.10
ctrl-2 ip=172.80.0.5
ctrl-3 ip=172.80.0.4
com-1 ip=172.80.0.7
com-2 ip=172.80.0.8
# 추가할 노드들의 이름과 매니지먼트 IP 추가
com-3 ip=172.80.0.17
com-4 ip=172.80.0.18
com-5 ip=172.80.0.19
[kube-node]
ctrl-1
ctrl-2
ctrl-3
com-1
com-2
# 추가할 노드의 이름 추가
com-3
com-4
com-5
[compute-node]
com-1
com-2
# 추가할 노드의 이름 추가
com-3
com-4
com-5
# 추가할 노드 수가 많은 경우 추가할 노드들로 구성된 그룹 추가
# scale.yml playbook 실행 시, limit 인자 값으로 새로 추가된 노드들만 넘길 때 유용하다
[new-nodes]
com-3
com-4
com-5
Scale playbook 실행¶
[centos@deployer tacoplay]$ ansible-playbook -b -i inventory/sample/hosts.ini scale.yml --limit etcd,new-nodes
Kubespray¶
주요기능¶
- Can be deployed on AWS, GCE, Azure, OpenStack, vSphere, Oracle Cloud Infrastructure (Experimental), or Baremetal
- Highly available cluster
- Composable (Choice of the network plugin for instance)
- Supports most popular Linux distributions
- Continuous integration tests
주요 Playbook¶
- cluster.yml : k8s 클러스터 설치
- remove-node.yml : 설치된 k8s 클러스터에서 노드 삭제
- reset.yml : k8s 클러스터 삭제
- scale.yml : 설치된 k8s 클러스터에 노드 추가
- upgrade-cluster.yml : 설치된 k8s 클러스터의 버전 업그레이드
Group¶
- kube-node : list of kubernetes nodes where the pods will run.
- kube-master : list of servers where kubernetes master components (apiserver, scheduler, controller) will run.
- etcd: list of servers to compose the etcd server. You should have at least 3 servers for failover purpose.
/kubespray/roles/¶
.
├── adduser
│ ├── defaults
│ ├── tasks
│ └── vars
├── bastion-ssh-config
│ ├── tasks
│ └── templates
├── bootstrap-os
│ ├── defaults
│ ├── files
│ ├── tasks
│ └── templates
├── container-engine
│ ├── cri-o
│ │ ├── defaults
│ │ ├── files
│ │ ├── tasks
│ │ ├── templates
│ │ └── vars
│ ├── defaults
│ ├── docker
.
.
├── download
│ ├── defaults
│ ├── meta
│ └── tasks
.
.
├── kubernetes
│ ├── client
│ ├── kubeadm
│ ├── master
│ ├── node
│ ├── preinstall
│ ├── secrets
│ └── tokens
├── kubernetes-apps
.
.
│ ├── helm
│ ├── network_plugin
│ │ ├── calico
│ │ │ └── tasks
│ │ ├── canal
│ │ │ └── tasks
│ │ ├── cilium
│ │ │ └── tasks
│ │ ├── contiv
│ │ │ └── tasks
│ │ ├── flannel
│ │ │ └── tasks
│ │ ├── kube-router
│ │ │ └── tasks
│ │ ├── meta
│ │ ├── multus
│ │ │ └── tasks
│ │ └── weave
│ │ └── tasks
│ ├── persistent_volumes
│ │ ├── meta
│ │ └── openstack
│ │ ├── defaults
│ │ ├── tasks
│ │ └── templates
│ ├── registry
│ │ ├── defaults
│ │ ├── tasks
│ │ └── templates
│ └── rotate_tokens
│ └── tasks
├── network_plugin
│ ├── calico
│ ├── canal
│ ├── cilium
│ ├── cloud
│ ├── contiv
│ ├── flannel
│ ├── kube-router
│ ├── meta
│ ├── multus
│ └── weave
├── remove-node
│ ├── post-remove
│ │ └── tasks
│ └── pre-remove
│ ├── defaults
│ └── tasks
├── reset
│ ├── defaults
│ └── tasks
├── upgrade
│ ├── post-upgrade
│ │ └── tasks
│ └── pre-upgrade
│ ├── defaults
│ └── tasks
└── win_nodes
└── kubernetes_patch
├── defaults
├── files
└── tasks
주요 인벤토리 파일¶
- inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml
- inventory/sample/group_vars/k8s-cluster/k8s-net-calico.yml
- inventory/sample/group_vars/k8s-cluster/addons.yml
- inventory/sample/group_vars/all/all.yml
- inventory/sample/group_vars/all/docker.yml
설치된 k8s 형상¶
[taco@centos01 ~]$ kubectl get all -n kube-system
NAME READY STATUS RESTARTS AGE
pod/calico-kube-controllers-df465b84f-nvhxh 1/1 Running 0 44h
pod/calico-node-6ndj6 1/1 Running 0 44h
pod/calico-node-g8nth 1/1 Running 0 44h
pod/calico-node-vlvn6 1/1 Running 0 44h
pod/coredns-788d98cc7b-hc8vs 1/1 Running 0 44h
pod/coredns-788d98cc7b-hvfcd 1/1 Running 0 44h
pod/dns-autoscaler-6bd55f77d4-9bx6s 1/1 Running 0 44h
pod/kube-apiserver-centos01 1/1 Running 0 44h
pod/kube-controller-manager-centos01 1/1 Running 0 44h
pod/kube-proxy-s764l 1/1 Running 0 44h
pod/kube-proxy-wnlbl 1/1 Running 0 44h
pod/kube-proxy-zbhbj 1/1 Running 0 44h
pod/kube-scheduler-centos01 1/1 Running 0 44h
pod/kubernetes-dashboard-5db4d9f45f-rm82h 1/1 Running 0 44h
pod/nginx-proxy-centos02 1/1 Running 0 44h
pod/nginx-proxy-centos03 1/1 Running 0 44h
pod/rbd-provisioner-86cbb58748-4qjmh 1/1 Running 0 44h
pod/tiller-deploy-bf6884cdb-qsfsh 1/1 Running 0 44h
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/coredns ClusterIP 10.233.64.3 <none> 53/UDP,53/TCP,9153/TCP 44h
service/kubernetes-dashboard ClusterIP 10.233.99.64 <none> 443/TCP 44h
service/tiller-deploy NodePort 10.233.103.53 <none> 44134:32134/TCP 44h
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/calico-node 3 3 3 3 3 <none> 44h
daemonset.apps/kube-proxy 3 3 3 3 3 beta.kubernetes.io/os=linux 44h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/calico-kube-controllers 1 1 1 1 44h
deployment.apps/coredns 2 2 2 2 44h
deployment.apps/dns-autoscaler 1 1 1 1 44h
deployment.apps/kubernetes-dashboard 1 1 1 1 44h
deployment.apps/rbd-provisioner 1 1 1 1 44h
deployment.apps/tiller-deploy 1 1 1 1 44h
NAME DESIRED CURRENT READY AGE
replicaset.apps/calico-kube-controllers-df465b84f 1 1 1 44h
replicaset.apps/coredns-788d98cc7b 2 2 2 44h
replicaset.apps/dns-autoscaler-6bd55f77d4 1 1 1 44h
replicaset.apps/kubernetes-dashboard-5db4d9f45f 1 1 1 44h
replicaset.apps/rbd-provisioner-86cbb58748 1 1 1 44h
replicaset.apps/tiller-deploy-bf6884cdb 1 1 1 44h
Supported Linux Distributions¶
- Container Linux by CoreOS
- Debian Buster, Jessie, Stretch, Wheezy
- Ubuntu 16.04, 18.04
- CentOS/RHEL 7
- Fedora 28
- Fedora/CentOS Atomic
- openSUSE Leap 42.3/Tumbleweed
Supported Components ( 2019.02.20 master )¶
Core
- kubernetes v1.13.3
- etcd v3.2.24
- docker v18.06 (see note)
- rkt v1.21.0 (see Note 2)
- cri-o v1.11.5 (experimental: see CRI-O Note. . Only on centos based OS)
Network Plugin
Application
- cephfs-provisioner v2.1.0-k8s1.11
- cert-manager v0.5.2
- coredns v1.2.6
- ingress-nginx v0.21.0
vs kubeadm¶
Kubeadm provides domain Knowledge of Kubernetes clusters〉 life cycle management, including self-hosted layouts, dynamic discovery services and so on. Had it belonged to the new operators world, it may have been named a 《Kubernetes cluster operator》. Kubespray however, does generic configuration management tasks from the 《OS operators》 ansible world, plus some initial K8s clustering (with networking plugins included) and control plane bootstrapping. Kubespray strives to adopt kubeadm as a tool in order to consume life cycle management domain knowledge from it and offload generic OS configuration things from it, which hopefully benefits both sides.
apiserver client connection¶

Ceph¶
Components¶
- Mon (Monitor Daemon) x 3: Cluster 관리, Client entry-point, Paxos 기반 합의 (최소 3개)
- Mgr (Manager Daemon) x 3: 통계 정보, 추가 모듈 제공 (dashboard, Prometheus exporter 등)
- OSD (Object Storage Daemon): OSD Disk 당 1개 (실제 Data 저장, 복제 등)
특징¶
Cluster Map¶
Ceph의 모든 컴포넌트와 사용자는 아래 5가지 Map을 바탕으로 클러스터의 멤버, 상태 및 변화 등을 인지 → Mon이 master copy 관리
- Monitor Map
- OSD Map
- PG Map
- CRUSH Map
- MDS Map
인증¶
사용자 별 Key 를 기반으로 인증 및 권한 관리
$ ceph auth list
...
client.cinder
key: AQAin8tU0CFgEhAATb7dfbseWsh+S5HEbg6MrGg==
caps: [mon] profile rbd
caps: [osd] profile rbd pool=volumes, profile rbd pool=backups, profile rbd pool=images
..

데이터 저장을 위한 자료구조¶
Pool:¶
Ceph이 데이터를 저장하는 논리적인 공간
- Ownership/Access to Objects
- The Number of Placement Groups, and
- The CRUSH Rule to Use.

Placement Group (PG):¶
데이터 배치는 object 단위가 아닌 PG 단위로 수행, Pool 마다 적정한 개수의 PG를 보유 (https://ceph.com/pgcalc/)

Object to OSD mapping¶

$ ceph osd map volumes foo osdmap e103 pool 'volumes' (3) object 'foo' -> pg 3.7fc1f406 (3.6) -> up ([26,7,0], p26) acting ([26,7,0], p26)
시스템 연동¶
명령어¶
$ ceph -s # 클러스터 상태 정보 요약
cluster:
id: 2e7d9617-1729-4763-ba7c-1f8736b2bbf4
health: HEALTH_OK
services:
mon: 1 daemons, quorum ceph-1
mgr: ceph-1(active)
osd: 4 osds: 4 up, 4 in
data:
pools: 4 pools, 128 pgs
objects: 65 objects, 256MiB
usage: 4.53GiBused, 215GiB / 220GiB avail
pgs: 128 active+clean
$ ceph -s
cluster:
id: 2e7d9617-1729-4763-ba7c-1f8736b2bbf4
health: HEALTH_WARN
1 osds down
Degraded data redundancy: 6 pgs undersized
services:
mon: 1 daemons, quorum ceph-1
mgr: ceph-1(active)
osd: 4 osds: 3 up, 4 in
data:
pools: 4 pools, 128 pgs
objects: 65 objects, 256MiB
usage: 4.53GiBused, 215GiB / 220GiB avail
pgs: 122 active+clean
6 active+undersized
$ ceph health detail # 문제 원인 파악 $ ceph df # 사용량 파악 $ ceph osd df
Troubleshooting¶
Log 파일 위치: /var/log/ceph¶
- ceph.log: 전체 클러스터 로그
- ceph.audit.log: 작업 감사 기록
- ceph-mgr.<Node>.log: Ceph Manager Daemon
- ceph-mon.<Node>.log: Ceph Monitor Daemon
- ceph-osd.<OSD ID>.log: Ceph OSD Daemon
- ceph-volume.og: ceph-volume cli log
OSD 상태 정보¶
- Status: Up or Down & In or Out → 〈Out’이 되는 시점에 클러스터 복구 등의 작업 수행 시작
- Up
- In (일반적인 상황)
- Out (운영자가 명시적으로 설정하지 않는 다면 발생할 가능성 낮음)
- Down
- In (오류 발생 및 감지)
- Out (In 에서 10분 경과 후 진입)
- OSD_DOWN: 특정 OSD 데몬이 비정상 상태, OSD 로그 파일: /var/lib/ceph/ceph-osd.*)
- 원인
- 데몬 자체가 버그 등의 오류 혹은 누군가의 실수로 종료됨
- 네트워크 문제로 인한 OSD Peer 및 Monitor 와 연결 실패
- OSD 데몬이 동작하는 호스트 전원 오류
- OSD 데몬이 사용하는 디스크 오류
- …
- OSD_FULL: 하나 이상의 OSD 디스크 사용량이 full 설정 한계 값을 초과 → 〈쓰기〉 작업 수행 실패
- OSD_BACKFILFULL: 하나 이상의 OSD 디스크 사용량이 backfillfull 설정 한계 값을 초과 (사전 경고) → 〈재배치〉 작업 수행 실패
- OSD_NEARFULL: 하나 이상의 OSD 디스크 사용량이 nearfull 설정 한계 값을 초과 (사전 경고)
- 〈ceph df〉 명령어를 통해 문제가 발생한 OSD 디스크 확인 가능
PG 상태 정보¶
- PG_DEGRADED: 설정한 replica 수보다 적은 데이터 복제본이 유지 중인 상태 (degraded, undersized)
- PG_DEGRADED_FULL: 설정한 replica 수보다 적은 데이터 복제본이 유지 중이며 가용 공간 부족으로 인해 데이터 손실 가능 (backfull_toofull, recovery_toofull)
- PG_INACTIVE: 데이터 보호 등을 위해 해당 PG에 대한 Read/Write 방지 (replicated pool일 경우 복제본이 min_size 이하 일 때)
- PG_DAMAGED: 데이터 일관성 (consistency)에 문제 발생 (inconsistent, snaptrip_error) → 데이터 손실 가능성 높음
- TOO_FEW_PGS: 충분한 데이터 배치 및 성능을 위한 PG 개수 미달, 증가 필요
- TOO_MANY_PGS: 많은 PG 개수는 OSD 데몬의 메모리 사용량 증가, 느린 Peering 유발, Manager와 Monitor 부담 증가
- MANY_OBJECTS_PER_PG: 하나 이상의 Pool 사용량이 다른 나머지와 비교하여 현저하게 높음, TOO_FEW_PGS와 유사한 상황
- OBJECT_MISPLACED: 하나 이상의 오브젝트가 재배치 필요 (데이터 안전성에는 아무런 이상이 없음)
- REQUEST_SLOW: 하나 이상의 OSD에서 처리 과정이 오래 걸림 → 심한 부하, 스토리지 장치 성능 문제, Bug 등으로 발생
- REQUEST_STUCK: 하나 이상의 OSD에서 처리 자체가 중단, 심각한 오류
설치¶
- ceph-ansible: Ceph 클러스터 구축 (tacoplay/ceph-ansible)
- rbd_provisioner role: Kubernetes external provisioner 생성 및 Storage class 등록 (tacoplay/roles/rbd_provisioner)
- armada-manifest.yaml.j2: Openstack 연동 (inventory/XXX/armada-manifest.yaml.j2)
옵션 1) Ceph 신규 구축¶
extra-vas.yml에 Ceph 설치 내역 정의
cluster: ceph # 생략 가능, 기본값: ceph
monitor_interface: eth0
public_network: 192.168.0.0/24
cluster_network: 192.168.1.0/24
ceph_monitors: 192.168.0.23,192.168.0.25,192.168.0.26
ceph_stable_release: luminous
osd_objectstore: bluestore
ceph_conf_overrides:
global:
mon_allow_pool_delete: true
mon_osd_down_out_subtree_limit: host
osd_pool_default_size: 3
osd_pool_default_min_size: 2
osd_pg_stat_report_internal_max: 1
openstack_config: true
kube_pool:
name: "kube"
pg_num: 64
pgp_num: 64
rule_name: "replicated_rule"
type: 1
erasure_profile: ""
expected_num_objects: ""
application: "rbd"
openstack_glance_pool:
name: "images"
pg_num: 64
pgp_num: 64
rule_name: "replicated_rule"
type: 1
erasure_profile: ""
expected_num_objects: ""
openstack_cinder_pool:
name: "volumes"
pg_num: 512
pgp_num: 512
rule_name: "replicated_rule"
type: 1
erasure_profile: ""
expected_num_objects: ""
openstack_pools:
- "{{ kube_pool }}"
- "{{ openstack_glance_pool }}"
- "{{ openstack_cinder_pool }}"
옵션 2) 기존 Ceph 연동¶
extra-vars.yml 에 Ceph Mon IP 주소와 user ID, Key 값을 지정
# ceph
ceph_monitors: 192.168.99.01
ceph_admin_keyring: ABCDEFGHJKAjEhAAUFQ1xmhsc7PccAx0r+NGPA==
rbd_provisioner_admin_id: admin
rbd_provisioner_secret: "{{ ceph_admin_keyring }}"
rbd_provisioner_user_id: kube
rbd_provisioner_user_secret: ABCDEFGHJAA4BhAACAaJLcqnmTHIFzS3cJwbAQ==
Helm / openstack-helm¶
helm¶
개념¶
Kubernetes의 패키지 매니저
- 링크: https://helm.sh/
- Kubernetes 애플리케이션을 정의, 설치 및 업그레이드 할 수 있는 chart를 만들고 관리할 수 있도록 함.
- chart 작성 표준에 맞춰서 chart를 작성한 후 repository에 넣어서 관리하고 kubernetes에 배포
internet setting¶
일단 오픈소스를 할 때는 인터넷을 연결해봅시다.
$ sudo vi /etc/resolv.conf
# openstack-helm 기본 image 다운로드를 위해 nameserver 추가
nameserver 8.8.8.8
helm local repo setting¶
https://docs.helm.sh/using_helm/#quickstart
tiller server 설치 init
$ helm init --client-only
localhost에 helm chart repository server up serve
$ helm serve . &
add repo
$ helm repo add local http://localhost:8879/charts
dependencies:
- name: helm-toolkit
repository: http://localhost:8879/charts
version: 0.1.0
remove repo
$ helm search
$ helm repo remove stable
helm chart 만들어보기¶
chart 작성 표준
wordpress/
Chart.yaml # A YAML file containing information about the chart
LICENSE # OPTIONAL: A plain text file containing the license for the chart
README.md # OPTIONAL: A human-readable README file
requirements.yaml # OPTIONAL: A YAML file listing dependencies for the chart
values.yaml # The default configuration values for this chart
charts/ # A directory containing any charts upon which this chart depends.
templates/ # A directory of templates that, when combined with values,
# will generate valid Kubernetes manifest files.
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
helm create
$ cd ~
$ helm create my-chart
$ ls -al my-chart/
total 16
drwxr-xr-x. 4 centos centos 93 Feb 21 10:51 .
drwx------. 14 centos centos 4096 Feb 21 10:51 ..
drwxr-xr-x. 2 centos centos 6 Feb 21 10:51 charts
-rw-r--r--. 1 centos centos 104 Feb 21 10:51 Chart.yaml
-rw-r--r--. 1 centos centos 333 Feb 21 10:51 .helmignore
drwxr-xr-x. 2 centos centos 106 Feb 21 10:51 templates
-rw-r--r--. 1 centos centos 1062 Feb 21 10:51 values.yaml
helm install
# helm install [CHART] [flags]
$ helm install my-chart --name test-chart
NAME: test-chart
LAST DEPLOYED: Thu Feb 21 12:09:57 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME AGE
test-chart-my-chart 9s
==> v1beta2/Deployment
test-chart-my-chart 9s
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
test-chart-my-chart-69957864df-dkcdb 0/1 ContainerCreating 0 5s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-chart,app.kubernetes.io/instance=test-chart" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
확인
$ helm list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
my-chart 1 Thu Feb 21 12:03:53 2019 DEPLOYED my-chart-0.1.0 1.0 default
$ kubectl get po
NAME READY STATUS RESTARTS AGE
my-chart-85847467b4-fx4bn 0/1 ErrImagePull 0 23s
수정
$ vi my-chart/value.yaml
...
image:
repository: nginx
tag: stable
pullPolicy: IfNotPresent
...
업그레이드
# helm upgrade [RELEASE] [CHART] [flags]
$ helm upgrade test-chart my-chart
Release "test-chart" has been upgraded. Happy Helming!
LAST DEPLOYED: Thu Feb 21 12:11:43 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME AGE
test-chart-my-chart 1m
==> v1beta2/Deployment
test-chart-my-chart 1m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
test-chart-my-chart-69957864df-dkcdb 0/1 ImagePullBackOff 0 1m
test-chart-my-chart-84b7cd789c-45c5s 0/1 ContainerCreating 0 1s
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-chart,app.kubernetes.io/instance=test-chart" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
확인
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
test-chart-my-chart-84b7cd789c-45c5s 1/1 Running 0 78s 10.233.24.102 test0-2 <none>
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.64.1 <none> 443/TCP 9h
test-chart-my-chart ClusterIP 10.233.74.213 <none> 80/TCP 57s
# connect to webserver

노드포트 적용
$ helm upgrade test-chart my-chart --set service.type=NodePort
Release "test-chart" has been upgraded. Happy Helming!
LAST DEPLOYED: Thu Feb 21 12:21:05 2019
NAMESPACE: default
STATUS: DEPLOYED
RESOURCES:
==> v1/Service
NAME AGE
test-chart-my-chart 11m
==> v1beta2/Deployment
test-chart-my-chart 11m
==> v1/Pod(related)
NAME READY STATUS RESTARTS AGE
test-chart-my-chart-84b7cd789c-45c5s 1/1 Running 0 9m
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services test-chart-my-chart)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
확인
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
test-chart-my-chart-84b7cd789c-45c5s 1/1 Running 0 44m 10.233.24.102 test0-2 <none>
$ kubectl get svc
[centos@test0-1 ~]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.64.1 <none> 443/TCP 9h
test-chart-my-chart NodePort 10.233.74.213 <none> 80:30129/TCP 45m
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
test0-2 Ready master,node 9h v1.12.3 192.168.97.66 <none> CentOS Linux 7 (Core) 3.10.0-957.1.3.el7.x86_64 docker://18.6.1
test0-3 Ready master,node 9h v1.12.3 192.168.97.68 <none> CentOS Linux 7 (Core) 3.10.0-957.1.3.el7.x86_64 docker://18.6.1
test0-4 Ready master,node 9h v1.12.3 192.168.97.53 <none> CentOS Linux 7 (Core) 3.10.0-957.1.3.el7.x86_64 docker://18.6.1

helm fetch
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com
$ helm search
...
stable/terracotta 1.0.0 5.5.1 Terracotta Ehcache is an improved version of Java's de fa...
stable/testlink 4.0.3 1.9.19 Web-based test management system that facilitates softwar...
stable/tomcat 0.2.0 7 Deploy a basic tomcat application server with sidecar as ...
...
$ helm fetch stable/tomcat
$ ls -al
...
drwxr-xr-x. 4 centos centos 111 Feb 21 12:11 my-chart
-rw-rw-r--. 1 centos centos 2705 Feb 21 11:57 my-chart-0.1.0.tgz
drwxrwxr-x. 15 centos centos 4096 Feb 21 06:32 tacoplay
-rw-rw-r--. 1 centos centos 6727062227 Feb 21 06:43 tacoplay-test.tar.gz
-rw-r--r--. 1 centos centos 3763 Feb 21 13:26 tomcat-0.2.0.tgz
$ tar zxvf tomcat-0.2.0.tgz
tomcat/Chart.yaml
tar: tomcat/Chart.yaml: implausibly old time stamp 1970-01-01 00:00:00
tomcat/values.yaml
tar: tomcat/values.yaml: implausibly old time stamp 1970-01-01 00:00:00
tomcat/templates/NOTES.txt
tar: tomcat/templates/NOTES.txt: implausibly old time stamp 1970-01-01 00:00:00
tomcat/templates/_helpers.tpl
tar: tomcat/templates/_helpers.tpl: implausibly old time stamp 1970-01-01 00:00:00
tomcat/templates/appsrv-svc.yaml
tar: tomcat/templates/appsrv-svc.yaml: implausibly old time stamp 1970-01-01 00:00:00
tomcat/templates/appsrv.yaml
tar: tomcat/templates/appsrv.yaml: implausibly old time stamp 1970-01-01 00:00:00
tomcat/README.md
tar: tomcat/README.md: implausibly old time stamp 1970-01-01 00:00:00
$ ls -al tomcat
total 16
drwxrwxr-x. 3 centos centos 77 Feb 21 13:28 .
drwxrwxr-x. 3 centos centos 44 Feb 21 13:28 ..
-rwxr-xr-x. 1 centos centos 299 Jan 1 1970 Chart.yaml
-rwxr-xr-x. 1 centos centos 4141 Jan 1 1970 README.md
drwxrwxr-x. 2 centos centos 85 Feb 21 13:28 templates
-rwxr-xr-x. 1 centos centos 1038 Jan 1 1970 values.yaml
helm delete
$ helm delete --purge $CHART_NAME
tiller log 확인
kubectl logs -f TILLER-POD-NAME -n kube-system
openstack-helm¶
개념¶
컨테이너화된 OpenStack을 Helm을 사용하여 Kubernetes상에 구축하고, Self-Healing, Upgrade, 확장등의 라이프 사이클 관리를 할 수 있도록 하는 프로젝트

#1 Container화된 OpenStack 서비스들을 Kubernetes에 설치하기 위해서 필요한 정보들을 Helm Chart에 정의 Helm Chart는 사용될 컨테이너에 대한 정보와 위치, 적용할 Configuration 값들, 그리고 Kubernetes에 어떠한 형태로 올릴지에 대한 정보를 모두 가지고 있다. (참조: 현재 TACO에서는 OpenStack 서비스들에 대한 Container화는 OpenStack Kolla 프로젝트를 통해서 만들어지고 있다)
#2 Helm의 Tiller 서버가 Chart에 있는 정보들을 기반으로 Kubernetes API를 호출하여 실제 구축을 수행한다.
#3 Helm을 통해서 단일 서비스 (예: Nova)에 대한 설치, 업그레이드등의 작업을 수행할 수 있으며, 필요한 서비스들만을 조합하여 설치하는 것도 가능하다.
openstack-helm in tacoplay¶
openstack-helm, openstack-helm-infra에 있는 helm chart로 etcd, ingress, mariadb, rabbitmq, memcached, keystone을 배포
helm chart의 위치¶
$ tree -L 2 charts/
charts/
├── openstack-helm
│ ├── barbican
│ ├── ceilometer
│ ├── cinder
│ ├── congress
│ ├── CONTRIBUTING.rst
│ ├── doc
│ ├── glance
│ ├── heat
│ ├── horizon
│ ├── ironic
│ ├── keystone
│ ├── LICENSE
│ ├── magnum
│ ├── Makefile
│ ├── mistral
│ ├── neutron
│ ├── nova
│ ├── rally
│ ├── README.rst
│ ├── senlin
│ ├── setup.cfg
│ ├── setup.py
│ ├── tempest
│ ├── tests
│ ├── tools
│ ├── tox.ini
│ └── zuul.d
└── openstack-helm-infra
├── calico
├── ceph-client
├── ceph-mon
├── ceph-osd
├── ceph-provisioners
├── ceph-rgw
├── doc
├── elastic-apm-server
├── elastic-filebeat
├── elastic-metricbeat
├── elastic-packetbeat
├── elasticsearch
├── etcd
├── falco
├── flannel
├── fluent-logging
├── gnocchi
├── grafana
├── helm-toolkit
├── helm-toolkit-0.1.0.tgz
├── ingress
├── ingress-0.1.0.tgz
├── kibana
├── kube-dns
├── kubernetes-keystone-webhook
├── ldap
├── libvirt
├── lockdown
├── Makefile
├── mariadb
├── memcached
├── mongodb
├── nagios
├── nfs-provisioner
├── openvswitch
├── playbooks
├── postgresql
├── prometheus
├── prometheus-alertmanager
├── prometheus-kube-state-metrics
├── prometheus-node-exporter
├── prometheus-openstack-exporter
├── prometheus-process-exporter
├── rabbitmq
├── README.rst
├── redis
├── registry
├── roles
├── setup.cfg
├── setup.py
├── tiller
├── tools
├── tox.ini
└── zuul.d
helm toolkit¶
openstack-helm, openstack-helm-infra를 사용할 때 필요한 기본적인 툴(function)과 모든 차트에서 공통적으로 사용되는 기능들을 제공하는 toolkit
# helm chart 위치
$ cd ~/tacoplay/charts/openstack-helm-infra/helm-toolkit
$ tree -L 2
.
├── charts
├── Chart.yaml
├── requirements.lock
├── requirements.yaml
├── templates
│ ├── endpoints
│ ├── manifests
│ ├── scripts
│ ├── snippets
│ ├── tls
│ └── utils
└── values.yaml
helm-toolkit 사용 예제
# 모든 openstack service는 db init이 필요
$ cat ~/tacoplay/charts/openstack-helm/keystone/templates/job-db-init.yaml
{{- if .Values.manifests.job_db_init }}
{{- $dbInitJob := dict "envAll" . "serviceName" "keystone" -}}
{{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }}
{{- end }}
$ cat ~/tacoplay/charts/openstack-helm/neutron/templates/job-db-init.yaml
{{- if .Values.manifests.job_db_init }}
{{- $dbInitJob := dict "envAll" . "serviceName" "neutron" -}}
{{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }}
{{- end }}
helm package를 대신해서 make를 사용
$ cd ~/tacoplay/charts/openstack-helm-infra
$ make helm-toolkit
$ helm search
NAME CHART VERSION APP VERSION DESCRIPTION
local/helm-toolkit 0.1.0
keystone 훑어보기
$ tree -L 2 keystone/
keystone/
├── Chart.yaml
├── requirements.yaml
├── templates
│ ├── bin
│ ├── configmap-bin.yaml
│ ├── configmap-etc.yaml
│ ├── cron-job-credential-rotate.yaml
│ ├── cron-job-fernet-rotate.yaml
│ ├── deployment-api.yaml
│ ├── ingress-api.yaml
│ ├── job-bootstrap.yaml
│ ├── job-credential-setup.yaml
│ ├── job-db-drop.yaml
│ ├── job-db-init.yaml
│ ├── job-db-sync.yaml
│ ├── job-domain-manage.yaml
│ ├── job-fernet-setup.yaml
│ ├── job-image-repo-sync.yaml
│ ├── job-rabbit-init.yaml
│ ├── network_policy.yaml
│ ├── pdb.yaml
│ ├── pod-rally-test.yaml
│ ├── secret-credential-keys.yaml
│ ├── secret-db.yaml
│ ├── secret-fernet-keys.yaml
│ ├── secret-ingress-tls.yaml
│ ├── secret-keystone.yaml
│ ├── secret-ldap-tls.yaml
│ ├── secret-rabbitmq.yaml
│ ├── service-api.yaml
│ └── service-ingress-api.yaml
└── values.yaml
internet disable¶
$ sudo vi /etc/resolv.conf
# nameserver 8.8.8.8
Airship-armada¶
개념¶
- 오픈소스 툴을 연동하여 인프라를 구성하는 Airship프로젝트 의 Subproject
- 여러 개의 helm chart를 그룹으로 묶어 설치 및 업그레이드 할 수 있도록 만든 orchestrator
- 하나의 armada manifest 파일로 여러 차트와 관련된 설정들을 관리
- 복잡한 마이크로 서비스 형태로 구성된 오픈스택 서비스들을 openstack-helm으로 패키징 하고, 이를 선언적으로 관리하고 오케스트레이션 할 수 있도록 함
- https://github.com/openstack/airship-armada
기능¶
- apply: armada manifest에 정의된 차트 배포
- delete: armada manifest에 정의된 차트 삭제
- rollback: armada manifest에 정의된 차트 롤백
- test: armada manifest 파일로 helm test 호출
- tiller: release 목록 조회 및 tiller 정보
- validate : armada manifest 검사
armada apply¶
우리가 주로 사용할 기능은 《armada apply》로, 《helm install》을 통해서 각각 배포하던 chart들을 한꺼번에 배포 가능
《armada apply》를 사용할 때 배포하려는 chart가 기존에 존재하는 경우
- 기존의 helm chart를 《helm upgrade》 명령을 통해서 chart를 upgrade 하며
- 기존에 배포된 helm chart와 배포하려는 armada-manifest 내의 chart를 비교하여, chart에 수정사항이 존재하지 않는 경우에는 upgrade 하지 않음
결국 우리는 1) armada manifest yaml 파일을 잘 만들어서, 2) armada apply를 통해 배포되어야 할 모든 chart를 배포하고, 3) 테스트를 수행
Armada manifest¶
주요 구조¶
- schema
- chart: armada manifest의 기본 단위로서 helm chart 1개를 의미
- chartGroup: chart들을 group별로 모아놓은 내용
- Manifest
- chartGroup data
- description
- sequenced: chart들을 순서대로 배포할 것인지, 한꺼번에 다 배포할 것인지 결정, 순서대로 배포하면 1개의 chart가 모두 Running 상태가 되고 나서 다음 chart를 배포
- chart_group: 해당 chartGroup에 포함될 chart의 목록
- chart data
- chartname
- namespace
- install: 《helm install》 명령과 관련된 내용을 기술
- upgrade: 《helm upgrade》 명령과 관련된 내용을 기술
- values: chart의 values.yaml 중 수정한 내용
- source: 배포할 chart의 타입, 위치에 대한 정보
- dependencies
예시)
chart_name: glance
release: glance
namespace: openstack
install:
no_hooks: false
upgrade:
no_hooks: false
pre:
delete:
- name: glance-bootstrap
type: job
labels:
application: glance
component: bootstrap
- name: glance-storage-init
type: job
labels:
application: glance
component: storage-init
...
values:
storage: rbd
images:
tags:
test: admin:5000/pike/ubuntu-source-rally:3.6.0
glance_storage_init: admin:5000/ceph-config-helper:v1.10.3
db_init: admin:5000/pike/ubuntu-source-heat-engine:3.6.0
...
source:
type: local
location: "/home/centos/tacoplay/charts/openstack-helm"
subpath: glance
dependencies:
- helm-toolkit
armada in TACO¶
TACO armada-manifest 주요 구조¶
- chartGroup
- openstack-infra
- ceph-provisioners
- ingress
- etcd
- rabbitmq
- memcached
- mariadb
- openstack-services
- libvirt
- openvswitch
- keystone
- glance
- cinder
- heat
- nova
- neutron
- horizon
- logging-infra
- ldap
- elasticsearch
- monitoring-infra
- grafana
- prometheus
- prometheus-alertmanager
- prometheus-kube-state-metrics
- prometheus-node-exporter
- prometheus-openstack-exporter
- openstack-infra
armada apply with tacoplay¶
$ ansible-playbook -b -v -i inventory/new_env/hosts.ini -e @inventory/new_env/extra-vars.yml armada-apply.yml
로그 확인¶
$ cat ~/armada.log
TACO OpenStack 네트워크 구조¶
TACO 네트워크 Overview¶
TACO는 OpenStack의 Community Version을 기반으로 하기 때문에 기본적으로는 OpenStack에서 제공하는 모든 종류의 네트워크 드라이버와 토폴로지를 지원할 수 있지만, 이번 릴리즈에서는 실질적인 구축 사례를 고려해 아래의 세 가지의 네트워크 모드를 선정하고 설정 및 검증을 진행했다.
- Provider Networks Only 모드
- Self-Service Networks 모드
- SONA 모드
위의 세 가지 옵션들 중에서 어떤 네트워크 모드를 선택할 지는 구축의 규모와 용도에 따라 결정된다 (표 1 참조).
예를 들어, 구축의 규모가 크지 않다면 FLAT 혹은 VLAN 같은 네트워크 타입을 선택하는 것이 효과적이다. 반면에 구축의 규모가 크거나 향후 규모가 증가할 가능성이 높다면 VXLAN과 같이 하부의 물리 네트워크 구조를 L3 기반으로 확장성 있게 구성할 수 있는 네트워크 타입을 선택하는 것이 좋다. 또한 고객 간의 격리가 매우 중요하고 다양한 종류의 워크로드가 실행되는 퍼블릭 클라우드의 경우에는 Self-Service Network 프로비저닝을 통해 서로 다른 고객의 가상 머신들을 L2 레벨에서 격리시키는 것이 안전하다. 반대로 신뢰할 수 있는 고객을 위한 특정 목적의 프라이빗 클라우드를 구축하는 경우에는 외부망, 사내망 등 가상 머신과 연동이 필요한 네트워크를 운영자가 미리 생성하고 관리하는 Provider Network Only 모드가 효율적이다. 그 밖에 NFV와 같이 가상 머신 간의 네트워크 연결을 원하는대로 프로그램해야 한다면 OpenFlow 기반의 드라이버인 SONA를 활용할 수 있다.
규모/용도 | Private | Public |
---|---|---|
소규모 | Provider Networks Only | Self-Service Networks (Vlan) |
중/대규모 | Routed Provider Networks Only | Self-Service Networks (Vxlan) |
가상 스위치의 선택은 네트워크 모드에 따라 결정된다 (표 2 참조).
가상 머신을 호스트가 연결된 물리 네트워크에 직접 연결하는 Provider Network Only 모드의 경우 네트워크 설정이 매우 단순하기 때문에 Linux bridge를 사용하는 편이 안정적이고 운영 측면에서도 유리하다. 반면에, 비교적 복잡한 VXLAN 타입의 가상 네트워크를 사용하거나 SONA 드라이버처럼 OpenFlow를 기반으로 가상 네트워크를 제어하는 경우, 혹은 DPDK를 활용한 데이터 플레인 가속을 고려한다면 Open vSwitch가 적합하다.
테넌트 네트워크 | 가상 스위치 | 네트워크 종류 | 메커니즘 드라이버 | 테넌트 격리 | 추가 구성 요소 | |
---|---|---|---|---|---|---|
Provider Only | 불가 | Linux bridge | Flat, Vlan | Linux Bridge | L3(security Group) | 없음 |
Self-Service | 가능 | Open vSwitch | Vlan, Vxlan | Open vSwitch | L2 | 없음 |
SONA | 가능 | Open vSwitch | Vxlan | SONA | L2 | ONOS, SONA-Gateway |
Provider Network Only 모드¶
Provider Network 모드는 호스트 머신이 연결된 물리 네트워크에 가상 머신의 인터페이스를 직접 브릿징하는 방식으로, 모든 네트워크 연결성을 물리 네트워크에 의존하기 때문에 VXLAN 기반의 Self-Service Network 모드와 비교했을 때 유연성은 떨어지지만 그만큼 단순하고 안정적이며 가상화에 따른 오버헤드가 거의 없다는 장점이 있다. 또한 네트워크 측면에서 보면 물리 머신과 똑같이 가상 머신을 다룰 수 있기 때문에 운영 상의 부담이 적다. 따라서 고객 별로 독립된 가상 네트워크를 할당해야 할 필요가 없는 경우의 구축에 가장 권장되는 모드다. 다만, 하부의 물리 스위치가 가상 머신의 네트워킹을 처리하게 되므로 ARP 테이블의 크기 등 확장성에 유의해야 하며, 2랙 이상의 규모로 구축하는 경우 랙 별로 L2 도메인을 나누고 서로 다른 랙에 존재하는 가상 머신 간의 통신은 L3 스위치에서 라우팅으로 처리하는 Routed Provider Network 모드를 사용하는 것을 권장한다.

Provider Network의 생성 및 관리 권한은 운영자에게만 허용되고 사용자는 미리 생성된 네트워크를 사용하는 것만 가능하다. 기본적으로 호스트 머신에 연결된 모든 네트워크는 Provider Network로 전용이 가능한데, 일반적으로 외부망, 사내망, 가상 머신 전용 망 정도를 구성한다. 보통은 호스트 머신과 연결된 스위치의 포트를 trunk 모드로 설정하고 호스트 머신에서 접근할 네트워크에 따라 VLAN을 태깅해서 패킷을 올리는 방식을 취함으로써, 필요한 네트워크 포트의 수를 줄이고 동적으로 Provider Network를 추가하거나 삭제할 수 있게 한다. Provider Network 기반의 TACO 구축에 대한 예시는 다음 링크에 자세히 설명되어 있다.
Self-Service Network 모드¶
Self-Service Network 모드는 고객이 직접 독립된 네트워크를 생성하는 것을 허용하는 모드로, 가상 라우터를 거쳐 NAT를 해야만 인터넷을 포함한 외부망과 통신이 가능하다. 고객이 생성한 네트워크는 보통 VLAN이나 VXLAN으로 구현되는데, VLAN의 경우 하부의 물리 네트워크를 L2로 구성해야 하기 때문에 확장성에 제한이 있다. VXLAN 모드의 경우 하부의 물리 네트워크를 L3로 구성할 수 있기 때문에 대규모 구축에 가장 선호되는 모드지만, VXLAN encapsulation 및 decapsulation 오버헤드로 인한 성능 저하가 발생할 수 있다.

SONA 모드¶
SONA는 ONOS 컨트롤러를 기반으로 Neutron의 ML2 driver를 구현한 것으로, ONOS 컨트롤러가 컴퓨트 노드에 존재하는 OVS를 OpenFlow 커넥션을 통해 직접 프로그램하기 때문에 agent가 전혀 필요 없다. 무엇보다 ONOS를 통해 가상 네트워크를 원하는 대로 제어할 수 있다는 점이 가장 큰 장점이다.

TACO Continuous Integration 구조¶
TACO CI 개요¶
TACO는 OpenStack을 포함한 다양한 오픈소스 소프트웨어 커뮤니티 버전의 소스코드를 기반으로 만들어진다. 따라서, 이러한 커뮤니티 소스코드에서 발생하는 많은 변경사항들을 지속적으로 가져와서 SKT 필요 부분을 추가하고 이를 테스트하여 안정적인 패키지를 만들어내는 과정, 즉 Continuous Integration 과정이 필요하다.
Continuous Integration (지속적인 통합)은 지속적으로 복잡한 소프트웨어의 Quality를 컨트롤하며 완성도 높은 결과물을 만들어내기 위한 대표적인 방법이다. 즉, 작은 단위로 그리고 자주 통합해, 통합 시 발생하는 여러가지 문제점을 조기에 발견하고, 피드백 사이클을 짧게 하여 SW개발의 품질과 생산성을 향상 시키도록 한다.
TACO에서는 위에 설명된 바와 같은 Continuous Integration 체계를 갖추고, SKT에서 필요한 다양한 테스트들을 자동으로 수행하여, 상용적용이 가능한 품질의 OpenStack을 지속적으로 만들어 낼 수 있도록 하고 있다.
TACO CI 구조¶
코드 저장소에 코드를 push하고 build 및 test를 거쳐 배포까지 하는 일련의 자동화된 과정이며 다음과 같은 특징이 있다.
- Upstream 코드 반영: Upstream 코드에 변경이 발생시마다 자체 기능 테스트를 수행하여 이상 없을 시 sync를 수행한다.
- 테스트: 코드를 push할 때마다 자동으로 단위 테스트를 수행하며, 매일 정기적으로 통합 테스트를 수행하여 artifact history를 관리한다.
- Profile 기반 자동화: 각 환경별 profile을 관리하여 서로 다른 형상의 다양한 환경에 deployment를 수행할 수 있다.

내부 저장소 관리¶
소스코드 저장소¶
소스 저장소는 크게 Upstream mirror repository와 Skt (wrapper) repository가 있다.
경고
소스 저장소 바꿔야할 듯
Mirror repository: upstream source code를 주기적으로 sync하여 최신 상태를 유지한다.
- openstack: openstack 소스코드
- kolla: 각각의 openstack service들을 container화하기 위한 configuration
- openstack-helm & openstack-helm-infra 생성된 container들을 kubernetes로 배포하기 위한 helm chart들
- kubespray: kubernetes 설치를 위한 ansible playbook
SKT Wrapper repository: kolla 및 helm chart 등에 대해 skt 추가, 변경사항 등을 포함한다.
Artifact 저장소¶
Artifact 저장소로는 Docker registry가 있다.
- Docker registry: 각 테스트 단계에서 생성된 docker image들을 저장한다.
테스트 Flow¶
단위 테스트¶
kolla, helm chart에 대해 mirror repository의 코드와 skt wrapper 내용을 함께 반영하여, 단위 테스트를 수행한다.
- kolla 단위 테스트: bats test 를 수행하여 docker image가 정상적으로 잘 build되었는지 테스트한다.
- helm 단위 테스트: rally의 scenario test 를 수행하여 해당 openstack 서비스의 기본적인 기능이 잘 동작하는지 확인한다.
통합 테스트¶
unit test를 통과한 docker image와 helm chart 및 armada-manifest를 사용하여 통합 테스트를 수행한다.
- API Test: 미리 준비된 Kubernetes cluster에 전체 openstack 서비스를 배포한 후 tempest test를 수행하여 openstack API들이 잘 동작하는지 검증한다.
- Resiliency (HA) Test: 자체 개발한 Cookiemonster 라는 tool을 사용하여 random하게 특정 pod들을 down시키면서, 동시에 Rally scenario test를 수행하여 HA가 잘 동작하는지 검증한다.
Promote¶
통합 테스트를 통과한 artifact들의 버전을 N.0.0 형식으로 promote하여 Production 환경에 대비한다.
TACO Deployment 구조¶
TACO Full Deployment 형상 (예시)¶
TACO의 Deployment 구조 (하드웨어, 네트워크, 설치된 소프트웨어 형상)은 다음과 같다.
Deployment 형상은 사용되어지는 네트워크 모델, HA 형상, 스토리지 구조등에 따라서 변경될 수 있다.

TACO Kubernetes Only Deployment 형상 (예시)¶
OpenStack 이 아닌, Kubernetes 만 단독으로 필요한 경우, 다음과 같은 형상으로 구성이 가능하다.
- Kubernetes Master 는 기본적으로 3개 노드 클러스터로 구성이 되며, 규모가 대규모로 확장이 되는 경우, 성능과 안정성을 확보하기 위한 Master 노드 확장도 가능하다.
- 100대 이상의 노드로 구성이 되는 경우, POD간 네트워크의 성능 보장 및 확장성 확보를 위하여 별도의 BGP Route Reflector 노드 구성이 필요할 수도 있다.
- Ingress Controller 는 외부에서 Kubernetes 상에 배포되는 서비스들에 접근하는 것을 제어하며, 필요에 따라 별도로 구성도 가능하다. (기본적으로는 별도 구성이 되지 않는다)
- 필요에 따라서, LMA (Logging, Monitoring, Alerting) 를 위한 EFK와 Prometheus 클러스터를 별도로 구성할 수도 있다.

Recommended Hardware 사양¶
아래 표는 Full HA 형상으로 설치 시 필요한 하드웨어 사양을 기술한다.
Category | 용도 | EA | service | 비고 |
---|---|---|---|---|
deploy | admin | 1 |
|
|
k8s | k8s-master | 3 |
|
|
openstack-controller | 3 |
|
|
|
openstack-compute | N |
|
|
|
Ceph | ADMIN | 4 |
|
|
Total | 10 대 +N Compute Nodes | core는 H/T Off 기준 |
TACO에서 설치하는 SW프로세스 리스트 (예시)¶
참고: 설치되는 OpenStack 서비스 종류 혹은 네트워크/스토리지 구조에 따라서 아래 리스트는 변경될 수 있다.
Kubernetes Master Nodes (only kube-system)
- calico-node
- kube-apiserver
- kube-controller-manager
- kube-proxy
- kube-scheduler
OpenStack Controller Node
경고
pcl20-stg??
kube-system (ns)
- calico-node
- kube-proxy
- nginx-proxy
openstack (ns)
- cinder-api
- cinder-scheduler
- glance-api
- heat-api
- heat-cfn
- heat-engine
- horizon
- ingress
- keystone-api
- mariadb-ingress
- mariadb-server
- neutron-dhcp-agent
- neutron-lb-agent
- neutron-lbaas-agent
- kubedns-autoscaler (only 1 on the cluster)
- neutron-server
- nova-api-metadata
- nova-api-osapi
- nova-conductor
- nova-consoleauth
- nova-novncproxy
- nova-placement-api
- nova-scheduler
- pcl20-stg-etcd-etcd
- pcl20-stg-memcached-memcached
- pcl20-stg-rabbitmq-rabbitmq
- ldap-0 (only 1 on the cluster)
- elasticsearch-data
- elasticsearch-master
- elasticsearch-client
- fluentbit
- kibana
- prometheus
- kube-state-metrics
- node-exporter
- prometheus-openstack-exporter
- alertmanager
OpenStack Compute Nodes
kube-system (ns)
- calico-node
- kube-proxy
- nginx-proxy
- tiller-deploy (only 1 on the cluster)
openstack (ns)
- libvirt
- neutron-lb-agent
- nova-compute
예시: 네트워크 Deployment 구조¶
주석
아래 설명된 네트워크 구조는 TACO를 Provider Network 모드로 구축하기 위해서 필요한 Physical Network 구성 예시이다. 실제 구축시에는 TACO에서 사용되는 네트워크 모드 종류와 보안 및 서비스 요구사항에 따라서 최적화된 네트워크 설계가 필하다.
TACO Provider Network 구성도 (예시)¶

필요 VLAN 구성 정보
- IPMI: 1G
- MANAGEMENT: Kubernetes 클러스터링, 오픈스택 서비스 간 통신, 운영자 관리 용도, 1G, 이중화
- EXTERNAL API: 포탈에서 오픈스택 API 접근 용도, 1G
- PROVIDER #1 (사내망): VM 용 공인망 네트워크, 10G
- PROVIDER #2 (공인망): VM 용 공인망 네트워크, 10G
- CEPH PUBLIC: VM 및 Kubernetes 컨트롤러에서 스토리지 접근 용도, 10G
- CEPH CLUSTER: CEPH 노드 간 클러스터링, 데이터 미러링 용도, 10G
TACO 외부접속을 위한 네트워크 구성도 (예시)¶

호스트 인터페이스 구성 (예시)¶

랙내 케이블링 (예시)¶

예시: Deployment 랙 형상¶
주석
구축을 위한 랙 및 하드웨어 형상은 요구사항 (SLA, 가용한 투자비용, 초기 필요 용량등) 에 따라 변경될 수 있다. TACO 구축은 All-In-One으로 하나의 노드에 설치하는 방법부터 가용성을 최대화하여 멀티랙에 설치하는 방법까지 다양하게 있을 수 있다. 이 부분은 상용 구축을 하고자 하는 부서와 함께 협력하여 해당 구축 사이트의 요구사항에 최적화된 구축 형상을 만들 필요가 있다.
최대한의 서비스 가용성 보장 (예시)¶
3 Node HA Cluster로 구성되는 Management 노드들이 세 개의 랙에 배치됨에 따라서, 1개 랙에 장애가 발생할 경우에도 서비스 연속성을 보장한다.
Ceph도 기본 적으로 세 개의 Rack에 분산되어서 설치되며, 이에 따라서 Ceph-OSD가 분산되어 설치됨에 따라서, 랙 장애시에도 Ceph 서비스 연속성을 최대한 보장한다.
초기 구성을 위해서 반드시 3개의 랙이 필요하다. 구체적으로는 다음과 같은 기본 장비들이 초기 구축시 준비되어야 한다.
- TACO Rack Type MSC 3개
- 10G 스위치 6식 (랙당 2식)
- 1G 스위치 3식 (랙당 1식)
- Deployer Node 1개 (Repository를 별도 이중화로 구성할 경우, 2개 Node가 추가됨)
- Kubernetes Controller Node 3개
- OpenStack Controller Node 3개
- Ceph Node (6대 - OSD Node 갯수는 초기 필요 스토리지 용량에 따라서 조정 가능함)
- 옵션 - Monitoring Node 3개 (Elasticsearch, Kafka등 모니터링용 시스템을 위한 노드)
- 옵션 - 요구사항에 따라서 Container Node와 OpenStack Compute Node의 비율 조정이 가능함
- 옵션 - 100대 이상 규모에서 Container Network의 확장성을 위해서 Calico BGP Route Reflector 역할을 하는 두 개 이상의 노드 추가 가능
초기 3 랙 구성에서 확장을 할 경우, 확장 요건에 따라서 두 타입으로 나눌수 있다.
TACO Rack Type SC: 컴퓨트와 스토리지를 같이 확장할 경우에 사용가능하며, 하나의 랙에 확장할 수 있는 Compute Node와 Ceph OSD Node가 위치한다.
- Compute Node와 Ceph OSD Node의 비율은 필요에 따라서 조정 가능하다.
TACO Rack Type C: 컴퓨트만 확장할 경우 사용가능하며, 하나의 랙에 Compute Node들만 위치한다.

초기 투자비용 최소 (예시)¶
하나의 랙으로 기본적인 OpenStack 서비스 제공이 가능하다.
초기 구성을 위해서 1개의 Rack이면 된다. 구체적으로는 다음과 같은 기본 장비들이 초기 구축시 준비되어야 한다.
- TACO Rack Type MSC 1개
- 10G 스위치 2식
- 1G 스위치 1식
- Deployer Node 1개
- Kubernetes Controller Node 3개
- OpenStack Controller Node 3개
- Ceph Node (4대 - OSD Node 갯수는 초기 필요 스토리지 용량에 따라서 조정 가능함)
- 옵션 - Monitoring Node 3개 (Elastic Search, Kafka등 모니터링용 시스템을 위한 노드)
- 옵션 - Container Node 2개 (Portal, Dashboard등 Kubernetes에 추가로 올릴 Admin 혹은 User용 APP들을 위한 별도 노드

참고: Deployment 순서¶
아래 그림은 TACO를 설치하기 위한 End-to-End 절차를 나타내고 있다.
인프라 준비
- 1단계: Baremetal Provisioning (OS설치 및 설정) 을 수행하고 필요한 Host 설정을 한다.
- 2단계: TACO Deployment 노드에서 TACO 설치에 필요한 Repository를 설치하고, Kubespray (Ansible 서버 포함)를 설치한다.
- 3단계: Deployment Node에 구성된 Repository에 OpenStack 컨테이너 이미지와 Helm Chart등 필요한 파일을 등록한다.
- 4단계: 설치를 위하여 필요한 OpenStack 컨테이너 이미지들과 Helm Chart, 그리고 구축환경에 맞추어 작성된 구축 프로파일 (Armada Manifest) 을 확인한다. 구축 프로파일에는 OpenStack을 설치하고 서비스 가능상태로 만들기 위한 모든 설정값들이 들어가 있다.
TACO 설치
5단계: Ansible을 통해서 Ceph을 자동 설치한다. 설치 후에는 TACO 설치에 필요한 Ceph 파라미터들을 설정해준다.
6단계: TACO Installer를 이용하여 Single Command Line 명령어로 Kubernetes와 OpenStack 설치를 수행한다. 설치시에는 아래와 같은 작업들이 자동으로 수행된다.
- 컨테이너화된 OpenStack을 관리하기 위한 Underlying Platform인 Kubernetes를 Kubespray를 이용하여 자동 설치한다.
- OpenStack을 Kubernetes 상에 설치하기 위해 필요한 Initial Setup (Helm 설치 등)이 자동으로 진행된다.
- OpenStack 구축 프로파일 (Armada Manifest) 을 기반으로, Kubernetes 상에 OpenStack 이 자동 구축된다.
설치 후 검증
- 7단계: 설치된 OpenStack 이상유무 검증 후, 구축을 완료한다. 참고로, 현재는 Ceph 노드들과 SONA Gateway 노드들은 기존과 같이 베어메탈상에 설치를 하여야 한다. 차후 버전에서는 이에 대한 컨테이너화 및 자동화를 진행할 계획이다.
TACO 매니지먼트 네트워크 구성¶
TACO 매니지먼트 네트워크 구성 옵션¶
TACO는 Kubernetes 네트워크 드라이버로 Calico를 사용하고 있다. Calico는 BGP를 이용해 pod 간의 통신을 구현하고 있는데, 이를 위해 기본적으로 클러스터를 구성하는 모든 노드 간에 full mesh 형상으로 BGP peering을 맺게 된다. (옵션 1) 이런 구성은 별도의 네트워크 전용 노드나 스위치 설정이 필요 없어 간편하지만, 클러스터의 규모가 100대 이상으로 늘어나면 BGP 운영에 과도한 리소스 소모와 컨트롤 트래픽이 발생할 수 있어 비효율적이다. 따라서, 100 노드 이상의 대규모 구축에는 BGP route reflector를 사용하는 것을 권장한다. Route reflector는 구축 환경에 따라 전용 노드를 사용할 수도 있고 (옵션 2) 상단의 aggregation 스위치를 활용할 수도 있다 (옵션 3). 장애 상황을 대비해 route reflector는 적어도 두 대 이상이 필요하다.
옵션 1) Full Node-To-Node Mesh - 가장 Simple 하며 별도의 Route Reflector 를 사용할 필요가 없음. 옵션 2) Global BGP Peers - 별도의 서버를 Route Reflector로 활용 옵션 3) Global BGP Peers - Aggregation Switch를 Route Reflector로 활용
Node-To-Node Mesh¶

Global BGP Peers - 별도의 서버를 Route Reflector로 활용¶

Global BGP Peers - Aggregation Switch를 Route Reflector로 활용¶

Contribute¶
Repository¶
개발방법¶
- github의 tacoplay repository를 자신의 계정으로 포크합니다.

- 포크한 repository를 다운로드 합니다.
git clone https://github.com/<your-github-id>/tacoplay.git
- 개발을 위해 새로운 브랜치를 만듭니다.
git checkout -b <TOPIC-BRANCH>
- 개발 / 테스트
- 개발내용을 커밋하고 github에 푸쉬합니다.
git commit -a
git push origin <TOPIC-BRANCH>
- tacoplay repository로 Pull Request를 합니다.
