Kubernetes (K8s) (2) — yum 설치로 Kubernetes 컨테이너 클러스터 관리 시스템 구축

본 문서에서는 yum 설치 방식을 사용하며, K8s 버전은 1.5.2입니다. 추후 업그레이드 및 다른 설치 방법에 대해서도 다루겠습니다.

(1). 설정 설명

노드 역할 IP 주소 CPU 메모리
master, etcd 192.168.128.110 4코어 2G
node1/minion1 192.168.128.111 4코어 2G
node2/minion2 192.168.128.112 4코어 2G

(2). Kubernetes 컨테이너 클러스터 관리 시스템 구축

1) 세 대의 호스트에 공통 소프트웨어 패키지 설치

# yum -y install bash-completion vim wget

bash-completion은 Tab 키 자동 완성을 지원하고, vim은 vi 편집기의 업그레이드 버전이며, wget은 Aliyun yum 저장소 파일을 다운로드하는 데 사용됩니다.

2) 세 대의 호스트에 Aliyun yum 저장소 설정

# mkdir /etc/yum.repos.d/backup
# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# yum clean all && yum list

3) hosts 파일 수정

[root@kube-master ~]# vim /etc/hosts
192.168.128.110 kube-master
192.168.128.110 etcd
192.168.128.111 kube-node1
192.168.128.112 kube-node2
[root@kube-master ~]# scp /etc/hosts 192.168.128.111:/etc/
[root@kube-master ~]# scp /etc/hosts 192.168.128.112:/etc/

4) master 및 etcd 노드에 구성 요소 설치 및 설정

먼저 master 노드에 K8s 구성 요소를 설치합니다.

[root@kube-master ~]# yum install -y kubernetes etcd flannel ntp

방화벽을 비활성화하거나 K8s 구성 요소의 포트를 엽니다. etcd 기본 포트는 2379이고, 웹 포트는 8080입니다.

[root@kube-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@kube-master ~]# firewall-cmd --permanent --zone=public --add-port={2379,8080}/tcp
success
[root@kube-master ~]# firewall-cmd --reload
success
[root@kube-master ~]# firewall-cmd --zone=public --list-ports 
2379/tcp 8080/tcp

etcd 설정 파일을 수정하고, 시작하여 상태를 확인합니다.

[root@kube-master ~]# vim /etc/etcd/etcd.conf
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"  # 데이터 저장 디렉토리
ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://192.168.128.110:2379"  # etcd 외부 서비스 수신 주소, 기본 포트 2379. 0.0.0.0으로 설정 시 모든 인터페이스 수신
ETCD_NAME="default"  # 노드 이름. 단일 노드 클러스터인 경우 주석 처리 가능, 기본값은 default
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.128.110:2379"  # 광고용 클라이언트 URL

[root@kube-master ~]# systemctl start etcd && systemctl enable etcd
Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /usr/lib/systemd/system/etcd.service.
[root@kube-master ~]# systemctl status etcd
● etcd.service - Etcd Server
   Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2020-01-14 14:02:31 CST; 11min ago
 Main PID: 12573 (etcd)
   CGroup: /system.slice/etcd.service
           └─12573 /usr/bin/etcd --name=default --data-dir=/var/lib/etcd/default.etcd --listen-client-urls=http://localhost:2379,http://192.168.128.110:2379

1月 14 14:02:31 kube-master etcd[12573]: raft.node: 8e9e05c52164694d elected leader 8e9e05c52164694d at term 2
1月 14 14:02:31 kube-master etcd[12573]: setting up the initial cluster version to 3.3
1月 14 14:02:31 kube-master etcd[12573]: set the initial cluster version to 3.3
1月 14 14:02:31 kube-master etcd[12573]: enabled capabilities for version 3.3
1月 14 14:02:31 kube-master etcd[12573]: published {Name:default ClientURLs:[http://192.168.128.110:2379]} to cluster cdf818194e3a8c32
1月 14 14:02:31 kube-master etcd[12573]: ready to serve client requests
1月 14 14:02:31 kube-master etcd[12573]: ready to serve client requests
1月 14 14:02:31 kube-master etcd[12573]: serving insecure client requests on 192.168.128.110:2379, this is strongly discouraged!
1月 14 14:02:31 kube-master etcd[12573]: serving insecure client requests on 127.0.0.1:2379, this is strongly discouraged!
1月 14 14:02:31 kube-master systemd[1]: Started Etcd Server.

[root@kube-master ~]# yum -y install net-tools
[root@kube-master ~]# netstat -antup | grep 2379
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      12573/etcd          
tcp        0      0 192.168.128.110:2379    0.0.0.0:*               LISTEN      12573/etcd          
tcp        0      0 192.168.128.110:2379    192.168.128.110:49240   ESTABLISHED 12573/etcd          
tcp        0      0 127.0.0.1:2379          127.0.0.1:35638         ESTABLISHED 12573/etcd          
tcp        0      0 192.168.128.110:49240   192.168.128.110:2379    ESTABLISHED 12573/etcd          
tcp        0      0 127.0.0.1:35638         127.0.0.1:2379          ESTABLISHED 12573/etcd 

[root@kube-master ~]# etcdctl cluster-health
member 8e9e05c52164694d is healthy: got healthy result from http://192.168.128.110:2379
cluster is healthy

[root@kube-master ~]# etcdctl member list
8e9e05c52164694d: name=default peerURLs=http://localhost:2380 clientURLs=http://192.168.128.110:2379 isLeader=true

master의 공통 설정 파일을 수정합니다.

[root@kube-master ~]# vim /etc/kubernetes/config
KUBE_LOGTOSTDERR="--logtostderr=true"  # 오류 로그를 표준 오류 출력(stderr)으로 보낼지 여부. false이면 파일에 기록
KUBE_LOG_LEVEL="--v=0"  # 로그 레벨
KUBE_ALLOW_PRIV="--allow-privileged=false"  # 권한이 있는 컨테이너 실행 허용 여부. false는 허용하지 않음
KUBE_MASTER="--master=http://192.168.128.110:8080"  # 마스터 URL

API Server 설정 파일을 수정합니다.

[root@kube-master ~]# vim /etc/kubernetes/apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"  # API Server가 모든 IP에서 수신 대기
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.128.110:2379"  # etcd 저장소 주소
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"  # Pod 및 Service에 할당할 IP 주소 범위
# 기본 허용 모듈: NamespaceLifecycle, NamespaceExists, LimitRanger, SecurityContextDeny, ServiceAccount, ResourceQuota
KUBE_ADMISSION_CONTROL="--admission-control=AlwaysAdmit"  # 접근 제어 플러그인, 제한 없음
KUBE_API_ARGS=""  # 추가 API Server 인자

Controller Manager 설정 파일은 기본값을 사용하므로 수정이 필요하지 않습니다.

[root@kube-master ~]# vim /etc/kubernetes/controller-manager
KUBE_CONTROLLER_MANAGER_ARGS=""
[root@kube-master ~]# rpm -qf /etc/kubernetes/controller-manager
kubernetes-master-1.5.2-0.7.git269f928.el7.x86_64

Scheduler 설정 파일을 수정합니다.

[root@kube-master ~]# vim /etc/kubernetes/scheduler
KUBE_SCHEDULER_ARGS="--address=0.0.0.0"

flanneld(오버레이 네트워크) 설정 파일을 수정합니다.

[root@kube-master ~]# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.128.110:2379"  # etcd 저장소 주소
FLANNEL_ETCD_PREFIX="/k8s/network"  # etcd 내 설정 저장 경로
FLANNEL_OPTIONS="--iface=ens33"  # 통신에 사용할 물리적 네트워크 인터페이스

[root@kube-master ~]# mkdir -p /k8s/network
[root@kube-master ~]# etcdctl set /k8s/network/config '{"Network":"10.255.0.0/16"}'  # IP 범위 설정
{"Network":"10.255.0.0/16"}

[root@kube-master ~]# etcdctl get /k8s/network/config  # 노드의 flanneld가 Docker IP 주소를 자동으로 가져옴
{"Network":"10.255.0.0/16"}

[root@kube-master ~]# systemctl start flanneld && systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.
Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.

[root@kube-master ~]# ip a sh  # flannel0 인터페이스 확인
3: flannel0:  mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 10.255.29.0/16 scope global flannel0
       valid_lft forever preferred_lft forever
    inet6 fe80::723e:875f:5995:76d0/64 scope link flags 800 
       valid_lft forever preferred_lft forever

Master에서 API Server, Controller Manager 및 Scheduler를 재시작하고, 부팅 시 자동 시작하도록 설정합니다.

[root@kube-master ~]# systemctl restart kube-apiserver kube-controller-manager kube-scheduler
[root@kube-master ~]# systemctl enable kube-apiserver kube-controller-manager kube-scheduler 
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-apiserver.service to /usr/lib/systemd/system/kube-apiserver.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-controller-manager.service to /usr/lib/systemd/system/kube-controller-manager.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-scheduler.service to /usr/lib/systemd/system/kube-scheduler.service.

5) node1/minion1 노드에 구성 요소 설치 및 설정

먼저 node1/minion1 노드에 K8s 구성 요소를 설치합니다.

[root@kube-node1 ~]# yum -y install kubernetes flannel ntp

방화벽을 비활성화하거나 K8s 구성 요소의 포트를 엽니다. kube-proxy 기본 포트는 10249, kubelet 기본 포트는 10248, 10250, 10255입니다.

[root@kube-node1 ~]# 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.

네트워크를 flanneld(오버레이 네트워크)로 설정한 후, flanneld를 재시작하고 부팅 시 자동 시작하도록 설정합니다.

[root@kube-node1 ~]# vim /etc/sysconfig/flanneld
FLANNEL_ETCD_ENDPOINTS="http://192.168.128.110:2379"  # etcd 저장소 주소
FLANNEL_ETCD_PREFIX="/k8s/network"  # etcd 내 설정 저장 경로
FLANNEL_OPTIONS="--iface=ens33"  # 통신에 사용할 물리적 네트워크 인터페이스

[root@kube-node1 ~]# systemctl restart flanneld && systemctl enable flanneld
Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.
Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.

K8s 공통 설정을 수정합니다.

[root@kube-node1 ~]# vim /etc/kubernetes/config
KUBE_MASTER="--master=http://192.168.128.110:8080"  # master 노드 주소

kube-proxy 설정을 확인합니다. 기본적으로 모든 IP를 수신 대기하므로 수정이 필요하지 않습니다.

[root@kube-node1 ~]# grep -v '^#' /etc/kubernetes/proxy
KUBE_PROXY_ARGS=""  # 기본적으로 모든 IP 수신

kubelet 설정 파일을 수정합니다. KUBELET_POD_INFRA_CONTAINER는 Pod 기본 이미지 주소를 지정합니다. 각 Pod가 시작될 때 이 이미지로 컨테이너를 생성하며, 로컬에 이미지가 없으면 kubelet이 외부 네트워크를 통해 다운로드합니다.

[root@kube-node1 ~]# vim /etc/kubernetes/kubelet
KUBELET_ADDRESS="--address=0.0.0.0"  # 모든 IP 수신, kubectl로 kubelet에 원격 연결하여 Pod 및 컨테이너 상태 확인
KUBELET_HOSTNAME="--hostname-override=kube-node1"  # 호스트 이름으로 변경하여 속도 향상
KUBELET_API_SERVER="--api-servers=http://192.168.128.110:8080"  # API Server 주소
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"  # Pod 기본 이미지 주소
KUBELET_ARGS=""  # 추가 kubelet 인자

kube-proxy, kubelet 및 docker를 재시작하고, 부팅 시 자동 시작하도록 설정합니다.

[root@kube-node1 ~]# systemctl restart kube-proxy kubelet docker
[root@kube-node1 ~]# systemctl enable kube-proxy kubelet docker
Created symlink from /etc/systemd/system/multi-user.target.wants/kube-proxy.service to /usr/lib/systemd/system/kube-proxy.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /usr/lib/systemd/system/kubelet.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/docker.service to /usr/lib/systemd/system/docker.service.

설정 상태를 확인합니다.

[root@kube-node1 ~]# ip a sh
3: flannel0:  mtu 1472 qdisc pfifo_fast state UNKNOWN group default qlen 500
    link/none 
    inet 10.255.42.0/16 scope global flannel0
       valid_lft forever preferred_lft forever
    inet6 fe80::a721:7a65:54ea:c2b/64 scope link flags 800 
       valid_lft forever preferred_lft forever
4: docker0:  mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:5c:5b:ae:8c brd ff:ff:ff:ff:ff:ff
    inet 10.255.42.1/24 scope global docker0
       valid_lft forever preferred_lft forever

[root@kube-node1 ~]# yum -y install net-tools
[root@kube-node1 ~]# netstat -antup | grep proxy
tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      1473/kube-proxy     
tcp        0      0 192.168.128.111:55342   192.168.128.110:8080    ESTABLISHED 1473/kube-proxy     
tcp        0      0 192.168.128.111:55344   192.168.128.110:8080    ESTABLISHED 1473/kube-proxy

[root@kube-node1 ~]# netstat -antup | grep kubelet
tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      1698/kubelet        
tcp        0      0 192.168.128.111:55350   192.168.128.110:8080    ESTABLISHED 1698/kubelet        
tcp        0      0 192.168.128.111:55351   192.168.128.110:8080    ESTABLISHED 1698/kubelet        
tcp        0      0 192.168.128.111:55354   192.168.128.110:8080    ESTABLISHED 1698/kubelet        
tcp        0      0 192.168.128.111:55356   192.168.128.110:8080    ESTABLISHED 1698/kubelet        
tcp6       0      0 :::4194                 :::*                    LISTEN      1698/kubelet        
tcp6       0      0 :::10250                :::*                    LISTEN      1698/kubelet        
tcp6       0      0 :::10255                :::*                    LISTEN

6) node2/minion2 노드에 구성 요소 설치 및 설정

node1/minion1에서 수행한 작업을 node2/minion2에서 반복합니다.

7) 테스트: Master 노드에서 전체 클러스터 상태 확인

[root@kube-master ~]# kubectl get nodes
NAME         STATUS    AGE
kube-node1   Ready     1h
kube-node2   Ready     2m

이것으로 K8s 컨테이너 클러스터 관리 시스템이 구축되었습니다. 현재는 웹 페이지를 통한 관리는 지원되지 않으며, kubectl 명령어로만 관리할 수 있습니다.

(3). 확장: flannel

flannel은 K8s에서 기본적으로 제공하는 네트워크 플러그인입니다. CoreOS 팀이 개발한 flannel은 L3 오버레이(Overlay) 모드를 사용하며, 각 호스트의 Pod가 동일한 서브넷에 속하고, 서로 다른 호스트의 Pod는 다른 서브넷에 속하도록 설계되었습니다.

flannel은 각 호스트에서 flanneld 에이전트를 실행하며, 이 에이전트는 호스트에 서브넷을 미리 할당하고 Pod에 IP 주소를 할당합니다. flannel은 Kubernetes 또는 etcd를 사용하여 네트워크 구성, 할당된 서브넷, 호스트 공용 IP 등의 정보를 저장합니다. 데이터 패킷은 VXLAN, UDP 또는 host-gw와 같은 백엔드 메커니즘을 통해 전달됩니다.

Kubernetes에서 flannel의 전체 실행 과정을 살펴보겠습니다.

flannel 동작 과정

태그: kubernetes k8s yum 설치 클러스터

7월 25일 04:36에 게시됨