Kafka #2. 설치

Zookeeper #1. 개요
Zookeeper #2. 설치와 설정
Zookeeper #3. 구동과 확인

Kafka #1. 개요
Kafka #2. 설치

Kafka 클러스터 구축을 위해서는 zookeeper 가 필요하다. 일반적으로 kafka 클러스터 구축은 3개 이상의 broker를 가지는데 이 ‘세 개 이상의 broker가 하나처럼 동작하기 위한 정보는 zookeeper가 관리’하기 때문에다.

기본적으로 프로듀서 혹은 컨슈머는 카프카에 연결할 때 직접 카프카 브로커에 연결하는 것이 아니라 주키퍼에 연결하여 카프카 브로커, 토픽, 파티션 등의 정보를 취득한 뒤 브로커에 연결하게 된다.1실제 카프카 연결 시 연결 옵션으로 브로커의 정보만 입력하더라도 주키퍼에 연결한 뒤 다시 브로커에 연결된다.

Zookeeper 설치

zoookeeper 설치는 zookeeper #1. 개요, #2. 설치와 설정, #3. 구동과 확인 포스트를 참고하면 된다.

다운로드 및 압축 해제

  • Apache kafka 공식 페이지에서 바이너리를 다운로드 한다.
  • 다운로드한 파일을 FTP 또는 SFTP등을 이용하여 서버에 업로드한다.
  • 또는 wget 명령을 이용하여 서버에서 다운로드 한다

설정

카프카 클러스터의 설정을 위해서는 ‘zookeeper’ 클러스터가 존재하는 상태에서 $KAFKA_HOME/config/server.config 파일에 기재된 설정만 잘 조절해주면 된다.

############################# Server Basics #############################
# 브로커 고유 ID. 각각의 브로커는 중복되지 않은 고유한 숫자 값을 가진다. 
broker.id=1

############################# Socket Server Settings #############################
# Broker 가 사용하는 호스트와 포트
listeners=PLAINTEXT://dist01.haedongg.net:9092

# Producer와 Consumer가 접근하는 호스트와 포트
# 다음의 연결 옵션을 제공한다 -PLAINTEXT:PLAINTEXT,SSL:SSL,SASL_PLAINTEXT:SASL_PLAINTEXT,SASL_SSL:SASL_SSL
advertised.listeners=PLAINTEXT://dist01.haedongg.net:9092

# 네트워크 요청 처리 스레드
num.network.threads=3

# IO 발생 시 생기는 스레드 수
num.io.threads=8

# 소켓 서버가 사용하는 송수신 버퍼
socket.send.buffer.bytes=1024000
socket.receive.buffer.bytes=1024000

# The maximum size of a request that the socket server will accept (protection against OOM)
socket.request.max.bytes=104857600

############################# Log Basics #############################
# Broker가 받은 데이터 관리를 위한 저장 공간
log.dirs=/home/kafka/data

# 여러 개의 디스크, 여러 개의 디렉토리를 사용하는 경우 콤마로 구분하여 추가한다.
# log.dirs=/home/kafka/data,/mnt/sdb1/kafka/data,/third_disk/mq-data

# 토픽 당 파티션의 수. 값 만큼 병렬 처리 가능하고, 파일 수도 늘어난다.
# 기본 값으로써 토픽을 생성할 때 파티션 숫자를 지정할 수 있고, 변경도 가능하다.
num.partitions=1

# The number of threads per data directory to be used for log recovery at startup and flushing at shutdown.
# This value is recommended to be increased for installations with data dirs located in RAID array.
num.recovery.threads.per.data.dir=1

############################# Internal Topic Settings #############################
# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state" 
# For anything other than development testing, a value greater than 1 is recommended to ensure availability such as 3.

# 토픽에 설정된 replication의 인수가 지정한 값보다 크면 새로운 토픽을 생성하고 작을 경우 브로커의 숫자와 같게 된다.
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1

############################# Log Flush Policy #############################
# The number of messages to accept before forcing a flush of data to disk
#log.flush.interval.messages=10000

# The maximum amount of time a message can sit in a log before we force a flush
#log.flush.interval.ms=1000

############################# Log Retention Policy #############################
# 수집 데이터 파일 삭제 주기. (시간, 168h=7days)
# 실제 수신된 메시지의 보존 기간을 의미한다. 
log.retention.hours=168

# A size-based retention policy for logs. Segments are pruned from the log unless the remaining
# segments drop below log.retention.bytes. Functions independently of log.retention.hours.
#log.retention.bytes=1073741824

# 토픽별 수집 데이터 보관 파일의 크기. 파일 크기를 초과하면 새로운 파일이 생성 된다. 
log.segment.bytes=1073741824

# 수집 데이터 파일 삭제 여부 확인 주기 (밀리초, 300000ms=5min)
log.retention.check.interval.ms=300000

# 삭제 대상 수집 데이터 파일의 처리 방법. (delete=삭제, compact=불필요 내용만 제거)
log.cleanup.policy=delete

# 수집 데이터 파일 삭제를 위한 스레드 수
log.cleaner.threads=1

############################# Zookeeper #############################
# zookeeper 정보.
# zookeeper 클러스터 모두 콤마(,)로 구분해서 기재한다.
zookeeper.connect=dist01.haedongg.net:2181,dist02.haedongg.net:2181,dist03.haedongg.net:2181

# Timeout in ms for connecting to zookeeper
zookeeper.connection.timeout.ms=6000

############################# Group Coordinator Settings #############################
# 초기 GroupCoordinator 재조정 지연 시간 (밀리초) 
# 운영환경에서는 3초를 권장 
group.initial.rebalance.delay.ms=3000

############################# 기타 ################################
# 최대 메시지 크기 (byte) 
# 예시는 15MB 까지의 메시지를 수신할 수 있다.
message.max.bytes=15728640

구동 및 확인

Kafka broker 구동을 위해서는 JAVA가 필요하다. JDK가 설치되어있고 환경변수($JAVA_HOME 및 $PATH)가 설정되어 있다면 별도의 설정 없이 카프카 브로커를 구동할 수 있다. 만약 JDK가 설치되어있지 않거나, 별도의 JAVA를 사용하고자 한다면 export 명령을 이용하여 변수를 선언하거나, $KAFKA_HOME/bin/kafka-run-class.sh 파일에 JAVA관련 변수를 넣어주도록 한다.

# Memory options
# 다음 $JAVA_HOME 관련 옵션을 적절히 수정한다.
# JAVA_HOME=/WHERE/YOU/INSTALLED/JAVA 이렇게 JAVA_HOME 변수를 지정하면 된다. 
# 만약 JAVA_HOME 변수가 선언되지 않았다면  PATH에 등록된 경로에서 java 명령을 찾게 된다. 
if [ -z "$JAVA_HOME" ]; then
  JAVA="java"
else
  JAVA="$JAVA_HOME/bin/java"
fi

# Memory options
# 카프카 구동을 위한 java heap memory 옵션
if [ -z "$KAFKA_HEAP_OPTS" ]; then
#  KAFKA_HEAP_OPTS="-Xmx256M"   이 값이 기본
  KAFKA_HEAP_OPTS="-Xms256M -Xmx1G"
fi

broker 실행

  • broker로 구동할 모든 Kafka 서버에서 수행한다.
$KAFKA_HOME/kafka-server-start.sh -daemon $KAFKA_HOME/config/server.properties
ex) /home/apps/kafka/bin/kafka-server-start.sh -daemon /home/apps/kafka/config/server.properties
# 만약 -daemon 옵션을 추가하지 않으면 브로커가 background가 아닌 foreground에서 구동된다.
  • 프로세스 및 리슨 포트 확인
jps -l

18320 kafka.Kafka
18403 sun.tools.jps.Jps
17899 org.apache.zookeeper.server.quorum.QuorumPeerMain

netstat -nltp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      973/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1286/master
tcp6       0      0 :::8080                 :::*                    LISTEN      17899/java
tcp6       0      0 :::40434                :::*                    LISTEN      17899/java
tcp6       0      0 :::22                   :::*                    LISTEN      973/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      1286/master
tcp6       0      0 :::34880                :::*                    LISTEN      18320/java
tcp6       0      0 :::9092                 :::*                    LISTEN      18320/java
tcp6       0      0 :::2181                 :::*                    LISTEN      17899/java
  • 종료
$KAFKA_HOME/bin/kafka-server-stop.sh

 

 

 

Kafka #1. 개요

Zookeeper #1. 개요
Zookeeper #2. 설치와 설정
Zookeeper #3. 구동과 확인

Kafka #1. 개요
Kafka #2. 설치

아파치 카프카(Apache Kafka)는 아파치 소프트웨어 재단이 스칼라로 개발한 오픈 소스 메시지 브로커 프로젝트이다. 이 프로젝트는 실시간 데이터 피드를 관리하기 위해 통일된, 높은 처리량, 낮은 지연시간을 지닌 플랫폼을 제공하는 것이 목표이다. 요컨대 분산 트랜잭션 로그로 구성된, 상당히 확장 가능한 pub/sub 메시지 큐로 정의할 수 있으며, 스트리밍 데이터를 처리하기 위한 기업 인프라를 위한 고부가 가치 기능이다.

큐 (Queue)

먼저 큐에 대한 이해가 필요한데, 말 그대로 ‘기다리는 줄(열)’, ‘대기 열’을 생각하면 된다. 전공자라면 자료구조, 알고리즘 과목 등에서 접하게 되는데 Stack 과 함께 배운다.
FIFO1First In First Out 구멍이 두 개인 파이프의 한쪽에 동전을 넣는다고 생각하면 된다. 계속 동전을 밀어 넣다 보면 가장 먼저 넣었던 동전부터 동전이 밀려나오는 구조가 된다.
이와 반되 되는 것이 Stack. 쌓는다는 의미의 stack으로 FILO2First In Last Out 컵에 동전을 쌓는 것을 상상하면 된다. 컵에 동전을 쌓아 넣다다가 동전을 꺼내면 나중에 넣었던 동전을 먼저 꺼내야 한다.

 

Message Queue

이렇게 먼저 넣은 값이 먼저 출력되는 구조를 이용해 메시지3여기서 말하는 메시지는 특별한 개념이 아니다. 송/수신되는 데이터를 종류, 형태와 상관 없이 통틀어 메시지라고 칭하는 것이다. 이 메시지는 단순한 텍스트일 수도 있고, 파일일 수도 있고 다양하다.를 전송하는 것이 Message Queue이다. Rabbit MQ, IBM MQ, Apache active MQ , Rocket MQ 등 다양한 종류의 Message Queue가 존재한다.
기본적인 개념은 모두 같지만 메시지를 주고 받는 방식에 따라 크게 두 종류로 구분할 수 있다.
– Push : 서버가 메시지를 클라이언트에 보내주는 방식
– Pull : 클라이언트가 메시지를 서버에서 가져오는 방식

별것 아닌 것 같지만 Pull 과 Push는 큰 차이를 가진다.

종류PushPull
장점· 메시지 발생 즉시 클라이언트에 전달· 필요한 클라이언트만 메시지를 가져가므로 서버 부하 감소
· 네트워크 부하 감소
단점· 서버가 모든 클라이언트에 연결해야 하므로 서버 부하 증가· 메시지를 전달한 클라이언트 확인 불가
주 용도카카오톡 등 메시지, 알림 전달분석용 서버 로그 데이터 등
Push 방식과 Pull 방식 비교

 

Apache Kafka

Apache Kafka는 Pull 방식의 Message Queue이다.
중요한 개념으로 메시지를 발생 시키는 (또는 서버의 Queue에 메시지를 보내는) Producer(또는 Publisher)와 메시지를 가져가는 Consumer(또는 subscriber)가 있다.4실제 이 프로듀서와 컨슈머는 추상적인 개념으로만 존재하며 Kafka 자체를 칭하지는 않고 Kafka를 구성하는 구성요소는 아니다!!

일반적인 개념에서 Kafka는 Broker를 의미한다.

즉, 누군가 메시지를 보내는 곳, 누군가 메시지를 꺼내갈 곳이 Kafka 이다. 5물론 kafka connect, mirror-maker 등 카프카가 직접 메시지를 읽어오는 개념이 존재하긴 하다. 하지만, 어쨌거나 프로듀서, 컨슈머 등을 이야기하는 개념에서의 kafka는 broker 를 떠올리면 된다.

이 Kafka Broker가 하는 일과 핵심적인 개념은 다음과 같다.

  • Queue : 가장 핵심적인 기능이다. 수신된 메시지를 저장한다. kafka가 인지하는 형식으로 디스크에 저장된다.
  • Offset 관리 : 프로듀서가 보낸 메시지와 컨슈머가 가져간 메시지의 offset, 즉, 몇 개의 메시지가 수신되었고 어떤 클라이언트가 어디서부터 어디까지의 메시지를 가져갔는지 기억하고 관리한다.
  • Topic : Topic은 앞서 설명한 메시지를 담는 파이프 하나를 떠올리면 된다. 메시지를 넣을 파이프를 만들고 이름을 붙여서 관리한다. 이 Topic은 여러개의 Pratition으로 나뉠 수 있다.
  • Replica : 데이터의 복제, Broker나 디스크의 장애 등에 대비해 데이터를 복제하는 기능이다.

 

Public cloud에서

AWS : MKS(Managed Kafka Service)
GCP : Pub/Sub (Publisher와 Subscriber)
AZURE: HDInsight Kafka

 

 

 

 

 

Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

Worker node cluster join

Dockerkubernetes 구성 요소를 설치한 뒤 이전 포스트에서 cluster 초기화 시 생성된 스크립트를 실행하면 worker node로써 설정이 된다.

kubeadm join 192.168.4.78:6443 --token abcdefg.8rpr4mfmetbabcde --discovery-token-ca-cert-hash sha256:3a12345caaef12334567890cd3953d1234c3904ab70a8b949f32d6df12345

[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

worker 노드에서도 kubernetes config 관련 명령을 수행해주면 kubectl 명령을 이용할 수 있다.

kubectl get nodes

NAME       STATUS     ROLES                  AGE    VERSION
centos7    NotReady   control-plane,master   104s   v1.23.5
centos71   NotReady   <none>                 36s    v1.23.5

master node 설정 후 확인한 것과 같이 STAUS는 NotReady 상태로 표시된다. 이는 kubernetes 네트워크 관련 배포가 필요한 것으로 이후 관련 인스턴스를 배포하면 Ready 상태로 표시된다.

 

cluster 생성 후 24시간 경과 시

kubeadm init 수행 시 생성된 join 스크립트의 token은 24시간의 만료 시간을 가진다. 즉 24시간이 지나면 생성된 join script, 정확히 말하자면 token이 만료되어 사용이 불가능하다.

따라서 24시간 이후에는 갱신된 token을 확인하고 새 token을 이용한 join 스크립트를 사용해야 한다.

  • token 확인: TTL(Time To Live) 값을 보면 22h시간 사용가능함을 알 수 있다.
kubeadm token list
TOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS
abcdef.2zha2oqwp12abcd1   22h         2022-04-08T00:46:45Z   authentication,signing   The default bootstrap token generated by 'kubeadm init'.   system:bootstrappers:kubeadm:default-node-token
  • 해당 token에 해당하는 sha256 값 확인
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
871c73bfcb0d0421f029faa7ba07201abf4f00abcdefghijklmnopqrstuvwxyz
  • 확인된 token, 과 sha256 값을 이용하여 join 명령을 수행한다.
kubeadm join 192.168.4.78:6443 --token abcdef.2zha2oqwp12abcd1 --discovery-token-ca-cert-hash sha256:871c73bfcb0d0421f029faa7ba07201abf4f00abcdefghijklmnopqrstuvwxyz

 

 

 

Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 클러스터 생성 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

kubeadm init

sudo kubeadm init –apiserver-advertise-address $MASTER_NODE_IP_ADDRESS –pod-network-cidr=10.244.0.0/16
명령을 수행하면 설치가 시작된다.
–apiserver-advertise-address : 마스터노드 IP
–pod-network-cidr : pod간 통신을 위한 내부 네트워크 CIDR 1사이더(Classless Inter-Domain Routing, CIDR)는 클래스 없는 도메인 간 라우팅 기법으로 1993년 도입되기 시작한, 최신의 IP 주소 할당 방법이다. 사이더는 기존의 IP 주소 할당 방식이었던 네트워크 클래스를 대체하였다. 사이더는 IP 주소의 영역을 여러 네트워크 영역으로 나눌 때 기존방식에 비해 유연성을 더해준다. 특히 다음과 같은 장점이 있다.
급격히 부족해지는 IPv4 주소를 보다 효율적으로 사용하게 해준다.
접두어를 이용한 주소 지정 방식을 가지는 계층적 구조를 사용함으로써 인터넷 광역 라우팅의 부담을 줄여준다.

sudo    kubeadm   init   --apiserver-advertise-address $MASTER_NODE_IP_ADDRESS --pod-network-cidr=10.244.0.0/16

...전략...
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.192.168:6443 --token abcdefg.8rpr4mfmetbabcde --discovery-token-ca-cert-hash sha256:3a12345caaef12334567890cd3953d1234c3904ab70a8b949f32d6df12345
  • /etc/kubernetes/admin.conf 에는 마스터노드의 kube-proxy 관련 정보가 들어있다. mkdir 부터 시작하는 명령을 수행해줘야 kubectl 명령을 사용할 수 있다.
  • 마지막 kubeadm join 명령은 worker 노드를 추가하기 위한 명령이다. worker 노드가 될 서버에kubernetes 관련 패키지(kueadm,kubectl,kubelet 및 image 등)를 설치한 뒤 수행해주면 worker 노드로 클러스터의 멤버가 된다. token 관련 값은 24시간의 유효시간이 있으므로 나중에 클러스터 멤버로 join 하려면 새로 새로 발행해야 한다.

확인

init 스크립트가 완료되고 kubernetes config 관련 설정을 마쳤다면 kubectl 명령을 사용할 수 있다. 다음 명령을 통해 상태를 확인한다.

kubectl get nodes
NAME      STATUS     ROLES                  AGE   VERSION
centos7   NotReady   control-plane,master   20s   v1.23.5

현재 노드의 status 가 NotReady로 나오지만 정상적으로 설정 된 것이다.

Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

이전 포스트에서 설치한 kubeadm을 위해 클러스터를 생성할 때 필요한 몇 가지 이미지가 존재한다. 폐쇄망 환경에서는 해당 이미지를 가져올 수 없기 때문에 외부 네트워크 연결이 가능한 환경에서 이미지를 가져온(pull) 다음 클러스터를 생성할 곳에 넣어주는(push) 과정이 필요하다.

Image pull

  • image pull 외부 네트워크 연결이 가능한 환경에서 수행한다.
kubeadm config images pull
[config/images] Pulled k8s.gcr.io/kube-apiserver:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-scheduler:v1.23.5
[config/images] Pulled k8s.gcr.io/kube-proxy:v1.23.5
[config/images] Pulled k8s.gcr.io/pause:3.6
[config/images] Pulled k8s.gcr.io/etcd:3.5.1-0
[config/images] Pulled k8s.gcr.io/coredns/coredns:v1.8.6
  • 이미지 저장 위의 7개 이미지를 export하여 압축파일로 저장한다. (별도의 결과 메시지는 출력되지 않는다)
docker image save k8s.gcr.io/kube-apiserver:v1.23.5             > kube-apiserver.tgz
docker image save k8s.gcr.io/kube-controller-manager:v1.23.5    > kube-controller-manager.tgz
docker image save k8s.gcr.io/kube-scheduler:v1.23.5             > kube-scheduler.tgz         
docker image save k8s.gcr.io/kube-proxy:v1.23.5                 > kube-proxy.tgz                 
docker image save k8s.gcr.io/pause:3.6                          > pause.tgz                     
docker image save k8s.gcr.io/etcd:3.5.1-0                       > etcd.tgz
docker image save k8s.gcr.io/coredns/coredns:v1.8.6             > coredns.tgz 

이미지 추출이 완료되면 대상 SCP 명령 등을 이용하여 해당 파일들을 복사한다.

Image push

  • 대상 서버는 인터넷에 연결이 불가능하므로 복사한 image를 push 해줘야 한다.
docker load    <    kube-apiserve
docker load    <    kube-controll
docker load    <    kube-schedule
docker load    <    kube-proxy.tg
docker load    <    pause.tgz    
docker load    <    etcd.tgz     
docker load    <    coredns.tgz  
  Loaded image: k8s.gcr.io/kube-apiserver:v1.23.5  
  Loaded image: k8s.gcr.io/kube-controller-manager:
  Loaded image: k8s.gcr.io/kube-scheduler:v1.23.5  
  Loaded image: k8s.gcr.io/kube-proxy:v1.23.5      
  Loaded image: k8s.gcr.io/pause:3.6               
  Loaded image: k8s.gcr.io/etcd:3.5.1-0            
  Loaded image: k8s.gcr.io/coredns/coredns:v1.8.6
  • 확인
 docker images |grep k8s.gcr.io
k8s.gcr.io/kube-apiserver                                        v1.23.5            3fc1d62d6587   2 weeks ago    135MB
k8s.gcr.io/kube-proxy                                            v1.23.5            3c53fa8541f9   2 weeks ago    112MB
k8s.gcr.io/kube-controller-manager                               v1.23.5            b0c9e5e4dbb1   2 weeks ago    125MB
k8s.gcr.io/kube-scheduler                                        v1.23.5            884d49d6d8c9   2 weeks ago    53.5MB
k8s.gcr.io/etcd                                                  3.5.1-0            25f8c7f3da61   5 months ago   293MB
k8s.gcr.io/coredns/coredns                                       v1.8.6             a4ca41631cc7   6 months ago   46.8MB
k8s.gcr.io/pause                                                 3.6                6270bb605e12   7 months ago   683kB

 

모든 클러스터 적용

Master node 및 Worker node로 설정 될 모든서버에서 위 작업을 수행해준다.

 

 

 

Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

Yum repository를 추가해서 설치하는 방법, 바이너리를 직접 다운로드 한 다음 스크립트를 생성하는 방법, 두 가지가 있다

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

      

패키지 매니저를 이용한 설치

CentOS yum repository 추가

sudo cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch
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

Ubunt

sudo apt-get install -y apt-transport-https ca-certificates curl
# 구글 클라우드의 공개 signing 키 다운로드
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# Kubernetes 리포지터리 추가
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

      

패키지 설치

CentOS

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

Ubuntu

sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

      

서비스 등록 및 활성화

CentOS, Ubuntu 동일

sudo systemctl enable kubelet.service

sudo systemctl start kubelet.service

      

      

바이너리 다운로드를 통한 설치

CNI 플러그인1yum 등을 이용해서 설치하는 경우 의존성 패키지로 설치된다., kubeadm, kubelet, kubectl 을 설치한다.

아래 설명에서 curl 대신 wget을 이용하거나, 작업중인 PC에서 다운로드 후 업로드 하는 방법으로 대체해도 무방하다.

CNI 플러그인 설치

CNI_VERSION="v0.8.2" 
sudo mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-amd64-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz
#curl -LO 옵션으로 다운로드 후 별도로 압축을 해제해도 된다. 이 경우 압축 해제된 파일을 /opt/cni/bin 디렉토리로 이동 해야 한다.

clictl 설치

DOWNLOAD_DIR=/usr/local/bin
sudo mkdir -p $DOWNLOAD_DIR

kubeadm, kubelet, kubectl 바이너리 설치

RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)" 
cd $DOWNLOAD_DIR
sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/amd64/{kubeadm,kubelet,kubectl}
sudo chmod +x {kubeadm,kubelet,kubectl}

서비스 스크립트 다운로드

RELEASE_VERSION="v0.4.0" 
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
sudo mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

 

서비스 스크립트 생성 (위 스크립트 다운로드 방법 대체)

sudo vi /etc/systemd/system/kubelet.service
# 아래 내용을 붙여넣기 한다.
[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/home/
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/bin/kubelet
Restart=always
StartLimitInterval=0
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
# 아래 내용을 붙여넣기 한다.
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

 

서비스 등록 및 시작

systemctl enable kubelet.service
systemctl start kubelet.service

 

 

 

 

Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)

[Kubernetes #1. 사전작업 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – 컨테이너 런타임 (offline, 폐쇄망)]
[Kubernetes #2-2. 사전작업 – docker 설정 (offline, 폐쇄망)]
[Kubernetes #3. Kubernetes 바이너리 설치 (offline, 폐쇄망)]
[Kubernetes #4. Kubernetes 클러스터 구축 – image pull (offline, 폐쇄망)]
[Kubernetes #4-2. Kubernetes 클러스터 구축 – 단일 마스터노드 생성 (offline, 폐쇄망)]
[Kubernetes #4-3. Kubernetes 클러스터 구축 – worker node join (offline, 폐쇄망)]

망분리 환경에서 proxy등을 통한 외부 연결이 가능하거나, 망 내부적으로 proxy를 통해 통신하는 경우 proxy 설정이 필요하다.
linux OS 레벨에서는 .bash_profile 등에 proxy 변수를 등록하는 것으로 처리가 가능하지만 docker 런타임은 별도로 proxy 정보를 정의해 줘야 한다

이 포스트의 작업은 쿠버네티스 클러스터에 포함하는 모든 노드에서 수행해야 한다.

     

Docker Proxy 설정

서비스 설정 (docker login 등의 작업 에 사용된다.)

[haedong@haedong:~:]$ sudo /lib/systemd/system/docker.service
전략...
# [service] 섹션에 아래 추가
Environment="HTTP_PROXY=http://120.121.122.123:8080" 
Environment="HTTPS_PROXY=https://120.121.122.123:8080" 
Environment="NO_PROXY=.haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local" 
[haedong@haedong:~:]$ sudo systemctl daemon-reload
[haedong@haedong:~:]$ sudo systemctl restart docker.service

컨테이너 설행 시 변수로 전달

[haedong@haedong:~]$ docker run \
-e http_proxy=http://120.121.122.123:8080 \
-e https_proxy https://120.121.122.123:8080 \
-e no_proxy .haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local \
CONTAINER_NAME

이미지 빌드 시 포함

ENV PATH /home/haedong/bin:$PATH
ENV LD_LIBRARY_PATH /lib:/lib64:$LD_LIBRARY_PATH
...중략...
# 아래 내용 추가
ENV http_proxy http://120.121.122.123:8080
ENV https_proxy https://120.121.122.123:8080
ENV no_proxy .haedong.net,localhost,127.0.0.1/8,192.168.0.0/16,.local

     

Docker root directory 변경

pull 한 image나 컨테이너 임시 데이터 등이 저장되는 디렉토리이다. 기본 값은 /var/lib/docker 인데, /var directory가 포함된 파티션의 크기가 작거나 하는 경우 disk full 로 인해 문제를 야기할 수 있다.

현재 docker root 확인

docker info | grep "Docker Root Dir" 

 Docker Root Dir: /var/lib/docker

#docker volume inspect my-vol

준비

docker root dirctory로 사용할 디스크를 확정하고 파티션 생성, 마운트 등의 작업을 마친다.
sudo systemctl stop docker.service 명령으로 서비스를 중지하고(시간이 걸릴 수 있다. 프로세스가 완전히 사라졌는지 확인하도록 하자) 이전의 docker 파일들을 대상 디렉토리로 복사한다.

mkdir /data
cp -rp /var/lib/docker /data

     

서비스 수정

sudo vi /usr/lib/systemd/system/docker.service
# Service 섹션에 ExecStart= 로 시작하는 줄을 수정한다.
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/data
sudo systemctl daemon-reload
sudo systemctl restart docker.service

     

cgroup driver 변경

현재 상태 확인

sudo docker info | grep cgroup
 Cgroup Driver: cgroupfs

서비스 수정

sudo vi /etc/systemd/system/docker.service

# ExecStart 로 시작하는 줄에  --exec-opt native.cgroupdriver=systemd 추가
# ExecStart=/usr/bin/dockerd -g /home/data/ -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -g /home/data/ -H fd:// --containerd=/run/containerd/containerd.sock --exec-opt native.cgroupdriver=systemd
sudo systemctl daemon-reload
sudo systemctl restart docker.service