Tagged: Kubernetes

K8S dnstools 사용하기

K8S 를 사용하다보면 여러가지 검증을 위해 Pod 를 필요로 하는 경우가 있는데, dnstools 이 유용하다. 다음과 같이 사용할 수 있다.

Pod 가 생성되면서 dnstools 컨테이너에 진입하게 되고 exit 를 하게 되면 Pod 는 삭제된다.

혹은 curl 이미지를 이용하는 방법도 있다.

kubeadm join 시 discovery-file 이용하기

새로운 Worker 노드를 추가하기 위한 문법은 대략 다음과 같다.

그런데, token 값은 시간이 지나면 만료되 사용할 수 없게 된다. 설사 token 을 알아도 ca-cert-hash 값을 알아야 한다. 이를 위해서 K8S 의 루트 CA 인증서를 이용해 hash 값을 알아내는 명령어를 사용한다.

Discovery-file 만들기

하지만 이 방법외에도 discovery-file 을 이용하는 방법도 있다. 이는 kube-public 네임스페이스에 ConfigMap 에서 cluster-info 의 정보를 가지고 오면 된다. 다음과 같다.

위 파일을 추가하고자 하는 새로운 Worker 노드에 복사해준다.

Discovery-file 을 이용한 새로운 Worker 노드 추가

이제 discovery-file 를 이용해 새로운 Worker 노드를 추가할 수 있다. 다음과 같다.

CSR Approved

이렇게 한 후에 csr 을 보면 pending 상태의 인증서들이 보인다. 이를 Approved 해주면 된다.

쿠버네티스, 새로운 Worker 노드 Join 시 토큰 값 확인하기

쿠버네티스(Kubernetes) 를 운영하다가 새로운 Worker 노드를 추가할때에 kubeadm 명령어와 함께 join 옵션을 함께 쓴다. 이때 token 값과 hash 값을 줘야 하는데, 최초 설치할때에 값을 출력해주지만 시간이 지나서 잃어버리면 어떻게 해야 할까..

Token 확인

불행하게도 Token 값은 영구적이지 않다. 어디다 잘 적어놨어도 시간이 지나면 자동으로 폐기되도록 되어 있다.

아무것도 안나온다. 이는 자동 폐기 됐기 때문이다.

Token 생성

Token 값을 확인할 수 없다면 새로운 worker 노드를 추가할 수 없다. 아니, 정확하게는 Token 값을 이용해 추가할 수 없다. Token 값을 이용하기 위해서는 새로운 Token 값을 만들어 주면 된다.

위와같이 새로운 토큰이 생성되었다. 만료일이 기재되어 있어 이 기간동안만 유효하다.

Kubernetes 관련 기술 스택..

쿠버네티스 관련된 기술들이 워낙 많다보니 뭘 어디서부터 손대야할지 모를때도 있고 하다보면 어디에 서 있는지도 모를때가 있다. 더 나가 쿠버네티스를 시작하려고할때에 이게 어디에 있는건지를 알고 싶을때가 종종 있는데, 웹 서핑을 하다가 주운걸 기록해본다.

딱봐도 채용공고에 내용인데, 굵직하게 정리가 되어서 긁어왔다. 여기서 한가지 추가해야 한다면 IaC 부분인데, 요새는 쿠버네티스에 뭔가를 설치할때는 다음과 같은 걸 많이 사용한다.

  • Helm
  • Operator

ArgoCD 도 있지만 이것은 사실 애플리케이션 배포에 쓰인다고 보면 된다.

요새 하도 공부를 하지 않아서 잃어버리는 기억도 많고 이제는 쓰지 않는 기술들도 많은데, 슬슬 다시 공부를해야 겠다고 다짐한다. 해야할게 얼마나 많은지… 덕분에 잘 심심하지 않게 살수 있다는 것에 위안을 받는다.

컨테이너에서 Java 힙 덤프 뜨기

Kubernetes 에서 Java 애플리케이션을 운영할때에, Java 힙 덤프를 떠야하는 경우가 있다. 하지만 다음과 같이 덤프를 떠지지 않는다.

“Unable to get pid of LinuxThread manager thread” 오류가 발생한다.

이 오류가 나오는 이유는 Java 애플리케이션의 Pid 값이 1이기 때문이다. 이를 해결하는 방법을 소개한다.

Container 이미지에 tini 설치, 배포

먼저 Openjdk 의 컨테이너 이미지에 tini 프로그램을 설치해야 한다. 이 tini 라는 프로그램은 인자값을 받은 프로그램을 실행 시켜 준다. 이렇게 하면 tini 는 Pid 1을 가지지만 tini 가 실행시킨 프로그램은 1보다 큰 Pid 값을 가지게 된다.

문제는 Openjdk 에 tini 라는 프로그램이 없다. 더군다나 아무 컨테이너 이미지에 이것을 설치할 수 있는게 아니라 Alpine 기반 이미지에서 쉽게 설치가 가능하다. Alpine 에서는 패키지로 제공하기 때문에 명령어로 간단하게 설치할 수 있다.

Dockerfile 을 다음과 같이 수정한다.

apk 명령어를 이용해 tini 를 설치해주고 ENTRYPOINT 에 실행 명령어에 tini 를 넣고 인자값으로 java 애플리케이션 명령어를 넣는다.

이렇게 컨테이너 이미지를 제작하고 배포를 한다.

tini 프로그램 이 후 Pid

tini 프로그램으로 Java 애플리케이션이 어떻게 실행되는 다음과 같이 확인 할 수 있다.

jcmd 뿐만 아니라 jstat, jmap 등 모든 명령어를 사용할 수 있다.

Kubernetes API 서버 인증서에 도메인 추가하기

Kubernetes API 서버는 http 를 통해서 쿠버네티스에 대한 연산을 제공해 준다. kubectl 명령어로 실행되는 것들은 모두 API 서버를 거쳐서 이루어진다. 하지만 API 서버는 인증서를 기반으로 통신이 이루어지는데, 이 인증서에 기재된 도메인이나 IP가 아니면 통신이 이루어지지 않는다.

API 서버의 인증서는 SAN 인증서여야 한다. 도메인 리스트를 가지고 있는 SAN 인증서. 현재 API 서버의 인증서 상태는 다음과 같다.

위 apiserver.crt 파일 상태를 보면 SAN 에 이미 도메인과 IP 들이 들어가 있다. 내용을 보면 haproxy2.systemv.local 도메인, 192.168.96.7 IP 가 들어가 있는데 이 서버에서 API 서버와 통신이 가능하다.

만일 추가적으로 도메인, IP 를 추가하고 싶다면 어떻게 해야할까? 이에 대해서 알아본다.

kubeadm-config 업데이트

kubeadm-config 라고 불리는 ConfigMap 을 업데이트 해줘야 한다. 이를 위해서 먼저 기존이 설정을 뽑아내야 하는데 다음과 같이 하면 된다.

파일 내용을 보면 SAN 리스트가 없다. 도메인이나 IP 를 SAN 으로 추가하기 위해서 apiServer 아래에 certSANs 를 추가해 준다. 이미 다른 도메인이 있다면 제거하나 추가할 수도 있다.

위와같이 SAN 에 추가할 도메인, IP를 적어준다.

apiserver.crt 파일 업데이트

기존의 존재하는 apiserver.crt 파일을 백업한다.

kubeadm 을 이용해 새로운 인증서를 생성해 준다.

새로운 인증서가 생성되면서 certSANs 에 설정된 도메인, IP 주소들이 모두 인증서에 업데이트 된다. 이제 새로운 인증서를 가지고 구동되도록 api 서버를 재시작 시켜줘야 한다.

Docker 기반의 경우에는 다음과 같이 하면 된다.

  • docker ps | grep kube-apiserver 명령어로 kube-apiserver 의 컨테이너 ID 를 파악한다.
  • docker kill <containerID> 로 컨테이너를 킬(kill) 한다. 이렇게 하면 api 서버가 재시작 된다.

만약 containerd 를 이용하는 경우에는 다음과 같이 하면 된다.

  • crictl pods | grep kube-apiserver 로 kube-apiserver 의 Pod ID 를 파악한다.
  • crictl stopp <pod-id> 로 pod 를 정지
  • crictl rmp <pod-id> 로 pod 를 제거 합니다. 이렇게하면 다시 Pod 가 재시작 된다.

위와같이 Api 서버가 재시작되면서 새롭게 만들어진 API 서버 인증서를 인식하게 된다.

클러스터 설정 업데이트

마지막으로 클러스터 설정을 업데이트 해줘야 한다.

이렇게 하면 최종적으로 Api 서버에 인증서가 업데이트 된다.

Kubernetes 의 Role Based Access Control(RBAC)

쿠버네티스는 RBAC 기반으로 허가권(Permission) 을 조정하도록 설계 되었다. 그런데, 쿠버네티스는 다음과 같이 네가지의 Role 관련 리소스를 가지고 있다. 그 차이는 다음과 같다.

  1. ClusterRole – 전체 클러스터에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  2. ClusterRoleBinding – 특정 계정(Account) 에 ClusterRole 을 바인딩
  3. Role – 특정 네임스페이스에 적용하기 위한 역할(Role) 에 할당된 허가권(Permission)
  4. RoleBinding – 특정 계정(Account) 에 Role 을 바인딩

RBAC 을 적용하기 위해서는 계정이 필요하다. 이 계정은 쿠버네티스의 사용자를 말하는것이 아닌 쿠버네티스에서 운영되는 자원에 대한 계정을 말한다.

예를들어 ingress-nginx 라는 계정을 생성했다면 이제 이 계정에 ClusterRole 과 Role 을 Binding 을 통해서 ingress-nginx 계정과 연결하는 형식이다.

참고: Role Based Access Control (RBAC)