티스토리 뷰

longhorn: 저장공간 추상화. storageClass를 oci-bv 로 했다가 노드별로 블록 볼륨이 생기는 대참사를 겪지 않을 수 있습니다. 프리티어는 전부 해서 200기가로 제한되어있으니까요.

그냥 longhorn을 설치하면 시스템 볼륨을 사용하게 됩니다. 그건 싫으니까, 노드풀의 노드에 자동으로 별도의 블록 볼륨을 넣어주고 싶죠. 블록 볼륨은 자동으로 삭제되지 않으니까 데이터 보존 면에서도 혹시나 모를 사태를 방지할수도 있구요.

물론 가이드에서 언급하는 longhorn 은 리전간 백업을 목적으로 하는 것 같지만 전 그런 건 아무래도 상관없구요... 춘천이 불바다나면 내 데이터는 어차피 끝장이야~

공식 가이드가 있는데, 어딘가 나사가 빠진 부분이 있습니다.

https://docs.oracle.com/en/learn/deploy-longhorn-on-oke/index.html#prerequisites

1. 파이썬 스크립트의 들여쓰기가 잘못되어 있습니다. 이건 적당히 고치면 되는거고

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh

echo "installing python3-pip , oci sdk\n"
sudo yum install python3 -y
sudo yum install python3-pip -y
pip3 install oci
pip3 install requests

cat << EOF > pyscript.py
#!/usr/bin/python

import oci
import requests

size_in_gbs = 50
vpus_per_gb = 10
mode = 'PARA'
device_path = "/dev/oracleoci/oraclevdb"
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()

def get_current_instance_details():
    r = requests.get(url= 'http://169.254.169.254/opc/v2/instance', headers={"Authorization": "Bearer Oracle"})
    return r.json()

instanceDetails = get_current_instance_details()

compute_client = oci.core.ComputeClient({"region": instanceDetails["region"]}, signer = signer)
block_storage_client = oci.core.BlockstorageClient({"region": instanceDetails["region"]}, signer = signer)


def create_volume(block_storage, compartment_id, availability_domain, display_name: str):
    print("--- creating block volume ---")
    result = block_storage.create_volume(
        oci.core.models.CreateVolumeDetails(
            compartment_id=compartment_id,
            availability_domain=availability_domain,
            display_name=display_name,
            size_in_gbs = size_in_gbs,
            vpus_per_gb = vpus_per_gb
        )
    )
    volume = oci.wait_until(
        block_storage,
        block_storage.get_volume(result.data.id),
        'lifecycle_state',
        'AVAILABLE'
    ).data
    print('--- Created Volume ocid: {} ---'.format(result.data.id))
    return volume

def attach_volume(instance_id, volume_id,device_path):
    volume_attachment_response = ""
    if mode == 'ISCSI':
        print("--- Attaching block volume {} to instance {}---".format(volume_id,instance_id))
        volume_attachment_response = compute_client.attach_volume(
            oci.core.models.AttachIScsiVolumeDetails(
                display_name='IscsiVolAttachment',
                instance_id=instance_id,
                volume_id=volume_id,
                device= device_path
                )
            )
    elif mode == 'PARA':
        volume_attachment_response = compute_client.attach_volume(
            oci.core.models.AttachParavirtualizedVolumeDetails(
            display_name='ParavirtualizedVolAttachment',
            instance_id=instance_id,
            volume_id=volume_id,
            device= device_path
        )
    )
    oci.wait_until(
        compute_client,
        compute_client.get_volume_attachment(volume_attachment_response.data.id),
        'lifecycle_state',
        'ATTACHED'
    )
    print("--- Attaching complete block volume {} to instance {}---".format(volume_id,instance_id))
    print(volume_attachment_response.data)

# Call instance metadata uri to get current instace details

volume = create_volume(block_storage= block_storage_client, compartment_id= instanceDetails['compartmentId'], availability_domain=instanceDetails['availabilityDomain'], display_name= instanceDetails['displayName'])
attach_volume(instance_id=instanceDetails['id'], volume_id=volume.id, device_path= device_path)

EOF

echo "running python script\n"
chmod 755 pyscript.py
./pyscript.py

echo "creating file system on volume\n"
sudo /sbin/mkfs.ext4 /dev/oracleoci/oraclevdb
echo "mounting volume\n"
sudo mkdir /mnt/volume
sudo mount /dev/oracleoci/oraclevdb /mnt/volume
echo "adding entry to fstab\n"
echo "/dev/oracleoci/oraclevdb /mnt/volume ext4 defaults,_netdev,nofail 0 2" |  sudo tee -a /etc/fstab

2. 노드풀의 노드에 권한을 부여해줘야 합니다.

위 스크립트는 Instance Principals 라는 인증방법을 사용하고 있는데, 노드에 부여되는 인증방법인 셈이죠.

  • 169.254.169.254 주소는 cloud-init 의 표준적인 주소입니다. 그냥 제공되는 거니까 신경 안 쓰셔도 됩니다.
  • 원본 가이드의 스크립트에는 v1 HTTP API 가 기술되어 있는데 문서 보니까 v2 나왔다길래 바꿔보니까 쓰는 부분은 영향이 없더라구요.

이를 위해 Dynamic Group (동적 그룹) 을 만들어서 노드를 매칭시킬 ID같은 걸 만들고, 이 동적 그룹에 권한을 부여해줘야 합니다.

  • Compartment (구획): 개념적인 리소스 분할의 단위입니다. 루트 테넌시가 루트 구획(Compartment) 입니다.

Dynamic Group 생성

ID -> 도메인 (우측 위 메뉴에서 현재 도메인 선택) -> 동적 그룹

All {instance.compartment.id='ocid1.tenancy.oc1..그냥테넌시넣음',tag.태그를.미리부여해놨습니다.value='yes'}

https://docs.oracle.com/en-us/iaas/Content/Identity/dynamicgroups/Writing_Matching_Rules_to_Define_Dynamic_Groups.htm#Writing

개인적 취향으로 태그를 부여해놓아야겠다 싶어서 노드 풀의 설정에서 노드에 자동으로 태그를 부여하게 해놨습니다.

딱히 태그의 이름이나 값에 의미가 있지는 않습니다. ".value" 부분은 킵하는 게 정답이더라구요.

권한 부여 (정책 / Policy)

노드 셀렉팅은 했으니 노드에 권한을 부여해줘야 합니다.

Allow dynamic-group 'Default'/'내_동적_그룹' to manage volume-family in tenancy
Allow dynamic-group 'Default'/'내_동적_그룹' to use instance-family in tenancy
Allow dynamic-group 'Default'/'내_동적_그룹' to manage volume-attachments in tenancy

대충해서 맞는지는 몰?루겠네요. 앞의 2개는 규칙 작성기로 만들었고 나머지 하나만 수동으로...

volume-attachments 는 실제로 존재하는 리소스입니다.

https://docs.oracle.com/en-us/iaas/Content/Block/Tasks/enablingblockvolumemanagementplugin.htm

가이드대로 마저 하기

이제 노드풀의 cloud-init 에 위의 스크립트를 (용량 같은 거 확인해보고) 붙여넣으신 뒤 만드시면 됩니다.

내가 인간 승리자다!!!

노드 트러블슈팅

bastion 연결은 여러차례 실패해서... 포기하고 cloud-shell 에서 일봤습네다. 노드가 있는 전용망을 선택하고, 노드 풀의 트러블슈팅 메뉴에서 노드를 만들 때 썼던 ssh 키로 접속하면 이것저것 실행해볼 수 있습니다. 다른 방법은 다 실패함...

내 bastion이 ssh-rsa를 안 받아요!

~/.ssh/config

Host *.oci.oraclecloud.com
    PubkeyAcceptedKeyTypes=+ssh-rsa
    HostKeyAlgorithms=+ssh-rsa

오라클-감사합니다

https://stackoverflow.com/a/74258486/4394750

ChatGPT에게 도움을 받은 흔적

올해의 명예 오라클 직원상을 줄 수 있다면 GPT4에게 주고 싶네요

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함