서문
다음은 숙련된 쿠버네티스 실무자를 위한 Edgio Delivery CDN 서비스와 쿠버네티스를 통합하는 예입니다. Kubernetes에 대한 지식 수준과 TCP, DNS 및 HTTP/HTTPS와 같은 표준 인터넷 프로토콜에 대한 지식을 가정합니다. 마지막 목표는 Edgio Delivery CDN 서비스를 표준 침투로 보이게 하는 방법을 시연하는 것입니다. 쿠버네티스 사용자는 Portainer 또는 Terraform 과 같은 익숙한 시스템에서 인그레스 구성을 유지할 수 있다.
쿠버네티스
Kubernetes.io는 Kubernetes를 “컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하는 오픈 소스 시스템”이라고 정의합니다. 클러스터를 실행하는 방법에는 여러 가지가 있습니다. 가장 빠르고 쉬운 방법은 “원 클릭” 배포를 허용하는 많은 클라우드 공급자 중 하나를 활용하는 것입니다.
쿠버네티스 클러스터는 많은 부분을 포함한다. 데모에서는 전체의 하위 집합에 중점을 둡니다.
쿠버네티스 부품
- 노드: 워크로드 및 서비스를 호스팅하는 시스템 또는 VM입니다.
- 워크로드: 애플리케이션 단순 또는 복합
- POD: 어플리케이션 소프트웨어가 실행되고 있는 컨테이너입니다. 하나 이상의 POD가 워크로드를 구성합니다.
- 서비스: 워크로드를 다른 워크로드에 노출시키거나 침투시키는 메커니즘
- 수신: 서비스를 외부 세계에 노출시키는 메커니즘
에드지오
Edgio는 원활하게 통합된 전송, 애플리케이션 및 스트리밍 솔루션을 통해 엣지에서 탁월한 속도, 보안 및 단순성을 제공함으로써 커넥티드 라이프를 더욱 빠르고 안전하고 간편하게 관리할 수 있도록 지원합니다. 전 세계적으로 확장된 기술과 전문가 서비스는 세계 유수의 브랜드들에게 가장 빠르고, 가장 역동적이며, 마찰 없는 교육, 엔터테인먼트, 이벤트 및 애플리케이션을 모든 사용자에게 제공할 수 있는 역량을 제공합니다. 탁월한 고객 서비스를 제공하고 모든 단계에서 가치를 확장하기 위해 최선을 다하는 Edgio는 가장 인기있는 쇼, 영화, 스포츠, 게임 및 음악, 즉석 로딩 웹 사이트를 지원하기 위해 전 세계 인터넷 트래픽을 유도하는 파트너입니다.
아키텍처
Edgio 전송 CDN
이 데모에서는 GitHub에서 Edgio Python SDK를 사용합니다 – llnw/llnw-sdk-python: Limelight Networks Python SDK. 기본 구성은 단순하게 유지됩니다.
CDN을 구성하는 경우 인증 이외의 다음과 같은 데이터가 필요합니다.
- 약식 이름: CDN 규칙이 포함된 Edgio Delivery CDN 내의 고유 식별자입니다.
- 게시된 호스트 이름: CDN에서 인터넷과 마주하는 호스트 이름. 이 데모의 경우 호스트 이름 cstradtman.s.llnwi.net 이전에 구성되었습니다.
- 게시된 URL 경로: 문제의 특정 규칙에 매핑된 경로입니다.
- 소스 호스트 이름: 오리진의 호스트 이름입니다. 이 경우, 라운드 로빈 레코드는 쿠버네티스 클러스터를 가리킨다.
- 소스 URL 경로: 호스트 이름과 연결된 대상 경로입니다. 이 경우 이 문서의 뒷부분에서 설명하므로 비어 있습니다. 이 데모에서는 경로가 아닌 포트 번호로 워크로드를 구분합니다.
DNS
이 데모에서는 Vultr DNS API를 사용합니다. IP 주소를 오리진으로 사용하여 CDN을 구성하는 것은 Best Practice가 아닙니다. 이 데모에서는 API를 사용하여 클러스터 노드를 가리키는 라운드 로빈 A 레코드를 생성하거나 수정합니다.
클러스터
이 데모는 Vultr에서 3노드 클러스터로 구성되어 있습니다.
네임스페이스
데모는 이 클러스터에서 실행되는 유일한 것이므로 기본 네임스페이스 아래에 존재합니다.
노드
- VKE 클러스터 – 각각 다음을 포함하는 3개의 노드
- 4G 램
- 80g 디스크
- vCPU 2개
- 1G 네트워크
워크로드
워크로드는 HTTP 연결에 대한 기본 정보를 반환하는 간단한 Python 프로그램입니다. 이 데모는 일반적인 배포 방법이 아닌 인라인으로 배포합니다. 그러나 컨테이너를 빌드하고 저장하기 위한 외부 의존성이 아니라 데모를 완전히 독립적으로 사용할 수 있습니다. 소스 코드는 부록 1에 나와 있습니다. 실제 Python 코드는 기울임꼴로 표시되고 배포를 설명하는 YAML 코드는 기울임꼴로 표시되지 않습니다. 워크로드는 TCP 포트 8000을 사용합니다.
서비스
여러 가지 서비스 유형을 사용할 수 있습니다. “NodePort” 서비스 유형을 사용하고 있습니다. 무작위로 선택된 상위 포트 번호에 있는 클러스터의 외부 IP 주소에 서비스를 노출합니다. Kubernetes는 워크로드가 실행되는 노드와의 연결을 관리합니다.
인그레스
Kubernetes Ingress는 클러스터 외부에서 Kubernetes 서비스를 사용할 수 있게 하는 리소스 컬렉션의 동작을 설명하는 소프트웨어 객체입니다.
수신 컨트롤러는 수신 소프트웨어 개체를 인스턴스화하는 소프트웨어 및/또는 하드웨어를 결합합니다.
CDN은 풍부한 기능을 갖춘 분산 역방향 프록시입니다. 역방향 프록시 기능 외에도 CDN은 일반적으로 유연한 캐시 알고리즘, 지리적 다양성, 보안 기능(ACL(GEO, Method, regex), 웹 애플리케이션 방화벽, 워터마킹 및 기타 단순한 역방향 프록시에서는 찾을 수 없는 고급 기능을 갖추고 있습니다.
쿠버네티스 객체 모니터링을 위한 API는 잘 정의되어 있으며, 다수의 HTTP 리버스 프록시와 로드 밸런서가 수신 컨트롤러로 작동하도록 확장되었습니다. 예를 들어, NGINX 와 HAProxy 는 침투 컨트롤러로 작동하도록 확장된 오래된 학교 프록시이며 Traefik 과 Itsio 와 같은 프록시는 쿠버네티스 와 병행하여 개발되었습니다. CDN은 단순한 역방향 프록시에서 자연스럽게 다음 단계로 진행되는 과정입니다. 이 데모의 경우 Edgio Delivery CDN을 제어하는 맞춤형 수신 컨트롤러를 만들 것입니다. 일반적으로 침입을 설명하는 데 필요한 데이터는 다음과 같습니다.
- 공용 호스트 이름: 쿠버네티스 서비스가 사용할 수 있는 호스트 이름
- public path: 쿠버네티스 서비스가 사용할 수 있는 Public 호스트 이름과 연관된 경로
- 백엔드 서비스 이름: Kubernetes 서비스 stanza에 의해 정의된 service-name
- 백엔드 포트: 서비스 설명의 포트 설명과 일치하는 이름
Edgio Delivery CDN 자산 매핑:
쿠버네티스 |
Edgio 전송 CDN |
공용 호스트 이름 |
게시된 호스트 이름 |
공용 경로 |
게시된 URL 경로 |
백엔드 서비스 이름 쿠버네티스 클러스터 내에서 유일함 외부 세계에 알려지지 않음/사용할 수 없음 |
소스 호스트 이름 정규화된 도메인 이름 실제로 일대일이 아닙니다. |
그 뒤에있는 논리는 다음과 같습니다.
- 클러스터에서 네임스페이스 수신 이벤트 수신 대기
- 이벤트 유형이 “추가”인 경우
- 클러스터에 있는 노드의 IP 주소 가져오기
- vultr에서 DNS 레코드 만들기
- 생성된 DNS 레코드와 NodePort 서비스에 의해 할당된 포트를 가리키는 Edgio CDN에서 CDN 규칙을 만듭니다.
- 이벤트 유형이 “수정됨”인 경우
- Edgio CDN에서 기존 수신과 일치하는 CDN 규칙 찾기
- 이벤트에 새 데이터를 반영하도록 Edgio CDN의 규칙 수정
- 이벤트 유형이 “삭제됨”인 경우
- Edgio CDN에서 제거된 수신과 일치하는 CDN 규칙 찾기
- 이 수신과 연결된 Vultr에서 DNS 레코드 제거
- 제거된 수신과 일치하는 CDN 규칙을 Edgio에서 제거합니다.
구성
개체
쿠버네티스 오브젝트는 YAML 파일에 설명되어 있다. 쿠버네티스에서 모든 설정은 객체이다. 모든 배포 구성을 단일 파일에 저장할 수 있습니다. 배포의 어느 부분에 대해 설명했는지에 따라 분해하는 것이 일반적입니다.
배포
부록 1에는 파이썬 코드와 YAML이 결합된 큰 YAML 파일이 있습니다. “spec.template.spec.containers.command” 이후의 모든 것은 배포 중에 컨테이너로 변환되는 파이썬 코드입니다. 쿠버네티스 객체의 관점에서 볼 때, 데모를 위해 우리에게 중요한 라인들은 다음과 같다:
- Kind: Deployment – 개체를 배포로 설명합니다.
- Metadata.name: Name 은 서비스 개체에서 둘 사이의 링크를 만드는 데 사용됩니다.
- Spec.selector.matchlabels.app: 배포가 적용될 파드를 알려줍니다.
- spec.template.spec.containers.image: 도커 허브 파이썬 3 공식 이미지를 가리킵니다.
- Spec.template.spec.containers.ports.name: 이 경우 다른 개체 서비스에서 참조할 포트의 레이블
- spec.template.spec.containers.ports.containerport: 실행 중인 컨테이너에서 노출되는 TCP 포트를 나열합니다.
서비스
- Kind: Deployment – 개체를 배포로 설명합니다.
- Metadata.name: Name 은 Ingress 객체에서 둘 사이의 링크를 만드는 데 사용됩니다.
- Spec.selector.app: 배포 개체에 명명된 pywai-inline-service라는 배포 이름을 가리킵니다.
- Spec.selector.type: Nodeport 위에서 설명한 대로 이 서비스를 Nodeport 형식으로 정의합니다.
- Spec.ports.name: 다른 개체에서 참조할 포트의 레이블(이 경우 Ingress)
- Spec.ports.protocol: 사용 중인 IP 프로토콜 정의 – TCP
- spec.ports.port: 이 서비스에 의해 노출되는 포트를 정의합니다.
- spec.ports.targetPort: 배포에 의해 노출되는 포트를 가리킵니다 – 이 경우 pywai-inline-deployment
인그레스
부록 3에서, Edgio 인그레스 컨트롤러를 위한 쿠버네티스 객체를 설명하는 YAML 파일을 볼 수 있다. 관련 객체는 다음과 같습니다.
- 종류: Ingress – 쿠버네티스에게 Ingress 객체임을 알려줍니다.
- Medatdata.name – 쿠버네티스의 모든 것에는 이름이 있어야 합니다.
- metadata.labels.cdn – 이 태그는 이 객체가 edgio 수신 컨트롤러를 위한 것임을 수신 컨트롤러에 알리는 데 사용됩니다.
- Spec.rules.host – 서비스를 노출할 공용 호스트 이름입니다.
- Spec.rules.http.paths.path – 서비스와 연결된 경로입니다.
- Spec.rules.http.paths.backend.service.name – 노출할 서비스의 레이블
- Spec.rules.http.paths.backend.service.port.name – 노출할 서비스 포트 레이블
구성 맵
비밀
쿠버네티스는 민감한 데이터의 저장을 위한 비밀 개념을 내장하고 있다. 이 데모에서는 Edgio SDK와 Vultr DNS API의 사용자 이름과 공유 키에 이 기능을 활용합니다.
코드 예제
이 데모의 코드는 git Repos에 포함되어 있습니다.
- Edgio 배달 파이썬 SDK
- 쿠버네티스 데모 배포
- https://github.com/llnw/edgio-delivery-k8s-demo
- 이것은 YAML로 묘사된 쿠버네티스 객체 시리즈로, Edgio Delivery 통합을 배포하는 방법을 보여줍니다.
- Edgio Delivery 인그레스 컨트롤러 데모
- https://github.com/llnw/edgio-delivery-k8s-ingress-demo
- 이것은 Edgio Delivery Ingress Controller를 구현하는 실제 코드입니다.
- 장기적으로는 Kubernetes 내에서 서비스로 실행되어야 하지만, 데모를 단순하게 유지하기 위해서는 별도의 프로세스로 실행됩니다.
현재 설계에 대한 향후 추가 및 개선 사항
향후 포스트에서는 어플리케이션 등의 다른 Edgio 솔루션을 활용하는 방법을 보여드리겠습니다. Kubernetes 클러스터를 다양한 워크플로우를 위해 여러 Edgio CDN 오퍼링 간에 구성을 활용하고 동기화하는 방법으로 사용할 수 있습니다.
부록 1 – pywai-inline-deployment.YAML
apiVersion: 앱/v1
종류: 배포
메타데이터:
이름: pywai-inline-deployment
사양:
선택기:
일치 레이블:
앱: pywai-인라인-배포
복제본: 1
템플릿:
메타데이터:
레이블:
앱: pywai-인라인-배포
사양:
컨테이너:
– 이름: 파이썬
이미지 : 파이썬 : 3
명령:
– /bin/sh
– “c”
– |
CAT > /test.py <<EOF
#!/usr/bin/env 파이톤3
“”
요청 로깅을 위한 파이썬의 매우 간단한 HTTP 서버
사용법::
./server.py [<포트>]
“”
http.server 가져오기 – BaseHTTPRequestHandler, HTTPServer
로깅 가져오기
인쇄 가져오기
클래스 S(BaseHTTPRequestHandler):
DEF _SET_RESPONSE(자체):
self.send_response(200)
self.send_header(‘Content-type’, ‘text/html’)
SELF.END_HEADERS()
DEF do_get(self):
logging.info(“GET 요청,\n경로: %s\n헤더:\n%s\n”, str(self.path), str(pprint.pformat(self.headers))
self._set_response()
headerinfo=pprint.pformat(self.headers.items())
clientinfo=pprint.pformat(self.client_address)
lineinfo=pprint.pformat(self.requestline)
versioninfo=pprint.pformat(self.request_version)
self.wfile.write(“<pre> {} </pre>”.format(headerinfo).encode(‘UTF-8’))
self.wfile.write(“<pre> {} </pre>”.format(clientinfo).encode(‘UTF-8’))
self.wfile.write(“<pre> {} </pre>”.format(lineinfo).encode(‘UTF-8’))
self.wfile.write(“<pre> {} </pre>”.format(versioninfo).encode(‘UTF-8’))
def run(server_class=HTTPServer, handler_class=S, port=8080):
logging.basicConfig(level=logging.Info)
server_address = (“, port)
httpd = server_class(server_address, handler_class)
logging.info(‘Starting httpd…\n’)
시도:
httpd.serve_forever()
키보드인터럽트 제외:
통과
httpd.server_close()
logging.info(‘Stopping httpd…\n’)
__NAME__ == ‘__MAIN__’인 경우:
sys 가져오기 argv에서
len(argv) == 2인 경우:
RUN(port=int(argv[1]))
기타:
실행()
EOF
실행 파이썬 /test.py 8000
포트:
– 이름: HTTP
컨테이너포트: 8000
부록 2 – pywai-inline-service.YAML
버전: V1
종류: 서비스
메타데이터:
이름 : 피와이 인라인 서비스
사양:
선택기:
앱: pywai-인라인-배포
유형: 노드 포트
포트:
– 이름: HTTP
프로토콜: TCP
포트: 80
타겟포트: 8000
부록 3 – pywai-edgio-ingress.yaml
버전: networking.k8s.io/v1
종류: 수신
메타데이터:
이름: 외부 pywai 인라인 진입
주석:
kubernetes.io/ingress.class: edgio
레이블:
CDN: 비디오
사양:
규칙:
– 호스트: <고유한 약칭을 입력하십시오> .s.llnwi.net
HTTP:
경로:
– 경로: /fred
경로 유형: 정확한
백엔드:
서비스:
성명 : 외부-피와이-인라인-서비스
포트:
이름: 피와이포트