본문 바로가기
서버인프라/kubernetes

쿠버네티스 설치

by techwold ted 2022. 12. 13.

오늘은 쿠버네티스 설치를 해보려 합니다.

우리가 사용할 것은 kubernetes + crio + calico 입니다. 이렇게 조합해서 사용해 보겠습니다. weabenet으로 테스트 해봤는데 잘 안되서 calico로 변경했습니다. 혹시 weabnet으로 잘 되신 분이 계시면 상세히 공유 해주심 감사하겠습니다.

우선 아래와 같이 구성을 해볼 생각 입니다.

목표 구성

자 그럼... 이제 설치를 시작해 보겠습니다. 설치 환경은 총 3대의 서버가 필요하고 저는 proxmox로 3대를 구성해서 사용하겠습니다.

HOST OS IP
MASTER Ubuntu 20.04 10.0.1.180
NODE-1 Ubuntu 20.04 10.0.1.181
NODE-2 Ubuntu 20.04 10.0.1.182

그리고 저와 같이 항해를 하실 분들을 위해서 아래와 같이 스크립트를 만들었습니다.

아래와 같이 만들어 주세요

vi k8s_install.sh
#!/bin/bash

os_version=$(cat /etc/os-release | grep VERSION_ID | sed 's/VERSION_ID=//g' | sed 's/\"//g')

function timedate() {
    apt update
    timedatectl set-timezone 'Asia/Seoul'
    apt install -y rdate
    sleep 3
    rdate -s time.bora.net
    sleep 2
}


function crio() {
if [ ${os_version} == "20.04" ]; then
export OS=xUbuntu_20.04
export VERSION=1.25

echo -e "레포지토리 "
sleep 1
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list
sleep 2

curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -

sleep2

apt update
sleep 2

apt install cri-o cri-o-runc
sleep 2

systemctl daemon-reload
systemctl enable crio --now
systemctl status crio
echo -e "설치가 완료 되었습니다."

else
    echo "OS 확인이 필요합니다. Ubuntu 20.04 LTS 에서 동작합니다."
fi
}

function k8s() {
#https://kubernetes.io/docs/setup/production-environment/container-runtimes/
cat <<EOF | tee /etc/modules-load.d/k8s.conf 
overlay 
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

sleep 2

# sysctl params required by setup, params persist across reboots
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sysctl --system

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

apt-get update
apt-get install -y apt-transport-https ca-certificates curl
sleep 2

mkdir /etc/apt/keyrings
curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

sleep 1

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sleep 1

apt-get update
sleep 2
apt-get install -y kubelet kubeadm kubectl
sleep 3
apt-mark hold kubelet kubeadm kubectl

echo -e "k8s 설치 완료\n\n\n kubelet start ...."
systemctl start kubelet
systemctl enable kubelet

echo -e "kubelet 실행 완료"

version_kubelet=$(kubelet --version)
version_kubeam=$(kubeadm version)
version_kubectl=$(kubectl version)

echo -e "kubelet Version : ${version_kubectl}\n\n"
echo -e "kubeam Version : ${version_kubeam}\n\n"
echo -e "kubectl Version : ${version_kubectl}\n\n\n\n\n"

echo -e "설치 완료 Kubernetes ..."

}

function master() {
echo -e "kubeadm init ... \n\n"
kubeadm init --cri-socket=/var/run/crio/crio.sock --pod-network-cidr=192.168.0.0/16 | tee init.log
echo -e "kubeamd init ... sucess"
echo -e "init.log 확인하여 적용해 주세요"
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
export KUBECONFIG=/etc/kubernetes/admin.conf
}

function weave() {
# weave net
echo -e "Weave Networks 설치를 시작 합니다."
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
sleep 3
echo -e "Weave Networks 설치가 끝났습니다."
sleep 10
kubectl get nodes
echo "kubectl get nodes 를 확인합니다."
}

function calico() {
# Calico net
echo -e "Calico Networks 설치를 시작 합니다."
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
echo -e "Calico Networks 설치가 끝났습니다."
sleep 10
kubectl get nodes
echo "kubectl get nodes 를 확인합니다."
}


function delete() {
apt-get purge kubelet kubeadm kubectl cri-o cri-o-runc
sleep 1
echo "디렉토리 삭제합니다 .... "
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
echo -e "delete directory /var/lib/docker \n delete directory /var/lib/containerd"
}

case $1 in
    timedate)
        timedate
        ;;
    crio)
        crio
        ;;
    upgrade)
        upgrade
        ;;
    k8s)
        k8s
        ;;
    master)
        master
        ;;
    weave)
        weave
        ;;
    calico)
        calico
        ;;
    delete)
        delete
        ;;
    *)
        echo -e "아래와 같이 입력해 주세요 \n./k8s_install.sh { timedate | crio | k8s | master | weave | calico | delete } \n"
        echo -e "delete는 주의해 주세요"
        exit 1
        ;;
esac
exit 0

주의 사항

꼭 서버의 호스트 네임 변경을 해주세요 그렇지 않면 join할때 에러가 발생합니다.

1. Master 

  • 아래와 같이 입력하고 한단계 한단계 넘어갑니다.
  • 우리가 이 master라고 부르는 녀석은 컨트롤 노드가 될 것입니다.
  • 시작전 apt update와 시간 동기화해주세요
./k8s_install.sh timedate

cri-o 라는 컨테이너 런타임을 설치 합니다. 우리가 이전 시간에 이녀석이 뭘 하는지 구성으로 확인했습니다.

./k8s_install.sh crio

kubelet과 kubeadm kubectl을 사용하기 위해 아래와 같이 입렵해서 실행합니다.

./k8s_install.sh k8s

그리고 쿠버네티스 네트워크를 사용하기 위해 아래와 같이 calico를 설치 합니다.

./k8s_install.sh calico

이렇게 마스터(컨트롤 노드)에 설치가 완료 되었습니다. 다음은 node-1, node-2의 설치를 진행 합니다.

 

2. NODE-1, NODE-2

  • NODE의 설치 방법은 같기 때문에 하나로 묵어서 설명하겠습니다.
  • 각기 서버에서 아래와 같이 진행해 주세요
  • 설치전 apt update 와 시간 동기화 작업을 해주세요
./k8s_install.sh timedate

cri-o 설치 이전 master에서 설치 했던 방법과 같은 방법으로 설치해 주세요

./k8s_install.sh crio

kubelet과 kubeadm kubectl을 사용하기 위해 아래와 같이 입렵해서 실행합니다.

./k8s_install.sh k8s

node-1, node-2는  위 2가지만 설치 하시면 끝납니다.

 

그럼 이제 우리는 다시 master로 돌아가서 아래와 같은 작업을 해줘야 합니다.

 

3. kubeadm init

  • 아래와 같이 입력하시고 완료 되면 init.log를 확인해 주세요
  • 이건 master 에서만 실행 합니다. 
./k8s_install.sh master

init 실행 결과가 저장 됐을 것이고, 저장파일을 확인해 보면 아래와 같은 내용들을 확인 하실 수 있습니다.

우리는 여기서 맨 아래줄 kubeadm join이라고 시작 하는 줄을 복사하여 node에서 붙여 넣어 줄 것입니다.

cat init.log

[init] Using Kubernetes version: v1.26.0
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master] and IPs [10.96.0.1 10.0.1.180]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [localhost master] and IPs [10.0.1.180 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [localhost master] and IPs [10.0.1.180 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key
[kubeconfig] Using kubeconfig folder "/etc/kubernetes"
[kubeconfig] Writing "admin.conf" kubeconfig file
[kubeconfig] Writing "kubelet.conf" kubeconfig file
[kubeconfig] Writing "controller-manager.conf" kubeconfig file
[kubeconfig] Writing "scheduler.conf" kubeconfig file
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Starting the kubelet
[control-plane] Using manifest folder "/etc/kubernetes/manifests"
[control-plane] Creating static Pod manifest for "kube-apiserver"
[control-plane] Creating static Pod manifest for "kube-controller-manager"
[control-plane] Creating static Pod manifest for "kube-scheduler"
[etcd] Creating static Pod manifest for local etcd in "/etc/kubernetes/manifests"
[wait-control-plane] Waiting for the kubelet to boot up the control plane as static Pods from directory "/etc/kubernetes/manifests". This can take up to 4m0s
[apiclient] All control plane components are healthy after 11.002016 seconds
[upload-config] Storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config" in namespace kube-system with the configuration for the kubelets in the cluster
[upload-certs] Skipping phase. Please see --upload-certs
[mark-control-plane] Marking the node master as control-plane by adding the labels: [node-role.kubernetes.io/control-plane node.kubernetes.io/exclude-from-external-load-balancers]
[mark-control-plane] Marking the node master as control-plane by adding the taints [node-role.kubernetes.io/control-plane:NoSchedule]
[bootstrap-token] Using token: ra4dfx.jjw17duwcsocdjhs
[bootstrap-token] Configuring bootstrap tokens, cluster-info ConfigMap, RBAC Roles
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes
[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstrap-token] Creating the "cluster-info" ConfigMap in the "kube-public" namespace
[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 10.0.1.180:6443 --token ra4dfx.jjw17duwcsocdjhs \
	--discovery-token-ca-cert-hash sha256:4af2ed233ec09999b3e6e4f6e0977bb22e99b3d8d1954d1c72dc64b5ffd63013

 

4. NODE JOIN

  • node-1과 node-2에서 우리는 위에서 복사해두었던 kubeadm join을 붙여 넣어 줄 것입니다.
  • 특별하게 에러 로그가 없었다면 항해를 위한 과정을 잘 진행 한 것이라고 확인 할 수 있습니다.
kubeadm join 10.0.1.180:6443 --token ra4dfx.jjw17duwcsocdjhs \
	--discovery-token-ca-cert-hash sha256:4af2ed233ec09999b3e6e4f6e0977bb22e99b3d8d1954d1c72dc64b5ffd63013

 

5. 클러스터 확인

  • 아래와 같이 kubectl get nodes 라는 명령어로 확인해 보면 status 상태가 Ready 라고 나온다면 정상 입니다.
root@master:~/install# kubectl get nodes
NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   37h   v1.26.0
node-1   Ready    <none>          37h   v1.26.0
node-2   Ready    <none>          37h   v1.26.0

그리고 -o wide를 추가하여 확인해 보도록 하겠습니다.

  • OS-IMAGE 정보 와 버전 정보들 그리고 런타임 정보, 아이피 정보를 추가하여 조금 더 상세하게 확인 할 수 있습니다.
root@master:~/install# kubectl get nodes -o wide
NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   Ready    control-plane   37h   v1.26.0   10.0.1.180    <none>        Ubuntu 20.04.5 LTS   5.4.0-135-generic   cri-o://1.25.1
node-1   Ready    <none>          37h   v1.26.0   10.0.1.181    <none>        Ubuntu 20.04.5 LTS   5.4.0-135-generic   cri-o://1.25.1
node-2   Ready    <none>          37h   v1.26.0   10.0.1.182    <none>        Ubuntu 20.04.5 LTS   5.4.0-135-generic   cri-o://1.25.1

 

어떻게 지금까지 같이 항해를 시작할 준비를 잘 마치셨나요??

중간에 err가 발생하신 분들도 계시겠지만 같이 소통하며, 하신다면 문제 없이 같이 공부하실 수 있으리라 믿습니다.

잘 안되시는 분들은 댓글 남겨주세요

댓글