ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Linux에서 사용자에 따른 환경변수 설정
    인프라/linux 2024. 3. 17. 15:40

     

    Code Deploy를 사용해서 ci/cd를 구축하던 중 만난 이슈를 정리해봅니다.

    Code Deploy에서 실행시킬 스크립트의 작동을 확인하기 위해서 EC2에서 실행시키면서 발생하는 권한과 환경변수 설정 이슈 입니다.

    (EC2에서 RHEL을 사용하고 있습니다.)

     


     

    글은 크게 4가지 항목으로 진행됩니다.

     

    1. 환경변수가 적용이 되지 않거나 도커가 실행이 되지 않거나

    2. 왜? bash_profile!?

    3. 해결책

     

     

     

    1. 환경변수가 적용이 되지 않거나 도커가 실행이 되지 않거나

     

    CI/CD에 사용되는 스크립트에 쓰일 환경변수를 ./bash_profile에 미리 설정을 하였습니다.

    #!/bin/bash
    echo "export USER_ID=your_aws_id" >> ~/.bash_profile
    echo "export REGION=your_aws_region" >> ~/.bash_profile
    echo "export REPO=your_ecr_repo_name" >> ~/.bash_profile
    echo "export IMAGE_TAG=your_docker_image_tag" >> ~/.bash_profile
    echo "export CONTAINER_NAME=your_docker_container_name" >> ~/.bash_profile
    source ~/.bash_profile

     

     

    Code Deploy를 통해서 작동시키려는 스크립트는 아래와 같았습니다.

    #!/bin/bash
    
    # 사용자의 .bash_profile에서 환경변수 로드
    source ~/.bash_profile
    
    # 컨테이너 정지 및 삭제
    if docker ps -a | grep -q "$CONTAINER_NAME"; then
        echo "Stopping and removing container: $CONTAINER_NAME"
        docker stop "$CONTAINER_NAME"
        docker rm "$CONTAINER_NAME"
    else
        echo "Container $CONTAINER_NAME does not exist."
    fi
    
    # Docker 이미지 삭제
    IMAGE="$USER_ID.dkr.ecr.$REGION.amazonaws.com/$REPO"
    if docker images | grep -q "$REPO"; then
        echo "Removing Docker image: $IMAGE"
        docker rmi "$IMAGE"
    else
        echo "Image $IMAGE does not exist."
    fi

     

     

    Code Deploy를 통해 실행하는데 계속 Exception이 발생하여, 우선 스크립트 자체에는 문제가 없는지 확인하기 위해서 EC2에 직접 동일한 스크립트를 작성해서 실행해보았습니다.

    docker를 실행하는데 루트 권한이 필요하여 sudo를 붙여야하는데 그러지 않아서 permission denied가 발생합니다. 하지만 모자이크 처리한 부분에 환경변수가 제대로 적용되는 것을 확인할 수 있었습니다.

    $ sh stop.sh

     

     

    그래서 이번에는 sudo를 추가해서 실행시켜보았습니다.

    그랬더니 이번에는 docker는 작동을 하는데 필요한 환경변수를 가져오지 못하는 것을 확인할 수 있습니다.

    $ sudo sh stop.sh

     

     

     

    2. 왜? bash_profile!?

    기본적으로 ./.bash_profile 파일 자체의 용도를 제대로 모르고 사용했기에 발생하는 이슈였습니다.

    sudo를 사용하면 root 권한으로 실행되기 때문에, 기존 유저에 적용한 bash_profile이 적용되지 않습니다.

    (bash_profile에 있는 악의적인 환경변수가 영향을 줄 수 있기 때문에 os 레벨에서 사용하지 않도록 조치)

     

    따라서 sudo를 사용해서 script를 실행시키면 script는 실행이되나 환경변수를 찾을 수 없었고,

    sudo를 사용하지 않으면 docker가 실행되지 않는 상태였습니다.

     

    2-1. bash_profile의 용도

    bash_profile은 로그인 shell의 사용자 설정을 위한 파일 (로그인 shell은 ssh를 사용해서 로그인하는 경우를 생각할 수 있습니다.)

    로그인 쉘의 사용자의 환경 변수 설정, shell 옵션, alias 등 세션의 초기 설정 입력하는 파일입니다.

     

    2-2. bash_profile의 위치

    사용자의 홈 디렉토리에 숨김파일로 존재. 사용자별로 별도의 bash_profile을 가지고 있습니다.

     

    2-3. bash_profile의 실행 시점

    로그인 shell에서 로그인이 진행될 때마다 해당 유저의 세팅을 적용하기 위해 bash_profile이 실행되고 초기화가 진행됩니다.

     

    2-4. bash_profile과 bashrc

    bash_profile은 로그인이 필요한 shell을 위해 작성되는 반면, bashrc는 로그인이 필요없는 bash shell에 적용되기 위해 작성됩니다.

     

     

     

    3. 해결책

    script 파일 자체는 sudo를 사용하지 않고 실행시키나 docker를 실행할 때만 sudo를 적용하도록 script 수정

    #!/bin/bash
    
    # sudo 미적용으로 사용자의 .bash_profile에서 환경변수 로드 가능
    source ~/.bash_profile
    
    # 컨테이너 정지 및 삭제
    if sudo docker ps -a | grep -q "$CONTAINER_NAME"; then
        echo "Stopping and removing container: $CONTAINER_NAME"
        sudo docker stop "$CONTAINER_NAME"
        sudo docker rm "$CONTAINER_NAME"
    else
        echo "Container $CONTAINER_NAME does not exist."
    fi
    
    # Docker 이미지 삭제
    IMAGE="$USER_ID.dkr.ecr.$REGION.amazonaws.com/$REPO"
    if sudo docker images | grep -q "$REPO"; then
        echo "Removing Docker image: $IMAGE"
        sudo docker rmi "$IMAGE"
    else
        echo "Image $IMAGE does not exist."
    fi

     

     

    정상적으로 동작하는 것을 확인 가능합니다!

    $ sh stop.sh

     

     

     

    감사합니다.

     

     

     

     

     

Designed by Tistory.