Kubernetes Basics
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
The original author of this page is Jorge (read his original post here)
컨테이너를 컨테이너 엔진에서 실행할 수 있게 해줍니다.
스케줄링을 통해 컨테이너의 임무를 효율적으로 수행합니다.
컨테이너를 유지합니다.
컨테이너 간의 통신을 허용합니다.
배포 기술을 허용합니다.
정보의 양을 처리합니다.
Node: 포드 또는 포드가 있는 운영 체제.
Pod: 하나의 컨테이너 또는 여러 컨테이너를 감싸는 래퍼입니다. 포드는 일반적으로 하나의 애플리케이션만 포함해야 합니다(따라서 보통 포드는 1개의 컨테이너만 실행합니다). 포드는 Kubernetes가 실행 중인 컨테이너 기술을 추상화하는 방법입니다.
Service: 각 포드는 노드의 내부 범위에서 1개의 내부 IP 주소를 가집니다. 그러나 서비스로 노출될 수도 있습니다. 서비스는 또한 IP 주소를 가지며 그 목표는 포드 간의 통신을 유지하는 것입니다. 따라서 하나가 죽으면 새로운 대체(다른 내부 IP를 가진)가 서비스의 동일한 IP로 노출됩니다. 내부 또는 외부로 구성할 수 있습니다. 서비스는 또한 2개의 포드가 동일한 서비스에 연결될 때 로드 밸런서 역할을 합니다.
서비스가 생성되면 kubectl get endpoints
를 실행하여 각 서비스의 엔드포인트를 찾을 수 있습니다.
Kubelet: 기본 노드 에이전트. 노드와 kubectl 간의 통신을 설정하는 구성 요소이며, 포드만 실행할 수 있습니다(API 서버를 통해). Kubelet은 Kubernetes에 의해 생성되지 않은 컨테이너를 관리하지 않습니다.
Kube-proxy: apiserver와 노드 간의 통신(서비스)을 담당하는 서비스입니다. 기본적으로 노드를 위한 IPtables입니다. 가장 숙련된 사용자는 다른 공급자의 kube-proxy를 설치할 수 있습니다.
Sidecar container: 사이드카 컨테이너는 포드의 주요 컨테이너와 함께 실행되어야 하는 컨테이너입니다. 이 사이드카 패턴은 현재 컨테이너의 기능을 변경하지 않고 확장하고 향상시킵니다. 현재 우리는 애플리케이션이 어디에서나 실행될 수 있도록 모든 종속성을 래핑하기 위해 컨테이너 기술을 사용한다는 것을 알고 있습니다. 컨테이너는 단 하나의 작업만 수행하며 그 작업을 매우 잘 수행합니다.
Master process:
Api Server: 사용자가 마스터 프로세스와 통신하는 방법입니다. 인증된 요청만 허용되어야 합니다.
Scheduler: 스케줄링은 포드가 노드에 매칭되도록 보장하는 것을 의미합니다. Kubelet이 이를 실행할 수 있도록 합니다. 어떤 노드가 더 많은 가용 자원을 가지고 있는지 결정할 수 있는 충분한 지능을 가지고 있으며, 새로운 포드를 그 노드에 할당합니다. 스케줄러는 새로운 포드를 시작하지 않으며, 노드 내에서 실행 중인 Kubelet 프로세스와 통신하여 새로운 포드를 시작합니다.
Kube Controller manager: 복제 세트나 배포와 같은 리소스를 확인하여 예를 들어 올바른 수의 포드나 노드가 실행되고 있는지 확인합니다. 포드가 누락된 경우, 새로운 포드를 시작하기 위해 스케줄러와 통신합니다. API에 대한 복제, 토큰 및 계정 서비스를 제어합니다.
etcd: 데이터 저장소, 지속적이고 일관되며 분산된. Kubernetes의 데이터베이스이며 클러스터의 전체 상태를 유지하는 키-값 저장소입니다(여기서 모든 변경 사항이 기록됩니다). 스케줄러나 컨트롤러 매니저와 같은 구성 요소는 어떤 변경이 발생했는지(노드의 가용 자원, 실행 중인 포드 수 등)를 알기 위해 이 데이터에 의존합니다.
Cloud controller manager: AWS 또는 OpenStack에 클러스터가 있는 경우 흐름 제어 및 애플리케이션을 위한 특정 컨트롤러입니다.
여러 노드(여러 포드 실행)일 수 있으므로 여러 마스터 프로세스가 있을 수 있으며, 이들의 Api 서버 접근은 로드 밸런싱되고 etcd는 동기화됩니다.
Volumes:
포드가 사라질 때 잃어버리지 말아야 할 데이터를 생성할 경우, 물리적 볼륨에 저장해야 합니다. Kubernetes는 데이터를 지속하기 위해 포드에 볼륨을 연결할 수 있게 해줍니다. 볼륨은 로컬 머신에 있거나 원격 저장소에 있을 수 있습니다. 서로 다른 물리적 노드에서 포드를 실행하는 경우, 모든 포드가 접근할 수 있도록 원격 저장소를 사용해야 합니다.
Other configurations:
ConfigMap: 서비스에 접근하기 위한 URL을 구성할 수 있습니다. 포드는 나머지 서비스(포드)와 통신하는 방법을 알기 위해 여기서 데이터를 가져옵니다. 이곳은 자격 증명을 저장하는 데 권장되는 장소가 아닙니다!
Secret: 비밀번호, API 키 등과 같은 비밀 데이터를 저장하는 곳입니다... B64로 인코딩됩니다. 포드는 필요한 자격 증명을 사용하기 위해 이 데이터에 접근할 수 있습니다.
Deployments: Kubernetes가 실행할 구성 요소가 지정되는 곳입니다. 사용자는 일반적으로 포드와 직접 작업하지 않으며, 포드는 ReplicaSets(복제된 동일한 포드 수)로 추상화되어 배포를 통해 실행됩니다. 배포는 무상태 애플리케이션을 위한 것입니다. 배포의 최소 구성은 이름과 실행할 이미지입니다.
StatefulSet: 이 구성 요소는 데이터베이스와 같이 동일한 저장소에 접근해야 하는 애플리케이션을 위해 특별히 설계되었습니다.
Ingress: 애플리케이션을 URL로 공개적으로 노출하기 위해 사용하는 구성입니다. 이는 외부 서비스를 사용하여도 가능하지만, 애플리케이션을 노출하는 올바른 방법입니다.
Ingress를 구현하면 Ingress Controllers를 생성해야 합니다. Ingress Controller는 요청을 수신하고 확인하며 서비스를 로드 밸런싱할 엔드포인트가 될 포드입니다. Ingress Controller는 구성된 Ingress 규칙에 따라 요청을 전송합니다. Ingress 규칙은 서로 다른 경로나 심지어 서로 다른 내부 Kubernetes 서비스에 대한 하위 도메인을 가리킬 수 있습니다.
더 나은 보안 관행은 Kubernetes 클러스터의 어떤 부분도 노출되지 않도록 클라우드 로드 밸런서나 프록시 서버를 진입점으로 사용하는 것입니다.
어떤 Ingress 규칙과도 일치하지 않는 요청이 수신되면, Ingress Controller는 이를 "Default backend"로 안내합니다. 이 매개변수의 주소를 얻으려면 Ingress Controller를 describe
할 수 있습니다.
minikube addons enable ingress
CA는 클러스터 내 모든 인증서의 신뢰할 수 있는 루트입니다.
구성 요소가 서로를 검증할 수 있게 해줍니다.
모든 클러스터 인증서는 CA에 의해 서명됩니다.
etcd는 자체 인증서를 가지고 있습니다.
유형:
apiserver cert.
kubelet cert.
scheduler cert.
Minikube는 전체 Kubernetes 환경을 배포할 필요 없이 Kubernetes에서 빠른 테스트를 수행하는 데 사용할 수 있습니다. Minikube는 하나의 머신에서 마스터 및 노드 프로세스를 실행합니다. Minikube는 노드를 실행하기 위해 virtualbox를 사용할 것입니다. 여기에서 설치 방법을 확인하세요.
**Kubectl
**은 kubernetes 클러스터를 위한 명령줄 도구입니다. 이는 kubernetes에서 작업을 수행하거나 데이터를 요청하기 위해 마스터 프로세스의 Api 서버와 통신합니다.
대시보드를 통해 minikube가 무엇을 실행하고 있는지 더 쉽게 확인할 수 있으며, 액세스할 URL은 다음에서 찾을 수 있습니다:
각 구성 파일은 3부분으로 구성됩니다: 메타데이터, 사양 (실행해야 할 내용), 상태 (원하는 상태). 배포 구성 파일의 사양 안에는 실행할 이미지를 정의하는 새로운 구성 구조로 정의된 템플릿을 찾을 수 있습니다:
같은 구성 파일에 선언된 배포 + 서비스의 예 (출처 여기)
서비스는 일반적으로 하나의 배포와 관련이 있으므로, 같은 구성 파일에 두 가지를 선언하는 것이 가능합니다 (이 구성에서 선언된 서비스는 내부에서만 접근할 수 있습니다):
외부 서비스 구성 예시
이 서비스는 외부에서 접근할 수 있습니다 ( nodePort
및 type: LoadBlancer
속성을 확인하세요):
이것은 테스트에 유용하지만, 프로덕션에서는 내부 서비스만 있고 애플리케이션을 노출하기 위한 Ingress가 있어야 합니다.
Ingress 구성 파일의 예
이것은 http://dashboard.com
에서 애플리케이션을 노출합니다.
비밀 구성 파일의 예
비밀번호가 B64로 인코딩되어 있는 것을 주목하세요(안전하지 않습니다!).
ConfigMap의 예시
A ConfigMap은 파드에 제공되는 구성으로, 파드가 다른 서비스를 찾고 접근하는 방법을 알 수 있도록 합니다. 이 경우, 각 파드는 mongodb-service
라는 이름이 그들이 통신할 수 있는 파드의 주소임을 알게 됩니다(이 파드는 mongodb를 실행할 것입니다):
그런 다음, deployment config 내에서 이 주소는 다음과 같은 방식으로 지정되어 pod의 env 내에서 로드될 수 있습니다:
볼륨 구성 예시
다양한 저장소 구성 yaml 파일의 예시는 https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes에서 찾을 수 있습니다. 볼륨은 네임스페이스 안에 있지 않다는 점에 유의하세요.
Kubernetes는 동일한 물리적 클러스터를 기반으로 하는 다수의 가상 클러스터를 지원합니다. 이러한 가상 클러스터를 네임스페이스라고 합니다. 이는 여러 팀이나 프로젝트에 걸쳐 많은 사용자가 있는 환경에서 사용하기 위해 설계되었습니다. 사용자 수가 몇 명에서 수십 명인 클러스터의 경우, 네임스페이스를 생성하거나 고려할 필요가 없습니다. Kubernetes에 배포된 애플리케이션의 각 부분을 더 잘 제어하고 조직하기 위해서만 네임스페이스를 사용하기 시작해야 합니다.
네임스페이스는 이름에 대한 범위를 제공합니다. 리소스의 이름은 네임스페이스 내에서 고유해야 하지만, 네임스페이스 간에는 고유할 필요는 없습니다. 네임스페이스는 서로 중첩될 수 없으며, 각 Kubernetes 리소스는 하나의 네임스페이스에만 존재할 수 있습니다.
기본적으로 minikube를 사용하는 경우 4개의 네임스페이스가 있습니다:
kube-system: 사용자 사용을 위한 것이 아니며 건드리지 말아야 합니다. 마스터 및 kubectl 프로세스를 위한 것입니다.
kube-public: 공개적으로 접근 가능한 데이터. 클러스터 정보를 포함하는 configmap이 포함되어 있습니다.
kube-node-lease: 노드의 가용성을 결정합니다.
default: 사용자가 리소스를 생성하는 데 사용할 네임스페이스입니다.
대부분의 Kubernetes 리소스(예: pods, services, replication controllers 등)는 일부 네임스페이스에 있습니다. 그러나 네임스페이스 리소스와 노드 및 persistenVolumes과 같은 저수준 리소스와 같은 다른 리소스는 네임스페이스에 없습니다. 어떤 Kubernetes 리소스가 네임스페이스에 있고 없는지 보려면:
해당 컨텍스트에서 모든 후속 kubectl 명령어에 대한 네임스페이스를 저장할 수 있습니다.
Helm은 Kubernetes의 패키지 관리자입니다. YAML 파일을 패키징하고 이를 공용 및 개인 저장소에 배포할 수 있습니다. 이러한 패키지를 Helm Charts라고 합니다.
Helm은 변수를 사용하여 구성 파일을 생성할 수 있는 템플릿 엔진이기도 합니다:
**비밀(Secret)**은 비밀번호, 토큰 또는 키와 같은 민감한 데이터를 포함하는 객체입니다. 이러한 정보는 Pod 사양이나 이미지에 포함될 수 있습니다. 사용자는 비밀을 생성할 수 있으며 시스템에서도 비밀을 생성합니다. 비밀 객체의 이름은 유효한 DNS 하위 도메인 이름이어야 합니다. 공식 문서를 참조하세요.
비밀은 다음과 같은 것일 수 있습니다:
API, SSH 키.
OAuth 토큰.
자격 증명, 비밀번호(일반 텍스트 또는 b64 + 암호화).
정보 또는 주석.
데이터베이스 연결 코드, 문자열… .
Kubernetes에는 다양한 유형의 비밀이 있습니다.
내장 유형 | 사용법 |
---|---|
Opaque | 임의의 사용자 정의 데이터(기본값) |
kubernetes.io/service-account-token | 서비스 계정 토큰 |
kubernetes.io/dockercfg | 직렬화된 ~/.dockercfg 파일 |
kubernetes.io/dockerconfigjson | 직렬화된 ~/.docker/config.json 파일 |
kubernetes.io/basic-auth | 기본 인증을 위한 자격 증명 |
kubernetes.io/ssh-auth | SSH 인증을 위한 자격 증명 |
kubernetes.io/tls | TLS 클라이언트 또는 서버를 위한 데이터 |
bootstrap.kubernetes.io/token | 부트스트랩 토큰 데이터 |
Opaque 유형은 기본값으로, 사용자가 정의한 전형적인 키-값 쌍입니다.
비밀이 작동하는 방식:
다음 구성 파일은 mysecret
이라는 비밀을 정의하며, 2개의 키-값 쌍 username: YWRtaW4=
및 password: MWYyZDFlMmU2N2Rm
을 포함합니다. 또한 mysecret
에서 정의된 username
및 password
를 환경 변수 SECRET_USERNAME
__ 및 __ SECRET_PASSWOR
로 노출하는 secretpod
라는 pod를 정의합니다. 또한 mysecret
내의 username
비밀을 /etc/foo/my-group/my-username
경로에 0640
권한으로 마운트합니다.
etcd는 모든 클러스터 데이터에 대한 Kubernetes 백업 저장소로 사용되는 일관성 있고 고가용성 키-값 저장소입니다. etcd에 저장된 비밀에 접근해 보겠습니다:
당신은 FS에 위치한 certs, keys 및 url을 볼 수 있습니다. 이를 얻으면 etcd에 연결할 수 있게 됩니다.
한 번 통신을 설정하면 비밀을 얻을 수 있습니다:
ETCD에 암호화 추가하기
기본적으로 모든 비밀은 일반 텍스트로 etcd에 저장되며, 암호화 계층을 적용하지 않는 한 그렇습니다. 다음 예시는 https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/를 기반으로 합니다.
그 후, 생성된 구성 파일의 위치를 가리키도록 kube-apiserver
에서 --encryption-provider-config
플래그를 설정해야 합니다. /etc/kubernetes/manifest/kube-apiserver.yaml
를 수정하고 다음 줄을 추가할 수 있습니다:
Scroll down in the volumeMounts: volumeMounts에서 아래로 스크롤하세요:
Scroll down in the volumeMounts to hostPath: volumeMounts에서 hostPath로 스크롤하세요:
데이터가 암호화되었는지 확인하기
데이터는 etcd에 기록될 때 암호화됩니다. kube-apiserver
를 재시작한 후, 새로 생성되거나 업데이트된 비밀은 저장될 때 암호화되어야 합니다. 확인하려면 etcdctl
명령줄 프로그램을 사용하여 비밀의 내용을 검색할 수 있습니다.
default
네임스페이스에 secret1
이라는 새 비밀을 생성합니다:
etcdctl 명령줄을 사용하여 해당 비밀을 etcd에서 읽습니다:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
여기서 [...]
는 etcd 서버에 연결하기 위한 추가 인수여야 합니다. 3. 저장된 비밀이 k8s:enc:aescbc:v1:
로 접두사가 붙어 있는지 확인합니다. 이는 aescbc
제공자가 결과 데이터를 암호화했음을 나타냅니다. 4. API를 통해 검색할 때 비밀이 올바르게 복호화되었는지 확인합니다:
mykey: bXlkYXRh
와 일치해야 하며, mydata는 인코딩되어 있습니다. 비밀을 완전히 복호화하려면 비밀 복호화를 확인하세요.
비밀은 기록 시 암호화되므로, 비밀을 업데이트하면 해당 내용이 암호화됩니다:
마지막 팁:
파일 시스템에 비밀을 저장하지 마세요. 다른 곳에서 가져오세요.
비밀을 보호하기 위해 https://www.vaultproject.io/ 를 확인하세요.
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE) GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)