bxm's IT Story
쿠버네티스 (#1. 개념, 설치, 설치 오류 해결, 재 Join, 컨테이너 네트워크 애드온 설치) 본문
## 쿠버네티스(Kubernetes) ##
쿠버네티스(Kubernetes)는 그리스어로 '조타수' 라는 뜻으로, 오늘날 사실상 표준으로 사용되고 있는 '컨테이너
오케스트레이션 도구'이다.
쿠버네티스는 도커 스웜 모드처럼 여러대의 도커 호스트를 하나의 클러스터로 만들어 준다는 점은 같지만,
세부적인 기능을 더욱 폭넓게 제공하고 있다.
## 쿠버네티스의 핵심 장점
① 서버 지원 클러스터링(하나로 묶음), 마이크로서비스 구조의 컨테이너 배포, 서비스 장애 복구 등 오케스트레이션 기능을 폭 넓게 지원한다. |
② 구글, 레드햇을 비롯한 많은 오픈소스 진영에서 쿠버네티스의 소스코드에 기여하고 있기 때문에, 성능과 안정성 면에서 신뢰를 받고 있다. |
③ 영속적 볼륨, 스케줄링, 장애복구, 오토 스케일링, 서비스 발견(디스커버리) 및 인그레스(Ingress) 등 컨테이너 기반의 클라우드를 운영할 때 필요한 대부분의 기능과 컴포넌트를 사용자가 직접 커스터마이징 할 수 있다. |
④ CNCF(Cloud Native Computing Foundation) 및 다른 클라우드 운영 도구들과 쉽게 연동되므로 확장성이 높다. |
## 쿠버네티스 설치 ##
- 쿠버네티스 설치 환경의 종류
쿠버네티스의 사용환경은 크게 2가지의 종류로 나뉜다.
1) AWS, GKE 등의 클루으드 플랫폼 환경
2) 자체적으로 보유한 온프레미스(On-premise) 서버 환경이다.
- 개발 용도의 쿠버네티스 설치
// Docker for Mac // Windows에서 쿠버네티스 사용
'Docker for Mac'이나 'Windows'로 도커를 설치했다면 쿠버네티스를 별도로 설치하지 않아도 된다.
- 여러 서버로 구성된 쿠버네티스 클러스터 설치
1개의 마스터와 3개의 워커 노드로 구성된 테스트용 쿠버네티스 클러스터를 설치하자. 각 서버에서 아래의 항목들이
준비되어 있는지 확인한 후에 설치를 진행해야 한다.
① 모든 서버의 시간이 ntp를 통해 동기화 되어 있는지 확인한다. |
② 모든 서버의 맥(Mac) 주소가 다른지 확인한다. |
③ 모든 서버가 2GB, 2 CPU 이상의 충분한 자원을 가지고 있는지 확인한다. |
④ 다음 명령어로 메모리 스왑(Swap) 기능을 비활성화 한다. 메모리 스왑이 활성화 되어 있으면 컨테이너 성능이 일관되지 않을 수 있으므로, 쿠버네티스 설치 도구는 메모리 스왑을 허용하지 않는다. swapoff -a |
- Kubeadm 으로 쿠버네티스 설치
쿠버네티스는 일반적인 서버 클러스터 환경에서도 쿠버네티스를 쉽게 설치할 수 있는 'kubeadm' 이라는 관리 도구를
제공한다.
kubeadm은 온프레미스 환경, 클라우드 인프라 환경에 상관없이 일반적인 리눅스 서버라면 모두 사용할 수 있다.
- 실습 환경
master | 172.31.0.100 |
worker1 | 172.31.0.101 |
worker2 | 172.31.0.102 |
worker3 | 172.31.0.103 |
단, 쿠버네티스는 도커 최신 버전을 지원하지 않는다.
따라서 현재 지원하는 버전인 'Docker-ce-19.03.0 // docker-ce-cli-19.03.0' 을 설치해야만 한다.
설치 단계 1) - kubeadm 설치
1) 도커 설치
[ 우분투 ] | wget -qO- get.docker.com | sh |
[ CentOS ] | yum -y install docker-ce-19.03.0 docker-ce-cli-19.03.0 systemctl start docker systemctl enable docker.service |
설치 단계 2) - 설정
[ 우분투 ] | curl -s https://packages.cloud.google.com/apt/doc/apt-dey.gpg | apt-key add - cat << EOF > /etc/apt/sources.list.d/kubernetes.list deb http://apt.kubernetes.io/kubernetes-xenial main EOF |
[ CentOS ] | vi /etc/yum.repos.d/kubernetes.repo ==> 솔직히 이 아래는 못외운다. 쿠버네티스 홈페이지 메뉴얼을 보며 옮겨적는게 최선 [Kubernetes] name=Kubernetes baseurl=htps://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enable=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 |
Manager, Worker1, Worker2] - Default Snapshot으로 이동
// Worker3를 새로 생성 (Worker1,2 깔았을 떄와 동일하게)
// 매니저 4GB, Worker들은 2GB
// 기존에 도커 최신버전이 깔려있으므로 Docker 삭제
// 첫번째 랜카드 - 브릿지, 두번쨰 랜카드 - VMnet2번
## IP 설정
vi /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl restart network
## 스왑(가상메모리) 해제 (이걸 안해주면 쿠버네티스가 동작을 하지 않는다!!)
swapoff -a
## 기존 도커 최신버전 삭제
yum -y remove docker-ce*
## 쿠버네티스에 맞는 도커 버전 설치 및 실행
yum -y install docker-ce-19.03.0 docker-ce-cli-19.03.0
systemctl start docker
systemctl enable docker.service
## 도커 업그레이드 및 버전 확인 (19.03인지 확인해야 한다. 이외에는 동작 안함)
wget get.docker.com
docker -v
Worker3] - 새로 생성
ifconfig
## Manager, Worker1, Worker2와 마찬가지로 쿠버네티스에 맞는 도커 버전 설치 및 실행
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum -y install docker-ce-19.03.0 docker-ce-cli-19.03.0
systemctl start docker
systemctl enable docker.service
// 역시 마찬가지로 도커 버전 업그레이드 및 버전 확인 (19.03인지 확인해야 한다. 이외에는 동작 안함)
wget get.docker.com
docker -v
## 모든 노드에서 쿠버네티스에 필요한 패키지 설치
//별도의 버전을 명시하지 않으면 최신버전을 설치한다.
[ 우분투 ] | apt-get install -y kubelet kubeadm kubectl kubernetes-cni |
[ CentOS ] | yum -y install kubelet kubeadm kubectl kubernetes-cni --disableexcludes=kubernetes systemctl enable kubelet.service |
전체]
vi /etc/yum.repos.d/kubernetes.repo
[Kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=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 ![]() |
yum -y install kubelet kubeadm kubectl kubernetes-cni --disableexcludes=kubernetes
systemctl start kubelet.service
systemctl enable kubelet.service
## 쿠버네티스 클러스터 초기화
// 마스터 노드로 사용할 호스트에서 다음과 같이 클러스터를 초기화 한다. (Swarm 만들때랑 매우 흡사하다!!)
Manager] - 쿠버네티스는 무조건 192.168. 대역으로 만들어야 한다고 한다!!
kubeadm init --apiserver-advertise-address 172.31.0.100 --pod-network-cidr=192.168.0.0/16


## 방화벽 에러 해결 - 전체
전체]
## 1차 방화벽 해제
vi /etc/sysconfig/selinux
setenforce 0
## 방화벽 포트번호 설정 (영구적, 런타임 모두 6443 tcp // 10250 tcp 포트 추가)
firewall-config
// 그냥 방화벽을 전부 끄고 하자 ^^..
systemctl stop firewalld
## Hostname 에러 해결 - 일단 현재 Manager만 해줬음.
vi /etc/hosts



## NTP 시간 동기화 시키기. 에러는 아닌데 해줘야함.
전체] - 사진은 Manager로 대표하여 올림.
yum -y install ntp
ls /etc | grep ntp
vi /etc/ntp.conf
server 0.kr.pool.ntp.org server 1.time.bora.net server 2.time.kornet.net server 3.asia.pool.ntp.org ![]() |
// 포트번호 에러 때문에 방화벽을 다 껐기에 아래의 명령어는 안해줘도 상관 없다.
firewall-cmd --add-service=ntp --permanent
firewall-cmd --reload
systemctl start ntpd
systemctl enable ntpd
clock

## 이 외에 발생할 수 있는 에러 해결법 - 결과론으로 sysctl 해결하니 됐음!!
## cgroup driver 변경하기 (시스템 자원을 관리해주는 역할)
cgroup | 단일 또는 테스크 단위의 프로세스 그룹에 대한 자원 할당을 제어하는 커널 모듈, 뿐만아니라 시스템 메모리, 네트워크 대역폭과 같은 자원을 시스템에서 실행 중인 사용자 정의 작업 그룹(프로세스)에게 할당해 준다. |
vi /usr/lib/systemd/system/docker.service
systemctl daemon-reload
systemctl restart docker
docker info | grep -i cgroup
## 다른 Error 종류들 해결하기.
iptables | iptables : 리눅스상에서 방화벽을 설정하는 도구이다. netfilter 프로젝트에서 개발했으며, 커널상에서 프로토콜 상태 추적, 패킷 어플리케이션 계층 검사, 속도 제한, 필터링 정책 등을 명시하기 위한 강력한 메커니즘을 제공한다. | 에러 : err /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1 |
<해결 방안> echo "net.bridge.bridge-nf-call-iptable=1" >> /etc/sysctl.conf 또는 vi /etc/sysctl.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptable = sysctl -p |
||
★★★ sysctl ★★★ |
런타임 중에 /proc/sys 하위 디렉토리에 대한 커널 매개변수 값을 변경한다. 리눅스 커널에 대한 설정값 변경 및 조회가 가능하며 커널 튜닝을 위한 명령어이다. | 에러 : error execution phase preflight: [preflight] Some fatal errors occurred: [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1 |
<해결 방안> modprobe br_netfilter // 쿠버네티스 설치 시 br-netfilter 모듈이 필요한데, 이 커널 모듈을 사용하면 브릿지를 통과하는 패킷이 필터링 및 포트 전달을 위해 iptables에 의해 처리되고 클러스터의 쿠버네티스 pod는 서로 통신이 가능하다. echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables |
||
에러 : error /proc/sys/net/ipv4/ip_forward contents are not set to 1 |
||
<해결 방안> echo 1 > /proc/sys/net/ipv4/ip_forward // 가상화 환경에서 서로 다른 네트워크를 사용하는 VM간의 라우팅이 필요로 한 경우가 있는데, 별도의 Router용 VM이 아닌 일반 Linux를 사용하여 아주 간단한 Router 역할을 할 수 있다. ip_forward를 활성화하면 해당 시스템 안에서 커널이 처리하는 패킷에 대하여 외부로 forwarding 가능하다. |
// 나에게 남은 마지막 에러가 sysctl 에러이다!! 마지막 에러 해결을 해보자 ㅠㅠ
modprobe br_netfilter
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
// 다시 생성해보자..
kubeadm init --apiserver-advertise-address 172.31.0.100 --pod-network-cidr=192.168.0.0/16
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Worker1, Worker2, Worker3]
kubeadm join 172.31.0.100:6443 --token 07hfqt.qck2zyqb2evsebc3 \
--discovery-token-ca-cert-hash sha256:a02bd17c3380df1f37c5befbb0f36c47362752f8178265ed830426aee32a6195
modprobe br_netfilter
echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/ipv4/ip_forward
// 여기서 잠깐!! 이 에러가 안떴지만 아래의 에러가 뜬다면 해결 방법이 있다.
The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error: Get "http://localhost:10248/healthz": dial tcp [::1]:10248: connect: connection refused. |
<해결 방안> vim /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"] } ![]() systemctl restart docker systemctl status docker kubeadm reset ![]() |
kubeadm join 172.31.0.100:6443 --token pnvki1.zho91111o36ozmc7 \
--discovery-token-ca-cert-hash sha256:bbbd8101d51b946145adb4cbe97b41df2fcb389c48eebe3c1ddfce3b5b929c65


Manager]
kubectl get nodes



## Join 성공 후 알아야 할 내용 ##
# 마스터 노드에서는 6443, 2379~2380, 10250, 10251, 10252 포트가 사용되고 있지 않아야 한다.
[마스터 노드에서 필요한 필수 포트]
6443 포트 : Kubernetes API Server / Used By All
2379~2380 포트 : etcd server client API / Used By kube-apiserver, etcd
10250 포트 : Kubelet API / Used By Self, Control plane
10251 포트 : kube-scheduler / Used By Self
10252 포트 : kube-controller-manager / Used By Self
# 워커 노드에서는 10250, 30000~32767 포트가 사용되고 있지 않아야 한다.
[워커 노드에서 필요한 필수 포트]
10250 포트 : Kubelet API / Used By Self, Control plane
30000~32767 포트 : NodePort Services / Used By All
위 포트가 사용중이라면서 에러가 발생하는 경우 마스터 컨트롤 플레인 노드에서 다음과 같이 리셋해준다.
# kubeadm reset cleanup-node
★★내가 쿠버네티스 조인을 위해서 방화벽 포트 에러가 떴을 때 그냥 'systemctl stop firewalld' 를 통해서
방화벽을 다 끈 상태에서 했었는데... 실제로는 이러면 안된다. 바이러스 먹어요~~~
위의 포트를 다 적어놓고 넣은 다음에 해야한다!!
## 클러스터에서 나가고 싶을 때 (자발적으로!!)
kubeadm reset
## 매니저에서 클러스터에 있는 노드를 강제로 내보내고 싶을 때 (강제로!!)
kubeadm reset <노드명>
// 그렇다면, 조인에서 나간 다음에 다시 들어올 때는? 들어올 때의 그 값을 기억하고 있어야 한다!!
① 토큰값 확인 | kubeadm token list |
② 토큰 생성 | kubeadm token create |
③ Hash 확인 | openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' |
④ Join | kubeadm join --token <2. Token 값> --discovery-token-ca-cert-hash sha256:<3. Hash 값></kubernetes api server:port> <예시> kubeadm join 172.31.0.100:6443 --token yfar6w.w83z3kboqitr4c8i --discovery-token-ca-cert-hash sha256:00885f00baa97edb6c4fbd49b6d74bebbea1bcad7196ed3ebe23040fdcab43cf |
⑤ 노드 삭제 | [해당 노드의 Pod 삭제] --> 엄청 무서운 명령어. 그 안에 있는 Pod들도 다 날라가는 것이다. (reset + Pod들이 다른 노드로 이전되는게 아니라 그냥 전부 삭제) kubectl delete node [노드명] [해당 노드의 Pod들을 다른 노드로 이동] kubectl drain [노드명] |
⑥ 노드 리셋 | // reset 하지 않으면 이전 정보(노드에 대한 고유 ID 및 고유 정보)가 남아 있어 추후 join 수행 시 error 발생 kubeadm reset // 노드의 정보를 다 날려버리는 것임. 이렇게 해야지 Join시에 에러가 발생하지 않는다. kubeadm reset cleanup-node |
⑦ Pod 상태 확인 | kubectl get pod -n kube-system |
## 주의할 점 !!!! Manager를 reset 해버리면, 클러스터고 뭐고 전부 다 절단나버리니까 조심하자ㅎ..

## 컨테이너 네트워크 애드온 설치 ##
칼리코가 설치가 안되어있으면 컨테이너가 설치되어 있는 노드에서는 실행이 되지만 다른 노드에서는 실행이 안됨!! 칼리코로 CNI 플러그인을 해야지만 연결이 된다!!
도커가 쿠버네티스를 쓰는 게 아니라, 쿠버네티스가 도커를 사용한다. Docker는 Swarm의 Overlay 네트워크를 쓰는데,
쿠버네티스가 도커의 상위 개념이기 때문에 이 도커를 사용할 지 다른 것을 사용할지 <가상화 네트워크를 선택할 수 있기 때문에 도커의 Overlay 네트워크에 의존하지 않음.> 그래서 플러그인이 필요한데 그것이 CNI이다.
쿠버네티스의 컨테이너 간의 통신을 위해서 [flannel], [weaveNet] 등 여러 오버레이 네트워크를 사용할 수 있지만,
이번 예제에서는 calico를 기준으로 한다.
따라서 CNI가 설치가 되어 있어야지만 Pods들이 통신할 수 있음. 쿠버네티스에는 도커처럼 따로 네트워크가 구성되어
있는 것이 아님!!
Manager]
kubectl apply -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
// 설치가 정상적으로 완료되었는지 확인하기 위해서, 다음 명령어로 쿠버네티스 핵심 컴포넌트들의 실행 목록을 확인
kubectl get pods --namespace kube-system
// 노드 확인 (Kube-system이 동작하고, 시간이 어느정도 지나면 Ready가 된다는데 나는 바로 됐다...?
심지어 나만 된다.)
kubectl get nodes
## 쿠버네티스의 시작 ##
쿠버네티스는 대부분의 리소스를 '오브젝트'라고 불리는 형태로 관리한다. 오브젝트는 추상화된 집합으로 보면 된다.
Swarm에서는 컨테이너의 집합을 Service라고 불렀는데, 쿠버네티스에서는 컨테이너의 집합을 Pods라고 한다.
컨테이너의 집합(Pods), 컨테이너의 집합을 관리하는 컨트롤러(Replica Set), 사용자(Service Account), 노드(Node)까지도
하나의 오브젝트로 사용할 수 있다.
Pod | 컨테이너를 다루는 기본단위이다. 쿠버네티스에서는 컨테이너 어플리케이션을 구동하기 위해 반드시 알아야 할 몇 가지 오브젝트가 있다. 파드(Pod), 레플리카셋(Replica Set), 서비스(Service), 디플로이먼트(Deployment)가 그것이다. |
// 쿠버네티스에서 사용할 수 있는 오브젝트에는 무엇이 있는지 확인해보자.
kubectl api-resources
// 특정 오브젝트의 간단한 설명을 보고 싶다면, (여기서는 예를 들어 Pod)
kubectl explain pod
## 쿠버네티스는 명령어로도 사용할 수 있지만, YAML 파일을 더 많이 사용한다.
Swarm 모드에서 스택(Stack)을 생성하기 위해 YAML 파일을 사용했던 것처럼, 쿠버네티스도 YAML 파일로 컨테이너
리소스를 생성하거나 삭제할 수 있다.
그러나, 쿠버네티스에서 YAML 파일의 용도는 컨테이너 뿐만 아니라 거의 모든 리소스 오브젝트들에 사용될 수 있다.
## 쿠버네티스는 여러 개의 컴포넌트로 구성되어 있다.
쿠버네티스 노드의 역할은 크게 'Master'와 'Worker'로 나누어져 있다.
Master 노드 | 쿠버네티스가 제대로 동작할 수 있게 클러스터를 관리하는 역할을 담당 |
Worker 노드 | 어플리케이션 컨테이너가 생성 |
도커 스웜 모드를 사용할 때는 단일 도커 데몬만을 설치하여 사용했지만,
쿠버네티스는 도커를 포함한 매우 많은 컴포넌트들이 실행된다. 예컨대, 마스터 노드에서는 API 서버(kube-apiserver),
컨트롤러 매니저(kube-controller-manager), 스케줄러(kube-scheduler), DNS 서버(coreDNS) 등이 실행되며,
모든 노드에서는 오버레이 네트워크 구성을 위해 프록시(kube-proxy)와 네트워크 플러그인(calico, flannel 등)이
실행된다.
이러한 컴포넌트들은 기본적으로 도커 컨테이너로서 실행되고 있다.
(아까 docker ps -a로 확인한 스스로 생성된 컨테이너들이 이 것이다!!)
docker ps -a
쿠버네티스 클러스터 구성을 위해서는 kubelet이라는 에이전트가 모든 노드에서 실행된다.
kubelet은 컨테이너의 생성, 삭제뿐만 아니라 마스터와 워커 노드 간의 통신 역할을 함께 담당한다.
쿠버네티스의 입장에서 보면 도커 데몬 또한 하나의 컴포넌트이다.
쿠버네티스는 도커에 내장된 기능이 아니라 오히려 컨테이너를 사용하기 위해 쿠버네티스가 도커를 이용하는 방식이다. 요컨대, kubelet 이라는 에이전트가 모든 노드에서 실행되며, 마스터 노드에는 API 서버 등이 컨테이너로 실행된다는 것이 핵심이다. (도커가 쿠버네티스를 이용하는 게 아니라, 쿠버네티스가 도커를 이용하는 것이다 !!)
// 에러가 있어 재 Join을 할 것임.
## 쿠버네티스 클러스터 Join 해제 및 다시 토큰값을 받아 재 Join 해보기 ##
위의 명령어들을 수행함에 있어서 Manager에서 수행한 'kubectl get nodes' 명령어에서 각 노드들의 Status가
사진처럼 Ready 상태여야 수행이 되지만, 클러스터로 Join까지 했음에도 NotReady상태인 경우가 있다. (내가 그랬음.)
그렇기에, 클러스터 내의 모든 노드들을 클러스터에서 나오게 한 뒤에 다시 조인을 하는 과정을 수행해보자.
Manager]
kubectl delete node worker1
kubectl delete node worker2
kubectl delete node worker3
kubeadm reset cleanup-node
Worker1, Worker2, Worker3]
kubeadm reset cleanup-node
Manager]
// 다시 aeviertise
kubeadm init --apiserver-advertise-address 172.31.0.100 --pod-network-cidr=192.168.0.0/16
// 기존에 있던것 삭제
rm -rf $HOME/.kube/config // 이걸 삭제 안하면 Already Exist 오류가 뜬다.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config |
Worker1, Worker2, Worker3]
kubeadm join 172.31.0.100:6443 --token vo5jks.l9bosn1x3lfqexb0 \
--discovery-token-ca-cert-hash sha256:de6e698378e5d621a3d4ad7570a9f375ab4532c1b1f19b97809107be608b81e3
Manager]
kubectl get nodes
## 파드(Pod)를 사용해보자
Pod | 컨테이너를 다루는 기본단위이다. 쿠버네티스에서는 컨테이너 어플리케이션을 구동하기 위해 반드시 알아야 할 몇 가지 오브젝트가 있다. 파드(Pod), 레플리카셋(Replica Set), 서비스(Service), 디플로이먼트(Deployment)가 그것이다. |
쿠버네티스에서는 컨테이너 어플리케이션의 기본 단위를 파드(Pod)라고 부르며, 파드는 1개 이상의 컨테이너로 구성된 컨테이너의 집합이다.
도커 엔진에서의 기본 단위는 컨테이너, 스웜 모드에서의 기본 단위는 여러 개의 컨테이너로 구성된 Service였다.
쿠버네티스에서는 컨테이너 어플리케이션을 배포하기 위한 기본 단위로 파드라는 개념을 사용한다.
1개의 파드에는 1개의 컨테이너가 있을 수도, 여러 개의 컨테이너가 존재할 수도 있다.
// Nginx 컨테이너로 구성된 파드를 직접 생성해 보자. 이 yaml 파일로 pod를 구성할 것임.
vi nginx-pod.yaml
apiVersion: v1 kind: Pod metadata: name: my-nginx-pod spec: containers: - name: my-nginx-container image: nginx:latest ports: - containerPort: 80 protocol: TCP ![]() - apiVersion: YAML 파일에서 정의한 오브젝트의 API 버전을 나타낸다. - kind: 리소스의 종류를 나타낸다. kind 항목에서 사용할 수 있는 오브젝트 종류는 kubectl api-resources 의 결과 중 KIND 항목에서 확인할 수 있다. - metadata: 라벨, 주석(Annotation), 이름 등과 같은 리소스의 부가 정보들을 입력한다. - spec: 리소스를 생성하기 위한 자세한 정보를 입력한다. |
- apiVersion: YAML 파일에서 정의한 오브젝트의 API 버전을 나타낸다. |
- kind: 리소스의 종류를 나타낸다. kind 항목에서 사용할 수 있는 오브젝트 종류는 kubectl api-resources 의 결과 중 KIND 항목에서 확인할 수 있다. |
- metadata: 라벨, 주석(Annotation), 이름 등과 같은 리소스의 부가 정보들을 입력한다. |
- spec: 리소스를 생성하기 위한 자세한 정보를 입력한다. |
// 다음과 같이 새로운 파드를 생성한다.
kubectl apply -f nginx-pod.yaml
위 Nginx 포드를 생성할 때, YAML 파일에 사용할 포트(containerPort)를 정의하긴 했지만, 아직 외부에서 접근할 수
있도록 노출된 상태는 아니다. 따라서 포트의 Nginx 서버로 요청을 보내려면 포트 컨테이너의 내부 IP로 접근해야 한다.
Nginx 포트의 보다 자세한 정보 중 IP를 확인하기 위해 아래의 명령어로 Pod의 위치 및 정보를 볼 수 있다.
kubectl describe pods my-nginx-pod
음... 근데 아래 명령어로도 확인해보면, External IP가 아닌 Internal IP 이다. 앗 이거 당연한거라고 한다!!!
kubectl get nodes -o wide
쿠버네티스 외부 또는 내부에서 포드에 접근하려면 서비스(service)라고 하는 오브젝트를 따로 생성해야 하지만,
지금은 서비스 오브젝트 없이 IP만으로 Nginx 포드에 접근해 본다.
클러스터 노드 중 하나에서 접속한 뒤 Nginx 포드의 IP로 HTTP 요청을 전송한다.
curl [Pod의 IP] 이거는 이후에 파드를 생성한 다음에 칼리코도 전부 Running이 된 이후에 사용할 명령어!!
## Pod vs 컨테이너 ##
위의 기능들만 놓고 본다면 포드는 docker run 으로 생성한 단일 nginx 컨테이너와 크게 다르지 않아 보인다.
포드는 컨테이너 IP 주소를 가지고 있어 쿠버네티스 클러스터 내부에서 접근할 수 있고, kubectl exec 명령어로 포드 컨테이너 내부로 들어갈 수도 있으며, kubectl logs 명령어로 포드의 로그를 확인할 수도 있기 때문이다.
쿠버네티스가 포드를 사용하는 이유는 여러가지가 있지만, 그 중에서도 여러 리눅스 네임스페이스(namespace) 를 공유하는 여러 컨테이너들을 추상화된 집합으로 사용하기 위해서이다.
이번에는 포트 컨테이너 내부로 직접 들어가 보자. 다음과 같이 my-nginx-pod 에서 배시 쉘을 실행하되,
-it 옵션으로 쉘을 유지할 수 있다.
kubectl exec -it my-nginx-pod bash
Manager]
watch kubectl get pods -n calico-system
## 칼리코 홈페이지를 참고하여 1,2,3,4,5 전부 다시 실행하여 칼리코를 설치해보자.
https://docs.projectcalico.org/getting-started/kubernetes/quickstart
1. kubectl create -f https://docs.projectcalico.org/manifests/tigera-operator.yaml
2. kubectl create -f https://docs.projectcalico.org/manifests/custom-resources.yaml
3. watch kubectl get pods -n calico-system
Worker3]
docker ps - a | grep my-nginx
Manager] - ☆★☆★☆★☆★☆★경축☆★☆★☆★☆★☆★
kubectl describe pods my-nginx-pod
Manager] - curl로 HTML 보기.
curl 192.168.182.4
Worker1, Worker2, Worker3]
curl 192.168.182.4
여기까지 오면 Worker3에만 있던 my-nginx POD를 모두 사용할 수 있으므로, CNI를 통해 네트워크가 연결된 것이다!!