hoonii2

[k8s] Calico unauthorized error 로 인한 Pod ContainerCreating Issue 본문

개념 공부/(인프라) 04. 컨테이너

[k8s] Calico unauthorized error 로 인한 Pod ContainerCreating Issue

hoonii2 2024. 7. 8. 16:00

1. 개요

vagrant 를 통해 virtualbox vm k8s 환경을 구성해서 사용 중이며 vagrant suspend 로 정지, up 을 통해 k8s cluster 를 다시 동작시키며 사용하고 있었습니다.

평소와 동일하게 vagrant up 후 helm 을 통해 prometheus 를 설치하였으나 Pod 상태가 ContainerCreating 에 stuck 되는 현상이 발생하여 관련 사항을 작성합니다.

 

2. Pod 상태 확인

root@cp-k8s:~# k get pod -A
NAMESPACE        NAME                                                 READY   STATUS              RESTARTS        AGE
...
monitoring       prometheus-alertmanager-0                            0/1     ContainerCreating   0               3m1s
monitoring       prometheus-kube-state-metrics-67848d7455-4f4fh       0/1     ContainerCreating   0               3m1s
monitoring       prometheus-prometheus-node-exporter-fhrss            1/1     Running             0               3m2s
monitoring       prometheus-prometheus-node-exporter-lmznh            1/1     Running             0               3m2s
...

위 처럼 특정 Pod 가 ContainerCreating 상태에 stuck 되는 현상입니다.

 

root@cp-k8s:~# k describe pod/prometheus-kube-state-metrics-67848d7455-4f4fh -n monitoring
...
Events:
Events:
  Type     Reason                  Age               From               Message
  ----     ------                  ----              ----               -------
  Normal   Scheduled               33s               default-scheduler  Successfully assigned monitoring/prometheus-kube-state-metrics-67848d7455-4f4fh to w2-k8s
  Warning  FailedCreatePodSandBox  33s               kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "3f81925a31940b8e0a284319dad5d42ebd2d164a1868921badfd0cf6fa93dc23": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
  Normal   SandboxChanged          3s (x3 over 32s)  kubelet            Pod sandbox changed, it will be killed and re-created.

Pod describe 의 Event 내용으로 "FailedCreatePodSandBox" Reason 의 메시지에서 calico failed 를 확인했습니다.

오류 내용은 ClusterInformation 리소스와 관련된 권한이 없는 오류입니다.

 

3. CNI RBAC 권한 확인

k8s RBAC 권한 문제인지 확인하기 위해 설정 값을 확인합니다.

 

root@cp-k8s:~# k get all -n kube-system
...
NAME                         DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/calico-node   4         4         4       4            4           kubernetes.io/os=linux   2d20h
daemonset.apps/kube-proxy    4         4         4       4            4           kubernetes.io/os=linux   2d20h
...

calico 는 daemonset 으로 모든 노드에 배포되므로 해당 daemonset 의 SA 정보를 확인합니다.

 

root@cp-k8s:~# k get daemonset.apps/calico-node -n kube-system -o yaml | grep serviceAccount
...
      serviceAccount: calico-node
...

daemonset 에서 사용하는 serviceAccount 는 calico-node 입니다. SA 정보를 확인합니다.

 

root@cp-k8s:~# k get clusterrolebinding calico-node -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
...
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: calico-node
subjects:
- kind: ServiceAccount
  name: calico-node
  namespace: kube-system

해당 SA 는 calico-node clusterrole 을 사용하는 것을 확인하고 해당 clusterrole 의 권한을 확인합니다.

 

root@cp-k8s:~# k get clusterrole calico-node -o yaml
apiVersion: rbac.authorization.k8s.io/v1
...
- apiGroups:
  - crd.projectcalico.org
  resources:
  - globalfelixconfigs
  - felixconfigurations
  - bgppeers
  - bgpfilters
  - globalbgpconfigs
  - bgpconfigurations
  - ippools
  - ipreservations
  - ipamblocks
  - globalnetworkpolicies
  - globalnetworksets
  - networkpolicies
  - networksets
  - clusterinformations
  - hostendpoints
  - blockaffinities
  - caliconodestatuses
  verbs:
  - get
  - list
  - watch
...

clusterrole 에 'clusterinformations' 리소스에 대한 권한이 있음을 확인했습니다.

추가로 권한 확인 명령어를 통해 실제 권한을 한번 더 확인합니다.

 

root@cp-k8s:~# kubectl --kubeconfig /etc/cni/net.d/calico-kubeconfig auth can-i get clusterinformations --all-namespaces
yes

root@cp-k8s:~# kubectl auth can-i get clusterinformations --as=system:serviceaccount:kube-system:calico-node --all-namespaces
yes

calico 에서 실제 사용하는 kubeconfig 와 SA 를 사용하여 권한에 문제가 없음을 확인합니다.

 

4. calico cni 토큰 만료

이벤트에서 확인한 권한 오류는 문제가 없어 구글링을 통해 추가 정보를 찾아봤습니다.

 

https://github.com/projectcalico/calico/issues/8379#issuecomment-1920339287

 

Failed to create pod sandbox: rpc - error getting ClusterInformation connection is unauthorized: Unauthorized · Issue #8379 ·

I have K8S up and running and able to deploy and run different Pods/containers. Today, I tried to deply mysql to it with PVC and PV After deploying, container get stuck in "ContainerCreating" statu...

github.com

위 calico issue 에서 토큰 만료 관련 사항을 확인했습니다.

( 위 issue 의 임시 방편은 calico pod 재배포였고 아쉽게도 이후 업데이트가 없습니다 )

 

root@w1-k8s:~# cat /etc/cni/net.d/calico-kubeconfig 
# Kubeconfig file for Calico CNI plugin. Installed by calico/node.
...
users:
- name: calico
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6InNMZmEwQndqMUtoTnpGeVJDY25ZSlRQdm9YNmRTSFRRaG1DazBWQlVYMkUifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzIwNDk1OTM3LCJpYXQiOjE3MjA0MDk1MzcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiMTE5YjMzYjktMzhkMS00NTg4LWFlNGItZTJlNDUyZmUxNjQzIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJjYWxpY28tY25pLXBsdWdpbiIsInVpZCI6IjdiYjA2ZWQ0LTRlOTYtNGNkYi1hODc3LTgwYjRkZjY0ZjdkOSJ9fSwibmJmIjoxNzIwNDA5NTM3LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Y2FsaWNvLWNuaS1wbHVnaW4ifQ.X9oUIWAvSx_16rGWXZPiGM3jTMAw9xaf4AC6l0ZIQIwF64EHDrzK0US5ilpHMMl1GK1DmOPa5dy2B-YtKcFAgIotiBg6DjTgeJu5MCuJyonw2UafXRAzcyn21oh13Jgwm0Axgq_oJ_0pQQMtGon_e09F-hZNRrfEqClrvzsgM2pXO0qU5dZNmr8WZC1t1z1VahsbEfKZkyVa9eFZ421bxqgIauANQNUrVybZLxIoma-IRO-51HsAcb3pi1DvujEoxLL_6ndp2vMufQmAU_OfQfdHiTh8WohWNtuzU0EBAWLaaUjE_hy4p567FdnQBenGYtrlk33wR6gyPdCw-th4ZA
...

"w1-k8s" 노드의 calico 에서 api server 로 접근 시 사용하는 토큰 값을 확인합니다.

해당 노드의 calico-node pod 를 재생성하여 위 토큰이 재생성 되는지 확인합니다.

 

root@cp-k8s:~# k get pods -n kube-system -o wide
NAME                                       READY   STATUS    RESTARTS        AGE     IP               NODE     NOMINATED NODE   READINESS GATES
calico-kube-controllers-6cdb97b867-rhjrx   1/1     Running   3 (2d4h ago)    2d23h   172.16.196.140   cp-k8s   <none>           <none>
calico-node-54t42                          1/1     Running   0               167m    192.168.1.10     cp-k8s   <none>           <none>
calico-node-cksqk                          1/1     Running   0               167m    192.168.1.101    w1-k8s   <none>           <none>
calico-node-clbhp                          1/1     Running   0               167m    192.168.1.103    w3-k8s   <none>           <none>
calico-node-gq9rj                          1/1     Running   0               167m    192.168.1.102    w2-k8s   <none>           <none>
root@cp-k8s:~# 
root@cp-k8s:~# k delete pod calico-node-cksqk -n kube-system
pod "calico-node-cksqk" deleted

"w1-k8s" 의 pod 는 "calico-node-cksqk" 이며 재생성을 위해 삭제합니다.

 

root@cp-k8s:~# k get pods -n kube-system -o wide
NAME                                       READY   STATUS    RESTARTS        AGE     IP               NODE     NOMINATED NODE   READINESS GATES
calico-kube-controllers-6cdb97b867-rhjrx   1/1     Running   3 (2d4h ago)    2d23h   172.16.196.140   cp-k8s   <none>           <none>
calico-node-54t42                          1/1     Running   0               3h3m    192.168.1.10     cp-k8s   <none>           <none>
calico-node-clbhp                          1/1     Running   0               3h3m    192.168.1.103    w3-k8s   <none>           <none>
calico-node-gq9rj                          1/1     Running   0               3h3m    192.168.1.102    w2-k8s   <none>           <none>
calico-node-nbx9p                          1/1     Running   0               14m     192.168.1.101    w1-k8s   <none>           <none>

새롭게 "nbx9p" pod 가 동작하는 것을 확인합니다.

 

root@w1-k8s:~# cat /etc/cni/net.d/calico-kubeconfig 
# Kubeconfig file for Calico CNI plugin. Installed by calico/node.
...
users:
- name: calico
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6InNMZmEwQndqMUtoTnpGeVJDY25ZSlRQdm9YNmRTSFRRaG1DazBWQlVYMkUifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNzIwNTA2MDc4LCJpYXQiOjE3MjA0MTk2NzgsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwianRpIjoiZTk5NGNjMWUtYWY1ZC00NjRiLTkwNDEtZjljNDMzY2I3ODc1Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJjYWxpY28tY25pLXBsdWdpbiIsInVpZCI6IjdiYjA2ZWQ0LTRlOTYtNGNkYi1hODc3LTgwYjRkZjY0ZjdkOSJ9fSwibmJmIjoxNzIwNDE5Njc4LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZS1zeXN0ZW06Y2FsaWNvLWNuaS1wbHVnaW4ifQ.m9Mi8xum8Lrs6w2ylUYSGQBnJQZ_89EjehpWMapJQ1aG0SgRQ-fk60FQtMVjGrQpePa4t69YN5hfRMtacTOXScPNPam-SBbGVHw9I8WhBuanuAce4ql6kHVs-P3K5GrShMo33cLk4Z1BXIXpNq187lFMSRjmuOp91rsGy7zunHjS0wPVYEB6wXdxj7AYC0vVBdGFVetB2xEgfCyN3ZqHOGGU-ak4LwJ9kO03AhLMhQBl7R93qnVQUdp1AQTiyG8BMJA0V6va--Zkp1RZslAmD6URoukWG5lzHNYRyh1wTymcQrPbDsYq2-RzKTPtc6m2pCg_FoUBHkZkWwy5m18-sQ
...

calico node pod 교체를 통해 토큰 값이 정상적으로 변경되었음을 확인합니다.

 

root@cp-k8s:~# k delete pod calico-node-54t42 calico-node-clbhp calico-node-gq9rj calico-node-nbx9p -n kube-system

위 작업을 모든 노드의 calico node pod 에 동일하게 작업합니다.

 

5. 정상 동작 확인

모든 pod 를 재가동하여 토큰을 재발급 한 뒤 ContainerCreating 상태였던 컨테이너가 정상적으로 작동되는 것을 확인합니다.

root@cp-k8s:~# k get pod -A
NAMESPACE        NAME                                                 READY   STATUS              RESTARTS        AGE
...
monitoring       prometheus-alertmanager-0                            1/1     Running             0               15h
monitoring       prometheus-kube-state-metrics-67848d7455-4f4fh       1/1     Running             0               15h
monitoring       prometheus-prometheus-node-exporter-fhrss            1/1     Running             0               15h
monitoring       prometheus-prometheus-node-exporter-lmznh            1/1     Running             0               15h
...

 

6. 참고 자료

https://github.com/projectcalico/calico/issues/4857

 

calico/node token is invalidated by Kubernetes when the pod is evicted, leading to CNI failures · Issue #4857 · projectcalico/

Expected Behavior Calico CNI plugin tears down Pod in a timely manner. Current Behavior Calico CNI plugin shows errors terminating Pods, and therefore eviction takes too long. Especially relevant i...

github.com

 

해당 이슈 해결을 위한 PR 작업
- TokenRefresh API 관련 내용인데 Pod 삭제보단 API 를 통한 토큰 업데이트 방안이 좋습니다. 추후 동일 증상 발생 시 이를 통해 확인을 해보고자합니다.

https://github.com/projectcalico/calico/pull/5910

 

Use TokenRequest API instead of calico-nodes service account token for CNI kubeconfig. by ScheererJ · Pull Request #5910 · pro

Description Use TokenRequest API instead of calico-nodes service account token for CNI kubeconfig. With projected service account tokens in kubernetes, the service account tokens of pods are bound ...

github.com

 

최신 이슈

https://github.com/projectcalico/calico/issues/8379

 

Failed to create pod sandbox: rpc - error getting ClusterInformation connection is unauthorized: Unauthorized · Issue #8379 ·

I have K8S up and running and able to deploy and run different Pods/containers. Today, I tried to deply mysql to it with PVC and PV After deploying, container get stuck in "ContainerCreating" statu...

github.com

 

7. 추가 사항

vagrant suspend 시 시스템 상태가 그대로 보존되어 추후 재기동 시 시간이 mismatch 되는 현상으로 인한것인지 calico-node pod 들에 해당 현상이 지속적으로 발생했습니다.

 

https://github.com/projectcalico/calico/pull/5910

 

Use TokenRequest API instead of calico-nodes service account token for CNI kubeconfig. by ScheererJ · Pull Request #5910 · pro

Description Use TokenRequest API instead of calico-nodes service account token for CNI kubeconfig. With projected service account tokens in kubernetes, the service account tokens of pods are bound ...

github.com

(6) 사항에 작성한 TokenRefresh API 내용 또한 살펴보니 refresh 발급에 관한 기능을 구현한 것이고 이를 활용하는 방안을 확인하지 못해 테스트를 못했습니다.

 

https://knowledge.broadcom.com/external/article/319420/calico-node-reports-unauthorized-error-a.html

 

Calico node reports unauthorized error after token expires, if TKR < 1.24

Symptoms: If the environment is configured using TKR < 1.24 version, regardless of TKGm or TKGs, Calico version is 3.19, and by default it doesn’t have CALICO_MANAGE_CNI set, so it won’t automatically refresh the token once the token used for Calico w

knowledge.broadcom.com

그리고 여러 자료를 찾아봤지만 broadcom 의 해당 버그 workaround 까지도 calico-node pod 를 재시작하는 것뿐이었습니다.
( calico-node pod 가 시작될 때 initContainer 로 Token 을 재생성한다고 합니다. 아마 위 PR 작업이 해당 내용의 로직을 추가한 것이지 않을까 싶습니다. )

 

그래서 calico-node Pod 재시작을 쉽게 하고자 스크립트로 작성하였고 이를 통해 해결하고 있습니다.

#!/bin/bash

# Get list of pods in kube-system namespaces
pods=$(kubectl get pods -A -n kube-system -o=jsonpath='{.items[*].metadata.name}')

# delete the pods starting with "calico-node-*"
for pod in $pods; do
    if [[ $pod == calico-node-* ]]; then
        kubectl delete pod $pod -n kube-system
    fi
done

 

Comments