Kubernetes는 Google에서 운영하는 컨테이너 오케스트레이션 오픈소스이다. 이 글에서는 Kubernetes 개념에 대해 소개하고, Ubuntu 18.04 버전을 기준으로 설치하는 방법을 정리하였다.
관련 키워드: Docker, Kubernetes
Kubernetes Architecture
Kubernetes는 Master-Slave 구조의 클러스터로 구성된다. Master Node에서 API를 통해 Kubernetes 클러스터에 접근하여 컨테이너를 생성하고 관리한다. Slave Node는 컨테이너가 생성되어 운영되는 노드이다. Kubernetes 클러스터에서는 GlusterFS, Openstack Cinder 등 원격 스토리지와 연결하여 동적으로 디스크를 할당하여 컨테이너를 운영 할 수 있다.
Kubernetes Concepts
Kubernetes를 이해하기 위해 필수적인 개념에 대해 간략히 소개한다. 개념에 대해서 자세하게 이해하고 싶다면 Kubernetes Docs를 참고하면 된다.
Pods
Pod는 클러스터에서 실행되는 프로세스를 의미한다. Kubernetes는 컨테이너 운영을 위해 Docker를 사용하는데, Pod의 개념이 Docker의 컨테이너라고 생각하면 된다. Pod를 통해서 어플리케이션 컨테이너, 스토리지 리소스, 네트워크 IP 관리 등의 기능을 캡슐화 할 수 있다.
[Network] 각각의 Pod는 고유한 IP 주소가 할당되고, 네트워크 포트를 포함하여 네트워크 네임스페이스를 공유한다. 서로 다른 노드에 존재하는 Pod 간에는 공유된 네트워크 네임 스페이스를 통해 통신이 가능하다. Pod의 네트워크는 Master Node에서 설정된 네트워크 정책을 통해 관리되는데, 공인 IP가 아닌 사설망을 구축하여 운영되기 때문에 외부와 통신을 위해서는 Master Node에서 포트포워딩을 통해 접근하여야 한다.
[Volume] Pod에는 공유 스토리지 볼륨을 설정하여 Pod간의 데이터를 공유하여 사용 할 수 있다. 또한 볼륨을 사용하여 컨테이너를 재실행해야 하는 경우에도 컨테이너의 데이터를 영구적으로 유지 할 수 있다.
Storage
스토리지는 컨테이너의 데이터를 영구적으로 유지하기 위해 사용되는 기능이다. GlusterFS, Openstack Cinder 등의 오픈소스 프로젝트와, AWS, Google Cloud 등에서 제공하는 스토리지와 연동하여 사용 할 수 있다.
[Persistent Volume (PV)] PV은 Kubernetes 클러스터에서 관리되는 저장소이다. PV은 Pod와 독립적으로 수명주기가 관리되어 Pod가 재실행되더라도 데이터가 유지된다.
[Persistent Volume Claims (PVC)] PVC는 PV를 추상화하여 사용 가능하도록 만들어주는 기능이다. PVC를 통해 Pod에서 필요한 용량을 지정하여 동적으로 볼륨을 할당 할 수 있다. PV를 지정하지 않고 동적으로 PVC를 사용하기 위해서는 GlusterFS 등과 연계된 StorageClass를 생성해야 한다.
Kubernetes Installation
먼저 Kubernetes 클러스터를 운영할 서버를 준비한다. 클러스터 구성을 위해 준비한 서버 모두에서 설치 과정을 진행한다. 이 글에서는 설치를 위해 Ubuntu 18.04 서버 4개를 설치하였다. 서버의 hostname과 IP는 아래와 같다. Kubernetes에서는 클러스터에 노드를 추가 할 때 hostname을 참조하기 때문에 설치를 진행하기 전에 적절한 hostname 설정이 필요하다.
- kube-master (192.168.5.1)
- kube-slave-1 (192.168.5.2)
- kube-slave-2 (192.168.5.3)
- kube-slave-3 (192.168.5.4)
먼저 Docker를 설치해야 한다.
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -0
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
Code language: JavaScript (javascript)
Docker 설치가 완료되었다면 kubeadm, kubelet, kubectl의 설치를 위해 아래의 명령어를 순차적으로 실행한다. 편리한 설치를 위해 먼저 root 권한으로 변경하여 진행한다.
$ sudo -s
$ swapoff -a
$ apt-get update && apt-get install -y apt-transport-https curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
$ cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
$ apt-get update
$ apt-get install -y kubelet kubeadm kubectl
$ apt-mark hold kubelet kubeadm kubectl
$ systemctl daemon-reload
$ systemctl restart kubelet
Code language: JavaScript (javascript)
설치가 완료되었다면 docker 정보를 확인하여 kubernetes의 설정을 변경하여준다.
$ docker info | grep -i cgroup
$ vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
파일을 편집 모드로 열었다면 Environment 항목에 아래와 같이 한줄을 추가한다.
...
Environment="KUBELET_CGROUP_ARGS=–cgroup-driver=cgroupfs"
...
Code language: JavaScript (javascript)
Master Node 설정
Master Node로 사용할 서버에 다음과 같은 명령어를 수행한다. 기존에 설정되었던 Master Node를 재설정하기 위해서는 reset 명령어를 수행한 후 진행한다. 아래의 명령어는 Master Node 초기 설정을 하고 네트워크 구성을 설정하는 과정을 포함하고 있다.
$ sudo -s
$ kubeadm reset
$ kubeadm init --pod-network-cidr=10.244.0.0/16
kubeadm init 명령어를 실한한 결과에는 “kubeadm join 192…” 이라는 항목이 출력되는데, 이 명령어는 나중에 Slave Node를 설정하기 위해 필요하기 때문에 복사해 놓는다.
$ rm -rf ~/.kube
$ mkdir -p ~/.kube
$ cp -i /etc/kubernetes/admin.conf ~/.kube/config
$ chown -R $(id -u):$(id -g) ~/.kube
$ kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/rbac.yaml
$ kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/canal/canal.yaml
$ kubectl get pods --all-namespaces
$ kubectl get nodes
$ kubectl taint nodes --all node-role.kubernetes.io/master-
Code language: PHP (php)
https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/#pod-network
네트워크 구성은 위의 링크에서 확인 할 수 있다. Calico, Canal, Cilium 등 다양한 설정 방법이 있는데, 클러스터 마다 하나의 방법만 적용이 가능하다. 네트워크 구성 방식에 따라 IP Subnet(–pod-network-cidr)을 적절하게 설정해야한다. 이 글에서는 canal을 사용하여 네트워크를 설정하였다.
Slave Node 설정
Slave Node의 설정은 Master Node를 설정할 때 복사해 놓은 명령어를 Slave Node 서버에서 실행하면 설정이 완료된다.
$ kubeadm join --token [token] [master-ip]:[master-port] --discovery-token-ca-cert-hash sha256:[hash]
join 명령어는 위와 같이 구성되는데, 토큰과 hash 정보는 Master Node에서 아래의 명령어를 통해 확인 할 수 있다. 기본적으로 포트의 경우 6443을 사용한다.
$ kubeadm token list
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
Code language: JavaScript (javascript)
토큰의 경우 24시간을 기준으로 폐기되기 때문에 나중에 클러스터에 Node를 추가하기 위해서는 토큰을 생성한 후 join 명령어를 실행해야 한다. 토큰 생성은 아래의 명령어를 통해 생성 할 수 있다.
$ kubeadm token create
Dashboard 설치
Dashboard는 웹 UI를 통해 Kubernetes 클러스터를 관리한다. 클러스터에 연결된 노드, 스토리지 등을 확인 할 수 있고, Pod의 생성 등의 작업 또한 수행 할 수 있다.
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
$ kubectl describe svc kubernetes-dashboard -n kube-system
Code language: JavaScript (javascript)
기본적으로 로컬에서 접속되도록 설정되는데, 원격에서 접근하기 위해서는 추가적인 설정이 필요하다.
$ kubectl -n kube-system edit service kubernetes-dashboard
$ kubectl -n kube-system get service kubernetes-dashboard
Code language: JavaScript (javascript)
위의 명령어를 사용하면 설정 편집 화면이 나오는데, 기본 설정에서는 spec의 type이 ClusterIP로 되어있는데, 이 설정을 NodePort로 변경 한 후 저장한다. 저장 한 후 두번째 줄의 명령어를 사용하면 외부에서 접속 할 수 있도록 바인딩 된 Port를 확인 할 수 있다. 호스트에 바인딩 되는 Port는 30000-32767 구간의 포트를 사용한다. 원격 접속을 하기 위해서는 https://[master-ip]:3xxxx 로 접속하면 된다.
원격에서 접속을 하기 위해서는 kubernetes에서 인증 설정을 해야한다. 다양한 인증 방식을 지원하는데 이 글에서는 인증을 위해 token을 사용하는 방식을 소개한다. 먼저 Master Node에서 아래 두개의 파일을 생성한다.
# admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
Code language: PHP (php)
# admin-role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system
Code language: PHP (php)
파일을 생성하였다면 아래 명령어를 실행한다.
$ kubectl apply -f admin-user.yaml
$ kubectl apply -f admin-role.yaml
명령어를 실행 한 후 로그인을 위한 토큰을 확인하기 위해서는 아래의 명령어를 실행한다.
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
Code language: JavaScript (javascript)
Dashboard 주소에 접근하면 Kubeconfig, Token을 선택 하는 화면이 나오는데, Token을 선택 한 후 위의 명령어의 Token 정보를 복사하여 로그인하면 된다.
References
- https://github.com/kubernetes/dashboard/wiki/Accessing-Dashboard—1.7.X-and-above
- https://github.com/kubernetes/dashboard/wiki/Creating-sample-user
- https://kubernetes.io/docs/concepts/storage/storage-classes/
- https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/
- https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/
“Kubernetes Installation with Dashboard”에 대한 한개의 댓글