기본 콘텐츠로 건너뛰기

[Kubernetes] Kubernetes Dashboard 설치 및 NodePort 접근 설정

How to install and access Kubernetes Dashboard

대시보드는 웹 기반 Kubernetes 사용자 인터페이스로 컨테이너화된 애플리케이션을 배포하고 문제를 해결하고, 클러스터 리소스들을 관리한다. 또한 클러스터의 쿠버네티스 리소스 상태 및 발생했을 수 있는 오류에 대한 정보도 확인할 수 있다.

  • Deployments
  • StatefulSets
  • DaemonSets
  • Jobs
  • Services
  • Ingress Deployments
  • Scaling
  • Rolling Update
  • Pod Management
  • Persistent Volume / Claim

배포 및 액세스

기본적으로 쿠버네티스에 포함되어있지 않기 때문에 별도 배포해 줘야 한다.

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml

namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

kubectl 명령줄 도구를 사용해서 대시보드에 접근할 수 있도록 프록시 처리를 해 준다. (8001 포트)

kubectl proxy

kubectl은 http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/로 대시보드에 접근할 수 있도록 구성한다.

Using NodePort

권장 사항을 배포하는 것이므로 수정을 해야하는 경우라면 다음과 같이 다운로드해서 처리해 줘야 한다.

sudo dnf -y install wget

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended.yaml

mv recommended.yaml kubernetes-dashboard-deployment.yml

위의 파일의 kind: Service 부분을 보면 아래와 같이 되어있다.

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard

이 부분의 spectype: NodePort 를 지정하고 저장한다.

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 443
      targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  type: NodePort

참고
NodePort는 각 노드에 정적 포트를 서비스로 노출하며 NodePort 서비스가 라우팅하는 ClusterIP 서비스는 자동으로 생성된다.

이제 변경된 대시보드를 아래와 같이 배포한다.

kubectl apply -f kubernetes-dashboard-deployment.yml

namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

배포된 상태는 아래의 명령으로 확인이 가능하다.

kubectl get deployments -n kubernetes-dashboard

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
dashboard-metrics-scraper   1/1     1            1           21s
kubernetes-dashboard        0/1     1            0           21s

위와 같이 두 개의 배포가 생성된 것을 확인할 수 있다.

kubectl get pod -n kubernetes-dashboard

NAME                                         READY   STATUS             RESTARTS   AGE
dashboard-metrics-scraper-79c5968bdc-fz4cl   1/1     Running            0          41s
kubernetes-dashboard-665f4c5ff-q22qg         0/1     ImagePullBackOff   0          41s

주의
위와 같이 ImagePullBackOff 상태가 나타날 수 있다. 일반적으로 도커에서 이미지 처리를 하는 과정 중에 발생할 수 있으므로 시간이 좀 지난 뒤에 확인해 보면 된다. 그러나 시간이 지나도 변화가 없이 똑같은 상태라면 오류가 발생했을 수 있으므로 아래의 명령으로 확인해 봐야 한다.

# kubectl describe pod {POD_ID} -n {namespace}

...
Events:
 Type     Reason     Age                    From               Message
 ----     ------     ----                   ----               -------
 Normal   Scheduled  5m42s                  default-scheduler  Successfully assigned kubernetes-dashboard/kubernetes-dashboard-665f4c5ff-q22qg to node-2
 Warning  Failed     5m24s                  kubelet            Failed to pull image "kubernetesui/dashboard:v2.0.4": rpc error: code = Unknown desc = Error response from daemon: Get https://registry-1.docker.io/v2/kubernetesui/dashboard/manifests/v2.0.4: Get https://auth.docker.io/token?scope=repository%3Akubernetesui%2Fdashboard%3Apull&service=registry.docker.io: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
 Warning  Failed     5m24s                  kubelet            Error: ErrImagePull
 Normal   BackOff    5m23s                  kubelet            Back-off pulling image "kubernetesui/dashboard:v2.0.4"
 Warning  Failed     5m23s                  kubelet            Error: ImagePullBackOff
 Normal   Pulling    5m11s (x2 over 5m41s)  kubelet            Pulling image "kubernetesui/dashboard:v2.0.4"
 Normal   Pulled     4m24s                  kubelet            Successfully pulled image "kubernetesui/dashboard:v2.0.4" in 46.672759653s
 Normal   Created    4m23s                  kubelet            Created container kubernetes-dashboard
 Normal   Started    4m22s                  kubelet            Started container kubernetes-dashboard

위의 정보에서 실제 이미지를 제대로 받지 못해서 오류가 발생했었으나 재 시도해서 성공한 것을 확인할 수 있다.


참고로 도커의 유료화 정책에 따라서 IP 당 또는 Docker ID 당 Rate Limit 제한이 걸린다. 한번 걸리면 1시간 이상 지나야 풀리므로 Describe를 통해서 오류 원인이 뭔지 확인해야 한다.

kubectl get pod -n kubernetes-dashboard

NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-79c5968bdc-fz4cl   1/1     Running   0          8m25s
kubernetes-dashboard-665f4c5ff-q22qg         1/1     Running   0          8m25s

위와 같이 두 개의 파드가 생성된 것을 확인할 수 있다.

kubectl get service -n kubernetes-dashboard

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.96.147.203    <none>        8000/TCP        8m55s
kubernetes-dashboard        NodePort    10.108.179.191   <none>        443:30568/TCP   8m56s

위와 같이 NodePort를 적용산 서비스가 생성된 것을 확인할 수 있다.

이제 https://localhost:30568 로 접근이 가능하다.

사용자 (관리자) 생성

클러스터 데이터를 보호하기 위해서 기본적으로 최소한의 RBAC 구성으로 배포되며 현재는 Bearer Token으로 로그인만 지원한다.

관리용 서비스 계정 만들기

서비스 계정 생성을 위해서 매니페스트부터 구성해야 한다.

# admin-sa.yml
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ccambo-admin        ## 생성할 계정이름
  namespace: kube-system

구성한 매니페스트 정보를 적용해서 쿠버네티스 클러스터에 객체를 생성한다.

kubectl apply -f admin-sa.yml

serviceaccount/ccambo-admin created

클러스터 역할 바인딩 생성

cluster-admin의 클러스터 역할 바인딩을 생성한 서비스 계정에 할당하기 위해 아래와 같이 매니페스트 파일을 구성한다.

# admin-rbac.yml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ccambo-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: ccambo-admin
    namespace: kube-system

구성한 매니페스트 정보를 적용해서 역할을 할당한다.

kubectl apply -f admin-rbac.yml

clusterrolebinding.rbac.authorization.k8s.io/ccambo-admin created

관리자 토큰 확인

생성된 서비스 계정으로 대시보드에 접근하기 위해서는 토큰 (Bearer Token)을 확인해야 한다.

# 변수에 사용사 설정
SA_NAME = "ccambo-admin"

# 토큰 확인
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep ${SA_NAME} | awk '{print $1}')

Name:         ccambo-admin-token-xdvfq
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: ccambo-admin
              kubernetes.io/service-account.uid: 1c84b3e8-caf7-4da4-8bac-bca612b7a274

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1066 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6Imo0Zzc5MWoyRzE2ZUxHQk5KMExDSlEyR1I4MnhaQlRxLXQ3Sm8waVlUTjQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW...
9MmJgFMXIrBVQtoLZ17a9nyM4oAd1Mqv6K3Gro-npeepSLO9d6hVWHdqsXjJkvhMGdYrCYtXSTf7vrDUKuRGRU-1Dv5Q

위의 결과에서 토큰 부분을 복사한다.

대시보드 액세스

만일 대시보드를 NodePort로 설정한 경우는 아래의 명령으로 포트 번호를 확인할 수 있다.

kubectl get services -n <namespace> | grep dashbaord

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   NodePort    10.111.76.69    <none>        443:32254/TCP   414d

해당 주소로 접근하면 액세스할 유형을 선택하는 화면이 나타나고 여기서 토큰 방식을 선택한 후 복사한 토큰을 입력하면 된다.

참고

Chrome등의 브라우저에서는 보안의 문제로 HTTPS 관련 인증서 문제가 발생하면 보안되지 않은 사이트로 처리되고 접근을 허용하지 않는다. 따라서 이런 상황이라면 Firefox를 설치해서 접근하면 보안 경고는 나오지만 고급 메뉴에 따라서 진입할 수는 있다.

참고 자료

댓글