파드의 상태를 체크해주는 livenessProbe라는 녀석이 있다.

파드의 상태를 주기적으로 체크하는 probe를 실행하여 실패시 컨테이너를 재시작한다.

 

처음에는 was서버를 쿠버네티스로 옮겼기에 이를 관리하기 위해 livenessProbe만 설정해주었다.

 

spec:
  container:
    livenessProbe:
      httpGet:
        path: /health.jsp
        port: 8080
      failureThreshold: 10
      periodSeconds: 30
      timeoutSeconds: 10

httpGet으로 해당 path와 port에서 http관련 응답을 받지 못하면 실패한 것으로 간주하는 동작이다.

10번 까지 실패횟수 누적이 가능하고

30초마다 probe를 실행하고

한 번의 probe당 10초 정도 통신대기 시간이 있다.

 

앱이 동작하는 동안 매 30초마다 10초동안 신호가 들어오는지 확인 하고

만약 실패 횟수가 10번을 넘어가면 파드를 재시작하는 방식이다.

 

그런데 이렇게만 설정하면 문제가 생긴다.

파드가 시동되고 어플리케이션이 시동하는 시간이 길어지면 probe에 실패를 하게 되어버린다.

위와 같은경우 만약 어플리케이션 기동 시간이 300초 (매  30초마다 10번의 실패 횟수)를 넘어가면

파드가 재시작 되어버리는 상황이 발생하기 때문이다.

 

위와 같은 경우에 대한 대비책이 2가지가 있다.

하나는 livenessProbe의 시작시간을 지연시키는 방법이고

다른 하나는 startupProbe를 이용하는 방법이다.

 

1. initialDelaySeconds

spec:
  container:
    livenessProbe:
      httpGet:
        path: /health.jsp
        port: 8080
      failureThreshold: 10
      periodSeconds: 30
      timeoutSeconds: 10
      initialDelaySeconds: 300

말그대로 초기 지연 시간이다. 300초 뒤에 livenessProbe가 동작하게 하는 설정이다.

 

2. startupProbe

spec:
  container:
    livenessProbe:
      httpGet:
        path: /health.jsp
        port: 8080
      failureThreshold: 10
      periodSeconds: 30
      timeoutSeconds: 10
      
    startupProbe:
      httpGet:
        path: /health.jsp
        port: 8080
      failureThreshold: 10
      periodSeconds: 10
      timeoutSeconds: 3
      initialDelaySeconds: 200

 

startupProbe는 말그대로 어플리케이션이 시작하는 기간을 체크하기 위한 옵션이다.

livenessProbe와 동작방식은 같지만 역할이 다르다.

startupProbe가 끝나면 livenessProbe같은 다른 Probe들이 동작하게된다.

 

위와 같은 경우 startupProbe가 200초 뒤에 시작하여 10초 마다 3초동안 통신을 시도하고

통신이 10번 실패시 재시작 하게 한다.

 

만약) 어플리케이션 기동시간이 270초 라고하면

어플리케이션이 기동을 시작하고 200초 뒤부터 startupProbe가 시작한다.

200초 부터 270초 까지 70초동안 startupProbe가 동작하였는데

70초 동안은 어플리케이션이 올라오지 않아 제대로된 통신이 불가하므로

failure threshold가 7이 된다.

 

startupProbe가 성공으로 나타나면

그때 livenessProbe가 시작되며, 매 30초마다 파드가 죽었는데 http 통신으로 확인한다.

 

 

 

여기까지 해도 문제가 또 발생했다.

통신에 관한 문제이다. 로드밸런서를 통해 파드를 바라보고 있던 상황에서

파드 수의 변화가 생겨버리는 경우, 생성 중인 파드에도 트래픽을 보내 트래픽 실패를 반환 받아 문제가 되곤했다.

이런경우 readinessProbe를 활용하면 좋다.

 

startup, liveness Probe들은 실패시 파드가 재시작한다.

그런데 readinessProbe는 실패시 파드를 서비스에서 제외 하여 트래픽을 받지 않게 한다.

제외시킨 파드는 계속해서 probe를 진행하고 통과되는 경우 복귀시킨다.

말 그대로 방치되는 상황이기 때문에 liveness나 startup Probe와 조합하여 문제시 파드를 재시작하게 한다.

readinessProbe도 startupProbe가 종료뒤에 진행된다고 한다.

 

spec:
  containers:
  - name: goproxy
    image: test-img
    ports:
    - containerPort: 8080
    readinessProbe:
      path:/health.jsp
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
      
    livenessProbe:
      httpGet:
        path:/health.jsp
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10

 

졸면서 씀

bastion을 설치해야하는지 ssl-VPN이나 ipsec-VPN을 사용해야 하던 고민하던 중에

 

Public Subnet 서버에 오픈소스 VPN을 설치하기로 하였다.

 

SoftEhter VPN은 리눅스에서 사용했던 간접경험(내가 설치하지 않고 정말 이용만 해본)이 있어서

SoftEhter VPN으로 결정했다.

 

기존 사내에 남아있던 문서는 리눅스 버전을 기반으로 되어 있었다.

 

좀더 기능과 파라미터들을 공부한 뒤 구축하고 작성하면 좋겠지만

그럴 수 없다. 길어야 2일 밖에 없기 때문에....

 

 

까먹을까 후딱 남긴다.

 

 

윈도우 서버에 VPN을 설치해준다.

rtm 버전으로 설치한다

 

이후에 나오는 것들은 그냥

 

 

 

 

 

 

 

설치후에 위와 같은 화면이 나타난다. Connect를 클릭하면 설정에 접속하기 위한 계정 비밀번호를 새로 입력해야한다.

 

 

 

 

 

 

 

간혹 한 노드에 같은 디플로이의 파드 2개가 같이 들어있는 경우가 있어서

알아보게 되었음



파드가 배포 되는 방식을 간단하게 보면

어떤 노드에 파드를 배치할 것인지(Node Affinity)

파드들을 어떻게 배치할 것인지(Pod Affinity, Anti-Affinity)

2가지 방식을 사용하는 것 같다.

 

Node affinity는 간단하게 어떤 노드들에 Pod들이 배치될 수 있는지 정해주는 옵션이다.

어떤 노드인지는, 노드에 할당된 label 값을 기준으로 선택하고

label이 있어야 하는지, 없어야 하는지에 따라

해당 label이 있는 노드에만 파드 배치 해당 label이 있는 노드를 피해서 파드 배치를 정할 수 있다.

 

Pod affinity는 어떤 파드들 끼리 모여있어야 한다고 정해주는 옵션이다.

노드와는 다르게 pod Anti Affinity 필드가 별도로 있다.

Pod Anti Affinity는 특정 파드들이 떨어져 있어야한다는 필드이다.

 


Node Affinity

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - antarctica-east1
            - antarctica-west1
            
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value

 

requiredDuringSchedulingIgnoredDuringExecution

조건을 필수로 적용하는 옵션이다.

파드가 배포될 노드에는

zone=antarctica-east1 또는

zone=antarctica-west1 이라는 label이 반드시 설정되어 있어야 한다

 

operator는 In, NotIn, Exist, DoesNotExist 가 있다.

In 특정 값이 포함되면 매칭 valus가 여러개의 경우 하나만 있으면 됨
NotIn 특정 값이 포함되지 않으면 매칭  
Exist 특정 라벨이 존재하면 매칭  
DoesNotExist 특정 라벨이 존재하지 않으면 매칭  

 

 

 

preferredDuringSchedulingIgnoredDuringExecution

선호 되는 조건이지만 꼭 지켜지지 않아도 되는 조건이다.

weight 필드 값으로 가중치를 부여

노드가 another-node-label-key=another-node-label-value의 label을 갖고 있으면 파드를 우선적으로 배치한다

 

 

아래와 같은 결과로 배치될 것이다.

 

zone=antarctica-east1 or anrarctica-west1을 만족하는 label을 갖고있는 노드여야 하고

another-node-label-key=another-node-label-value의 label을 갖고있는 노드에 파드를 우선적으로 배치하였다.

another-node-label-key=another-node-label-value의 label 만 있는 경우는

required 조건을 만족하지 않아 pod가 배포 되지 않는다.

 

 

만약 특정 조건의 노드를 피하고 싶다면 operator에 NotIn이나 DoesNotExist 연산자를 사용하면 된다.

 


 

 

Pod affinity , Pod AnitiAffinity

파드를 배포할때 특정 조건의 파드가 모여있을지 떨어져있을지를 결정하는 옵션이라고 보면 된다.

Node Affinity와 거의 유사하며 topologyKey라는 옵션에 배포될 노드에 관한 조건을 적는 부분이 추가된다.

 

특정 label을 가진 파드가 배포된 노드가 가진 label값을 기준으로 파드가 배포될지 아닐지 설정한다

spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: blog
            operator: In
            values:
            - test1
        topologyKey: topology.kubernetes.io/os
      
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: blog
              operator: In
              values:
              - test2
          topologyKey: topology.kubernetes.io/hostname

 

 

Pod Affinity vs Anti-Affinity

 

podAffinity 파드가 특정 조건에따라 "모여"있게

podAntiAffinity 파드가 특정 조건에따라 "흩어져" 있게

 

spec 필드 아래 affinity 필드아래에서 위의 두 옵션을 적용하여 운영한다.

 

특정 조건을 만족하는 파드가 배포된 노드와

특정 조건이 같은 노드에 파드를 배포할지 말지 결정한다.

 


예를 들면 위의

PodAffinity에서는 특정조건을 만족하는 pod가 배포된 노드에 pod를 배포한다는 의미이다.

 

1. blog=test1 이라는 label을 갖는 pod

2. blog=test1 이라는 label을 갖는 pod가 배포된 노드의 OS

 

위의 두 조건을 만족하는 노드에 파드를 배치하겠다는 이야기이다.

 

required가 적용되고, 아무것도 없는 상황에서 첫 스크립트에 위와 같은 PodAffinity 옵션을 적용하면

파드가 생성되지 않는다.

preferred가 적용되면, 조건을 만족하지 않아도 생성이 된다.

 

 

 

반대로 Pod Anti Affinity에서는

 

위의 두 조건을 만족하는 노드에는 파드를 배치하지 않겠다는 이야기 이다.

만약 기준을 os로 했는데 모든 노드가 같은 os를 사용중이면 파드가 생성되지 않는다.

마찬가지로 preffered가 적용된 상황에서는 파드가 생성된다.


topologyKey

 

 

topologyKey는 노드에 할당된 값들을 사용하거나

정해진 값이 아닌 경우에는 노드의 label을 기준으로 동작한다.

 

topology.kubernetes.io/hostname

* node의 hostname

topology.kubernetes.io/region

* node의 region // ex) us-west-1

topology.kubernetes.io/zone

* node의 AZ 같은 가용지역 // ex) kr2, 1

topology.kubernetes.io/instance-type

* node의 instance type // ex) m5.large, SVR.VSVR.HIMEM.C002.M016.G003

topology.kubernetes.io/os

* node의 os 종류 // ex) linux, windows

topology.kubernetes.io/arch

* node의 시스템 아키텍쳐 // ex) amd64 , amd32

 

 

 


파드를 각 노드에 골고루 분배해야 하는 경우

파드를 각 노드에 공고루 분배해야하는 경우

 

모든 노드가 기준이므로 node Affinity 는 사용하지 않고

분배되어야 하므로 Pod AntiAffinity를 사용한다.

 

Pod AntiAffinity에서 topologyKey를 hostname으로 하여

노드가 겹치지 않게 한다.

 

만약 특정 zone이나 os를 갖는 노드 중에서 골고루 분배하고 싶으면

NodeAffinity를 사용하여 묶는다

 

 

+ Recent posts