도커 실습 9 - Redis을 활용한 이기종 서버간 세션 공유 > 도커 & 쿠버네티스

본문 바로가기

[실습] 도커 실습 9 - Redis을 활용한 이기종 서버간 세션 공유

필기자
2024-11-13 10:48 152 0

본문

목차

  • 파이썬 커스텀 도커 이미지 생성
  • flask 프레임워크 로그인/로그아웃 app
  • php 세션 공유 프로그램


파이썬 커스텀 도커 이미지 생성

  • mkdir -p ~/flask/user
  • cd ~/flask
  • requirements.txt(python 패키지) 설정


Flask
Flask-Session
redis
PyMySQL

  • Dockerfile 파일 생성


# Python 3.9 기반 이미지 사용
FROM python:3.9

# 작업 디렉토리 설정
WORKDIR /app

# 요구 사항 파일 복사 및 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 애플리케이션 코드 복사
# COPY . .

# Flask 환경 변수 설정
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

# 컨테이너가 80 포트를 노출하도록 설정
EXPOSE 80

# Flask 애플리케이션 실행
CMD ["flask", "run", "--host=0.0.0.0", "--port=80"]

  • 커스텀 이미지 생성
  • docker build -t myflaskimage .

flask 프레임워크 로그인/로그아웃 app

  • nano ~/flask/user/app.py


from flask import Flask, request, jsonify
import pymysql
import redis
app = Flask(__name__)
app.url_map.strict_slashes = False  # 슬래시 구분을 비활성화
# Redis 설정
session_id = "cloud-native"
redis_client = redis.StrictRedis(host='myredis', port=6379, decode_responses=True)  # decode_responses=True로 설정해 문자열 데이터를 반환받음
# MySQL 연결 설정 (예외 처리 추가)
try:
    connection = pymysql.connect(
        host='mysql',
        user='php-mysql',
        password='123456',
        database='php-mysql',
        cursorclass=pymysql.cursors.DictCursor
    )
except pymysql.MySQLError as e:
    print(f"Error connecting to MySQL: {e}")
    connection = None
# 기본 테스트 페이지 라우트
@app.route('/', methods=['GET'])
def user_home():
    return "Welcome to the User Home Page! This is a test page."
# 로그인 라우트 (GET 및 POST 요청 허용)
@app.route('/login', methods=['GET', 'POST'])
def login():
    global session_id, redis_client
    ret = {}
    if request.method == 'GET':
        email = request.args.get('email', '')
        password = request.args.get('password', '')
    else:
        email = request.form.get('email', '')
        password = request.form.get('password', '')
    if not email:
        ret['result'] = "no"
        ret['msg'] = "이메일 정보가 없습니다."
        return jsonify(ret)
    if not password:
        ret['result'] = "no"
        ret['msg'] = "패스워드 정보가 없습니다."
        return jsonify(ret)
    password = str(password)
    if connection is None:
        ret['result'] = "no"
        ret['msg'] = "데이터베이스에 연결할 수 없습니다."
        return jsonify(ret)
    try:
        with connection.cursor() as cursor:
            query = "SELECT * FROM user WHERE email=%s AND pass=%s"
            cursor.execute(query, (email, password))
            row = cursor.fetchone()
            if not row:
                ret['result'] = "no"
                ret['msg'] = "로그인 정보가 틀립니다."
            else:
                # Redis에 세션 데이터 저장 (1시간 동안 저장)
                redis_client.setex(f"session:{session_id}:username", 3600, row['name'])
                redis_client.setex(f"session:{session_id}:useremail", 3600, row['email'])
                ret['result'] = "ok"
                ret['msg'] = "정상 로그인이 되었습니다."
    except pymysql.MySQLError as e:
        ret['result'] = "no"
        ret['msg'] = "데이터베이스 쿼리 오류: " + str(e)
    except Exception as e:
        ret['result'] = "no"
        ret['msg'] = "일반적인 오류: " + str(e)
    finally:
        if connection:
            connection.commit()
    return jsonify(ret)
# 로그아웃 라우트
@app.route('/logout', methods=['POST'])
def logout():
    global session_id, redis_client
    ret = {}
    try:
        # Redis에서 세션 데이터 삭제
        redis_client.delete(f"session:{session_id}:username")
        redis_client.delete(f"session:{session_id}:useremail")
        ret['result'] = "ok"
        ret['msg'] = "로그아웃이 완료되었습니다."
        print("Session data cleared")  # 디버깅 메시지
    except Exception as e:
        ret['result'] = "no"
        ret['msg'] = "로그아웃 중 오류가 발생했습니다: " + str(e)
        print(f"Error during logout: {e}")  # 디버깅 메시지
    return jsonify(ret)
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, debug=True)

20241113172738_7df2b3ed52647cdc84ef82ca4bd140f6_lqnh.png

php 세션 공유 프로그램

  • nano ~/php/task/redis_session_get.php


    // Redis에 연결
    $redis = new Redis();
    $redis->connect('myredis', 6379);
    // 세션 ID 설정 (Flask에서 사용한 것과 동일한 값)
    $session_id = "cloud-native";
    // Redis에서 세션 데이터 가져오기
    $username = $redis->get("session:$session_id:username");
    $useremail = $redis->get("session:$session_id:useremail");
    echo "사용자 이름 : " . ($username ? $username : '없음') . "<br>";
    echo "사용자 아이디 : " . ($useremail ? $useremail : '없음') . "<br>";

20241113172922_7df2b3ed52647cdc84ef82ca4bd140f6_l1rg.png
 

댓글목록0

등록된 댓글이 없습니다.
게시판 전체검색