나도 이제 최대 4CORE, 24RAM 무료 인스턴스를 생성할 수 있다는 설레는 마음으로 생성을 시도했다.
Out of capacity for shape VM.Standard.A1.Flex in availability domain AD-1. Create the instance in a different availability domain or try again later.If you specified a fault domain, try creating the instance without specifying a fault domain. If that doesn’t work, please try again later.Learn more about host capacity.
헛된 꿈이었음을...
싱가포르(가입 시 설정한 리전)에는 해당 인스턴스를 생성할 수 있는 여유가 없어서 생성을 할 수가 없다는 메세지이다.
운 좋으면 새벽에 된다길래 콘솔에 Create 버튼을 1분마다 클릭하는 스크립트를 넣었으나, 오랜 시간 지나면 자동으로 로그인이 풀리는 문제가 발생했다.
> 사용 스크립트
window.oracleAutoClicker = (() => {
const SELECTOR = `button[aria-label="Create"]`;
const INTERVAL_MS = 60 * 1000; // 60초
let intervalId = null;
let attemptCount = 0;
function nowTime() {
return new Date().toLocaleTimeString();
}
function log(msg) {
console.log(`[AutoCreateBot] [${nowTime()}] Attempt #${attemptCount} ${msg}`);
}
function start() {
if (intervalId !== null) {
log("Already running.");
return;
}
log("Auto clicker started.");
intervalId = setInterval(() => {
attemptCount++;
const btn = document.querySelector(SELECTOR);
if (btn) {
btn.click();
log("Create button clicked!");
} else {
log("Create button not found. Will retry.");
}
}, INTERVAL_MS);
}
function stop() {
if (intervalId !== null) {
clearInterval(intervalId);
intervalId = null;
log("Auto clicker stopped.");
} else {
log("Not running.");
}
}
return { start, stop };
})();
혹시라도 시도할 사람이 있다면 `oracleAutoClicker.start()` 로 실행하기 전에 관리자모드에서 Create 버튼을 셀렉해줘서 html 을 활성화 시켜줘야한다. 안그러면 계속 "Create button not found. Will retry" 메세지만 콘솔에 뜸.
방법은 리전을 바꿔서 시도하는건데, 리전은 변경이 안되므로 새로 가입해야한다. 탈퇴하고 가입했을 때 바로 되는지도 확실치 않아서 될 때까지 계속 생성을 시도하는 쪽으로 생각했다. 나같은 사람이 많았는지 여러가지 방법으로 자동화를 생성하는 사람들이 있었다. 내가 하고 싶은건 간단하고 24시간 돌릴 수 있는 방법이었는데, 서버가 없으니까 그냥 노트북에서 실행하기로 했다.
실행 환경은 Docker Desktop 이다.
실행 환경 구성 (Docker)
# Dockerfile
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
# 1. 필수 패키지 설치
RUN apt update && apt install -y \
curl unzip python3 python3-pip jq vim cron
# 2. Oracle CLI 설치
RUN bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)" -- --accept-all-defaults && \
ln -s /root/bin/oci /usr/local/bin/oci
# 3. 작업 디렉토리 설정
WORKDIR /app
# 4. 로그 디렉토리 생성
RUN mkdir -p /root/logs
# 5. 컨테이너가 계속 실행되도록 유지
CMD ["tail", "-f", "/dev/null"]
가장먼저 Dockerfile 을 생성하고 파일 저장 경로에 들어가서 `docker build -t oracle-auto .` 를 입력한다. 이렇게하면 oracle-auto 라는 이미지가 생성된다.
> 실행 로그
PS C:\work\oracle cloud\oracle-auto-instance> docker build -t oracle-auto .
[+] Building 157.1s (10/10) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 551B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:22.04 4.3s
=> [auth] library/ubuntu:pull token for registry-1.docker.io 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/5] FROM docker.io/library/ubuntu:22.04@sha256:31f0c161788b6d39b8d66dce2c729e42b294b0fc0e097792d8dff531f72287b0 2.4s
=> => resolve docker.io/library/ubuntu:22.04@sha256:31f0c161788b6d39b8d66dce2c729e42b294b0fc0e097792d8dff531f72287b0 0.0s
=> => sha256:e735f3a6b70199ad991c5715d965a4d858540eca2be18be0d889698e5a0a3e8c 29.54MB / 29.54MB 1.6s
=> => extracting sha256:e735f3a6b70199ad991c5715d965a4d858540eca2be18be0d889698e5a0a3e8c 0.8s
=> [2/5] RUN apt update && apt install -y curl unzip python3 python3-pip jq vim cron 90.2s
=> [3/5] RUN bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)" -- --accept-all-defaults 36.1s
=> [4/5] WORKDIR /app 0.2s
=> [5/5] RUN mkdir -p /root/logs 0.2s
=> exporting to image 23.3s
=> => exporting layers 15.0s
=> => exporting manifest sha256:d84a1695df8f371d0af31aee91176f45a53c849b1d90216959ab14791028dd0b 0.0s
=> => exporting config sha256:201bc34f78ccdcd9133a563c04c40768f1a5395c27f932ac22dc369090f2db8a 0.0s
=> => exporting attestation manifest sha256:a06ae0eacbe133d49e2404841efaa57ff4620608a9d8389a48d2472279edf391 0.0s
=> => exporting manifest list sha256:38c1aa20e500fddaa0c3d7b7162a085196fc0051693c28009354695a1b6e0262 0.0s
=> => naming to docker.io/library/oracle-auto:latest 0.0s
=> => unpacking to docker.io/library/oracle-auto:latest 8.3s
생성이 완료되면 실행 버튼을 눌러 컨테이너를 생성한다. (필요 시 실행옵션으로 이름과 볼륨 지정)
필요한 정보 수집
API key
Dockerfile 에서 설치한 오라클 OCI를 연결해야한다.
오라클 클라우드에 접속하여 Profile 첫 번째 본인 계정으로 들어가서 Tokens and keys > Add API key 로 키를 생성한다.
키파일 저장해두고 생성 후 나오는 정보 중 `user`, `tenancy`, `region` 을 복사해두자.
생성한 키는 도커에 넣어두기.
/instaces
에러났던 instances 네트워크를 찾아 `Copy as cURL (cmd)` 클릭
파일을 열어보면 이런 텍스트들이 나오는데 여기서 내가 인스턴스 생성할 때 사용한 설정인 `subnetid`, `imageid` 값 기록해두자.
그리고 저 인스턴스 생성 시도할 때 저장했던 ssh key 도 필요하니 삭제하면 안된다.
여태까지 정보가 이렇게 있어야한다.
* API key
[DEFAULT]
user=[ocid1.user.oc1...]
fingerprint=
tenancy=[ocid1.tenancy.oc1...]
region=[ap-singapore-1]
key_file=[도커에 API key 넣고 경로 미리 적어두기 ex) /app/volume/email123@xxx.com-2025-07-02T12_52_19.745Z.pem]
* /instance
subnetid=[ocid1.subnet.oc1.ap-singapore-1.aaaaaaa.....]
imageid=[ocid1.image.oc1.ap-singapore-1.aaaaaaaa....]
+ ssh key file
OCI 설정
root@a32453801d15:~/.oci# oci setup config
This command provides a walkthrough of creating a valid CLI config file.
The following links explain where to find the information required by this
script:
User API Signing Key, OCID and Tenancy OCID:
https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#Other
Region:
https://docs.cloud.oracle.com/Content/General/Concepts/regions.htm
General config documentation:
https://docs.cloud.oracle.com/Content/API/Concepts/sdkconfig.htm
Enter a location for your config [/root/.oci/config]: [엔터]
Enter a user OCID: [API key: user]
Enter a tenancy OCID: [API key: tenancy]
Enter a region by index or name(e.g.
1: af-johannesburg-1, 2: ap-chiyoda-1, 3: ap-chuncheon-1, 4: ap-chuncheon-2, 5: ap-dcc-canberra-1,
6: ap-dcc-gazipur-1, 7: ap-hyderabad-1, 8: ap-ibaraki-1, 9: ap-melbourne-1, 10: ap-mumbai-1,
11: ap-osaka-1, 12: ap-seoul-1, 13: ap-seoul-2, 14: ap-singapore-1, 15: ap-singapore-2,
16: ap-suwon-1, 17: ap-sydney-1, 18: ap-tokyo-1, 19: ca-montreal-1, 20: ca-toronto-1,
21: eu-amsterdam-1, 22: eu-crissier-1, 23: eu-dcc-dublin-1, 24: eu-dcc-dublin-2, 25: eu-dcc-milan-1,
26: eu-dcc-milan-2, 27: eu-dcc-rating-1, 28: eu-dcc-rating-2, 29: eu-dcc-zurich-1, 30: eu-frankfurt-1,
31: eu-frankfurt-2, 32: eu-jovanovac-1, 33: eu-madrid-1, 34: eu-madrid-2, 35: eu-marseille-1,
36: eu-milan-1, 37: eu-paris-1, 38: eu-stockholm-1, 39: eu-zurich-1, 40: il-jerusalem-1,
41: me-abudhabi-1, 42: me-abudhabi-2, 43: me-abudhabi-3, 44: me-abudhabi-4, 45: me-alain-1,
46: me-dcc-doha-1, 47: me-dcc-muscat-1, 48: me-dubai-1, 49: me-jeddah-1, 50: me-riyadh-1,
51: mx-monterrey-1, 52: mx-queretaro-1, 53: sa-bogota-1, 54: sa-santiago-1, 55: sa-saopaulo-1,
56: sa-valparaiso-1, 57: sa-vinhedo-1, 58: uk-cardiff-1, 59: uk-gov-cardiff-1, 60: uk-gov-london-1,
61: uk-london-1, 62: us-ashburn-1, 63: us-chicago-1, 64: us-gov-ashburn-1, 65: us-gov-chicago-1,
66: us-gov-phoenix-1, 67: us-langley-1, 68: us-luke-1, 69: us-phoenix-1, 70: us-saltlake-2,
71: us-sanjose-1, 72: us-somerset-1, 73: us-thames-1): [ap-singapore-1]
Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to a
n existing key.) [Y/n]: [n]
Enter the location of your API Signing private key file: [API key 경로 + 파일명 입력]
Fingerprint: 30:b6:f6:94:fe:08:0b:26:05:5f:09:c9:07:e6:57:fc
Config written to /root/.oci/config
If you haven't already uploaded your API Signing public key through the
console, follow the instructions on the page linked below in the section
'How to upload the public key':
https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#How2
root@a32453801d15:~/.oci# oci setup config
Enter a location for your config [/root/.oci/config]: [엔터]
Enter a user OCID: [API key: user]
Enter a tenancy OCID: [API key: tenancy]
Enter a region by index or name: [API key: region]
Do you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to a
n existing key.) [Y/n]: n
Enter the location of your API Signing private key file: [API key 경로 + 파일명 입력]
완료 후 `cat ~/.oci/config` 를 보면 위 설정대로 config 파일이 생성된걸 확인할 수 있다.
Permissions on user@xxx.com.pem are too open.
root@a32453801d15:~/.oci# oci os ns get
WARNING: Permissions on /app/volume/user@xxx.com.pem are too open.
To fix this please try executing the following command:
oci setup repair-file-permissions --file /app/volume/user@xxx.com.pem
Alternatively to hide this warning, you may set the environment variable, OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNI
NG:
export OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNING=True
{
"data": "axdv7fbsprxr"
}
`oci os ns get` 로 설정을 확인할 수 있는데, 위와같은 에러가 뜰 수 있다.
Oracle CLI는 API 키(private key) 파일의 권한이 너무 느슨하면 동작하지 않기 때문에, `chmod 600 [API key 파일]`로 권한을 변경해준다.
정상적으로 작동하면 data 가 표시된다.
Region name 복사
root@a32453801d15:~/.oci# oci iam availability-domain list --compartment-id [API key tenancy]
{
"data": [
{
"compartment-id": "ocid1.tenancy.oc1.....",
"id": "ocid1.availabilitydomain.oc1.....",
"name": "nawT:AP-SINGAPORE-1-AD-1"
}
]
}
실제로 인스턴스 생성할 때 필요한 리전이니 복사해두자.
실제 실행 파일
#!/bin/bash
INSTANCE_NAME="[인스턴스 이름]"
COMPARTMENT_ID="[API key tenancy]"
EXISTING_INSTANCE=$( /root/bin/oci compute instance list \
--compartment-id "$COMPARTMENT_ID" \
--display-name "$INSTANCE_NAME" \
--query "data[0].id" \
--raw-output )
if [ -n "$EXISTING_INSTANCE" ]; then
echo "[$(date)] Instance '$INSTANCE_NAME' already exist."
exit 0
fi
# 존재하지 않으면 생성 시도
echo "[$(date)] Start create instance..."
/root/bin/oci compute instance launch \
--availability-domain [위에서 복사한 리전 ex) nawT:AP-SINGAPORE-1-AD-1] \
--compartment-id "$COMPARTMENT_ID" \
--shape [원하는 shape ex) VM.M.Standard.A1.Flex] \
--subnet-id [/instances의 subnetid]
--assign-private-dns-record true \
--assign-public-ip true \
--availability-config '{"recoveryAction":"RESTORE_INSTANCE"}' \
--display-name "$INSTANCE_NAME" \
--image-id [/instances의 imageid] \
--instance-options '{"areLegacyImdsEndpointsDisabled": false}' \
--shape-config '{"ocpus": [원하는대로 ex) 2], "memoryInGBs": [원하는대로 ex) 14]}' \
--ssh-authorized-keys-file [인스턴스 생성할 때 저장한 ssh key ex) /root/oracle/ssh-key-2025-07-02.key.pub]
--no-retry
echo "[$(date)] End create instance..."
옵션 | 설명 |
--shape-config | Flex 타입의 shape에서 사용됨. CPU/메모리 크기 설정을 JSON 형태로 지정. 예: {"ocpus":2, "memoryInGBs":14} |
--assign-private-dns-record | 인스턴스에 대해 개인 DNS 이름을 자동 생성할지 여부 (true/false). |
--assign-public-ip | 인스턴스에 퍼블릭 IP를 자동 할당할지 여부 (true/false). |
--availability-config | 복구 설정을 위한 JSON. 예: {"recoveryAction": "RESTORE_INSTANCE"} ▶ 호스트 장애 시 자동 복구 기능을 설정 |
--instance-options | 인스턴스의 세부 동작을 제어하는 옵션. 예: {"areLegacyImdsEndpointsDisabled": false} ▶ IMDSv2 설정 등 |
--no-retry | 자동 재시도하지 않음 |
auto.sh 파일 생성한다.
무료 티어 계정이면 무료를 초과하는 인스턴스 생성이 안되는 걸로 알고 있는데, 혹시 몰라서 인스턴스 조회 후 있으면 진행하지 않는 스크립트를 추가했다.
echo 메세지는 위와 다를 수 있는데, 실행시켜보면 ServiceError 메세지가 "Out of host capacity" 로 뜨면 정상적으로 작동하는거다.
크론탭 설정
* * * * * /bin/bash /root/.oci/macro.sh >> /root/logs/oci.log 2>&1
`crontab -e` 에서 매 분마다 스크립트를 실행할 수 있도록 설정해준다.
아래 조건을 만족해야한다.
- `service cron start` 크론탭 활성화
- `chmod +x /root/.oci/auto.sh` 파일 x 권한 부여
- `touch /root/logs/oci.log` 로그 파일 생성
로그 확인해보면 계속되는 Out of host capacity 를 볼 수 있다.
마무리
생성이 완료되었습니다! 까지 보여주고 싶지만 언제 될지 모르므로 이대로 마무리하겠습니다...^^
무료 인스턴스 사용
밤사이 Windows 업데이트로 꺼지기도하고 이동시에는 노트북이 돌아가지 않아서 실행시간이 보장되지 않았다. 솔직히 하루정도면 되지 않을까란 기대를 하고 있었는데 그게 아닌 것 같아서 `VM.Standard.E2.1.Micro` 로 매크로 서버를 구현하기로 했다. 이건 사양이 작기 때문에 바로 생성이 가능하다.
Public IP와 저장한 sshkey파일로 접속한다.
이 다음은 위에서 한 것과 동일하게 진행하면 된다.
로그 압축
언제될지 알 수 없기 때문에 로그가 계속 쌓이게된다. 용량은 충분하지만 혹시모를때를 대비해 로그를 압축시켜놓는 cron도 추가해놓겠다.
#!/bin/bash
LOG_DIR="/home/ubuntu/app/logs"
LOG_FILE="oci.log"
DATE=$(date +\%Y-\%m-\%d)
RANDOM_STR=$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1)
# 로그 디렉토리가 없으면 생성
mkdir -p "$LOG_DIR"
# 로그 파일이 존재하면 날짜+난수 붙여 이름 바꾸고 압축
if [ -f "$LOG_DIR/$LOG_FILE" ]; then
NEW_NAME="${LOG_FILE%.*}-$DATE-$RANDOM_STR.log"
mv "$LOG_DIR/$LOG_FILE" "$LOG_DIR/$NEW_NAME"
gzip "$LOG_DIR/$NEW_NAME"
fi
# 새 oci.log 파일 생성
touch "$LOG_DIR/$LOG_FILE"
0 0 * * * /bin/bash /home/ubuntu/app/logs/compress-log.sh
LOG_DIR와 LOG_FILE만 설정해주면 매일 00시 00분에 기존 로그파일을 압축하고 새로운 파일을 생성한다.
'IT' 카테고리의 다른 글
[Cloudflare Tunnel] 우리집 IP 노출 없이 노트북을 연결해보자 (0) | 2025.07.16 |
---|---|
[Oracle Cloud] 오라클 클라우드 프리티어(Free Tier) 가입 (0) | 2025.07.02 |
[Spring Boot] 대용량 데이터 이관 JPA vs JDBC vs MyBatis 비교 (1) | 2025.06.27 |
[Spring Boot] Spring Security 추가 후 CORS/401/403 오류 해결 (0) | 2025.06.27 |
[데이터] Kaggle (캐글) (0) | 2025.05.05 |