Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions .github/workflows/bootc-build-and-push.yml

This file was deleted.

3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
- 리눅스를 프로젝트를 통해 공부해보고 싶은 사람
- 컨테이너를 넘어 머신(노드) 레이어의 OS 구성을 직접 커스텀하고 자동화해서 배포해보고 싶은 사람 (CI/CD)


---

<br>
Expand All @@ -47,8 +46,6 @@
<tr>
<td align="center"><a href="https://github.com/yucori"><img src="https://avatars.githubusercontent.com/u/110710238?v=4" width="100px;" alt=""/><br /><sub><b>
장지원</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/doxxx93"><img src="https://avatars.githubusercontent.com/u/51396905?v=4" width="100px;" alt=""/><br /><sub><b>
김도율</b></sub></a><br /></td>
<td align="center"><a href="https://github.com/jskim096"><img src="https://avatars.githubusercontent.com/u/40004210?v=4" width="100px;" alt=""/><br /><sub><b>
김종석</b></sub></a><br /></td>
</tr>
Expand Down
84 changes: 84 additions & 0 deletions jongseok/bootc-esxi-pipeline/CreateVM-bootcISO-ESXi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Build ISO and Deploy VM on ESXi

on: workflow_dispatch

env:
IMAGE_NAME: my_dashboard
IMAGE_VERSION: ${{ github.sha_short || github.run_id }}
ISO_DIRNAME: esxi_dir
VM_NAME: git-vm
VM_CPU: 2
VM_MEM: 4
VM_DISK: 30
VM_NETWORK: "VM Network"
Comment on lines +9 to +13

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VM 옵션을 configuration file로 만들거나, workflow_dispatch.inputs filed를 사용해서 상황에 맞게 동적으로 제공하는 것도 좋을 것 같습니다.


jobs:
deploy:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

# 1. 컨테이너 이미지 빌드
- name: Build Container Image
run: |
if [ -z "$IMAGE_VERSION" ]; then
echo "ERROR: IMAGE_VERSION must be set!"
exit 1
fi
podman build --network=host \
-t localhost/$IMAGE_NAME:$IMAGE_VERSION .

# 2. ISO 생성
- name: Generate ISO
run: |
mkdir -p output
sudo podman run --rm --privileged \
--network=host \
-v ./output:/output \
-v /var/lib/containers/storage:/var/lib/containers/storage:rw \
quay.io/centos-bootc/bootc-image-builder:latest \
--type iso \
--output /output/$ISO_DIRNAME \
localhost/$IMAGE_NAME:$IMAGE_VERSION

# 3. ISO 서빙 (파일명 동적 생성)
- name: Serve ISO
run: |
ISO_FILENAME="${IMAGE_NAME}-${IMAGE_VERSION}.iso"
cd output
mv $ISO_DIRNAME/bootiso/install.iso $ISO_FILENAME
nohup python3 -m http.server 8080 --bind 0.0.0.0 > http.log 2>&1 &
echo $! > http.pid
Comment on lines +45 to +51

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want to use working-directory syntax


# 4. ESXi 전송 (파일명 동적 생성)
- name: Transfer to ESXi
run: |
ISO_FILENAME="${IMAGE_NAME}-${IMAGE_VERSION}.iso"
RUNNER_IP=$(hostname -I | awk '{print $1}')
sshpass -p "${{ secrets.ESXI_PASS }}" ssh -o StrictHostKeyChecking=no \
${{ secrets.ESXI_USER }}@${{ secrets.ESXI_HOST }} \
"wget http://$RUNNER_IP:8080/$ISO_FILENAME -O /vmfs/volumes/${{ secrets.ESXI_DATASTORE }}/$ISO_FILENAME"
Comment on lines +56 to +60

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is rsync or scp package not available?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오... rsync 스크립트로 변경분만 넘기면 네트워크 대역폭도 적게 차고 동기화할 수 있군요 구웃 배워갑니다


# 5. VM 생성 (파일명 동적 생성)
- name: Create VM
run: |
ISO_FILENAME="${IMAGE_NAME}-${IMAGE_VERSION}.iso"
chmod +x esxi-vm-create.py
python3 esxi-vm-create.py \
-H ${{ secrets.ESXI_HOST }} \
-U ${{ secrets.ESXI_USER }} \
-P ${{ secrets.ESXI_PASS }} \
-n ${VM_NAME} \
-c ${VM_CPU} \
-m ${VM_MEM} \
-v ${VM_DISK} \
-S ${{ secrets.ESXI_DATASTORE }} \
-N "${VM_NETWORK}" \
-i /vmfs/volumes/${{ secrets.ESXI_DATASTORE }}/${ISO_FILENAME} \
-o "svga.autodetect=TRUE" "monitor_phys.host_triggers=TRUE" \

# 6. 정리
- name: Cleanup
if: always()
run: |
kill $(cat output/http.pid) || true
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image-4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image-5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added jongseok/bootc-esxi-pipeline/IMAGES/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
155 changes: 155 additions & 0 deletions jongseok/bootc-esxi-pipeline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
## 요약

```

컨셉 (왜 했는가)
|
워크플로우 구성 (2가지 Git Action 흐름)
|
워크플로우 결과 (2가지 Git Action 결과)
|
테스트 (테스트를 통한 bootc 이해)
+
피드백 (느낀점)

```


## 컨셉
- Github Action을 이용한 ESXi VM 자동화 파이프라인 형성

- Containerfile에는 **서비스 개념보단 OS에 초점을 맞춤**

- KISA의 리눅스 취약점 분석 평가 가이드 중 **'계정의 wheel 그룹 권한'** 과 **'파일 경로에 따른 권한 변경 불가'** 에 초점을 두었음

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a thought :
Harbor 배포 때 --with-trivy 넣거나, 컨테이너 이미지 빌드 후 vulnerability scanning step을 넣는 것으로 충족이 안될 지

fyi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아직까진 OS 초기 보안 설정에 대해 자동으로 설정해주는 과정은 없는 것고 자체적으로 자동화 툴(스크립트나 Ansible)을 만드는듯...
매번 담당자가 가이드 따라하면서 손으로 하기 때문에 누락되기도 해서 애매함 (나도 몇번 누락ㅎㅎ)

이건 자동화하려는 움직임같은데 자료 찾다가 가져옴!
http://isweb.joongbu.ac.kr/~jbuis/2023/report-2023-4.pdf


- wheel 그룹에 속하지 않은 일반 사용자는 su나 sudo 같은 명령어로 root 권한을 얻을 수 없게 제한할 수 있음

- /usr, /bin, /etc 등 주요 시스템 디렉터리는 운영체제의 핵심 파일이 위치한 경로로 bootc는 /usr, /bin을 읽기 전용으로 마운트 함

- 과연 컨테이너 파일에 **KISA 취약점 분석 가이드를 반영한 뒤, 생성한 OS에 대해 사용자가 설정을 바꾸면 바뀔까?**

- Hypervisor는 ESXi로 선택하여 원격지에서 python 코드로 VM 생성하는 Git을 참고
<img src="IMAGES/Screenshot_20250615_183810_Samsung Notes.jpg" width="1000"/>



---

## 워크플로우 구성
**CreateVM-bootcISO-ESXi.yml**
- 컨테이너 파일을 ISO로 빌드하고 파이썬 코드를 이용하여 ESXi VM 자동 생성

![alt text](IMAGES/image.png)

(1) Build ISO
```

아래 KISA 취약점 진단 가이드를 포함한 컨테이너 파일을 이용하여 /output 하위에 bootc ISO 생성

# Containerfile
---
wheel 그룹 설정 + 패스워드 정책 + 계정 잠금 임계값 + SUID/SGID 관련 보안 설정
( /etc/pam.d ) ( /etc/security/pwquality.conf ) ( /etc/security/faillock.conf ) ( /usr/bin/ )
```
(2) Downlaod ISO
```
Self-Runner는 ESXi로 SSH로 접근하고 wget을 통해 Bootc(Self-Runner)로 접근하여 ISO 파일을 다운로드

* scp로 ISO 2.6GB를 넘기려했으나 3시간 이상이 소요되어 방법을 바꾸었고 8초로 단축

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scp에서 wget으로 전송 방식을 전환했을 때, 소요 시간이 단축되는 이유가 무엇인가요??

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scp는 SSH기반 프로토콜인데 너무 오래걸려서ㅠ
보안 무시하고 HTTP를 이용하여 디렉토리를 공유하고 파일을 wget으로 가져왔어요!
대신 보안이 취약해서 이렇게 하면 안될거에여ㅎㅎ

```
(3) Create VM
```
esxi-vm-create.py를 이용하여 VM을 원격지에서 생성 가능하며 필요한 정보는 다음과 같음

(1) ESXi 정보 (아이디/비밀번호/주소)
(2) Datastore 경로
(3) VM Name
(4) VM CPU/MEM
(5) VM DISK (Thin/Think 할당 방식도)
(6) VM Geust OS
(7) VM Network
```


**Update-bootc-Client.yml**
- Harbor 레지스트리에 컨테이너 이미지를 관리하여 bootc 클라이언트 업데이트

![alt text](IMAGES/image-1.png)

(1) Build Container Image
```
빌드된 이미지는 Bootc-Server의 Harbor 저장
```
(2) Manage Bootc Client
```
기존 실습과 동일하게 Harbor 레지스트리 PULL
```

---

## 워크플로우 결과
- CreateVM 워크플로우 결과 : Containerfile > Build ISO file > Create VM : 19분 소요

![alt text](IMAGES/image-2.png)

- CreateVM 가상머신 생셩 결과 : ESXi(가상화호스트 자동 생성)

![alt text](IMAGES/image-3.png)

- Update 워크플로우 결과 : New Containerfile > Build Container Image > Push Harbor : 2분 이내 소요

![alt text](IMAGES/image-4.png)

- Update Harbor 결과 : PUSH 정상

![alt text](IMAGES/image-5.png)

---

## 테스트
테스트 목록
```
(A) root 비밀번호 변경 : echo 'root:c!0udc1u6b0oC' | chpasswd

(B) 새로운 패키지 설치 : yum install openjdk *

(C) 유저 생성 : useradd cloudclubuser

(D) wheel 그룹 추가 : useradd -m -G wheel cloudclubadmin

(E) 패스워드 정책 변경 : sed -i '/^PASS_MAX_DAYS/c\PASS_MAX_DAYS 9999' /etc/login.defs

(F) 파일 권한 변경 : chmod 4777 /usr/bin/su *

(G) 파일 권한 변경 : chmod 777 /etc/shadow

(H) 파일 삭제 : rm -rf /bin *

(I) 파일 삭제 : rm -rf /etc

(J) 파일 삭제 : rm -rf /usr *

(K) Seliunx 비활성화 : getenforce 0

(L) 부트 로더 삭제 : rm -rf /boot/grub2
```

bootc 수정 가능 목록
```
(A), (C), (D), (E), (G), (I), (K), (L)
```
bootc 수정 불가 목록 *
```
(B), (F), (H), (J)
```

## 피드백
- 버튼 한 번으로 ESXi VM 자동화 생성 및 버전 관리에 가능성에 대해 놀람

- 테스트 과정에서 rm -rf /etc 가 모두 삭제되어서 당황했으나 bootc rollback으로 복구

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


- 생각보다 수정 가능한 항목들이 많음 (에로 /etc, /boot 등)

- 레지스트리 Harbor에 컨테이너 이미지를 Push할 때 중복 데이터를 정확히 고려하지 않아 아쉬움 (태그로 관리하면 될까?)

- 여기서 CI/CD는 모르지만 테스트와 알림까지 더해지면 좋을 듯

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

34 changes: 34 additions & 0 deletions jongseok/bootc-esxi-pipeline/Update-bootc-Client.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Update Bootc Client (Multi-Image)

on:
workflow_dispatch:

env:
HARBOR_REGISTRY: harbor.bootc.com:80
IMAGE_NAME: "my_dashboard"
VERSION: ${{ github.sha_short || format('git-{0}', github.run_id) }}

jobs:
update:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

# 1. 이미지 빌드 (환경변수 IMAGE_NAME 사용)
- name: Build Image
run: |
podman build -f Containerfile_Update \
--network=host \
-t $HARBOR_REGISTRY/smarthome/$IMAGE_NAME:$VERSION .

# 2. latest 태그 추가
- name: Tag as latest
run: |
podman tag $HARBOR_REGISTRY/smarthome/$IMAGE_NAME:$VERSION $HARBOR_REGISTRY/smarthome/$IMAGE_NAME:latest

# 3. Harbor 푸시
- name: Push to Harbor
run: |
podman login -u ${{ secrets.HARBOR_USER }} -p ${{ secrets.HARBOR_PASS }} $HARBOR_REGISTRY
podman push $HARBOR_REGISTRY/smarthome/$IMAGE_NAME:$VERSION
podman push $HARBOR_REGISTRY/smarthome/$IMAGE_NAME:latest
Loading