폐쇄망 환경에서 kubernetes를 설치하여 사용하는 경우도 많이 있기 때문에 이런 상황을 가정하여 설치를 진행
docker
클러스터 정보
마스터 3대, 워커 1대 (CentOS8)
총 4개의 VM을 사용하여 구성
설치할 kubernetes 버전은 v1.19.4
컨테이너 런타임으로 CRI-O(v1.19.1)를 사용할 예정
전체 설치 과정은 모두 root 계정으로 진행
모든 노드에서 작업을 수행해야 합니다.
우선 방화벽을 꺼줍니다.
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
...
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
이미지 리스트 조회
<<예시>> curl -X GET <Repository URL:PORT/v2/_catalog>
$ curl -X GET 192.168.178.93:5000/v2/_catalog
{"repositories":["alpine","alpine/curl", ...]}
이미지 태그 조회
<<예시>> 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"]}
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
예비 마스터 노드와 워커 노드의 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
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
예비 마스터 노드에서는 세개를 모두 설치하고 워커 노드에서는 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
마스터와 워커가 여러개인 경우 마스터 노드를 한개씩 순차적으로 진행하고 이후 워커 노드들도 순차적으로 위 절차에 따라 진행하면 됩니다.
폐쇄망 환경의 경우 외부망 통신이 가능한곳에서 이미지 파일과 rpm파일을 다운받고 폐쇄망 환경으로 옮겨서 위 절차에 따라 진행하면 됩니다.