서버와 클라이언트 입장
- Server: ip와 이름을 DNS에 등록
- Client가 랜선/와이파이로 인터넷 접속하면, DNS의 ip주소가 internet provider에 의해 자동 세팅됨 (dhcp)
- Client: 이름에 접속 -> 호스트 파일에 없음 -> DNS에 ip 질의 -> ip 응답받음 -> 그걸로 접속
등록 과정!
- ICANN: 전세계 ip 주소 관리, 루트 네임 서버의 관리 (인터넷 체계 관리자)
- Root name server (a~m.root-servers.net)이 전 세계에 흩어져서 관리됨
- 수백개의 성능좋은 서버들이 전세계에 있음
- com, net 등 도메인이 어떤 Registry에서 관리되는지를 저장
- com NS a.gtld-servers.net 을 저장
- Registry: .com, .net 등 탑 레벨 도메인 관리
- authoritative name server를 저장해둠
- example.com NS a.lana-servers.net 을 저장
- NS 레코드를 저장!
- Registrar 등록 대행자
- authoritative name server를 통해 도메인을 등록하자
- example.com 과 내 IP를 연결
- example.com A 93.183.21.39 를 저장
- A 레코드를 저장!
접속 과정
- 클라이언트가 LAN/와이파이 꽂으면 ISP가 DNS 서버 ip 세팅함
- 전 세계에 있는 모든 DNS 서버는 Root Name Server를 알고 있음!
-
-
public dns
- dns server를 원래 isp가 자동으로 제공
- 자신이 원하는 dns server를 통해 ip 주소 조회하도록 변경할 수 있음
- 1.1.1.1 cloudflare가 만든 걸로 바꿔봄
nslookup
-
- nslookup -type=a joel-dev.site
- joel-dev.site의 A 레코드를 조회 (타입 안쓰면 이게 디폴트)
- DNS로 부터 순차적으로 NameServer-Registry-Registrar 조회하고 Registrar 등록 대행자에서 ip 주소와 도메인 정보를 가져옴
- 하지만 dns를 통해 가져온 친구들이 캐싱 및 원본 출처에서 직접 가져온게 아니니 권한없는 응답이라고 뜬것이여
- nslookup -type=ns joel-dev.site
- joel-dev.site의 네임 서버를 조회해와라
- 나는 가비아에서 등록했으니까, 가비아의 주소 반환
- nslookup joel-dev.site ns.gabia.co.kr
- 이게 가비아 Registrar 등록 대행자에서 joel-dev.site 땡겨와주세요
- 이러면 이제 원본 출처 명확하니까 권한 없음 생략되어 가져올 수 있지롱
DNS record & CNAME
- 참고: https://en.wikipedia.org/wiki/List_of_DNS_record_types
- DNS record: DNS 서버에 저장하는 어떤 도메인에 대한 정보 1건
- A 형식: IP 주소와 연결해주세요~
- NS 형식: 어떤 도메인에 대한 처리를 다른 도메인 네임 서버에 위임해주세요~
- CNAME 형식: 도메인에 대한 별명을 지정해주세요~
컨테이너는 프로세스를 관리
- 프로세스
- 실행중인 프로그램으로, '프로그램의 명령'과 '실행시에 필요한 정보' 조합의 오브젝트
- 프로그램이 OS에 의해 실행되는 단위
- 저장장치에 있는 프로그램 실행시, 실행할 때의 명령과 실행하는데 필요한 정보들을 메모리에 적재
- 단일 CPU는 하나의 프로세스만 수행
- 컨테이너는 프로세스를 추상화!
- 컨테이너가 프로세스 생성/운영/제거까지의 생애주기 관리
- 이때 필요한게 격리!
- 컨테이너는 Host OS의 시스템 커널 사용
- 하지만 파일시스템은 달라짐
- chroot: 루트 파일 시스템을 강제로 인식시켜 프로세스를 실행
- 컨테이너 안에서는 자기가 첫번째!
- 지가 init 프로세스
컨테이너 네트워크
- 컨테이너 생성시 => 독자적 파일시스템, 네트워크 인터페이스도 생성됨
- 컨테이너에 MAC 주소와 IP 주소가 할당되어 있음
- 해당 컨테이너의 라우팅 테이블에서, 모르는 대역의 경우 172.17.0.1으로 보내라고 설정
- docker0를 통해 다른 컨테이너에게 통신을 보내게 됨
- 172.17.0.1??
-
- gateway, 이 네트워크는 bridge를 활용
- HostOS의 docker0가 점유중
- 컨테이너마다 부여될 IP 주소 매번 확인 어려움
- 그래서 포트포워딩을 활용
- HostOS가 직접 요청을 처리할 수 있게됨!
- 약간 공유기 공부한거랑 느낌이 비슷한거같기도??
목표
- 완벽한 시스템은 없음. 일정 수준의 장애는 허용할 수 밖에 없음
- 사용자가 납득할만한 수준의 가용성 & 배포 사이클
가용성
- 시스템이 서비스를 정상적으로 제공할 수 있는 상태
- 가용성 높이기 위해 단일 장애점(SPOF) 없애고, 확장성 있는 서비스 만들것
- 단일 장애점(SPOF)
- 서버 장비 장애 / 어플리케이션 서버 장애 / DB 서버 장애날 경우 모두 서비스 중단됨
- 따라서 모든 요소를 이중화 해야 단일 장애점 극복!
- 다중화
- 장애가 발생해도 예비 운용장비로 시스템의 기능을 계속할 수 있도록 함
- 단일 장애점 없애고 다중화하자!
- Server, Load balancer, Network Device 등의 다중화
- Master-Slave DB Replication
사용자
- 성능 테스트 시엔 실제 지연이 발생하는 구간 파악하자
- 인터넷 구간: 정적 파일 크기, Connection 관리, NW 환경 등
- Server 구간: DB와 어플리케이션 간 연결의 문제, 프로그램 로직 상의 문제 혹은 서버의 리소스 부족
- 상위 5%의 화면이 95%의 사용자 요청을 받는다!
테스트 종류
- Smoke Test
- 최소한의 부하로 구성
- 테스트 시나리오 오류 체크
- 최소 부하 상태에서 시스템에 오류 발생하지 않는지 확인
- Load Test
- 서비스의 평소 트래픽과 최대 트래픽 상황에서 성능 확인
- 어플리케이션 배포 및 인프라 변경 시 성능 변화 확인
- 외부 요인 (결제 등) 예외 상황 확인
- Stress Test
- 서비스가 극한의 상황에서 어찌 돌아가는지 확인
- 장기간 부하 발생의 한계치 확인, 기능 정상 동작 확인
한 대의 WAS
- 성능 문제 발생 시, 단일 사용자에 대한 응답 속도 느려짐
- 확장성에 문제 있다면, 단일 사용자에게는 빠르지만 부하 많아질 경우 속도 느려질 수 있음
컨테이너
- 컨테이너 단위로 존재하면 타 컨테이너에 영향 주지 않음
- 문제점
- 어플리케이션 버전 변경 시 어떻게 배포할 것인가?
- 컨테이너 죽으면 Health Check는 어떻게?
- 새로 컨테이너 생성하면 IP는 Reverse Proxy에 어찌 등록?
- 부하를 감당하기 위해 컨테이너 어느 시점에 확장?
- 새로운 컨테이너에 대해 IP 중복 이슈는?
Orchestration
- Master Node의 관리 아래 다양한 컨테이너 구동하여 최상의 서비스 제공
- 쿠버네티스에는 "바라는 상태" 보유
- Controller가 시스템의 리소스 지켜보는 중
- Container 수가 "바라는 상태"와 다르면 조정
- 쿠버네티스가 서버의 리소스를 알아서 관리해줌
- 최적의 노드 찾아 배치
- 필요시 자동 리소스 확장
구성요소
-
- Pod
- 컨테이너의 생성/운영/제거 등을 관리
- 쿠버네티스는 Pod 기준으로 사고
- Pod 하나 당 하나의 컨테이너
- Service (Endpoint 담당)
- 하나의 애플리케이션 Pod 묶음
- Pod들의 안정적인 끝점 보장
- Replicaset (복제 담당)
- "바라는 상태"에서 Pod의 갯수가 하나 부족하다면 새로 생성
- Deployment (배포 담당)
- 롤링 업데이트 지원
- n대의 서버에 새로운 버전 교체해가는 방식
- 롤링 업데이트되는 Pod의 비율 조절 가능
- 배포되고 있는 상태 확인 가능
- 업데이트 히스토리 저장/롤백 가능
- Scale out 기능 지원
- Ingress (Reverse Proxy)
- TLS 및 도메인 기반 라우팅
쿠버네티스 아키텍쳐
-
- Master Node
- Worker Node 관리
- api server
- k8s 모든 구성요소 api 서버와 통신
- etcd
- 바라는 상태를 key-value로 저장
- 모든 object (pod/replicaset/service 등) 정보 분산저장
- etcd 인스터느는 홀수로 구성
- Worker Node
- Pod가 속해있음
- 절차
- kubectl 명령어로 요청
- api server로 요청 주고받음
- api server에서 object 변경하고 etcd에 기록
- controller가 변경 감지하고 다음 요청 진행
- scheduler가 적절한 Worker Node에 Pod 할당
- kubulet이 Pod의 container 실행
- Node의 상태를 kubelet이 전달