[kubernetes] 폐쇄망 환경에서 docker를 사용하지 않고 k8s 설치

김동완 (Joseph Kim)·2023년 5월 8일
0
post-thumbnail

포스팅 이유

폐쇄망 환경에서 kubernetes를 설치하여 사용하는 경우도 많이 있기 때문에 이런 상황을 가정하여 설치를 진행
docker

클러스터 정보

마스터 3대, 워커 1대 (CentOS8)
총 4개의 VM을 사용하여 구성
설치할 kubernetes 버전은 v1.19.4
컨테이너 런타임으로 CRI-O(v1.19.1)를 사용할 예정
전체 설치 과정은 모두 root 계정으로 진행

설치 방법

A. 사전 수행 절차

1. 방화벽, selinux, 스왑 메모리 끄기

모든 노드에서 작업을 수행해야 합니다.

우선 방화벽을 꺼줍니다.

systemctl stop firewalld
systemctl disable firewalld

이후 selinux 설정을 꺼줍니다.

setenforce 0

## selinux 비활성화 영구설정(SELINUX=disabled로 변경)
vi /etc/selinux/config
  ...
  SELINUX=disabled
  ...

마지막으로 스왑 메모리를 비활성화 합니다.

swapoff -a

## 스왑 메모리 비활성화 영구설정(swap부분 주석 처리)
vi /etc/fstab
  ...
  #/dev/mapper/cs-swap     none                    swap    defaults        0 0
  ...


2. local registry 구성

kubernetes 구성에 필요한 image를 가져올 local image registry를 구성합니다.

docker.io/library/registry 이미지를 미리 준비하여 예비 마스터 노드에 넣어줍니다.

registry의 가용성 보장을 위해서는 마스터 노드 세개에 local registry를 모두 구축하고
세개의 마스터 노드에 NAS를 mount하여 같은 디렉토리를 볼 수 있게 설정해주는 작업이 필요합니다.

가장 먼저 마스터로 사용할 노드 세개에 podman을 설치해줍니다.

## podman 설치
yum install -y podman

설치 후 /etc/containers/registries.conf에 insecure registry 등록을 해줍니다.

<<예시>>
[registries.insecure]
registries = ["<내부IP>:<PORT>"]
vi /etc/containers/registries.conf 
...
[registries.insecure]
registries = ["192.168.178.93:5000"]
...

이후 registry 이미지를 load하고 local registry를 띄웁니다.

## EX) podman run -it -d -p {내부망IP:PORT}:5000 --privileged -v {image 경로}:/var/lib/registry registry
podman run -it -d -p 192.168.178.93:5000:5000 --privileged -v /registry/supercloud-images:/var/lib/registry registry


(참고) local registry에 있는 이미지 조회하는 방법

  1. 이미지 리스트 조회

    <<예시>> curl -X GET <Repository URL:PORT/v2/_catalog>
    $ curl -X GET 192.168.178.93:5000/v2/_catalog
    {"repositories":["alpine","alpine/curl", ...]}
  2. 이미지 태그 조회

     <<예시>> curl -X GET <Repository URL:PORT/v2/<repository 이름>/tag/list>
     $ curl -X GET 192.168.178.93:5000/v2/alpine/curl/tags/list
     {"name":"alpine/curl","tags":["3.14"]}

3. 구축한 local registry에 kubernetes 설치 이미지 넣기

kubernetes v1.19.4 설치에 필요한 이미지들을 외부망이 되는 환경에서 tar 파일로 만들어 가져옵니다.

그리고 가져온 tar파일을 load합니다.

## image load
podman load -i kube-proxy.tar
podman load -i kube-apiserver.tar
podman load -i kube-controller-manager.tar
podman load -i kube-scheduler.tar
podman load -i etcd.tar
podman load -i coredns.tar
podman load -i pause.tar

이후 local registry 주소로 tag하여 local registry에 push 합니다.

## image tag
podman tag 192.168.178.93:5000/k8s.gcr.io/kube-proxy:v1.19.4
podman tag 192.168.178.93:5000/k8s.gcr.io/kube-apiserver:v1.19.4
podman tag 192.168.178.93:5000/k8s.gcr.io/kube-controller-manager:v1.19.4
podman tag 192.168.178.93:5000/k8s.gcr.io/kube-scheduler:v1.19.4
podman tag 192.168.178.93:5000/k8s.gcr.io/etcd:3.4.13-0
podman tag 192.168.178.93:5000/k8s.gcr.io/coredns:1.7.0
podman tag 192.168.178.93:5000/k8s.gcr.io/pause:3.2

## image push
podman push 192.168.178.93:5000/k8s.gcr.io/kube-proxy:v1.19.4
podman push 192.168.178.93:5000/k8s.gcr.io/kube-apiserver:v1.19.4
podman push 192.168.178.93:5000/k8s.gcr.io/kube-controller-manager:v1.19.4
podman push 192.168.178.93:5000/k8s.gcr.io/kube-scheduler:v1.19.4
podman push 192.168.178.93:5000/k8s.gcr.io/etcd:3.4.13-0
podman push 192.168.178.93:5000/k8s.gcr.io/coredns:1.7.0
podman push 192.168.178.93:5000/k8s.gcr.io/pause:3.2


B. kubernetes 설치

1. OS hostname 설정

예비 마스터 노드와 워커 노드의 hostname을 역할에 맞게 설정해줍니다.

## master01 노드
hostnamectl set-hostname master01

## master02 노드
hostnamectl set-hostname master02

## master03 노드
hostnamectl set-hostname master03

## worker01 노드
hostnamectl set-hostname worker01

모든 노드의 /etc/hosts 파일에 hostname과 ip를 등록합니다.

vi /etc/hosts

 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
 ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

 ## kubernetes node 
 192.168.178.93 master01
 192.168.178.107 master02
 192.168.178.108 master03
 192.168.178.109 worker01


2. runtime 설치 및 설정 (CRI-O)

runtime은 모든 노드에서 설치를 진행합니다.

CRI-O 사용 전 환경 설정을 합니다.

modprobe overlay
modprobe br_netfilter

cat << "EOF" | sudo tee -a /etc/sysctl.d/99-kubernetes-cri.conf
 net.bridge.bridge-nf-call-iptables  = 1
 net.ipv4.ip_forward                 = 1
 net.bridge.bridge-nf-call-ip6tables = 1
 EOF
 
sysctl --system

CRI-O(v1.19.1) 설치를 합니다.

## 폐쇄망용 file-repo를 설치했다고 가정하고 진행
yum install -y crio
systemctl enable crio
systemctl start crio

추후 설치 예정인 network plugin과 crio의 가상 인터페이스 충돌을 막기 위해 CRI-O의 default 인터페이스 설정을 제거합니다.

cd /etc/cni/net.d/
mkdir bck
mv 100-crio-bridge.conf  bck
mv 200-loopback.conf  bck
mv 87-podman-bridge.conflist  bck

crio.conf 내용을 수정합니다.

<<예시>>
  ...
  pause_image: "<local-regisrty 주소>:<PORT>/k8s.gcr.io/pause:3.2" # local-registry 정보 추가
  ...
  insecure_registry = ["<local-regisrty 주소>:<PORT>"] # 추가
  ...

vi /etc/crio/crio.conf
  ...
  pause_image: "192.168.178.93:5000/k8s.gcr.io/pause:3.2"
  ...
  insecure_registry = ["192.168.178.93:5000"]
  ...

위 작업이 끝나면 CRI-O를 재시작합니다.

systemctl restart crio


3. kubeadm, kubelet, kubectl 설치

예비 마스터 노드에서는 세개를 모두 설치하고 워커 노드에서는 kubeadm, kubelet 설치를 진행한다.
설치할 kubernetes에 맞는 rqm파일들을 외부망이 되는 환경에서 사전에 다운 받아 가져옵니다.

<< 준비할 rpm 리스트 >>
kubelet-1.19.4-0.x86_64.rpm
kubeadm-1.19.4-0.x86_64.rpm
kubectl-1.19.4-0.x86_64.rpm
cri-tools-1.19.0-0.x86_64.rpm
conntrack-tools-1.4.4-10.el8.x86_64.rpm
kubernetes-cni-0.8.7-0.x86_64.rpm
## master node
rpm -ivh --nodeps --force kubelet-1.19.4-0.x86_64.rpm
rpm -ivh --nodeps --force kubeadm-1.19.4-0.x86_64.rpm
rpm -ivh --nodeps --force kubectl-1.19.4-0.x86_64.rpm

## 아래 세개는 위 세개로 진행했을 경우 문제가 생기면 설치 후 다시 진행
rpm -ivh --nodeps --force cri-tools-1.19.0-0.x86_64.rpm
rpm -ivh --nodeps --force conntrack-tools-1.4.4-10.el8.x86_64.rpm
rpm -ivh --nodeps --force kubernetes-cni-0.8.7-0.x86_64.rpm

## worker node
rpm -ivh --nodeps --force kubelet-1.19.4-0.x86_64.rpm
rpm -ivh --nodeps --force kubeadm-1.19.4-0.x86_64.rpm

이후 keepalived를 설치하여 마스터 노드 세개를 하나의 ip로 묶어줍니다.

## keepalived 설치
yum install -y keepalived

## keepalived 설정
vi /etc/keepalived/keepalived.conf

vrrp_instance VI_1 {    
state {MASTER or BACKUP}   
interface {network interface}    
virtual_router_id {virtual router id}    
priority {priority}    
advert_int 1    
nopreempt    
authentication {        
	auth_type PASS        
	auth_pass {password}  
	}   
virtual_ipaddress {        
	{VIP}  
	} 
}

이후 kubeadm-config.yaml 파일을 작성합니다.

<<예시>>
 apiVersion: kubeadm.k8s.io/v1beta2
 kind: InitConfiguration
 localAPIEndpoint:
 	advertiseAddress: {api server IP}
 	bindPort: 6443
 nodeRegistration:
 	criSocket: /var/run/crio/crio.sock
 ---
 apiVersion: kubeadm.k8s.io/v1beta2
 kind: ClusterConfiguration
 kubernetesVersion: {k8s version}
 controlPlaneEndpoint: {endpoint IP}:6443
 imageRepository: {registry}/k8s.gcr.io
 networking:
 	serviceSubnet: {SERVICE_IP_POOL}/{CIDR}
 	podSubnet: {POD_IP_POOL}/{CIDR}
 ---
 apiVersion: kubelet.config.k8s.io/v1beta1
 kind: KubeletConfiguration
 cgroupDriver: systemd
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.178.93
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/crio/crio.sock
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: 1.19.4
controlPlaneEndpoint: 192.168.178.93:6443
imageRepository: 192.168.178.93:5000/k8s.gcr.io
networking:
  serviceSubnet: 10.96.0.0/16
  podSubnet: 10.244.0.0/16
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd



마무리

  1. 마스터와 워커가 여러개인 경우 마스터 노드를 한개씩 순차적으로 진행하고 이후 워커 노드들도 순차적으로 위 절차에 따라 진행하면 됩니다.

  2. 폐쇄망 환경의 경우 외부망 통신이 가능한곳에서 이미지 파일과 rpm파일을 다운받고 폐쇄망 환경으로 옮겨서 위 절차에 따라 진행하면 됩니다.

profile
Kubernetes / DevOps / Git / Network / AWS / Terraform / Opensource / Java / Springboot

0개의 댓글