일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- ssh
- cloud controller manager
- jnlp
- Kubernetes
- RDS
- ingress-nginx
- elasticahe
- Tunneling
- helm-chart
- argocd
- ChatGPT
- AWS
- sshtunneling
- redis oss
- multibranch
- datagrip
- k8s
- 인프런
- ssafy #싸피 #ssafy 12기 #싸피 12기 #ssafy 합격 #싸피 합격 #합격 후기
- vue3
- 쿠버네티스
- ElastiCache
- Certbot
- kaniko
- Docker
- port forawrding
- EC2
- 인프런강의
- 워커노드
- helm
- Today
- Total
처누
[Infra] 마스터 노드 구축 본문
인스턴스들의 보안 그룹에서 인바운드 규칙을 설정해주어야 한다.
Calico를 사용하기로 했기 때문에 아래와 같이 설정을 해주었다.
모든 노드 공통
프로토콜 | 포트 | 출발지(CIDR) | 설명 |
---|---|---|---|
TCP | 6443 | 모든 IP | Kubernetes API 서버 (kubectl 등 클라이언트가 접근) |
TCP | 2379-2380 | 서브넷 IPv4 CIDR | etcd 통신 |
TCP | 10250 | 서브넷 IPv4 CIDR | Kubelet API (metrics-server, kubectl logs 등) |
TCP | 10255 | 서브넷 IPv4 CIDR | (선택) Kubelet 읽기 전용 포트 (보안상 권장 안됨) |
TCP | 30000-32767 | 모든 IP | NodePort 서비스용 포트 (외부에서 접근) |
마스터 노드에 필요한 포트
프로토콜 | 포트 | 출발지(CIDR) | 설명 |
---|---|---|---|
TCP | 10251 | 서브넷 IPv4 CIDR | kube-scheduler |
TCP | 10252 | 서브넷 IPv4 CIDR | kube-controller-manager |
TCP | 10259 | 서브넷 IPv4 CIDR | (v1.20+) scheduler |
TCP | 10257 | 서브넷 IPv4 CIDR | (v1.20+) controller-manager |
Calico에 필요한 포트
프로토콜 | 포트 | 출발지(CIDR) | 설명 |
---|---|---|---|
TCP/UDP | 179 | 서브넷 IPv4 CIDR | BGP 포트 (Calico의 default 통신 방식) |
UDP | 4789 | 서브넷 IPv4 CIDR | VXLAN UDP 포트 |
TCP | 5473 | 서브넷 IPv4 CIDR | Felix가 Typha와 통신하기 위한 포트 |
1. 시스템 초기 설정
# 스왑 비활성화
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# iptables가 브릿지 트래픽을 확인하도록 설정
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo 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
sudo sysctl --system
2. 컨테이너 런타임 설치(containerd 사용)
# 필요한 패키지 설치
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
# Docker 공식 GPG 키 추가
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Docker 저장소 추가
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# containerd 설치
sudo apt update
sudo apt install -y containerd.io
# containerd 구성
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
3. 쿠버네티스 저장소 설정(v1.30)
최신 버전으로 시도했으나 버전 충돌 에러로 인해 1.30으로 설치
sudo curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
4. kubeadm을 사용한 마스터 노드 초기화
kubeadm-config.yaml
#kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.30.0
controlPlaneEndpoint: <마스터노드에 연결된 EIP>:6443
networking:
podSubnet: 192.168.0.0/16 #Calico 기본 네트워크
apiServer:
timeoutForControlPlane: 4m0s
extraArgs:
enable-admission-plugins: NodeRestriction
service-account-issuer: https://kubernetes.default.svc.cluster.local
service-account-signing-key-file: /etc/kubernetes/pki/sa.key
service-account-key-file: /etc/kubernetes/pki/sa.pub
controllerManager:
extraArgs:
bind-address: 0.0.0.0
scheduler:
extraArgs:
bind-address: 0.0.0.0
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
criSocket: /run/containerd/containerd.sock
name: master-node
taints:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
apiServer:
timeoutForControlPlane: 4m0s
extraArgs:
enable-admission-plugins: NodeRestriction
service-account-issuer: https://kubernetes.default.svc.cluster.local
service-account-signing-key-file: /etc/kubernetes/pki/sa.key
service-account-key-file: /etc/kubernetes/pki/sa.pub
- enable-addmission-plugins : NodeRestriction(보안상 필수)
- NodeRestriction 플러그인은 kubelet이 자기 노드에 속한 리소스만 수정할 수 있도록 제한하는 역할을 함.
- 예를 들어, 어떤 노드의 kubelet이 다른 노드의 Pod나 Node 리소스를 건드릴 수 없게 막아주는 것.
- service-account-issuer, service-account-signing-key-file, service-account-key-file(필수)
- Service Account Token Volume Projection 기능을 제대로 쓰기 위한 설정.
- 쿠버네티스가 Pod에 JWT 토큰을 발급할 때, 그 토큰의 issuer가 뭔지 명시해주는 것, 해당 토큰을 사인(sign)하는 키도 명시하는 것.
- 쿠버네티스 1.22 이후부턴 필수
- OIDC 연동이나 외부 인증 시스템을 붙일거라면 꼭 필요함.
sudo kubeadm init --config=kubeadm-config.yaml
kubeadm join으로 시작하는 명령어는 따로 저장해놓자!
5. kubectl 설정
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
6. 네트워그 플러그인 설치(Calico)
custom-resoucers.yaml
# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
name: default
spec:
# Configures Calico networking.
calicoNetwork:
bgp: Disabled
ipPools:
- name: default-ipv4-ippool
blockSize: 26
cidr: 192.168.0.0/16
encapsulation: VXLAN
natOutgoing: Enabled
nodeSelector: all()
---
# This section configures the Calico API server.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.APIServer
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
name: default
spec: {}
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.4/manifests/tigera-operator.yaml
kubectl create -f custom-resources.yaml
게시글 작성일 기준 Calico 최신 버전인 3.29 설치 중 아래와 같은 에러가 발생했다.
The CustomResourceDefinition "installations.operator.tigera.io" is invalid: metadata.annotations: Too long: must have at most 262144 bytes
kubectl apply 명령어가 리소스를 적용할 때, 해당 리소스의 메타데이터에 `kubectl.kubernetes.io/last-applied-configuration`라는 주석을 추가하는데 이 주석이 너무 커서 발생하는 문제였다.
쿠버네티스를 여러번 설치해보면서 버전 문제로 인한 에러가 많았기에 한 버전 낮은 버전으로 설치했다.
공식문서를 보면 custom-resources.yaml 설치 명령어가 아래와 같이 돼있다.
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.4/manifests/custom-resources.yaml
하지만 해당 custom-resources.yaml을 열어보면 BGP가 Enabled로 돼있다.
calicoNetwork:
bgp: Enabled
Calico는 기본값으로 BGP 모드(BIRD 데몬 사용)를 활성화한다.
여기서 문제가 발생했다. 워커노드 조인 후 calico-node가 Running
상태였지만 READY
는 0/1
로 돼있었다.
에러 로그는 다음과 같았다.
calico/node is not ready: BIRD is not ready: BGP not established with
Calico가 BGP를 통해 노드 간 네트워크를 연결하려고 하지만 연결에 실패한 것.
단일 클러스터이거나 클러스터 간 BGP 피어가 없을 때, BGP 모드를 사용하면 BIRD가 외롭게 떠 있다가 계속 에러를 발생시킨다고 한다.
따라서 BGP 대신 VXLAN을 선택했다.
VXLAN을 사용한 이유
- AWS EC2 환경에서는 BGP 구성이 번거롭고 불필요함
- BGP를 사용하려면 EC2 간 IPsec 터널이나 외부 라우터, 또는 노드 간 BGP 피어링 구성이 필요함.
- 이는 추가적인 설정 부담과 복잡한 보안 정책, 라우팅을 요구함.
- VXLAN은 오버레이 네트워크이므로 인프라 제약 없이 작동
- 노드 간 직접 라우팅이 없어도 VXLAN 터널을 통해 Pod 간 통신이 가능.
- 따라서 클라우드 환경이나 VPC 내부 통신만 허용된 환경에서 매우 적합.
- EC2 노드 간의 VPC 통신만 되면 VXLAN이 자동으로 IP를 캡슐화하여 라우팅 처리해줌.
- VPC 환경에서는 VPC 라우팅과 BGP 충돌 위험이 있음
- AWS의 기본 라우팅 테이블과 BGP 경로가 충돌하거나 비효율적인 경로를 만들 수 있음.
- VXLAN을 쓰면 노드 간 트래픽은 VPC 경로를 그대로 사용하면서, 내부적으로 Pod 트래픽을 깔끔하게 캡슐화함.
- Calico 공식 문서도 클라우드 환경에서는 VXLAN을 권장
- 특히 AWS, GCP, Azure 같은 퍼블릭 클라우드 환경에선 대부분 BGP 대신 VXLAN을 기본 권장합니다.
7. 설치 확인
kubectl get pods -n calico-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-6778c58446-kv8kn 1/1 Running 0 19h
calico-node-ttpsg 1/1 Running 0 19h
calico-typha-556858b96d-btrjs 1/1 Running 0 19h
csi-node-driver-ghh88 2/2 Running 0 19h
kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-node Ready control-plane 20h v1.30.12
kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-apiserver calico-apiserver-88cc84d78-9jlcw 1/1 Running 0 19h
calico-apiserver calico-apiserver-88cc84d78-hg6px 1/1 Running 0 19h
calico-system calico-kube-controllers-6778c58446-kv8kn 1/1 Running 0 19h
calico-system calico-node-ttpsg 1/1 Running 0 19h
calico-system calico-typha-556858b96d-btrjs 1/1 Running 0 19h
calico-system csi-node-driver-ghh88 2/2 Running 0 19h
kube-system coredns-55cb58b774-gq4dw 1/1 Running 0 20h
kube-system coredns-55cb58b774-t4kgw 1/1 Running 0 20h
kube-system etcd-master-node 1/1 Running 0 20h
kube-system kube-apiserver-master-node 1/1 Running 0 20h
kube-system kube-controller-manager-master-node 1/1 Running 0 20h
kube-system kube-proxy-zpjm9 1/1 Running 0 20h
kube-system kube-scheduler-master-node 1/1 Running 0 20h
tigera-operator tigera-operator-8955b7496-6zs7w 1/1 Running 0 19h
우여곡절 끝에 마스터 노드 설정 완료!!! 이제 다음은 워커 노드 설정과 도메인 등록, helm, argocd 등등 할게 많이 남았다!