728x90
반응형

가상 머신 만들어서 CentOS 까지 설치가 끝났다.
이제 쿠버네티스 클러스터를 위한 노드 기본 설정을 해주어야 하는데 생각보다 해줄게 많다.
하나씩 해보면서 왜 해주어야 하는지 살펴볼 예정이다.

노드 기본 설정 요약 정리

1. SELinux 설정

setenforce 0

sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

sestatus

2. 방화벽 비활성화 - firewalld, NetworkManager

systemctl stop firewalld && systemctl disable firewalld

systemctl stop NetworkManager && systemctl disable NetworkManager

3. iptables 커널 옵션 활성화

lsmod | grep br_netfilter

sudo modprobe br_netfilter

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl --system

4. Swap 비활성화

swapoff -a && sed -i '/ swap / s/^/#/' /etc/fstab

5. 쿠버네티스 yum repository 설정

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
exclude=kubelet kubeadm kubectl
EOF

6. Docker 설치

# 도커 설치를 위한 패키지 설치
yum install -y yum-utils device-mapper-persistent-data lvm2 

# 도커 저장소 설정
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 도커 설치
yum update -y && yum install -y docker-ce

# 도커 cgroup 드라이버 systemd 로 변경
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d

systemctl enable docker
systemctl daemon-reload
systemctl restart docker

7. 쿠버네티스 설치

yum install -y --disableexcludes=kubernetes kubeadm kubectl kubelet

8. hosts 등록

cat << EOF >> /etc/hosts
10.0.2.10 k8s-master
10.0.2.11 k8s-worker1
10.0.2.12 k8s-worker2
EOF

설정한 부분들을 상세하게 정리한 내용이다.

1. SELinux 설정

SELinux는 관리자가 시스템 접근 권한을 제어하기 위한 보안 아키텍쳐라고 한다.
enforce, permissive, disable 세 가지 모드로 동작하고 기본적으로 enforce 모드로 동작한다.
쿠버네티스 클러스터에서는 SELinux 를 permissive 모드로 설정해주어야 한다.
그 이유는 쿠버네티스가 Pod 네트워크에 필요한 호스트 파일시스템에 접근하기 위해서
permissive 모드 설정을 해주어야 한다고 한다.
쿠버네티스 설치 관련 문서에서는 다음과 같이 설명해주고 있다.

  • setenforce 0  sed ... 를 실행하여 permissive 모드로 SELinux를 설정하면 효과적으로 비활성화된다. 컨테이너가 호스트 파일시스템(예를 들어, 파드 네트워크에 필요한)에 접근하도록 허용하는 데 필요하다. kubelet에서 SELinux 지원이 개선될 때까지 이 작업을 수행해야 한다.
  • 구성 방법을 알고 있는 경우 SELinux를 활성화된 상태로 둘 수 있지만 kubeadm에서 지원하지 않는 설정이 필요할 수 있다.

그래서 이렇게 SELinux 모드를 변경해준다.

setenforce 라는 명령어로 모드를 변경해줄 수 있다.

usage:  setenforce [ Enforcing | Permissive | 1 | 0 ]
[root@k8s-master ~]# setenforce 0

 

이렇게 설정하게 되면 일시적으로 적용되기 때문에 SELinux 의 설정 파일에서 영구적으로 수정해준다.
설정 파일을 vi 로 열어 직접 수정하거나 sed 명령어를 통해 수정해준다.

[root@k8s-master ~]# sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

수정된 내용은 sestatus 명령어로 확인할 수 있다.

[root@k8s-master ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   permissive
Mode from config file:          permissive
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      31

permissive 로 되어있으면 설정 끝!

 

2. 방화벽 해제

firewalld 와 NetworkManager 를 비활성화 해준다.

[root@k8s-master ~]# systemctl stop firewalld && systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@k8s-master ~]# systemctl stop NetworkManager && systemctl disable NetworkManager
Removed symlink /etc/systemd/system/multi-user.target.wants/NetworkManager.service.
Removed symlink /etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service.
Removed symlink /etc/systemd/system/network-online.target.wants/NetworkManager-wait-online.service.

방화벽을 비활성화 하게 되면 보안상 문제가 되지 않을까 하는 생각이 든다.
방화벽을 비활성화하는 이유는 쿠버네티스를 운영하기 위한 필수 포트가 열려있어야 하는데
쿠버네티스를 빠르게 설치하고 테스트하기 위한 쿠버네티스 클러스터를 구축하기 위해서
방화벽을 비활성화 시켜주었다.
방화벽을 활성화하려면 쿠버네티스와 관련된 포트 설정들을 다 해주어야 하지 않을까 싶다.
나중에 활성화하고 나서 어떻게 되는지 어떤 포트를 열어주어야 하는지 해봐야겠다.

3. iptables 커널 옵션 활성화

iptables 는 리눅스에서 방화벽 설정을 도와주는 도구다.
iptables는 커널상에서 netfilter 패킷필터링 기능을 사용자 공간에서 제어하는 수준으로 사용할 수 있다고 한다.
CentOS7 에서는 net.bridge.bridge-nf-call-iptables 값이 기본값이 0으로 되어있다.
0으로 되어있다는 것은 bridge 네트워크를 통해 송수신되는 패킷들이 iptables 의 설정을 우회한다고 한다.
그래서 사용할 때 iptables가 무시되어 트래픽이 잘못 라우팅되는 문제가 발생한다고 한다.
따라서, iptables 가 브리지된 네트워크 트래픽을 제대로 보기 위해서는
net.bridge.bridge-nf-call-iptables 값이 1으로 되어야 한다는 것이다.

간단하게 정리해보면,
iptables 에서 올바른 트래픽을 보기 위해서는 br_netfilter 가 활성화 되어야 한다.

다음 명령어로 br_netfilter 의 활성화 여부를 확인하고 되어 있지 않으면 활성화해준다.

[root@k8s-master ~]# lsmod | grep br_netfilter
[root@k8s-master ~]# modprobe br_netfilter
[root@k8s-master ~]# lsmod | grep br_netfilter
br_netfilter           22256  0
bridge                151336  1 br_netfilter

그리고 커널상 쿠버네티스 설정 파일에 추가한 뒤
커널 매개변수 값을 변경해주는 sysctl --system 명령어를 실행해준다.
--system 옵션은 모든 시스템 디렉토리의 값을 읽어온다.

[root@k8s-master ~]# cat <<EOF >  /etc/sysctl.d/k8s.conf
> net.bridge.bridge-nf-call-ip6tables = 1
> net.bridge.bridge-nf-call-iptables = 1
> EOF
[root@k8s-master ~]# cat /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
[root@k8s-master ~]# sysctl --system
* Applying /usr/lib/sysctl.d/00-system.conf ...
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
* Applying /usr/lib/sysctl.d/10-default-yama-scope.conf ...
kernel.yama.ptrace_scope = 0
* Applying /usr/lib/sysctl.d/50-default.conf ...
kernel.sysrq = 16
kernel.core_uses_pid = 1
kernel.kptr_restrict = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.promote_secondaries = 1
net.ipv4.conf.all.promote_secondaries = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
* Applying /etc/sysctl.d/99-sysctl.conf ...
* Applying /etc/sysctl.d/k8s.conf ...
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
* Applying /etc/sysctl.conf ...

 

4. Swap 비활성화

Swap 메모리는 실제 메모리가 부족할 경우 메모리처럼 사용하는 메모리다.
kubelet 이 제대로 동작하기 위해서는 swap 메모리를 비활성화 시켜주어야 한다고 한다.

swapoff -a 명령어로 swap 메모리 사용을 비활성화 시킬 수 있다.

[root@k8s-master ~]# swapoff -a

그리고 /etc/fstab 에서 swap 과 관련된 문장을 주석처리해준다.
/etc/fstab 은 리눅스 시스템에서 부팅시 자동으로 마운트해주는 정보를 저장하고 있다.

[root@k8s-master ~]# sed -i '/ swap / s/^/#/' /etc/fstab
[root@k8s-master ~]# cat /etc/fstab

#
# /etc/fstab
# Created by anaconda on Sat Aug 28 22:16:34 2021
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root /                       xfs     defaults        0 0
UUID=cdef2af7-6292-4a4e-aff4-a5aa2be9d34d /boot                   xfs     defaults        0 0
/dev/mapper/centos-home /home                   xfs     defaults        0 0
#/dev/mapper/centos-swap swap                    swap    defaults        0 0

이렇게 설정해줌으로써 swap 과 관련된 내용을 비활성화 해주었다.

 

5. 쿠버네티스 yum repository 설정

쿠버네티스 설치를 위한 yum 레퍼지토리를 설정해준다.
쉽게 말하면 쿠버네티스를 설치하기 위한 저장 공간을 만들어준다.

[root@k8s-master ~]# cat <<EOF > /etc/yum.repos.d/kubernetes.repo
> [kubernetes]
> name=Kubernetes
> baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
> enabled=1
> gpgcheck=1
> repo_gpgcheck=1
> gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
> exclude=kubelet kubeadm kubectl
> EOF

 

6. Docker 설치

도커를 설치하기 전에 필요한 패키지를 설치한다.
yum-utils 패키지는 yum 패키지 매니저 관련 유틸리지 모음이고
device-mapper-persistent-data 패키지와 lvm2 패키지와 관련된 내용은 도커 문서에서 확인할 수 있다.
https://docs.docker.com/storage/storagedriver/device-mapper-driver/

[root@k8s-master ~]# yum install -y yum-utils device-mapper-persistent-data lvm2

그리고 도커를 설치하기 위한 레퍼지토리를 설정해준다.

[root@k8s-master ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
Loaded plugins: fastestmirror
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo

이제 도커를 설치해보자.

[root@k8s-master ~]# yum update -y && yum install -y docker-ce

도커를 설치하고 나서 필요한 패키지가 잘 설치되었는지 확인해봤다.

[root@k8s-master ~]# rpm -qa | grep container
container-selinux-2.119.2-1.911c772.el7_8.noarch
containerd.io-1.4.9-3.1.el7.x86_64
[root@k8s-master ~]# rpm -qa | grep docker-ce
docker-ce-20.10.8-3.el7.x86_64
docker-ce-rootless-extras-20.10.8-3.el7.x86_64
docker-ce-cli-20.10.8-3.el7.x86_64

설치가 잘 된것을 확인했다.
그리고 Docker 데몬이 사용하는 드라이버를 cgroupfs 대신 systemd 를 사용하도록 설정해준다.
이유는 쿠버네티스에서 권장하는 도커 데몬 드라이버가 systemd 라고 한다.
쿠버네티스에서 컨테이너 런타임과 관련해 문서가 있어 확인해보니
systemd 를 cgroup 드라이버로 사용하도록 설정을 변경하면 시스템이 안정화 된다고 한다.

아래 url 에서 문서를 확인할 수 있다.

https://kubernetes.io/ko/docs/setup/production-environment/container-runtimes/#kubeadm%EC%9C%BC%EB%A1%9C-%EC%83%9D%EC%84%B1%ED%95%9C-%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0%EC%9D%98-%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B2%84%EB%A5%BC-systemd-%EB%A1%9C-%EB%B3%80%EA%B2%BD%ED%95%98%EA%B8%B0

따라서, 컨테이너 cgroup 관리에 systemd 를 사용하도록 도커 데몬을 구성해준다.

[root@k8s-master ~]# sudo mkdir /etc/docker
[root@k8s-master ~]# cat <<EOF | sudo tee /etc/docker/daemon.json
> {
>   "exec-opts": ["native.cgroupdriver=systemd"],
>   "log-driver": "json-file",
>   "log-opts": {
>     "max-size": "100m"
>   },
>   "storage-driver": "overlay2"
> }
> EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
[root@k8s-master ~]# cat /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
[root@k8s-master ~]# mkdir -p /etc/systemd/system/docker.service.d

이제 도커를 활성화해주고 도커와 데몬을 재시작해준다.

[root@k8s-master ~]# systemctl enable docker
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.
[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl restart docker
[root@k8s-master ~]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
   Active: active (running) since 일 2021-08-29 00:51:46 KST; 15s ago
     Docs: https://docs.docker.com
 Main PID: 17273 (dockerd)
    Tasks: 8
   Memory: 34.5M
   CGroup: /system.slice/docker.service
           └─17273 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.045127427+09:00" level=info msg="scheme \"unix\...e=grpc
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.045142642+09:00" level=info msg="ccResolverWrap...e=grpc
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.045152295+09:00" level=info msg="ClientConn swi...e=grpc
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.066243872+09:00" level=info msg="Loading contai...tart."
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.158166227+09:00" level=info msg="Default bridge...dress"
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.195870907+09:00" level=info msg="Loading contai...done."
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.217811826+09:00" level=info msg="Docker daemon"...0.10.8
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.217917628+09:00" level=info msg="Daemon has com...ation"
 8월 29 00:51:46 k8s-master systemd[1]: Started Docker Application Container Engine.
 8월 29 00:51:46 k8s-master dockerd[17273]: time="2021-08-29T00:51:46.245350365+09:00" level=info msg="API listen on ....sock"
Hint: Some lines were ellipsized, use -l to show in full.

도커 서비스가 실행되는 것을 확인했고 도커가 잘 작동하는지 테스트해봤다.

[root@k8s-master ~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:7d91b69e04a9029b99f3585aaaccae2baa80bcf318f4a5d2165a9898cd2dc0a1
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

 

7. 쿠버네티스 설치

kubeadm 사용해 쿠버네티스 클러스터를 만들거기 때문에 설치해주고
kebelet 각 노드마다 구동되는 에이전트로 마스터와 통신을 한다.
kubectl 클러스터에게 명령을 내리기 위한 cli 유틸리티이다.

--disableexcludes 옵션은 kubernetes 레퍼지토리에서 정의된 부분을 설치 제외를 중지시킨다는 말인데...
무슨 말이지 이게 ㅎㅎㅎ kubernetes 레퍼지토리를 제외하지 말고 설치하라는 걸까...
그래서 빼고 해봤다 ㅎㅎ

[root@k8s-master ~]# yum install -y kubectl kubeadm kubelet
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.kakao.com
 * extras: mirror.kakao.com
 * updates: mirror.kakao.com
No package kubectl available.
No package kubeadm available.
No package kubelet available.
Error: Nothing to do

패키지가 없다고 나온다ㅋㅋ 다시 옵션 넣고 실행~ 설치 완료~

[root@k8s-master ~]# yum update -y && yum install -y --disableexcludes=kubernetes kubelet kubeadm kubectl
[root@k8s-master ~]# rpm -qa | grep kube
kubeadm-1.22.1-0.x86_64
kubelet-1.22.1-0.x86_64
kubectl-1.22.1-0.x86_64
kubernetes-cni-0.8.7-0.x86_64

 

8. hosts 등록

마스터 노드 1개와 워커노드 2개의 호스트 이름과 ip를 등록해줘야 한다.
호스트 등록을 하지 않으면 나중에 kubeadm init 할 때 호스트 이름으로 ip를 찾을 수 없다고 한다.
그래서 /etc/hosts에 마스터노드와 워커노드 2개를 등록해주었다.
나는 VirtualBox에서 NatNetwork 에서 포트 포워딩한 호스트 이름과 호스트 IP를 등록해었다.

[root@k8s-master ~]# cat << EOF >> /etc/hosts
> 10.0.2.10 k8s-master
> 10.0.2.11 k8s-worker1
> 10.0.2.12 k8s-worker2
> EOF
[root@k8s-master ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.0.2.10 k8s-master
10.0.2.11 k8s-worker1
10.0.2.12 k8s-worker2

 

와아... 드디어 기본 설정을 마쳤다 !!
이제 가상 머신을 복사해서 워커 노드 2개를 만들고 조금 수정해준 뒤에
마스터 노드에 kubeadm 초기화 설정하고 쿠버네티스 환경 설정을 해주고
워커 노드에 kubeadm 연결을 해줄 예정이다.
가상 머신 만들고 기본 구성 설정하는 데만 거의 3시간 넘게 걸렸다. ㄷㄷ
물론 하나씩 찾아가며 정리해가며 한 것도 있지만 쉽진 않았다.
그래도 하나씩 하다보니 어느 정도 감은 오는 정도? ㅎㅎ😂😂

 

- 참고 사이트

https://twofootdog.tistory.com/8

 

쿠버네티스 시작하기(5) - CentOS에 쿠버네티스 설치하기

이전 장에서 쿠버네티스(Kubernetes)의 개념 및 아키텍쳐에 대해 정리를 해 보았다. 이번 장에서는 이제 실제 리눅스(CentOS) 환경에서 쿠버네티스를 설치를 해보도록 하겠다. 1. 쿠버네티스 설치 전

twofootdog.tistory.com

https://jordy-torvalds.tistory.com/46

 

쿠버네티스 설치 방법

개요 어떤 파일도 설치되어 있지 않은 CentOS 7에 쿠버네티스를 설치하는 방법에 대해 정리해보겠습니다. 공식 홈페이지의 가이드에 따라 설치했음에도 불구하고 알 수 없는 오류에 고심하시던

jordy-torvalds.tistory.com

https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

 

kubeadm 설치하기

이 페이지에서는 kubeadm 툴박스를 설치하는 방법을 보여준다. 이 설치 프로세스를 수행한 후 kubeadm으로 클러스터를 만드는 방법에 대한 자세한 내용은 kubeadm을 사용하여 클러스터 생성하기 페이

kubernetes.io

https://elfinlas.github.io/2019/02/14/install-docker/

 

CentOS에서 Docker 설치하기

CentOs에 Docker 설치하기프로젝트 운영을 Aws의 Ec2 CentOS에서 진행을 하는데 테스트를 위해 Docker를 설치해야 했다.이번 포스팅에서는 이 부분을 정리해보고자 한다. 설치 순서설치 순서는 아래와 같

elfinlas.github.io

 

728x90
반응형
복사했습니다!