현상
쿠버네티스 클러스터 환경에서 동작하고 있는 서비스가 정상적으로 동작하고 있지 않아 확인하던 중, 포드 컨테이너에서 외부로 나가야 하는 트래픽이 막혀 있는 것이 원인이라는 것을 알게 되었다.
쿠버네티스 클러스터 환경은 온 프레미스에서 kubeadm을 이용해 구성되었으며, 네트워크 플러그인으로는 calico를 사용하고 있다. calico가 어떤 방식으로 쿠버네티스 환경에서 네트워크를 설정하는지, 관련해서는 어떤 조건이 필요한지는 잘 모르겠으나…… 일단은 kube-system namespace에서 각 노드에 배포된 calico-node pod가 정상적으로 동작해야 하는 것으로 보인다.
확인해보니, 최근 서버 재부팅 후 일부 calico-node pod가 정상적으로 동작하지 않고 있었다. 그리고 정상적이지 않은 calico-node pod가 스케쥴링된 노드와 장애 상태인 서비스 포드가 스케쥴링된 노드가 동일했다.
kubectl get pod -n kube-system | grep calico
describe 명령으로 pod 상태 확인 시의 Events는 아래와 같았다. 확인했던 기록을 남기지 못해서 확실하진 않다.
kubectel describe pod -n kube-system <calico-node-pod-name>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Unhealthy 107s (x34333 over 3d23h) kubelet, node_name (combined from similar events): Readiness probe failed: calico/node is not ready: BIRD is not ready: BGP not established with 10.x1.2x.x23,10.x1.x7.x53,10.x1.1x.1x5,10.x1.2x.1x22020-04-12 08:40:48.567 [INFO][27813] health.go 156: Number of node(s) with BGP peering established = 0
대략 네트워크 인터페이스, IP, 포트, 방화벽 정도가 확인을 해볼 지점이 되는 것 같다.
이 글의 경우, node를 join 시키는 시점에 node에서 동작하는 docker container가 존재해 host의 IP를 정상적으로 확인하지 못하는 것이 원인이라고 한다. 따라서 서버에서 동작하고 있는 docker container를 전부 stop 시키거나, calicoctl을 이용해 node 리소스를 수동으로 설정해야 한다.
이 글에서는 node 리소스를 수동으로 수정할 것이다.
방법
1. calicoctl 설치
아래 글에 사용한 설치 방법을 정리해두었다.
2022.03.05 - [calico] calicoctl 설치 - k8s pod
2. node 구성 확인
kubectl exec 명령으로 calicoctl pod가 명령을 수행하도록 한다.
# node 목록 확인
calicoctl get node
# 특정 노드 확인
calicoctl get node <NODE_NAME>
# 특정 노드 정보를 yaml 형식으로 확인
calicoctl get node <NODE_NAME> -o yaml
3. 노드 구성 설정 파일 수정
calicoctl get node <NODE_NAME> -o yaml > <node.yaml>
vi <node.yaml>
node 구성 설정 파일에서 metadata.creationTimestamp와 metadata.uid 삭제, spec 섹션에서 ipv4Address 또는 address를 적절하게 수정한다. 이 글의 경우에는 node의 실제 ip로 설정한다.
apiVersion: projectcalico.org/v3
kind: Node
metadata:
annotations:
projectcalico.org/kube-labels: '{"beta.kubernetes.io/arch":"amd64","beta.kubernetes.io/os":"linux","kubernetes.io/arch":"amd64","kubernetes.io/hostname":"node01","kubernetes.io/os":"linux"}'
creationTimestamp: "2022-02-22T13:28:39Z" # 삭제
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/hostname: node01
kubernetes.io/os: linux
name: node01
resourceVersion: "1380"
uid: 60042d60-7b76-44bb-8e13-6f31824839fd # 삭제
spec:
addresses:
- address: 10.35.59.3 # 수정
type: InternalIP
orchRefs:
- nodeName: node01
orchestrator: k8s
status:
podCIDRs:
- 10.244.1.0/24
4. 노드 구성 파일 적용
calicoctl apply -f <node.yaml>
# 예시
kubectl exec -n kube-system calicoctl -i -- calicoctl apply -f - < <node.yaml>
5. calico-node pod 상태 확인
get 명령어로 문제가 되었던 calico-node pod의 STATUS가 Running 상태인지, READY가 1/1인지 확인한다.