kubeadm
1 kubeadm
- 레퍼런스
- 쿠버네티스는 일반적인 서버 클러스터 환경에서도 쿠버네티스를 쉽게 설치할 수 있는 kubeadm이라는 관리 도구를 제공한다
- kubeadm은 쿠버네티스 커뮤니티에서 권장하는 설치 방법 중 하나이다
- 온프레미스 환경, 클라우드 인프라 환경에 상관없이 일반적인 리눅스 서버라면 모두 사용할 수 있다
- Minikube, kubespary와 같은 설치 도구도 내부적으로 kubeadm을 사용하고 있다.
1.1 사전조건
- 레퍼런스
- 리눅스 호스트
- 머신 당 2기가 이상의 메모리
- 머신 당 2개 이상의 CPU
- 클러스터를 구성하는 머신들의 네트워크
- 유니크한 호스트 이름, MAC 주소, product_uuid
- 특정 포트를 오픈해야 함
- Swap disabled
MAC address and product_uuid 확인하기
ip link
: MAC 주소를 확인한다.sudo cat /sys/class/dmi/id/product_uuid
: product_uuid를 확인한다.
포트 확인하기
nc 127.0.0.1 6443
- required ports 쿠버네티스에서 필요한 포트를 여기서 확인한다.
- nc 명령어로 포트가 열려있는지 확인한다.
2 공통 설치
- 클러스터를 구성하는 모든 노드에 kubeadm, kubelet, kubectl, docker runtime을 설치한다.
2.1 Installing a container runtime
- 레퍼런스
- container runtime interface의 여러 구현체 중 하나를 선택해 사용할 수 있다.
- container runtime을 지정하지 않으면 kubeadm이 자동으로 설치된 container runtime 감지한다.
- 여러 container runtime 또는 container runtime이 감지되지 않으면 kubeadm은 예러를 던진다.
- 쿠버네티스 1.26에서는 컨테이너 런타임 인터페이스(CRI) 요구사항을 만족하는 런타임을 사용해야 한다.
2.1.1 Docker
참고
도커 엔진은 쿠버네티스와 함께 작동하기 위한 요구 사항인 CRI를 구현하지 않았다. 이러한 이유로 추가 서비스 cri-dockerd도 설치해야 한다.
Set up the repository
sudo apt-get update
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
Add Docker’s official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
Use the following command to set up the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Install Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo service docker start
2.1.2 CRI-O
Forwarding IPv4 and letting iptables see bridged traffic
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
## 필요한 sysctl 파라미터를 설정하면, 재부팅 후에도 값이 유지된다.
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
## 재부팅하지 않고 sysctl 파라미터 적용하기
sudo sysctl --system
CRI-O Installation Instructions
OS=xUbuntu_22.04
VERSION=1.24
echo "deb [signed-by=/usr/share/keyrings/libcontainers-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb [signed-by=/usr/share/keyrings/libcontainers-crio-archive-keyring.gpg] https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
mkdir -p /usr/share/keyrings
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-archive-keyring.gpg
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/Release.key | gpg --dearmor -o /usr/share/keyrings/libcontainers-crio-archive-keyring.gpg
apt-get update
apt-get install cri-o cri-o-runc
sudo systemctl daemon-reload
sudo systemctl enable crio --now
service crio status
2.1.3 cgroup 드라이버
- kubelet과 컨테이너 런타임이 같은 cgroup 드라이버를 사용해야 한다.
- 두 가지의 cgroup 드라이버가 이용 가능하다.
- cgroupfs
- systemd
- systemd가 init 시스템으로 선택되었을 때에는 systemd를 kubelet과 컨테이너 런타임의 cgroup 드라이버로 사용해야 한다.
kubelet 설정
- v1.22부터 kubeadm을 이용하면 kubelet의 cgroup 드라이버는 기본적으로
systemd
이다. - 레퍼런스
## kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.21.0
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
kubeadm init --config kubeadm-config.yaml
CRI-O 설정
- 레퍼런스
- CRI-O systemd를 기본 값으로 사용한다.
- cgroupfs를 사용하기 위해선 아래와 같이
/etc/crio/crio.conf
파일을 수정한다.
[crio.runtime]
conmon_cgroup = "pod"
cgroup_manager = "cgroupfs"
2.2 Swap disabled
- Kubernetes 1.8 이후 kubelet이 정상적으로 작동하기 노드에서 스왑을 비활성화해야 함
- kubernetes의 아이디어는 인스턴스를 최대한 100%에 가깝게 성능을 발휘하는 것
- 모든 배포는 CPU/메모리 제한을 고정하는 것이 필요
- 따라서 스케줄러가 파드를 머신에 보내면 스왑을 사용하지 않는 것이 필요
- 스왑 발생시 속도가 느려지는 이슈 발생
## 현재 커널에서 스왑 기능 끄기
sudo swapoff -a
## 리 부트 후에도 스왑 기능 유지
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
2.3 kubelet kubeadm kubectl 설치
- 레퍼런스
- Debian 기준
Update the apt
package index and install packages needed to use the Kubernetes apt
repository
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
Download the Google Cloud public signing key
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
Add the Kubernetes apt
repository
- Debian 12 and Ubuntu 22.04이상의 경우
/etc/apt/keyrings
해당 디렉토리를 만들고 진 행한다.
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Update apt
package index, install kubelet, kubeadm and kubectl, and pin their version
sudo apt-get update
sudo apt-get install -y kubelet=1.26.1-00 kubeadm=1.26.1-00 kubectl=1.26.1-00
sudo apt-mark hold kubelet kubeadm kubectl
2.3.1 kubeadm
- 클러스터를 부트스트랩하는 명령
2.3.2 kubelet
- 클러스터 내에 모든 노드에서 실행되는 에이전트이다.
- Master Node와 커뮤니케이션을 위해 필요함
- kubelet의 역할
- 쿠버네티스 클러스터에 노드를 등록한다
- pod를 생성하기 위해 컨테이너 런타임에 요청을 전달한다.
- 노드와 pod 모니터링하고 그 결과를 kube-apiserver에 주기적으로 전송한다.
2.3.3 kubectl
- Command Line Util이다
- kubectl을 통해 클러스터와 커뮤니케이션한다.
3 master node
- control-plane node는 control plane components가 실행되는 노드를 말한다.
- control plane components에는 etcd, API Server(kubectl이 소통하는) 등이 있다.
3.1 master node 초기화
$ kubeadm init \
--apiserver-advertise-address=192.168.121.61 \
--pod-network-cidr=192.168.0.0/16
--apiserver-advertise-address
옵션
- 다른 노드가 마스터에 접근할 수 있는 IP 주소를 입력한다.
--pod-network-cidr
옵션
- 쿠버테니스에서 사용할 컨테이너의 네트워크 대역이며 각 서버의 네트워크 대역과 중복되지 않게 선택한다.
kubeadm으로 생성한 클러스터의 드라이버를 systemd
로 변경하기
- 레퍼런스
- 아래와 같이 kubeadm-config.yaml 파일을 작성하고
kubeadm init --config kubeadm-config.yaml
- --config 옵션으로 설정 파일 전달 가능
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.154.133
bindPort: 6443
nodeRegistration:
criSocket: /var/run/crio/crio.sock
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.26.1
controlPlaneEndpoint: 192.168.154.133:6443
networking:
serviceSubnet: 10.96.0.0/16
podSubnet: 10.10.0.0/16
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
초기화가 완료되면 아래와 같은 출력 결과가 나온다. 하니씩 살펴보자.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.155.69:6443 --token vcp2e0.v4ljeneis6crciyz \
--discovery-token-ca-cert-hash sha256:8054c511d04396aa2cee5e8235f69951472a51b08da71057a7cd957acf37f45d
3.2 사용자 세팅
kubectl
이 루트 사용자가 아닌 사용자에게 작동하도록 하려면 다음 명령을 실행합니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
echo 'export KUBECONFIG=$HOME/.kube/config' >> $HOME/.bashrc
3.3 Pod 네트워크 추가
- CNI(Container Network Interface)의 원하는 구현체를 선택해 추가한다.
- 아래의 예시는 weavenet 플러그인을 추가한다.
weavenet
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
칼리코
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/tigera-operator.yaml
curl https://raw.githubusercontent.com/projectcalico/calico/v3.24.1/manifests/custom-resources.yaml -O
kubectl create -f custom-resources.yaml
4 worker node
4.1 워커 노드를 클러스터에 조인하기
- control-plane node에서 kubeadm init의 결과 맨 마지막 출력된 명령어를 실행한다.
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
kubeadm join \
--token frumf0.zzpuudwj4h65426d 192.168.154.133:6443 \
--discovery-token-ca-cert-hash sha256:403b27ec0901a9a274e51270a46c1a357b38ca0bdda9d23c3b14ce41984110c4
Token 조회하기
- Token을 모르겠다면 control-plane node에서 아래 커맨드를 통해 조회할 수 있다.
$ kubeadm token list
Token 생성하기
- 기본 Token의 만료기간은 24시간이기 때문에 만료되었다면 새로운 토큰을 생성해야 한다.
- 아래 커맨드로 Token을 생성한다.
$ kubeadm token create
--discovery-token-ca-cert-hash 밸류 얻기
- control-plane node에서 아래 커맨드를 통해 조회할 수 있다.
$ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
참고