[Infra] 쿠버네티스(kubernetes)(8) invalid Host header 에러

업데이트:

쿠버네티스 exec -it 명령어 invalid Host header 에러

참고 링크

1. 문제 현상

새롭게 구축한 쿠버네티스 클러스터에서 간단하게 nginx이미지를 활용해 nginx01이라는 파드를 생성한 후 kubectl exec -it {파드명} -- {명령어} 옵션을 활용해 파드 내부로 접속하려고 시도했습니다.

$ kubectl exec -it nginx01 -- /bin/sh
error: Internal error occurred: error executing command in container: http: invalid Host header

그랬더니 위와 같이 invalid Host header 에러 메시지가 발생했습니다.

2. 원인

원인은 쿠버네티스를 설치하기 전에 cri-dockerd를 설치하는데 cri-dockerd를 설치하기 전에 go lang을 설치해야합니다. 그런데 go lang의 버전이 저와 같이 1.20.6 이상이면 위와 같은 invalid Host header 에러가 발생합니다.

$ go version
go version go1.21.0 linux/amd64

즉, 1.20.5까지는 에러 안나는데 1.20.6 부터는 에러가 발생하는 것입니다. 저는 위와 같이 1.21.0버전으로 1.20.6 이후 버전임을 알 수 있습니다.

3. 해결 방법

해결 방법을 간단하게 말하면 쿠버네티스 전체를 다시 설치할 필요는 없고, cri-docker와 go lang만 삭제한 후 다시 설치하면 됩니다.

3.1. cri-docker 정지

먼저 cri-docker를 멈추겠습니다.

$ sudo systemctl stop cri-docker.socket
$ systemctl status cri-docker.socket

○ cri-docker.socket - CRI Docker Socket for the API
     Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor prese>
     Active: inactive (dead) since Sat 2023-08-19 08:38:47 UTC; 3s ago
   Triggers: ● cri-docker.service
     Listen: /run/cri-dockerd.sock (Stream)
        CPU: 762us

3.2. 기존 go lang 삭제 및 go lang 1.20.5 버전 설치

go lang 1.20.6 부터 에러가 발생하므로 go lang 1.20.5 버전을 다시 설치하겠습니다. 설치방법은 https://go.dev/doc/install을 참고하시면 됩니다.

# wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
# rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz
# exit

$ go version
go version go1.20.5 linux/amd64

위와 같이 설치하면 go lang이 1.20.5 버전인 것을 알 수 있습니다.

3.3. cri-dockerd 재설치

끝으로 cri-dockerd를 재설치 합니다. 삭제 커맨드를 입력할 필요는 없고 설치 사이트 참고해서 다시 설치하면 됩니다.

$ cd cri-dockerd
$ make cri-dockerd

$ pwd
/home/eevee/work/cri-dockerd

$ sudo -i
# cd /home/eevee/work/cri-dockerd
# mkdir -p /usr/local/bin
# install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd
# install packaging/systemd/* /etc/systemd/system
# sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
# systemctl daemon-reload
# systemctl enable --now cri-docker.socket
# exit
$

위와 같이 cri-dockerd를 설치하고 다음과 같이 cri-docker 작동 확인을 합니다.

$ systemctl status cri-docker.socket
● cri-docker.socket - CRI Docker Socket for the API
     Loaded: loaded (/etc/systemd/system/cri-docker.socket; enabled; vendor prese>
     Active: active (listening) since Sat 2023-08-19 08:43:44 UTC; 10s ago
   Triggers: ● cri-docker.service
     Listen: /run/cri-dockerd.sock (Stream)
      Tasks: 0 (limit: 4667)
     Memory: 0B
        CPU: 671us
     CGroup: /system.slice/cri-docker.socket

Aug 19 08:43:44 k8s-master systemd[1]: Starting CRI Docker Socket for the API...
Aug 19 08:43:44 k8s-master systemd[1]: Listening on CRI Docker Socket for the API.

그리고 kubelet도 재시작 해줍니다.

$ sudo systemctl restart kubelet
$ kubectl get node
NAME         STATUS   ROLES           AGE     VERSION
k8s-master   Ready    control-plane   3d20h   v1.26.5



4. 접속 확인

이제 nginx 파드에 제대로 접속이 되는지 확인해보겠습니다.

$ kubectl apply -f nginx-test01.yml
pod/nginx01 created

$ kubectl exec -it nginx01 -- /bin/bash
root@nginx01:/#

접속이 제대로 되는 것을 알 수 있습니다.