본문 바로가기

회고

명명 규칙을 바꾸다 Kubernetes 내부 동작을 이해하게 된 이야기

인프라 고도화를 통해 온프레미스 K8S를  AWS의 EKS서비스로 이전까지 완료 되었습니다.

 

본격적인 운영에 앞서 마음에 걸렸던 Namespace, Deployment, Service, Ingress등의 이름이 명확하지 않고, 이름 내에 리소스 이름이 중복으로 들어가서 명확하지 않은 부분이 있었습니다.

 

예를들어 이번에 글쓰기 주제의 redis의 경우, redis-deployment, redis-service, redis-ingress등으로 이름을 명명하였고, AI 조언을따라 각 자원의 이름을 제외하는 작업을 진행하였습니다.

 

결과적으로 kubectl 또는 k9s등으로 접근할때 다음과 같이 명확한 이름으로 나오게 되었습니다.

(나머지 자원요소가 포함된 대상은 이름 정리 대상 입니다.) 

$ kubectl get service -n system-dev
NAME                                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
system-app-sto-service-dev         ClusterIP   172.20.155.8     <none>        3000/TCP   46d
system-app-sv-service-dev          ClusterIP   172.20.15.185    <none>        3000/TCP   46d
system-core-server-service-dev     ClusterIP   172.20.163.133   <none>        3000/TCP   24d
system-cron-server-service-dev     ClusterIP   172.20.78.208    <none>        3000/TCP   20d
system-system-server-service-dev   ClusterIP   172.20.10.58     <none>        3000/TCP   46d
system-web-admin-service-dev       ClusterIP   172.20.78.31     <none>        3000/TCP   46d
redis                              ClusterIP   172.20.32.180    <none>        6379/TCP   17d

 

 

이를통해 다음과 같이 좀 더 명확한 주소로 접근 할 수 있었습니다.

 redis-service.system-dev.svc.cluster.local  -> redis.system-dev.svc.cluster.local

 

redis에 대한 자원 이름 제외 정리를 성공적으로 마치고 작업을 마무리 하였습니다.

 

문제는 그 이후 발생하였습니다.

redis에 의존적인 system-server Pod의 기동실패가 일어나게 되었습니다.

node:net:1302
    validatePort(port);
    ^

RangeError [ERR_SOCKET_BAD_PORT]: Port should be >= 0 and < 65536. Received type number (NaN).
    at lookupAndConnect (node:net:1302:5)
    at Socket.connect (node:net:1259:5)
    at connect (node:net:242:17)
    at /app/node_modules/.pnpm/ioredis@5.9.0/node_modules/ioredis/built/connectors/StandaloneConnector.js:54:66
    at process.processTicksAndRejections (node:internal/process/task_queues:85:11) {
  code: 'ERR_SOCKET_BAD_PORT'
}

 

환경변수에 포트는 다음과 같이 number type으로 잘 들어가 있었습니다.

REDIS_HOST = 'redis.fc-system-dev.svc.cluster.local'
REDIS_PORT = 6379
REDIS_PASSWORD = 'SECRET'

 

redis에 의존적인 system-server Pod의 기동시에 환경변수를 확인하기 위해 코드를 추가하고 로그를 살펴봅니다.

=== Redis 환경 변수 확인 ===
REDIS_HOST: redis.fc-system-dev.svc.cluster.local
REDIS_PORT: tcp://172.20.32.180:6379
REDIS_PASSWORD: (설정됨)

 

분명 환경변수에는 6379로 넣었으나, 실제로 들어간 환경변수는 tcp://172.20.139.131:6379임을 확인하였고, 문자열 값으로 들어갔기 때문에 에러와 함께 Pod 기동이 실패하였습니다.

 

혹시 redis 관련 자원 이름을 변경한게 문제가 되나 싶어서 원복 해봅니다.  

service 자원 이름 원복:  redis -> redis-service

 

system-server Pod가 정상적으로 기동되고 REDIS_PORT도 정상적으로 나옵니다.

=== Redis 환경 변수 확인 ===
REDIS_HOST: redis.fc-system-dev.svc.cluster.local
REDIS_PORT: 6379
REDIS_PASSWORD: (설정됨)

 

system-server Pod로 접근하여 환경변수를 확인해봅니다.

제가 선언하지 않은 redis 관련 환경변수들이 Pod에 설정되었음을 확인 하였습니다.

/app/system-server $ env | grep REDIS
REDIS_SERVICE_SERVICE_PORT=6379
REDIS_SERVICE_PORT=tcp://172.20.32.180:6379
REDIS_SERVICE_PORT_6379_TCP_ADDR=172.20.32.180
REDIS_SERVICE_PORT_6379_TCP_PORT=6379
REDIS_SERVICE_PORT_6379_TCP_PROTO=tcp
REDIS_SERVICE_PORT_6379_TCP=tcp://172.20.32.180:6379
REDIS_SERVICE_SERVICE_HOST=172.20.32.180

 

AI를 통한 확인 결과

문제가 되었던 system-server Pod와, redis Pod는 동일한 namespace에 배포가 된 상황에서 k8s 특성상 모든 Service에 대해 동일한 규칙으로 환경변수를 자동 생성하는 것으로 확인이 되었습니다.

 

system-server Pod는 redis 연결관련 환경변수를 쓰고 있습니다. 

다만 이 값이, k8s에 의해 덮어씌워지면서 문제가 발생하였습니다.

#사용하는 변수
REDIS_HOST = 'redis.fc-system-dev.svc.cluster.local'
REDIS_PORT = 6379
REDIS_PASSWORD = 'SECRET'

 

 

저의 경우는 redis-service ->  redis 로 전환하면서 위의 변수가 다음과 같이 치환 된 것입니다.

# k8s에서 자동으로 주입하는 변수
REDIS_SERVICE_PORT=6379
REDIS_PORT=tcp://172.20.32.180:6379
REDIS_PORT_6379_TCP_ADDR=172.20.32.180
REDIS_PORT_6379_TCP_PORT=6379
REDIS_PORT_6379_TCP_PROTO=tcp
REDIS_PORT_6379_TCP=tcp://172.20.32.180:6379
REDIS_SERVICE_HOST=172.20.32.180

 

 

이런 현상을 막기 위해 기본으로 활성화된 enableServiceLinks를 false로 변경해야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: system-server
  template:
    metadata:
      labels:
        app: system-server
    spec:
      enableServiceLinks: false
      containers:
        - name: system-server
          image: system-server:latest
          ports:
            - containerPort: 3000