쿠버네티스 환경 설정

DONGJIN IM·2022년 7월 18일
0

Kubernetes

목록 보기
3/3

Kubernetes 환경 설정

1. VirtualBox 및 CentOS 설치

1.5. 원격접속 툴 XShell 설치

꼭 필요한 과정은 아니다.
단지 Virtual Box가 불편한 점이 몇 개 존재한다
(복사 붙여넣기가 잘 안된다는 점이라던가 마우스 포인터가 잘 안된다는 점이라던가...)

그리서 원격접속 툴이 있으면 편하게 활용 가능하다

2. XShell Host 등록

원격접속 툴이므로 "내가 원하는 IP 주소"를 입력해야 해당 IP 주소를 통해 접근 가능할 것이다.

Server의 고정 IP 주소는 아래와 같이 설정했다.

  • Master : 192.168.0.30
  • Node1 : 192.168.0.31
  • Node2 : 192.168.0.32

2.1 : 새로 만들기 클릭

2.2 원하는 IP 주소 및 이름 설정

  • IP 주소는 위에서 설정하려고 한 IP 주소, 이름은 아무렇게나 해도 상관없지만 Master와 Node간 구별이 가능하도록 설정

2.3 : 복사 + 붙여넣기로 원하는 만큼 Node 생성

2.4 : Node 설정 변경

  • Node2도 똑같이 변경

3. VM Setting

3.1 가상 머신 만들기

  • 이름 : 구분만 가능하면 됨

  • 종류 : 사용할 OS. Linux 기반으로 만들 것이므로 Linux 선택

  • 버전 : CentOS는 Other Linux에 포함됨

  • 이후 계속 확인 선택

    • 메모리 크기 : 4096MB 추천. 각자 컴퓨터 사양에 맞춰 설정하는 것이 좋음
    • 하드 디스크 : 지금 새 가상 하드 디스크 만들기 \rightarrow 만들기 버튼 클릭 \rightarrow VDI 선택 이후 다음 클릭 \rightarrow 동적 할당 선택 후 다음 클릭 \rightarrow 각자 컴퓨터 사양에 맞춰 하드 디스크 크기 설정(150 추천)

3.2 가상 머신 설정

  1. 시스템 \rightarrow 프로세서 \rightarrow CPU 2개

    • 매우 중요한 단계
    • 쿠버네티스 및 도커는 CPU 2개를 추천하고 있다. 따라서, CPU가 1개로 설정되어 있으면 설치할 때 경고 문구가 뜨고 설치가 중단된다. 따라서, 꼭 CPU를 2개로 설정하자
  2. 저장소 선택

    • 저장소에서 디스크 파일 선택 후 아까 설치했던 CentOS iso 파일을 넣어주면 된다
  3. 네트워크 선택 후 어댑터에 브리지 선택

4. CentOS 설치

  1. Test this media & install CentOS 7 선택

  2. Language : 한국어

  3. Disk 설정 [시스템 > 설치 대상]

    • [기타 저장소 옵션 > 파티션 설정] 파티션을 설정합니다 [체크] 후 [완료]
    • 새로운 CentOS 설치 > 여기를 클릭하여 자동으로 생성합니다 [클릭]
    • /home [클릭] 이후 5.12GB로 변경
    • / [클릭] 후 140GiB로 변경
      • 만약 150으로 설정되었다면 140이 그대로 들어갈 것이다.
      • 그보다 작게 설정했을 경우 최댓값으로 들어간다
    • [완료] \rightarrow [변경 사항 적용]
  4. 네트워크 설정 [시스템 > 네트워크 및 호스트명 설정]

    • 호스트 이름 : k8s-master [적용]
      • 꼭 [적용] 버튼을 클릭해주자!
    • [IPv4 설정] 탭 선택
    • 방식 : 수동으로 선택
    • [Add] 클릭 후 아래와 같이 입력
      • 주소 : 192.168.0.30(Master IP)
      • 넷마스크 : 255.255.255.0
      • 게이트웨이 : 192.168.0.1
      • DNS 서버 : 8.8.8.8(구글 DNS 서버)
    • [저장] 후 [완료]
  5. 설치 시작 & [설정 > 사용자 설정] ROOT 암호 설정

  6. 설치 완료 후 [재부팅]

5. SELinux 설정

쿠버네티스가 Pod Network에 필요한 호스트 파일 시스템에 액세스 가능하도록 하기 위해 하는 설정들이다.

특정 서비스들이 Selinux라는 보안을 강화해주는 보안 강화 커널 때문에 오류가 발생하는 경우가 존재하는데, 이런 경우를 없애기 위한 과정이다

SELinux를 permissive로 변경하는 설정 과정으로, SELinux를 끄는 과정이다.

참고로 여기서부터 XShell에서 수행시키면 더욱 편하다

수행해야 하는 CLI 명령들(순서대로 수행)

setenforce 0

  • SELinux 끔

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

  • SELinux는 보안 커널이기 때문에 재부팅하면 다시 SELinux가 켜진다. 쿠버네티스를 활용할 때 SELinux를 계속 껐다 켰다 하기엔 귀찮기 때문에, 리부팅을 시켜도 SELinux가 꺼져있게 하기 위하여 영구적으로 SELinux를 끄도록 설정하는 명령어이다.

  • /etc/selinux/config, 즉 SELinux에 대한 설정값들이 들어있는 파일에서 SELINUX의 Default Setting을 enforcing에서 permissive로 변경한다는 의미이다

sestatus

  • Current Mode:permissive로 나온다면 성공!

6. 방화벽 해제

나중에 우리는 calico.yaml 파일을 활용하는데, 여기에서 열어줘야 하는 포트가 몇 개 존재한다.

6443은 Kubernetes API Server를 위한 Port, 10250은 kubelet API를 위한 Port 등등이다.

나중에 실제 서비스를 제공할 때는 이런 Port 번호만 열여주는 형식으로 방화벽을 해제하겠으나, 지금은 어디까지나 "활용"해보는 단계이므로 그냥 모든 방화벽을 내려서 모든 Port를 활용 가능하게 만들어버리자

방화벽 및 NetworkManager 비활성화

  • systemctl stop firewalld && systemctl disable firewalld
    • 방화벽 비활성화
  • systemctl stop NetworkManager && systemctl disable NetworkManager
    • NetworkManager 비활성화

7. Swap 비활성화

Swap에 대한 고찰

Swap이 쿠버네티스에 필요한가를 알기 위해서는 먼저 Swap이 무엇인지부터 알 필요가 있다.
Swap은 RAM 용량이 부족할 때 하드 디스크 일부를 메모리처럼 활용하는 것이다.

RAM에 100개의 프로세스가 적재될 수 있는 경우, 101번째 프로세스가 들어온다고 가정하자.
Swap out은 100개의 적재된 프로세스 중 특정 프로세스가 Swap Partition으로 이동하는 Case, Swap in은 Swap Partition에 있는 프로세스에 이벤트가 와서 다시 메모리 영역으로 돌아오는 Case를 말한다.

먼저, 처음에 쿠버네티스에서 Swap을 고려하지 않았던 이유를 생각해보자.

쿠버네티스는 Pod를 생성할 때 "필요한 만큼의 리소스"를 할당 받을 수 있도록 설계되었다.

Swap 기능은 본래 허락된 메모리보다 더 큰 메모리 할당을 가능하게 하기 위한 기능이다.
하지만 쿠버네티스 자체가 "자원을 100% 활용하자!"라는 목표로 나왔고, 당연히 Pod는 "필요한 만큼의 리소스"를 받을 수 있다는 가정이 깔려있다. Swap 기능을 사용하는 순간 필요한 만큼의 리소스를 받지 못한다는 가정이 깔리기 때문에, 쿠버네티스의 목적에 맞지 않다고 생각하여 처음 kubelet은 이런 상황을 아예 고려하지 않도록 만들어졌다.

하지만, 위 사이트(Github Issues)에는 Swap에 대한 다양한 의견이 존재했다.
물론, 쿠버네티스는 자원을 모두 활용하는 것이 좋기 때문에 Swap이 발생하지 않는 것이 가장 좋다.
하지만, 위 사이트 중 "Deavid" 의견을 인용하자면, Host OS 자체 메모리가 작을 경우 Host 시스템의 안정성을 위해 Swap이 필요할 수도 있다고 주장한다.
즉, 쿠버네티스의 "자원을 최대한 활용하자"라는 목표에는 안 맞을 수도 있지만, "어떤 환경에서도 동작 가능하도록 만들자"라는 목표를 맞추기 위해서는 Swap 기능이 필요하다는 것이다.

Host OS 메모리가 작은데 이 Memory보다 큰 App을 실행시켜야 할 경우, 당연히 Host쪽에서는 OOM이 발생할 것이다.
Swap 기능이 존재한다면 이를 활용하여 최대한 OOM 문제를 피할 수 있겠으나, 존재하지 않는 쿠버네티스의 경우 OOM을 발생시킬 것이며, 이 OOM은 Host OS에 Critical한 문제(예를 들어 서버 다운)을 발생시킨다는 것이다.
이런 배포 환경에 대한 다양성을 고려하기 위해서 어느 정도 Swap 기능이 필요하다는 의견이였다.

이런 의견과 토론을 쿠버네티스측에서 보았는지 쿠버네티스 쪽에서도 Swap 기능을 활용할 수 있도록 Update를 진행한 것 같다.
하지만, 이런 제한적인 상황에서 활용되는 기능을 Main으로는 고려하지 않았는지 중요한 Update로 생각하지도 않은 것 같다.(일단 기능을 Update시키고 나중에 Docs를 배포하는 것을 보고 그렇게 생각이 들었다)

우리는 이런 제한적인 상황을 고려하지 않을 것이므로, Swap 설정을 끄자!
(사실 현업에서도 절대로 고려하지 않을 문제일거 같은게, 1개의 App Size가 크다면 Server가 될 컴퓨터 사양을 키워서 최소 1개 App은 돌아가도록 만들지 Swap 기능을 굳이 활용해서 꾸역꾸역 돌아가도록 만들지는 않을 것 같다)

Swap 비활성화

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

  • Swapoff를 통해 비활성화시키고, sed를 통해 Reboot시킬 때도 Swap이 비활성화되도록 설정했다(/etc/fstab 파일에서 swap에 관련된 내용을 모두 주석 처리함)

8. 기타 설정

iptables 커널 옵션 활성화

RHEL이나 CentOS7을 사용할 때 iptables가 무시되어 트래픽이 잘못 Routing되는 문제가 발생된다고 한다.
이를 해결하기 위한 설정 방법이다.

  • iptables : 리눅스에서 방화벽을 설정하는 도구
cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
  • k8s.conf라는 파일을 생성하는 명령어

    원래 net.bridge.bridge-nf-call-iptables 값의 Default가 0이라고 한다.
    이는 Bridge 네트워크를 통해 송수신되는 패킷이 iptables 설정을 우회한다는 의미라고 한다.
    Container의 네트워크 패킷이 Host OS의 iptables 설정에 따라 제어되는 것이 바람직한 상황이다.
    따라서, net.bridge.bridge-nf-call-iptables 값을 1로 설정하여 Bridge 네트워크를 통해 송수신되는 패킷도 iptables를 따르게 하고, 이는 IPv6 버전에서 활용되는 iptable인 ip6tables에도 똑같이 적용되도록 설정하는 것이다

sysctl --system

  • 모든 시스템 디렉토리의 값 읽기
  • Applying /etc/sysctl.d/k8s.conf가 존재하면 성공적으로 설정 된 것

쿠버네티스 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=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
  • /etc/yum.repos.d/kubernetes.repo 파일에 대한 설정을 해주는 과정

CentOS Update

yum update -y

Hosts 등록

cat << EOF >> /etc/hosts
192.168.0.30 k8s-master
192.168.0.31 k8s-node1
192.168.0.32 k8s-node2
EOF
  • Master 및 Node들에 대한 IP와 Hostname을 등록해주는 과정
  • 설정해주지 않을 경우 Host 이름으로 IP를 찾을 수 없다는 에러가 발생함
    • /etc/hosts : 현 컴퓨터의 호스트 이름 및 FQDN이 들어 있는 파일
    • 내가 설정한 Node들은 DNS에 등록되어 있는 IP 주소가 아니므로 직접 설정해주어 찾을 수 있도록 해줘야 한다

9. Docker 설치(순서대로 실행)

yum install -y yum-utils device-mapper-persistent-data lvm2

  • 도커 설치 전 필요한 패키지 설치
    • yum-utils, lvm2, device-mapper-persistent-data 설치

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

  • 도커 설치를 위한 저장소 설정

yum update -y && yum install -y docker-ce-18.06.2.ce

  • 도커 패키지 설치
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "60m"
  },
  "storage-driver": "overlay2",
  "storage-opts": [
    "overlay2.override_kernel_check=true"
  ]
}
EOF
  • /etc/docker 디렉토리 생성
  • /etc/docker/daemon.json 파일 생성 & 내용 추가

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

10. 쿠버네티스 설치

yum install -y --disableexcludes=kubernetes kubeadm-1.15.5-0.x86_64 kubectl-1.15.5-0.x86_64 kubelet-1.15.5-0.x86_64

11. Node들 생성

Master VM을 Clone하여 Node를 위한 VM 생성

shutdown now

  • Master를 복사하기 위해서는 먼저 Master가 꺼져 있어야 함

  • 이후 VirtualBox Master 마우스 오른쪽 클릭 \rightarrow [복제] 버튼 클릭

    • 이름 : k8s-node1(원하는 Node이름으로 설정하면 됨)
    • MAC 주소 정책 : 모든 네트워크 어댑터의 새 MAC 주소 생성
    • 복제 방식 : 완전한 복제

12. Node 설정 변경

  • 참고로, Master의 이름은 아무 설정 없었을 경우 root로 되었을 것이며, 비밀번호는 아까 위에서 설정했던 root 비밀번호 값 그대로 입력하면 된다

Network 변경

  • 여기서 중요한 점은, Master에서 Hosts를 등록했을 때 등록한 Node 이름 및 IP와 "동일"해야 한다는 점이다.
    아래서 설정한 값들은 해당 값을 통해 IP 주소나 Hostname을 검색하여 찾아오기 때문에 꼭 Master의 Hosts에 등록한 대로 값을 설정해줘야 한다!

Network 변경하기

vi /etc/sysconfig/network-scripts/ifcfg-enp0s3

이후 IPADDR=부분을 해당 Node의 IP로 변경해준다.
(ex) Node1을 변경할 경우, Node1은 192.168.0.31로 설정해야한다.
즉, IPADDR="192.168.0.31"로 변경한다

마지막으로, 네트워크를 재시작하여 변경한 설정값을 적용시킨다.
systemctl restart network

  • 이 과정은 Virtual Box에서 Terminal에 접근해 직접 입력해줘야 한다. 이 과정을 거치기 이전에는 Node들의 IP 주소가 모두 192.168.0.30으로 설정되어 있으므로 XShell이 접속하지 못한다

Hostname 변경하기

hostnamectl set-hostname k8s-node1

  • k8s-node1 대신 다른 이름으로 hosts를 설정하였을 경우, 설정한 값으로 입력해준다

  • 이후 XShell에서 접근 가능해진다

Master에서 실행하는 내용

13. 도커 및 쿠버네티스 실행

  • 먼저 Master Server의 VM을 실행시켜줘야 한다

도커 실행

systemctl daemon-reload
systemctl enable --now docker

도커 설치 확인

docker run hello-world

  • 중간에 Hello from Docker! 문구가 나오면 설치가 잘 된 것이다

쿠버네티스 실행

systemctl enable --now kubelet

14. 쿠버네티스 초기화 명령 실행

kubeadm init --pod-network-cidr=20.96.0.0/12 --apiserver-advertise-address=192.168.0.30

  • --pod-network-cidr : Pod Network IP

    • Pod Network IP의 주소역대는 항상 20으로 시작함
    • Service Network IP는 항상 10으로 시작
  • --apiserver-advertise-address : Master IP

  • 실행 이후 가장 아래에 kubeadm join ~이라는 문구가 뜰 텐데, 이 문구를 항상 잘 저장해 놓아야 한다

    • Master에 연결되는 Node를 추가시킬 때 사용하는 값

15. 환경변수 설정 및 kubectl 자동완성 기능 설치

환경변수 설정

root 계정을 이용하여 kubectl을 실행하기 위한 환경 변수를 설정하는 것이다
mkdir -p $HOME/.kube

  • $HOME/.kube 디렉토리 생성

sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

  • /etc/kubernetes/admin.conf에 쿠버네티스의 Master로써 실행시킬 수 있는 kubectl에 관한 설정이 들어있는데 이를 복사하여 $HOME/.kube/config에 옮겨줌으로써 root 계정에서도 kubectl을 실행시킬 수 있게 해주는 것이다

sudo chown $(id -u):$(id -g) $HOME/.kube/config

  • config파일의 권한 변경(-rw-------)

kubectl 자동완성 기능 설치

  • kubectl 이후 [tab]을 이용해서 다음에 올 명령어 리스트를 조회할 수 있게 하는 것

  • 필수 기능은 아님

  • 명령 실행 후 Server를 재시작해야 활용 가능

yum install bash-completion -y
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

Node에서 수행할 것

  • 모든 Node에서 아래 과정을 다 실행시켜줘야 함

16. 도커 및 쿠버네티스 실행

systemctl daemon-reload
systemctl enable --now docker
systemctl enable --now kubelet

17. Node 연결

Master Init 했을 때 복사한 값 붙여 넣기

  • My Case
    kubeadm join 192.168.0.30:6443 --token acmwi3.dhvx1d8h2hm9tmu8 --discovery-token-ca-cert-hash sha256:2114bb74a3594caa37b0f8d380b1e69b5db3c23c45be82b45db2c035513c22b0

Master에 가서 아래 명령어 입력

kubectl get nodes

  • 설정했던 node 및 master이름이 다 보이면 성공
    • 나의 경우 k8s-master, k8s-node1, k8s-node2가 다 보이므로 성공!
    • STATUS는 NotReady인 상태가 맞음

Master 가서 다시 실행

Calico 설치

curl -O https://docs.projectcalico.org/v3.9/manifests/calico.yaml

sed s/192.168.0.0\\/16/20.96.0.0\\/12/g -i calico.yaml

kubectl apply -f calico.yaml

kubectl get pods --all-namespaces

  • 시간이 좀 지난 이후, 모든 STATUS가 Running으로 바뀌면 성공!

Dashboard 설정

  • Dashboard를 보이게 하는 명령어

Dashboard 설치

kubectl apply -f https://kubetm.github.io/documents/appendix/kubetm-dashboard-v1.10.1.yaml

백그라운드로 Proxy 띄우기

nohup kubectl proxy --port=8001 --address=192.168.0.30 --accept-hosts='^*$' >/dev/null 2>&1 &

접속 URL

http://192.168.0.30:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

profile
개념부터 확실히!

0개의 댓글

관련 채용 정보