CloudNet@ - KANS 3기 2주차 스터디
Kubernetes 클러스터 내의 네트워크를 설정하고 관리하기 위한 표준 인터페이스
4가지 요구사항
4가지 문제 해결 요구
kubelet을 통해 신규 파드가 생성되면 네트워크 관련 설정 추가
CNI 플러그인은 전달되는 설정 정의서를 보고 실제 파드가 통신하기 위한 네트워크 설정 실행
IPAM(IP Address Management), IP 할당 관리를 수행하며, 파드 간 통신을 위한 라우팅 설정 처리
Kubernetes 클러스터 내 네트워크를 설정하기 위한 간단하고 효율적인 CNI 플러그인
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
labels:
mynode: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
controllerManager:
extraArgs:
bind-address: 0.0.0.0
etcd:
local:
extraArgs:
listen-metrics-urls: http://0.0.0.0:2381
scheduler:
extraArgs:
bind-address: 0.0.0.0
- |
kind: KubeProxyConfiguration
metricsBindAddress: 0.0.0.0
- role: worker
labels:
mynode: worker
- role: worker
labels:
mynode: worker2
networking:
disableDefaultCNI: true
kind create cluster --config kind-cni.yaml --name myk8s --image kindest/node:v1.30.4`
아직 CNI가 없기 때문에 IP를 못 받고 pending 상태
docker exec -it myk8s-control-plane sh -c 'apt update && apt install tree jq psmisc lsof wget bridge-utils tcpdump iputils-ping htop git nano -y'
docker exec -it myk8s-worker sh -c 'apt update && apt install tree jq psmisc lsof wget bridge-utils tcpdump iputils-ping -y'
docker exec -it myk8s-worker2 sh -c 'apt update && apt install tree jq psmisc lsof wget bridge-utils tcpdump iputils-ping -y'
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
# 확인
kubectl get ns --show-labels
kubectl get ds,pod,cm -n kube-flannel
kubectl describe cm -n kube-flannel kube-flannel-cfg
kubectl describe pod -n kube-system -l k8s-app=kube-dns
kind를 사용했을 때 bridge 파일이 없다는 에러가 있으므로 다음 참고
#
docker exec -it myk8s-control-plane bash
---------------------------------------
apt install golang -y
git clone https://github.com/containernetworking/plugins
cd plugins
chmod +x build_linux.sh
#
./build_linux.sh
Building plugins
bandwidth
firewall
portmap
sbr
tuning
vrf
bridge
host-device
ipvlan
loopback
macvlan
ptp
vlan
dhcp
host-local
static
# 파일 권한 확인 755
ls -l bin
-rwxr-xr-x 1 root root 4559683 Sep 3 04:54 bridge
...
exit
---------------------------------------
# 자신의 PC에 복사 : -a 권한 보존하여 복사(755)
docker cp -a myk8s-control-plane:/plugins/bin/bridge .
ls -l bridge
docker cp bridge myk8s-control-plane:/opt/cni/bin/bridge
docker cp bridge myk8s-worker:/opt/cni/bin/bridge
docker cp bridge myk8s-worker2:/opt/cni/bin/bridge
docker exec -it myk8s-control-plane chmod 755 /opt/cni/bin/bridge
docker exec -it myk8s-worker chmod 755 /opt/cni/bin/bridge
docker exec -it myk8s-worker2 chmod 755 /opt/cni/bin/bridge
docker exec -it myk8s-control-plane chown root root /opt/cni/bin/bridge
docker exec -it myk8s-worker chown root root /opt/cni/bin/bridge
docker exec -it myk8s-worker2 chown root root /opt/cni/bin/bridge
# flannel 정보 확인 : 대역, MTU
for i in myk8s-control-plane myk8s-worker myk8s-worker2; do echo ">> node $i <<"; docker exec -it $i cat /run/flannel/subnet.env ; echo; done
docker exec -it myk8s-worker bash
flannel pod의 ip는 노드 서버의 ip 와 동일합니다.
network namespace를 공유하기 때문.
# 라우팅 정보 확인 : 다른 노드의 파드 대역(podCIDR)의 라우팅 정보가 업데이트되어 있음을 확인
ip -c route
default via 172.18.0.1 dev eth0
10.244.0.0/24 via 10.244.0.0 dev flannel.1 onlink
10.244.1.0/24 dev cni0 proto kernel scope link src 10.244.1.1
10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
172.18.0.0/16 dev eth0 proto kernel scope link src 172.18.0.3
iptables -t filter -S | grep 10.244.0.0
iptables -t nat -S | grep 'flanneld masq' | grep -v '! -s'
위와 같이 확인해보면 kubectl → CNI → iptables 이야기 했던 바와 같이 룰들을 설정해놓은 걸 알 수 있습니다.
# [터미널1,2] 워커 노드1,2 - 모니터링
docker exec -it myk8s-worker bash
docker exec -it myk8s-worker2 bash
-----------------------------
watch -d "ip link | egrep 'cni|veth' ;echo; brctl show cni0"
-----------------------------
# [터미널3] cat & here document 명령 조합으로 즉석(?) 리소스 생성
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
name: pod-1
labels:
app: pod
spec:
nodeSelector:
kubernetes.io/hostname: myk8s-worker
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
---
apiVersion: v1
kind: Pod
metadata:
name: pod-2
labels:
app: pod
spec:
nodeSelector:
kubernetes.io/hostname: myk8s-worker2
containers:
- name: netshoot-pod
image: nicolaka/netshoot
command: ["tail"]
args: ["-f", "/dev/null"]
terminationGracePeriodSeconds: 0
EOF
# 파드 확인 : IP 확인
kubectl get pod -o wide
cni0 interface(bridge) 생성 → veth interface 부착 + peer 정보
cni0 dump 확인
외부 통신할 때 flannel.1 거치지 않는 모습
⇒ flannel interface는 다른 노드의 파드와 통신할 때 VXLAN으로 오버레이 네트워크가 필요할 때만 사용합니다.
eth0 (서버의 인터페이스) 에서 tcpdump를 해도 보이지 않는다. (기존 패킷을 감싸버린 UDP 이기 때문)