Serive proxy

proxy and service

(이미지는 ClusterIP 기준)

  • kube-proxy는 고전적 의미의 proxy가 아니라 서비스에 대한 가상 IP를 구현하기 위함
  • proxy를 사용하는 이유는 인바운드 트래픽을 백엔드에 전달하기 위함.

Proxy mode

  1. Userspace
    • Service가 생성되면 Node에 Proxy port 생성
    • 클라이언트 요청 인입 시, iptables는 요청한 ClusterIP와 Port를 확인하고, Proxy Port로 트래픽 라우팅
    • kube-proxy는 기본적으로 Round Robin 방식으로 백엔드 Pod 선택 + Session Affinity(AWS ELB의 Stick Session과 동일)에 따라 Pod 중 하나를 선택하여 트래픽 전달
      • Pod로의 요청 실패 시 자동으로 다른 Pod로 연결 재시도
      Userspace
  2. iptables : default proxy mode. userspace와 달리 kube-proxy는 iptables만 관리하며, 직접 트래픽을 받지 않음. iptables을 거쳐 요청이 직접 포드로 전달되어 userspace보다 빠르다.
    • Service 생성되면 Node에 kube-proxy에 의해 iptables 갱신
    • 클라이언트 요청 인입 시, 패킷의 Target이 Service의 IP와 Port로 설정
    • iptables의 rule 중 맞는 Backend가 있다면 Random하게 선택
      • pod로의 요청 실패 시 재시도 없이 그냥 실패. 방지를 위해 Readiness Probe(컨테이너의 요청 준비 여부 확인) 설정 필요
    • 지정된 Pod으로 패킷 전달 전, 패킷의 Target의 IP와 Port를 해당 Pod으로 수정
    iptables
  3. IPVS : Linux 커널 제공 L4 LB인 IPVS가 Proxy 역할을 수행. iptables보다 높은 성능(low latency & high throughput)IPVS

'Docker & k8s' 카테고리의 다른 글

[K8S] 4. Cluster Networking  (0) 2022.02.03
[K8S] 3. Kubernetes Network Commands  (0) 2022.02.03
[K8S] 2. Kubernetes Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17

Cluster Networking

  1. Pod 내 Container간 통신
  • veth0(VNI)는 하나의 IP를 사용하며, 각 컨테이너끼리는 port 번호로 서로를 구분

2. Pod-to-Pod 통신

  • Pod 하나는 고유한 IP 주소를 가지며, IP 주소로 서로 통신

3. Pod-to-Serivce 통신

  • Pod는 죽었다가 살아날 수 있고, IP 주소가 동일할 것이라는 보장이 없기 때문에, Service 앞단에 reverse-proxy나 Load Balancer를 둠으로써 통신이 가능
  • service 정의 시 selector를 통해 트래픽을 전달할 Pod를 결정

4. External-to-Service 통신

Service

  • Pod는 클러스터 내에서 노드를 옮기며 IP가 변경됨
  • 동적으로 변하는 Pod의 IP를 특정하기 위한 방법이 Service
  • label과 label selector를 활용하여, 어떤 Pod를 Service로 묶을지 정의

Service Type (서비스를 외부 IP 주소에 노출하는 방법)

ClusterIP

  1. ClusterIP : 클러스터 내부에서만 접근. 실서비스에서 단독 사용 X
    • 기본적으로 외부와 통신 불가
    • 외부와 통신을 위해서는
      • netfilter chain rule을 통해 IP로 들어온 패킷을 각 Pod에 포워딩하는 설정을 하거나
      • worker node 내 reverse proxy를 생성하여 ClusterIP로 패킷 포워딩
      • 위 세팅을 EKS에서 진행하기 위해서는 EKS cluster 생성 시에 ssh 접근을 위한 값들을 입력해주어야 함
  2. NodePort : 모든 Node에서 특정 포트를 열고, 이 포트로 보내지는 모든 트래픽을 서비스로 forwarding
    • 포트당 한 서비스만 할당
    • 30000~32767 사이 포트만 사용 가능
    • Node의 IP주소가 바뀌면 이를 반영해야 함
  3. LoadBalancer : 모든 트래픽이 로드밸런스를 거쳐 서비스로 포워딩
    • AWS EKS에서 LoadBalancer 타입은 NLB를 프로비저닝 (L7을 사용하려면 Ingress 타입으로 배포)
  4. Ingress : 도메인 및 경로를 기반으로 들어오는 패킷을 특정 서비스로 포워딩
    • AWS EKS에서 Ingress 타입은 ALB를 프로비저닝함
    • ingress 사용 이전에 clusterIP나 NodePort 타입의 서비스가 생성되어 있어야 함
    • worker node 내부에 ingress를 감지하여 로드밸런서를 프로비저닝하는 ingress controller가 있어야 함

ETCD

  • 2379 포트에서 클라이언트 통신을 받고, 2380포트에서 서버간 통신

Reference

'Docker & k8s' 카테고리의 다른 글

[K8S] 5. Kubernetes Service Proxy  (0) 2022.02.03
[K8S] 3. Kubernetes Network Commands  (0) 2022.02.03
[K8S] 2. Kubernetes Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17

Command network

  • Network interface : ip a, ip link
    • state 확인 가능
  • MAC address of ControlPlane : ip link show etho0
  • arp -a
  • 외부 통신 : ip route show default
  • 모든 열린 TCP 소켓 리스트 : netstat -nplt
  • 포트의 상태 확인 : netstat -anp

CNI

  1. /opt/cni/bin : 설치된 CNI의 배포 패키지 확인
    • 네트워크 인터페이스 : 인터페이스를 컨테이너의 Network Namespace에 추가하고, 호스트와 연결 (veth pair)
      • BRIDGE, VLAN, IPVLAN, MACVLAN, WINDOWS 등
    • IPAM 플러그인 : 인터페이스에 IP를 할당하고, Routing Table 갱신
      • host-local, dhcp, static 등
  2. /etc/cni/net.d : 설치된 CNI의 설정 파일
    • 예를 들어 Calico 설치시, 설정 파일을 /etc/cin/net.d/10-calico.conflist에 저장하는 식
  3. kubectl get daemonset -n kube-system : CNI에 해당하는 daemonset 확인
  • weave-net deploy : kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
  • cluster ip range : cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep cluster-ip-range
  • kube exec -it pod -- sh로 쉘 실행 이후, curl http://web-service.default.svc 등 FQDN을 통해 액세스 여부 판단 가능
    • ex> bacekend-database.default.svc.cluster.local
      • backend-database : 서비스 이름
      • default: 서비스가 정의된 namespace
      • svc.cluster.local : 클러스터의 도메인 접두사
  • k exec -it hr -- nslookup mysql.payroll > /root/CKA/nslookup.out

'Docker & k8s' 카테고리의 다른 글

[K8S] 5. Kubernetes Service Proxy  (0) 2022.02.03
[K8S] 4. Cluster Networking  (0) 2022.02.03
[K8S] 2. Kubernetes Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17

image list

kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
  • k get nodes
  • k get pods --all-namespaces
  • pod이 어느 노드인지 : kubectl get pods -o wide
  • replicaset : k get rs

컨테이너 이미지 변경

kubectl patch rs new-replica-set --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"busybox"}]'
  • rs yaml 추출 : k get rs new-replica-set -o yaml
  • 리소스 강제 교체 : k replace --force -f sample.yaml
  • rs replicas 수 변경 : k scale --replicas=2 rs/new-replica-set
  • namespace list : kubectl get ns
  • k apply -f sample.yaml --namespace=finance
  • 도메인 명명 : 서비스. namespace. svc.cluster.local
  • imperative pod deploy : k run nginx-pod --image=nginx:alpine
  • 리소스 수정 : kubectl edit deployment frontend

--label 옵션 지원 종료

k run redis --image=redis:alpine
k label pod redis tier=db

서비스 명령형 생성

k expose pod redis --port=6379 --name=redis-service --type="ClusterIP"

  • 모든 라벨 : k get pod --show-labels
  • 특정 라벨 모든 리소스 : k get all -l env=prod
  • taint 걸기 : k taint node node01 spray=mortein:NoSchedule
    • 순서 : key=value:효과

yaml 파일 생성 (기본 토대)

  • k run nginx --image=nginx --dry-run=client -o yaml > nginx.yaml
  • dry-run 옵션을 통해 실제 리소스를 생성하지 않고 yaml만 생성

Node Affinity

required

  • kubectl apply -f https://k8s.io/examples/pods/pod-nginx-required-affinity.yaml --dry-run=client -o yaml > require.yaml

prefered

  • kubectl apply -f https://k8s.io/examples/pods/pod-nginx-preferred-affinity.yaml --dry-run=client -o yaml > prefer.yaml
  • daemonset describe : k describe daemonset kube-flannel-ds -n kube-system
  • static pod path 등 config 확인
    1. ps -aux | grep kubelet
    2. 결과 중 --config=/var/lib/kubelet/config.yaml 확인
    3. vi /var/lib/kubelet/config.yaml 중 static pod path 확인

multiple scheduler

  • leader-elect
  • 여러 개 secret 생성 : k create secret generic db-secret --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123

유지보수 (drain)

  • k drain node01 --ignore-daemonsets
  • cordon과 차이는 SchedulingDisable된 노드의 Pod를 삭제하고 재생성
    • 이러한 특징으로 사용 가능한 node가 없을 때 drain 대신 cordon을 써야함
  • 오류 뜨면 --force 옵션 추가
  • 다시 스케줄링 추가 : k uncordon node01

Control Plane node 업그레이드

Kubeadm 업그레이드
  • k drain controlplane --ignoe-daemonsets으로 master node SchedulingDisable 한 이후
  • apt-get update && apt-get install -y --allow-change-held-packages kubeadm=1.20.0-00
  • kubeadm upgrade plan
  • kubeadm upgrade apply v1.20.0
    kubelet 업그레이드
  • apt install kubelet=1.20.0-00
  • kubelet 재시작
    • sudo systemctl daemon-reload
    • sudo systemctl restart kubelet

worker node 업그레이드

  • ssh node01
  • apt-get update && apt-get install -y --allow-change-held-packages kubeadm=1.20.0-00
  • kubeadm upgrade node
  • apt install kubelet=1.20.0-00
  • sudo systemctl restart kubelet
  • exit

Etcd snapshot

  • export ETCDCTL_API=3
  • ps -aux | grep -i etcd
etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \                                           
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key \
snapshot save /opt/snapshot-pre-boot.db

Etcd backup restore

  1. etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \

--cert=/etc/kubernetes/pki/etcd/server.crt
--key=/etc/kubernetes/pki/etcd/server.key
--data-dir=/var/lib/etcd_backup --initial-advertise-peer-urls=https://10.5.159.9:2380 --initial-cluster=controlplane=https://10.5.159.9:2380 --name=controlplane snapshot restore /opt/snapshot-pre-boot.db

  1. /etc/kubernetes/manifests의 hostPath 수정

name of CA

  • openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text

cluster 변경

  • k config use-context research --kubeconfig=/root/my-kube-config

Assign 된 Role

  • k describe rolebinding kube-proxy -n kube-system

Role yaml

  • k create role developer --verb="*" --dry-run=client --resource=pod -o yaml > drole.yaml

RoleBinding yaml

  • k create rolebinding dev-user-binding --role=developer --user=dev-user --dry-run=client -o yaml > rb2.yaml

PV yaml

  • kubectl create -f https://k8s.io/examples/pods/storage/pv-volume.yaml --dry-run=client -o yaml > pv.yaml

'Docker & k8s' 카테고리의 다른 글

[K8S] 4. Cluster Networking  (0) 2022.02.03
[K8S] 3. Kubernetes Network Commands  (0) 2022.02.03
[K8S] 1. Kubernetes Core Component  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17
쿠버네티스(k8s)는 무엇인가  (0) 2020.12.17

Cluster Architecture

  • worker node : 컨테이너를 로드할 수 있는 노드
    • pod(컨테이너의 집합-network 스택을 공유하여 localhost를 통해 서로에 도달 가능)를 호스팅
  • control plane : 노드에 대한 정보를 저장하고, 노드 내 컨테이너의 위치를 모니터링 하고 추적
    • 워크 노드와 클러스터 내 pod를 관리
    • 여러 인스턴스에 분산되어 실행되고, 클러스터는 여러 노드를 실행 -> 고가용성 및 내결함성

Control Plane Component

클러스터에 대해 스케줄링 등을 수행 & 클러스터 이벤트를 감지하고 반응

  1. kube-apiserver
    • 쿠버네티스 API를 제공하는 API 서버
  2. etcd
    • key-value 형태로 컨테이너가 어떤 노드에 위치하는지, 로드된 시간 등 모든 클러스터 데이터를 저장하는 DB
  3. kube-scheduler
    • Kubelet(클러스터의 각 노드에서 실행되는 agent)가 pod를 실행할수 있도록 pod가 노드에 적합한지 확인하는 것
    • 새로 생성된 pod를 실행할 노드를 선택하는 컴포넌트
    • 즉, scheduler는 pod가 어디로 갈 지만 결정하고, 실제 pod를 노드에 위치하는 건 kubelet의 역할

  1. kube-controller-manager
    • 스케줄러를 참고하여 정확한 수의 pod이 실행되게 하며, pod에 문제가 생겼을 시 감지하고 대응
    • 노드 컨트롤러 : 노드가 다운되었을 때 통지와 대응 (상태 감시 및 대응 조치)
    • replication 컨트롤러 : 알맞은 수의 pod를 유지하기 위함
    • endpoint 컨트롤러 : 서비스와 pod를 endpoint로 연결
    • service account & token 컨트롤러 : namespace(클러스터 안에서 논리적으로 분리 - ex:dev,stage,prod)에 대한 계정과 API 접근 토큰을 생성
  2. cloud-controller-manager
    • 클러스터를 CSP의 API에 연결하며, CSP, 클러스터와만 각각 상호작용하는 컴포넌트를 구분함
    • 노드 컨트롤러 : 노드가 응답을 멈춘 후, 클라우드에서 삭제되었는지 확인 요청
    • 라우트 컨트롤러 : 클라우드 인프라에 경로 구성
    • 서비스 컨트롤러 : CSP 로드밸런서를 생성, 업데이터, 삭제 요청

Node Component

  1. kubelet
    • 클러스터의 각 노드에서 실행되는 agent
    • kube-apiserver를 경유하여 node에 컨테이너를 배포하거나 파괴
  2. kube-proxy
    • worker node의 애플리케이션끼리 서로 통신이 가능하도록 함(ex:db<->server)
    • 노드의 네트워트 규칙을 관리
  3. container runtime
    • Docker, ContainerD, Rocket 등 런타임 엔진

'Docker & k8s' 카테고리의 다른 글

[K8S] 3. Kubernetes Network Commands  (0) 2022.02.03
[K8S] 2. Kubernetes Commands  (0) 2022.02.03
도커란? (Docker)  (0) 2020.12.17
쿠버네티스(k8s)는 무엇인가  (0) 2020.12.17
도커 컨테이너 한꺼번에 종료  (0) 2020.11.28

Docker

도커는 컨테이너 기반 오픈소스 가상화 플랫폼이며,
라이브러리, 시스템 도구, 코드, 런타임을 포함한 소프트웨어를 컨테이너로 패키징시키는 것이다.

로컬 PC, AWS, GCP, Azure 등 환경에 관계없이 빠르게 배포 및 테스트할 수 있다.

Container 가상화

VM:container

  • Virtual Machine 가상화
    • Hypervisor 위에 Guest OS가 구동
    • 별도의 VM과 OS를 필요로 하기 때문에 자원의 비효율성(용량, 메모리)
  • Container 가상화
    • Docker 엔진을 통해 각 App이 OS 자원을 직접 사용 (앱 실행에 필요한 자원만 사용)
    • 별도의 OS 없이 Docker 엔진 공유 (가벼움)

Docker image

이미지는 컨테이너 실행에 필요한 파일과 설정값을 포함하고 있는 것이다. 즉, 컨테이너는 이미지를 실행한 상태이다.

Docker Container

컨테이너란 격리된 공간에서 프로세스가 동작하는 기술이다. 컨테이너는 프로세스를 격리하는 방식이기 때문에 기존 가상화 기술에 비해 가볍고 빠르다.

Docker cacheing

한번 이미지를 빌드한 뒤 dockerfile에 동일한 명령어가 있으면 이전의 빌드에서 사용했던 캐시를 사용한다. build할 때 using Cache log가 나오는 것을 확인할 수 있다. 캐시가 필요하지 않다면 --no-cache 옵션을 추가하면 된다.

Dockerfile

  • FROM절 : 컨테이너의 원형(틀) 역할을 할 도커 이미지(OS)를 정의한다.
  • COPY절 : 쉘 스크립트 파일을 도커 컨테이너 안의 /usr/local/bin에 복사하기 위하여 정의한다.
  • RUN절 : 도커 컨테이너 안에서 명령을 수행하기 위함. 여기까지 도커 빌드 과정에서 실행되며 그 결과로 새로운 이미지가 만들어진다.
  • CMD절 : 완성된 이미지를 도커 컨테이너로 실행하기 전에 먼저 실행할 명령을 정의한다.

코드로 관리하는 인프라(IaC)와 불변 인프라(Immutable Infrastructure)

  • IaC : 서버를 어떻게 구성할 것인지, 어떤 라이브러리와 도구를 설치할지를 코드로 정의하고 Chef나 Ansible 같은 프로비저닝 도구로 서버를 구축
    • stable 버전을 install하는 코드를 실행하는 예시를 들면, stable 버전은 자주 변하기 때문에 항상 같은 결과를 보장하지 않는 단점이 있음
  • 불변 인프라(Immutable Infrastructure) : 어떤 시점의 서버 상태를 저장해 복제할 수 있게 하는 개념
    • 서버에 변경을 원할 때는 새로운 서버를 구축하고 그 상태를 이미지로 저장한 다음, 해당 이미지를 복제
  • 도커를 사용하면 IaC와 불변 인프라의 개념을 간단하고 낮은 비용으로 실현할 수 있음
    • 인프라 구성이 Dockerfile로 관리되므로 IaC는 도커의 대원칙
    • 컨테이너형 가상화 기술 사용을 통해, 기존 컨테이너를 빠르게 폐기하고 새롭게 구축 가능 (불변 인프라)

Container Orchestration

  • 도커 컴포즈를 단일 서버를 넘어 여러 서버에 걸쳐 있는 여러 컨테이너를 관리할 수 있도록 한것이 도커 스웜(Docker Swarm)이다.
  • 도커 스웜은 컨테이너 증가, 감소는 물론, 노드의 리소스를 효율적으로 활용하기 위해 컨테이너 배치 및 로드 밸런싱 등의 기능을 갖춤
  • 배포 시 롤링 업데이트가 가능 (오래된 컨테이너와 새로운 컨테이너를 단계적으로 서비스에 교체 투입하는 것)
  • 이렇게 여러 서버에 걸쳐 있는 여러 컨테이너를 관리하는 기법은 컨테이너 오케스트레이션이라고 한다.
  • 컨테이너 오케스트레이션의 표준은 쿠버네티스(k8s)이다.

Docker Network Mode

  1. bridge
    • docker 기본 네트워크 방식
    • 각 컨테이너마다 고유한 network namespace 영역이 생성
    • docker daemon을 실행하면 docker0라는 bridge가 생성되며 해당 bridge에 container들의 인터페이스들이 하나씩 binding되는 구조
  2. host
    • 컨테이너가 독립적인 네트워크 영역을 갖지 않고 host와 네트워크를 함께 사용
    • docker run --net=host httpd web01 과 같이 생성
    • 컨테이너의 ip와 인터페이스 정보는 host의 네트워크 정보와 동일
    • host옵션으로 생성된 컨테이너는 bridge를 사용하지 않으므로 docker0에 바인딩되지 않는다.
  3. container
    • 기존 존재하는 다른 컨테이너의 network 환경을 공유
  4. none
    • 격리된 네트워크 영역을 가지지만, 인터페이스가 없는 상태로 컨테이너 생성
    • bridge에도 연결되지 않은 상태이며, 이 상태로는 외부 통신 불가
    • 인터페이스를 직접 커스터마이징하기 위한 옵션

+ Recent posts