Go, Vantage point
가까운 곳을 걷지 않고 서는 먼 곳을 갈 수 없다.
Github | https://github.com/overnew/
Blog | https://everenew.tistory.com/
티스토리 뷰
Kubeadm으로 쿠버네티스 직접 설치하기
Kubeadm은 직접 서버와 네트워크 인프라를 구축하여 그 위에 쿠버네티스를 설치한다.
VM에 직접 설치하는 표준 방법이지만, 버전에 따른 정확한 절차를 따라야 하기 때문에 어렵다.
또한 자동화가 불가능하기 때문에 관리가 힘들다.
하나하나 따라가며 설치해 보자.
Vagrantfile로 VM 올리기
일단 Vagrant와 Virtual box의 설치가 필요하다.
[Window] Vagrant 설치 및 활용 (synced_folder, Docker)
SCRIPT에 ssh 보안 관련 설정이 등장한다.
/etc/ssh/sshd_config
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
systemctl restart sshd
PermitRootLogin prohibit-password -> yes
PasswordAuthentication no -> yes
외부에서 root 계정으로 로그인을 허용
대신 키를 사용한 접속으로
이대로 생성
$ssh_config = <<-SCRIPT
echo ">>>> root password <<<<<<"
printf "qwe123\nqwe123\n" | passwd
echo ">>>> ssh-config <<<<<<"
sed -i "s/^PasswordAuthentication no/PasswordAuthentication yes/g" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin prohibit-password/PermitRootLogin yes/g" /etc/ssh/sshd_config
systemctl restart sshd
SCRIPT
Vagrant.configure("2") do |config|
config.vm.define "k8s-m" do |m1|
m1.vm.box = "ubuntu/focal64"
m1.vm.network "private_network", ip: "192.168.56.200"
m1.vm.network "forwarded_port", guest: 22, host: 50000, auto_correct: true, id: "ssh"
m1.vm.provision "shell", inline: $ssh_config
m1.vm.host_name = "k8s-m"
m1.vm.provider "virtualbox" do |vb1|
vb1.memory = "4096"
vb1.cpus = "4"
vb1.linked_clone = true
end
end
config.vm.define "k8s-w1" do |w1|
w1.vm.box = "ubuntu/focal64"
w1.vm.network "private_network", ip: "192.168.56.210"
w1.vm.network "forwarded_port", guest: 22, host: 50010, auto_correct: true, id: "ssh"
w1.vm.provision "shell", inline: $ssh_config
w1.vm.host_name = "k8s-w1"
w1.vm.provider "virtualbox" do |vb1|
vb1.memory = "4096"
vb1.cpus = "2"
vb1.linked_clone = true
end
end
config.vm.define "k8s-w2" do |w2|
w2.vm.box = "ubuntu/focal64"
w2.vm.network "private_network", ip: "192.168.56.220"
w2.vm.network "forwarded_port", guest: 22, host: 50020, auto_correct: true, id: "ssh"
w2.vm.provision "shell", inline: $ssh_config
w2.vm.host_name = "k8s-w2"
w2.vm.provider "virtualbox" do |vb1|
vb1.memory = "4096"
vb1.cpus = "2"
vb1.linked_clone = true
end
end
end
vagrant up 으로 실행.
**여기서부터 특정 노드를 지칭하지 않는 이상 모든 VM에 진행한다.**
모든 VM에 접속하여 업데이트 진행
sudo apt-get update && sudo apt-get -y full-upgrade
sudo reboot -f
필요한 패키지 다운로드
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
- curl: URL을 통해 데이터를 전송하고 받는 명령줄 도구입니다. 주로 네트워크 상에서 데이터를 송수신하고 스크립트에서 사용됩니다.
- gnupg2: GNU Privacy Guard(GPG)의 버전 2입니다. 암호화 및 디지털 서명 기능을 제공합니다. 이는 소프트웨어의 인증 및 보안을 확인하기 위해 사용됩니다.
- software-properties-common: 소프트웨어 소스를 추가하고 관리하기 위한 도구를 제공합니다. 이 도구를 사용하면 새로운 패키지 저장소를 추가하거나 기존 저장소를 관리할 수 있습니다.
- apt-transport-https: HTTPS를 통해 안전하게 apt 패키지 관리자가 패키지를 다운로드하고 설치할 수 있도록 합니다.
- ca-certificates: 공인 인증 기관(Certificate Authority)의 루트 인증서를 관리합니다. 이를 통해 HTTPS 연결 시 서버의 신뢰성을 확인할 수 있습니다.
도커 리포지터리 등록(모든 서버)
# Ubuntu 20.04 이하에서는 아래의 폴더가 없어서 만들고 사용해야함.
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
확인해보면 다운되어 있음.
레퍼지토리 등록(모든 서버)
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
.deb은 데비안의 소프트웨어 패키지 포맷의 확장자이며 데비안 소프트웨어 포맷의 바이너리 패키지에서 가장 자주 사용되는 파일 이름이다.
- echo: 텍스트를 표준 출력에 출력하는 명령어입니다.
- deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable: Docker 패키지 저장소의 정보를 출력합니다. 여기서 사용되는 구성 요소는 다음과 같습니다.
- sudo tee /etc/apt/sources.list.d/docker.list: echo로 출력된 내용을 /etc/apt/sources.list.d/docker.list 파일에 덮어쓰기. tee 명령어는 표준 출력으로부터 데이터를 읽어서 파일에 쓰는 동시에 표준 출력으로도 보낸다.
- > /dev/null: 표준 출력을 /dev/null로 리디렉션하여 출력을 무시합니다. 이 부분은 출력을 표시하지 않도록 하는데 사용됩니다.
특정 버전인 1.27 다운로드
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.27/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.27/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
- curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.27/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg: curl을 사용하여 Kubernetes 패키지 저장소의 1.27 버전의 GPG 키를 다운로드하고, 이를 gpg를 사용하여 디코딩한 후 `/etc/apt/keyrings/kubernetes-apt-keyring.gpg` 파일로 저장합니다. 여기서 사용되는 옵션은 다음과 같습니다:
- -fsSL: curl의 옵션으로, 에러 메시지를 표시하지 않고, SSL 연결을 사용하여 안전하게 다운로드하며, 서버의 리다이렉션을 따릅니다.
- https://pkgs.k8s.io/core:/stable:/v1.27/deb/Release.key: Kubernetes 패키지 저장소의 GPG 키 파일의 URL입니다.
- --dearmor 옵션은 GPG 키를 디코딩하는 옵션입니다.
- echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.27/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list: Kubernetes 패키지 저장소를 시스템의 패키지 관리자에 추가합니다. 이 부분은 다음과 같이 동작합니다:
#모든 노드에 업데이트
sudo apt update -y
containerd설치 진행
sudo apt install -y containerd.io
containerd.io: 이는 컨테이너 런타임을 관리하는 도구인 containerd의 패키지이다. containerd는 Docker의 하부 컨테이너 런타임으로 사용. 이 명령을 실행하면 컨테이너 런타임인 containerd의 최신 버전이 시스템에 설치.
sudo mkdir -p /etc/containerd #폴더 만들어 주기 -p는 필요시 상위디렉토리 생성
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
containerd의 기본 설정을 편집하여 새로운 구성 파일로 저장하는 명령어
1. containerd config default: 이 명령은 containerd의 기본 설정을 출력합니다.
2. |: 이 부분은 파이프 연산자로, 첫 번째 명령의 출력을 두 번째 명령의 입력으로 전달합니다.
3. sudo tee /etc/containerd/config.toml: tee 명령은 표준 입력에서 데이터를 읽어와서 파일에 쓰는 동시에 표준 출력으로도 전달합니다. 이 부분은 containerd의 설정을 /etc/containerd/config.toml 파일에 씁니다.
4. > /dev/null: 이 부분은 표준 출력을 /dev/null로 리디렉션하여 출력을 무시합니다. 따라서 표시되는 출력이 없습니다.
결과적으로, 이 명령은 containerd의 기본 설정을 읽어와서 /etc/containerd/config.toml 파일에 저장.
쿠버네티스 설치(모든 서버)
#핵심 세가지 설치
sudo apt -y install kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
apt-mark hold
apt-mark hold 명령어는 Debian 계열의 리눅스 시스템에서 사용되는 APT(Advanced Packaging Tool) 패키지 관리 도구의 기능 중 하나입니다. 이 명령어는 특정 패키지의 버전을 고정시켜, 해당 패키지가 업그레이드되거나 제거되지 않도록 방지합니다.
일반적으로 시스템에서 특정 패키지를 hold 상태로 두면 해당 패키지의 업그레이드나 제거 작업이 APT를 통해 수행될 때 무시됩니다. 이것은 특히, 사용자가 특정 버전의 패키지를 유지하고자 할 때 유용합니다.
스왑 비활성화(모든 서버)
sudo sed -i '/swap/s/^/#/' /etc/fstab # 파일의 swap 문자열 앞에 #을 붙이도록 만들어 줌.
sudo swapoff -a && sudo mount -a
이 명령어는 시스템에서 swap 영역을 해제하고, /etc/fstab 파일에 정의된 모든 파일 시스템을 마운트한다.
1. sudo swapoff -a: 이 명령은 시스템에서 모든 swap 영역을 비활성화. Swap은 시스템 메모리가 부족할 때 사용되는 가상 메모리 공간으로, 일반적으로 하드 디스크의 일부를 사용합니다. swapoff 명령을 사용하여 시스템에서 swap을 비활성화하면 현재 메모리 상태에 대한 정보를 swap 영역으로 다시 저장하지 않습니다.
2. &&: 이 부분은 두 개의 명령어를 순차적으로 실행하는 데 사용됩니다. 앞의 명령이 성공적으로 실행된 후에만 뒤의 명령이 실행됩니다.
3. sudo mount -a: 이 명령은 /etc/fstab 파일에 정의된 모든 파일 시스템을 마운트한다. /etc/fstab은 시스템 부팅 시 자동으로 마운트할 파일 시스템을 정의하는 파일이다. 이 명령은 시스템 재부팅 후에 수동으로 마운트해야 하는 파일 시스템을 자동으로 마운트한다.
쿠버네티스는 가상메모리를 최대한 배제해야 관리가 편하기 때문에 스왑 기능을 비활성화한다.
커널 기능 설정 변경(모든 서버)
sudo su - -c "echo 'net.bridge.bridge-nf-call-ip6tables = 1' \
>> /etc/sysctl.d/kubernetes.conf"
sudo su - -c "echo 'net.bridge.bridge-nf-call-iptables = 1' \
>> /etc/sysctl.d/kubernetes.conf"
sudo su - -c "echo 'net.ipv4.ip_forward = 1' \
>> /etc/sysctl.d/kubernetes.conf"
echo를 사용하여 특정한 설정을 파일에 추가한다. 0으로 off된 것을 1로 On 시킨다.
- sudo su - -c "echo 'net.bridge.bridge-nf-call-ip6tables = 1' >> /etc/sysctl.d/kubernetes.conf": 이 명령어는 IPv6의 IPTables 호출을 활성화하는 설정을 /etc/sysctl.d/kubernetes.conf 파일에 추가합니다.
- sudo su - -c "echo 'net.bridge.bridge-nf-call-iptables = 1' >> /etc/sysctl.d/kubernetes.conf": 이 명령어는 IPTables 호출을 활성화하는 설정을 /etc/sysctl.d/kubernetes.conf 파일에 추가합니다.
- sudo su - -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.d/kubernetes.conf": 이 명령어는 IPv4 포워딩을 활성화하는 설정을 /etc/sysctl.d/kubernetes.conf 파일에 추가합니다.
주요 구성 요소들은 아래와 같다.
- su -: 루트 사용자로 스위치하여 해당 명령을 실행합니다. - 옵션은 루트 사용자로 전환되면서 루트 사용자의 환경을 사용하도록 합니다.
- -c: 명령어를 실행하는데 사용됩니다.
- >> /etc/sysctl.d/kubernetes.conf: echo로 출력한 문자열을 /etc/sysctl.d/kubernetes.conf 파일에 추가합니다. >>는 파일에 내용을 추가하는 리디렉션입니다.
커널 모듈 로드 설정(모든 서버)
echo를 사용하여 특정한 모듈을 파일에 추가하는 명령어들
sudo su - -c "echo 'overlay' >> /etc/modules-load.d/containerd.conf"
overlay 모듈을 /etc/modules-load.d/containerd.conf 파일에 추가합니다. overlay는 Linux 컨테이너 런타임인 containerd가 사용하는 파일 시스템 드라이버입니다
sudo su - -c "echo 'br_netfilter' >> /etc/modules-load.d/containerd.conf"
br_netfilter 모듈을 /etc/modules-load.d/containerd.conf 파일에 추가합니다. br_netfilter는 Linux 브리지 네트워킹에 사용되는 커널 모듈입니다.
#위에서 추가한 커널 모듈 및 설정 활성화(모든 서버)
sudo modprobe overlay
sudo modprobe br_netfilter
sudo sysctl --system
#모든 노드에서 서비스 활성화
sudo systemctl restart containerd kubelet
sudo systemctl enable containerd kubelet
모든 노드에 호스트 파일(/etc/hosts)에 새로운 엔트리를 추가
sudo echo "192.168.56.200 k8s-m" >> /etc/hosts
sudo echo "192.168.56.210 k8s-w1" >> /etc/hosts
sudo echo "192.168.56.220 k8s-w2" >> /etc/hosts
하지만 이 명령어에서 sudo는 명령어 전체를 실행하는 것이 아니라 echo만을 실행하므로 리디렉션(>>)은 슈퍼 유저 권한이 적용되지 않는다.
따라서 sudo su로 슈퍼 유저로 진입 후 진행하자.
이제 각각의 노드에 host 이름을 바꾸는 명령어를 실행
master→ hostnamectl set-hostname k8s-m
worker1→ hostnamectl set-hostname k8s-w1
worker2→ hostnamectl set-hostname k8s-w2
컨트롤러 노드(마스터 노드)에 쿠버네티스 관련 서비스 이미지 설치
sudo kubeadm config images pull
kubeadm: Kubernetes 클러스터를 설정하는 데 사용되는 도구.
이 명령어를 실행하면 Kubernetes 클러스터 설정에 필요한 컨테이너 이미지가 로컬 머신으로 다운로드되어 준비된다. 이렇게 하면 Kubernetes 마스터 및 워커 노드를 구성하는 동안 인터넷에 액세스할 필요가 없으며, 클러스터를 보다 빠르게 구성할 수 있다.
즉, 미리 필요한 데이터를 모두 마스터 노드에 다운로드 받아오고, 마스터 노드가 워커 노드에게 전달하게 된다. 그러므로 설정 중에는 더 이상 인터넷에서 파일을 다운로드 받아올 필요가 없게 된다.
#마스터 노트에, kubeadm으로 부트스트랩 진행
sudo kubeadm init --apiserver-advertise-address 192.168.56.200 \
--pod-network-cidr 172.30.0.0/16 \
--upload-certs \
Kubernetes 클러스터를 초기화하는 명령어
- kubeadm init: Kubernetes 클러스터를 초기화하는 명령어.
- --apiserver-advertise-address 192.168.56.200: Kubernetes API 서버가 사용하는 IP 주소를 지정합니다. 이 경우, API 서버는 192.168.56.200 주소를 사용하게 됩니다.
- --pod-network-cidr 172.30.0.0/16: 클러스터 내부의 Pod 네트워크를 위한 CIDR 블록을 지정합니다. 이 블록은 클러스터 내의 Pod 간 통신을 위한 IP 주소 범위를 설정합니다.
- --upload-certs: 클러스터의 인증서를 업로드하는 옵션입니다. 이 옵션을 사용하면 마스터 노드에서 생성된 인증서를 나중에 추가할 워커 노드로 전송할 수 있습니다.
이 명령어는 지정된 설정을 사용하여 Kubernetes 클러스터를 초기화하고, 클러스터의 마스터 노드를 설정합니다. 클러스터 초기화 후에는 마스터 노드에 접속할 수 있는 kubeconfig 파일이 생성되며, 이 파일을 사용하여 클러스터를 제어할 수 있다.
아래에 생성된 join 명령어에 토큰을 워커 노드에 넣어주면 클러스터링이 된다.
워커 노드들에 join 실행
kubeadm join 192.168.56.200:6443 --token t9j2dq.2m8e0r5fmhr9dwac \
--discovery-token-ca-cert-hash sha256:a6a10a52aa55f4002a7ada8401dfb21541e79750032643aa3f8619129d12776a
마스터에서 현재 계정으로 kubectl 명령을 사용할 수 있도록 설정
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
이 명령어들은 Kubernetes 클러스터를 관리하기 위해 필요한 kubeconfig 파일을 사용자 홈 디렉토리에 복사하고 권한을 설정하는 것.
1. mkdir -p $HOME/.kube: $HOME/.kube 디렉토리를 생성합니다. 이 디렉토리는 Kubernetes 클러스터 관리를 위한 kubeconfig 파일이 저장됩니다. -p 옵션은 디렉토리가 이미 존재하는 경우에도 에러를 발생시키지 않고, 디렉토리가 존재하지 않을 경우에만 생성합니다.
2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config: /etc/kubernetes/admin.conf 파일을 사용자의 홈 디렉토리에 있는 .kube/config 파일로 복사합니다. 이 파일은 Kubernetes 클러스터를 관리하기 위한 중요한 설정 정보를 담고 있습니다. -i 옵션은 대상 파일이 이미 존재할 경우 덮어쓸지 사용자에게 확인을 요청합니다.
3. sudo chown $(id -u):$(id -g) $HOME/.kube/config: $HOME/.kube/config 파일의 소유자를 현재 사용자로 변경합니다. 이것은 보안상의 이유로 필요한 작업으로, 해당 파일에 대한 접근 권한을 현재 사용자로 제한합니다. $(id -u):$(id -g)는 현재 사용자의 사용자 ID와 그룹 ID를 나타냅니다.
이러한 명령어들을 실행하면 Kubernetes 클러스터를 관리하기 위한 kubeconfig 파일이 생성되고, 이를 통해 클러스터를 제어할 수 있게 됩니다.
이제 마스터 노드에서만 명령어가 되도록 바뀐다.
이제 마스터 노드에서 아래 명령어로 노드 확인.
Kubectl get node -A
아직은 container 생성 중.
쿠버네티스의 컨테이너 네트워크 인터페이스 설치 및 설치 파일 다운로드 (CNI)
kubectl create -f \https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/\manifests/tigera-operator.yaml
create로 파드를 만들게 됨.
Kubernetes 클러스터에 Calico 네트워킹 솔루션을 설치하기 위해 사용.
- kubectl create: Kubernetes 리소스를 생성하는 명령어입니다.
- -f: 파일 또는 URL을 통해 리소스를 생성하도록 지정하는 옵션입니다.
- https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml: Calico 프로젝트의 GitHub 저장소에서 제공되는 tigera-operator.yaml 파일의 URL입니다. 이 파일은 Calico 네트워킹 솔루션을 설치하는 데 필요한 Kubernetes 오브젝트의 정의를 포함합니다.
따라서 이 명령어는 해당 URL에서 tigera-operator.yaml 파일을 가져와서 Kubernetes 클러스터에 있는 kubectl을 사용하여 해당 파일에 정의된 리소스를 생성하게 됩니다. 이를 통해 Calico 네트워킹 솔루션을 Kubernetes 클러스터에 설치할 수 있습니다.
칼리코는 네트워크 인터페이스로 BGP의 지원을 해주기 때문에 많이 사용된다.
#이건 커스텀 리소스 파일 하나를 다운로드
wget https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/\manifests/custom-resources.yaml
이 명령어는 Calico 네트워킹 솔루션을 Kubernetes 클러스터에 설치하기 위해 필요한 Custom Resource 정의 파일을 다운로드한다.
따라서 이 명령어를 실행하면 해당 URL에서 custom-resources.yaml 파일이 다운로드되어 로컬 시스템에 저장됩니다. 이 파일은 나중에 Kubernetes 클러스터에 kubectl apply 명령어를 사용하여 Custom Resource를 생성할 때 사용된다.
#172.30으로 네트워크 설정 변경
sed -i 's/cidr: 192\.168\.0\.0\/16/cidr: 172\.30\.0\.0\/16/g' \custom-resources.yaml
192.168을 172.30으로 변경한다.
nano custom-resources.yaml 확인
아래의 명령어를 실행 후, 들어가서 yml 파일 들여쓰기 맞춰주자.
sed -i '7a registry: quay.io/' custom-resources.yaml
# custom-resources.yaml을 통해 클러스터에 새로운 리소스 생성
kubectl create -f custom-resources.yaml
결과 확인
kubectl get pod -A
아직 생성 중
필요한 이미지를 받아서 실행시키기까지 시간이 꽤 소요된다.
Kube-systemd에서 running 되는 것들은 다 마스터 노드에서 동작중인 것이다.
'개발 > Kubernetes' 카테고리의 다른 글
Kubernetes Pod 활용하기 (Pause container, label, volume) (0) | 2024.03.03 |
---|---|
Kubernetes Kubectl 기본 명령어 정리 (0) | 2024.03.03 |
Kubernetes Namespaces VS Linux Namespaces (Pause 컨테이너) (0) | 2024.03.03 |
KubeSpary로 Kubernetes 설치하기 (0) | 2024.03.03 |
쿠버네티스 란? (0) | 2024.03.02 |