제목 : [ CKA ] #1. 쿠버네티스 설치하기
Kubenertes 설치 방식
# 쿠버네티스는 여러가지 방식으로 설치할 수 있으나 CKA 과정을 고려한하여
공식 오픈문서의 kubeadm 방식으로 설치를 진행하였다.
구성 서버 ( VM )
Controller Server : 1EA
Worker Server : 1EA
OS
Ubuntu 20.04 Server Minimal
# SWAP 은 기본적으로 해제하는 것을 권장하고 있다.
sudo swapoff /swap.img
sudo sed -i -e '/swap.img/d' /etc/fstab
# 호스트네임을 설정한다. 모든 작업은 일반 계정(regular user)에서 sudo 를 사용하여 권한을 빌려 실행하는 것을 권장한다.
sudo hostnamectl set-hostname controller
sudo hostnamectl set-hostname worker
Traffic Setup
# 컨테이너 런타임(예: Docker), kube-proxy에서 사용하는 브릿지 네트워크의 트래픽을 확인할 수 있도록 iptables 커널 옵션을 지정한다.
## Container / Worker
이 모듈을 로드하면, 브릿지를 통과하는 트래픽이 netfilter(iptables) 를 거치도록 활성화된다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
Container Runtime 설치
# 쿠버네티스의 기본 단위인 POD 에서 컨테이너를 구동하는 런타임은 여러 종류가 존재하지만 CKA 과정 상 Docker 를 설치하였다.
쿠버네티스는 외부 추가 서비스/모듈의 일관성을 보장하지는 않는다.
## Controller / Worker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
## Check
sudo docker -v
sudo docker ps -a
cgroup 드라이버 설정
# cgroup 은 런타임 프로세스의 리소스를 제약할 수 있는 관리자이다.
설치한 OS의 cgroup 기본 관리자인 systemd 와, docker, kubelet 의 cgroupfs 관리가 별개로 작동하는 혼란을 방지하기 위해 systemd 로 통합해 주는 과정이다.
## Controller / Worker
sudo mkdir /etc/docker
cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
## Docker enable && restart
sudo systemctl enable docker
sudo systemctl daemon-reload
sudo systemctl restart docker
## Docker 의 cgroup driver 확인 시, 기본 cgroupfs 에서 systemd 로 변경된 것을 확인할 수 있다.
sudo docker info | grep -i cgroup
Cgroup Driver: systemd
Cgroup Version: 1
쿠버네티스 패키지 설치
# 레포지토리 구성 후 kebe 관련 관리/명령줄 패키지를 설치한다. 일반적으로 모든 서버에 설치한다.
에러 발생시 한줄씩 진행한다.
## Controller / Worker
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
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
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
Kube 컨트롤 노드의 InitIalize.
# Controller Node 의 시작을 위해 init 하는 과정이다. 옵션을 통해 구성을 지정할 수 있다.
--cri-socket : 지정하지 않을 경우 kubeadm이 socket 으로 내부에 설치된 컨테이너 런타임을 자동 감지하여 구성한다. 다중으로 설치되어 있으면 에러가 발생한다.
--pod-network-cidr : pod 간 통신할 수 있는 network 를 지정한다. 내부 CoreDNS Service 의 조건이다.
--apiserver-advertise-address=<ip-address> : 지정하지 않으면 Controller 의 기본 네트워크 인터페이스를 사용하여 API서버를 선언한다.
## Controller. 일반적으로 컨트롤러 자신의 공인IP 를 통해 API 서버임을 알린다 (Advertise)
sudo kubeadm init --ignore-preflight-errors=all --pod-network-cidr=192.168.0.0/16 --apiserver-advertise-address=203.248.23.192
# 정상적으로 init 되면 하단에 아래의 메세지가 나온다.
1) 설명과 같이, 일반 유저(regular user) + sudo 권한으로 cluster를 사용하고 있다면, 아래의 환경 변수를 실행한다.
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
## Check
kubectl get nodes
NAME STATUS ROLES AGE VERSION
user1-controller NotReady control-plane,master 6m28s v1.23.5
2) pod network 를 사용하기 위해 Network Plugin 을 설치할 수 있다.
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/
## Pod Network 통신이 구성되지 않으면 CoreDNS 가 작동하지 않는다(Pending)
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-64897985d-9sj9j 0/1 Pending 0 12m
kube-system coredns-64897985d-zfl8q 0/1 Pending 0 12m
kube-system etcd-user1-controller 1/1 Running 0 12m
kube-system kube-apiserver-user1-controller 1/1 Running 0 12m
kube-system kube-controller-manager-user1-controller 1/1 Running 0 12m
kube-system kube-proxy-g5xdv 1/1 Running 0 12m
kube-system kube-scheduler-user1-controller 1/1 Running 0 12m
## Pod Network Plugin Install
다양한 네트워크 플러그인이 있으며, 해당 CKA 과정 글에서는 Callico 의 Plugin 을 사용한다.
curl https://projectcalico.docs.tigera.io/manifests/calico.yaml -O
kubectl apply -f calico.yaml
kubectl get nodes
## Check
플러그인 설치 후, coredns의 status 가 Running 되는지 체크한다.
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-56fcbf9d6b-bnxz5 0/1 Pending 0 20s
kube-system calico-node-khp2h 0/1 Init:2/3 0 20s
kube-system coredns-64897985d-9sj9j 0/1 Pending 0 22m
kube-system coredns-64897985d-zfl8q 0/1 Pending 0 22m
kube-system etcd-user1-controller 1/1 Running 0 22m
Multi NIC 를 가지는 환경에서 INTERNAL-IP 설정
다수의 네트워크가 존재하는 서버의 경우 K8S 에서 첫 번째 NIC 의 IP 가 INTERNAL-IP 로 자동 설정된다.
해당 INTERNAL-IP 를 Init 시 설정한
kubeadm --apiserver-advertise-address 와 동일한 IP 대역을 사용하도록 수동 설정한다.
# INTERNAL-IP 가 10.0.2.15 ( Calico Network Default ) 로 되어 있다
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
user-controller Ready control-plane,master 44h v1.23.5 10.0.2.15 <none> Ubuntu 20.04.1 LTS 5.4.0-64-generic docker://20.10.14
user-worker Ready <none> 44h v1.23.5 10.0.2.15 <none> Ubuntu 20.04.1 LTS 5.4.0-64-generic docker://20.10.14
# Controller. 상황에 따라 수동 설정한다
cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS='--node-ip $(hostname -I | cut -d ' ' -f2)'
EOF
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl cluster-info
# Worker. 상황에 따라 수동 설정한다
cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS='--node-ip $(hostname -I | cut -d ' ' -f2)'
EOF
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# Check 시 Internal-IP 가 advertise 인터페이스로 변경되었다.
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
user-controller Ready control-plane,master 45h v1.23.5 203.248.23.214 <none> Ubuntu 20.04.1 LTS 5.4.0-64-generic docker://20.10.14
user-worker Ready <none> 44h v1.23.5 203.248.23.215 <none> Ubuntu 20.04.1 LTS 5.4.0-64-generic docker://20.10.14
Worker 에서 Controller 에 Join
Then you can join any number of worker nodes by running the following on each as root:
root 로 실행하라고 안내하고 있으나
일반 유저로 Worker 에서 kebeadm을 실행하고 싶다면 Controller 의 /etc/kebenertes/admin.conf 파일을 Worker 로 복제 후 동일 환경 구성을 해준다.
# Controller
sudo scp /etc/kubernetes//admin.conf vagrant@203.248.23.193:/home/vagrant/admin.conf
# Worker
mkdir -p $HOME/.kube
sudo cp -i ./admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm join 203.248.23.192:6443 --token wy11vq.bk2rze7g9lilg2d9 \
--discovery-token-ca-cert-hash sha256:f7bc17bb974c804821b21427d500cb96615f66c1fd88cb53c023d8b2c598d3f7
오류가 발생할 경우 ignore 옵션을 추가해 본다
sudo kubeadm join 203.248.23.192:6443 --token wy11vq.bk2rze7g9lilg2d9 --ignore-preflight-errors=all --discovery-token-ca-cert-hash sha256:f7bc17bb974c804821b21427d500cb96615f66c1fd88cb53c023d8b2c598d3f7
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.
### Check
위의 환경 설정을 했을 경우 Worker 에서도 일반 유저로 pod 확인이 가능하다
kubectl get nodes
NAME STATUS ROLES AGE VERSION
user1-controller Ready control-plane,master 33m v1.23.5
user1-worker Ready <none> 84s v1.23.5
kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-56fcbf9d6b-bnxz5 1/1 Running 0 11m
kube-system calico-node-khp2h 1/1 Running 0 11m
kube-system calico-node-skdjl 1/1 Running 0 2m3s
kube-system coredns-64897985d-9sj9j 1/1 Running 0 33m
kube-system coredns-64897985d-zfl8q 1/1 Running 0 33m
kube-system etcd-user1-controller 1/1 Running 0 33m
kube-system kube-apiserver-user1-controller 1/1 Running 0 33m
kube-system kube-controller-manager-user1-controller 1/1 Running 0 33m
kube-system kube-proxy-g5xdv 1/1 Running 0 33m
kube-system kube-proxy-m6ztf 1/1 Running 0 2m3s
kube-system kube-scheduler-user1-controller 1/1 Running 0 33m
(Trouble) 설치 중 에러 발생시 클린 삭제 후 재 설치를 진행한다
# All Node
sudo systemctl stop kubelet
sudo kubeadm reset -f
sudo rm -rf ~/.kube
sudo rm -rf /root/.kube
sudo rm -rf /var/lib/etcd
Network Plugin Status
앞서서 Pod Network 를 관리하는 애드-온 플러그인으로 Calico 를 설치하였는데, 간단한 Status 명령을 확인할 수 있다.
별도 명령어(calicoctl) 설치도 가능하고, Kubectl 의 옵션 플러그인으로 설치할수도 있는데 전자로 진행했다.
# Host 의 명령어 타입으로 설치
$ cd /usr/local/bin
$ sudo curl -L https://github.com/projectcalico/calico/releases/download/v3.22.1/calicoctl-linux-amd64 -o calicoctl
$ sudo chmod +x calicoctl
# Check
$ calicoctl ipam show --show-blocks
+----------+--------------------+-----------+------------+--------------+
| GROUPING | CIDR | IPS TOTAL | IPS IN USE | IPS FREE |
+----------+--------------------+-----------+------------+--------------+
| IP Pool | 192.168.0.0/16 | 65536 | 8 (0%) | 65528 (100%) |
| Block | 192.168.136.0/26 | 64 | 3 (5%) | 61 (95%) |
| Block | 192.168.153.192/26 | 64 | 5 (8%) | 59 (92%) |
+----------+--------------------+-----------+------------+--------------+
Kubernetes Auto Complation
# 주요 명령어의 alias 및 Tab 키를 사용한 자동완성을 권장한다
echo '' >>~/.bashrc
echo 'source <(kubectl completion bash)' >>~/.bashrc
echo 'alias k=kubectl' >>~/.bashrc
echo 'complete -F __start_kubectl k' >>~/.bashrc
. ~/.bashrc
# Check
## Tab 자동완성 확인
k get nodes -o wide
kubectl get nodes -o wide