728x90

Kubernetes에서 서비스 어카운트란?

Kubernetes에서 서비스 어카운트(Service Account)는 클러스터 내의 애플리케이션이 Kubernetes API 서버와 상호작용할 수 있도록 인증 정보를 제공하는 역할을 함

보통 사용자가 직접 API 서버와 상호작용하기 위해 사용자 계정(User Account)을 사용하는 것과는 달리, 서비스 어카운트는 애플리케이션(즉, 파드)이 API 서버와 통신할 수 있도록 만들어진 특수한 계정임

Kubernetes 클러스터 내에서 파드가 실행 중일 때, 이 파드가 클러스터의 상태를 모니터링하거나 다른 리소스에 접근하기 위해서는 Kubernetes API 서버에 인증된 요청을 보내야 함

이를 가능하게 하는 것이 바로 서비스 어카운트 토큰(serviceAccountToken)

이 토큰을 통해 파드는 자신을 인증하고 필요한 작업을 수행할 수 있음

서비스 어카운트 토큰 자동 마운트

서비스 어카운트가 제공하는 토큰은 파드가 Kubernetes API에 접근할 때 중요한 역할을 하며, 이는 자동으로 파드에 마운트됨 Kubernetes에서는 기본적으로 파드가 생성될 때 서비스 어카운트의 토큰을 자동으로 마운트하도록 설정되어 있음

이 설정은 서비스어카운트나, 파드의 메타데이터에서 automountServiceAccountToken: true로 설정됨

apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-account
automountServiceAccountToken: true
apiVersion: v1
kind: Pod
metadata:
  name: example-pod
spec:
  serviceAccountName: example-account
  automountServiceAccountToken: true
  ...

위와 같이 설정된 경우, Kubernetes는 파드 생성 시 서비스 어카운트 토큰을 파드의 파일 시스템에 Projected Volume을 통해 자동으로 주입함

이 토큰은 보통 /var/run/secrets/kubernetes.io/serviceaccount/token 경로에 파일로 저장됨

애플리케이션은 이 경로에 있는 토큰을 읽어 Kubernetes API 서버에 요청을 보낼 때 사용할 수 있음

서비스 어카운트 토큰의 만료와 갱신

Kubernetes 서비스 어카운트 토큰은 기본적으로 expirationSeconds 설정을 통해 토큰이 약 1시간 후에 만료되도록 구성됨

만료된 토큰은 더 이상 유효하지 않으므로 새로운 토큰이 필요함

다행히도, Kubernetes는 이 과정도 자동으로 처리함

즉, 파드에 마운트된 토큰이 만료되면, Kubernetes는 자동으로 새로운 토큰을 생성하고 기존 토큰이 저장된 경로(/var/run/secrets/kubernetes.io/serviceaccount/token)에 업데이트함

이를 통해 애플리케이션은 지속적으로 유효한 토큰을 사용하여 Kubernetes API에 접근할 수 있음

이렇게 자동으로 갱신되는 메커니즘 덕분에 관리자는 토큰 만료에 신경 쓰지 않아도 되고, 애플리케이션은 중단 없이 Kubernetes API 서버와 상호작용할 수 있음

 

아래 파이썬 코드를 실행하면 파드에 마운트 되어있는 서비스 어카운트 토큰을 이용하여 kubernetes api를 호출해 볼 수 있음

import ssl
from kubernetes import client, config

config = client.Configuration()

config.api_key['authorization'] = open('/var/run/secrets/kubernetes.io/serviceaccount/token').read()
config.api_key_prefix['authorization'] = 'Bearer'
config.host = 'https://kubernetes.default'
config.ssl_ca_cert = '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt'
config.verify_ssl=True

api_client = client.CoreV1Api(client.ApiClient(config))
ret = api_client.list_namespaced_pod("example-namespace", watch=False)

print("Listing pods with their IPs:")
for i in ret.items:
    print(f"{i.status.pod_ip}\t{i.metadata.name}")

보안 관점에서의 서비스 어카운트 관리

서비스 어카운트 토큰이 Kubernetes 클러스터에서 중요한 역할을 하기 때문에 이를 안전하게 관리하는 것이 매우 중요함

보안 관점에서 중요한 원칙 중 하나는 최소 권한 원칙(Least Privilege Principle)

각 서비스 어카운트는 그들이 수행해야 할 작업에 필요한 최소한의 권한만을 가져야 함

Kubernetes에서는 Role, RoleBinding, ClusterRole, ClusterRoleBinding을 통해 각 서비스 어카운트에 부여된 권한을 제한할 수 있음

만약 특정 파드가 Kubernetes API에 접근할 필요가 없다면, automountServiceAccountToken: false로 설정하여 서비스 어카운트 토큰이 자동으로 마운트되지 않도록 설정하는 것이 좋음

728x90
728x90

Kubernetes 클러스터에서 애플리케이션의 보안을 유지하고, 다양한 리소스에 대한 접근을 제어하는 것은 매우 중요함

이를 위해 Kubernetes는 RBAC(Role-Based Access Control)와 ServiceAccount를 제공하여, 클러스터 내에서의 접근 권한을 체계적으로 관리할 수 있음

Kubernetes RBAC(Role-Based Access Control)란?

Kubernetes의 RBAC는 사용자나 서비스가 클러스터 내에서 어떤 리소스에 접근하고, 어떤 동작을 수행할 수 있는지를 제어하는 메커니즘임

RBAC를 통해 특정 리소스에 대해 읽기, 쓰기 등의 권한을 세밀하게 설정할 수 있음

RBAC는 Role, ClusterRole, RoleBinding, ClusterRoleBinding으로 구성됨

  • Role: 특정 네임스페이스 내에서 리소스에 대한 권한을 정의함
  • ClusterRole: 클러스터 전체에서 권한을 정의함
  • RoleBinding: 네임스페이스 내에서 특정 주체(사용자, 그룹, ServiceAccount)에게 Role을 할당함
  • ClusterRoleBinding: 클러스터 전체에서 특정 주체에게 ClusterRole을 할당함

ServiceAccount란?

ServiceAccount는 Kubernetes 클러스터 내에서 파드(Pod)가 Kubernetes API 서버에 접근할 수 있도록 해주는 계정임

기본적으로 Kubernetes에서 파드는 ServiceAccount와 연동되며, 이 계정을 통해 Kubernetes API에 인증된 요청을 할 수 있음

apiVersion: v1
kind: ServiceAccount
metadata:
  name: example-serviceaccount
  namespace: example-namespace

RBAC와 ServiceAccount 연동하기

RBAC는 ServiceAccount와 함께 사용되어, 파드나 애플리케이션이 특정 리소스에 대해 어떤 권한을 가질지 제어할 수 있음

예를 들어, 특정 파드가 pods 리소스에 대한 읽기 권한만 가지도록 설정할 수 있음

이를 위해 Role과 RoleBinding을 활용할 수 있음

Role 정의

Role은 네임스페이스 내에서 리소스에 대한 권한을 정의함

아래는 pods 리소스에 대해 get, list, watch 권한을 가진 Role을 정의한 예시임

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: example-namespace
  name: example-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

RoleBinding 정의

RoleBinding은 특정 ServiceAccount가 위에서 정의한 Role의 권한을 사용할 수 있도록 바인딩하는 역할을 함

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: example-rolebinding
  namespace: example-namespace
subjects:
- kind: ServiceAccount
  name: example-serviceaccount
  namespace: example-namespace
roleRef:
  kind: Role
  name: example-role
  apiGroup: rbac.authorization.k8s.io

위의 예시에서 example-serviceaccount는 example-role에서 정의된 권한을 사용하여 pods 리소스에 대한 get, list, watch 동작을 수행할 수 있음

ClusterRole과 ClusterRoleBinding

Role과 RoleBinding은 네임스페이스 내에서만 작동하지만, 클러스터 전역에서 권한을 설정하고자 할 때는 ClusterRole과 ClusterRoleBinding을 사용함

ClusterRole 정의

ClusterRole은 클러스터 전체에서 리소스에 대한 권한을 정의할 수 있음

예를 들어, 클러스터 내의 모든 nodes와 pods에 대한 읽기 권한을 정의한 예시는 다음과 같음

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: example-clusterrole
rules:
- apiGroups: [""]
  resources: ["nodes", "pods"]
  verbs: ["get", "list", "watch"]

ClusterRoleBinding 정의

ClusterRoleBinding은 특정 ServiceAccount가 클러스터 전역에서 ClusterRole을 사용할 수 있도록 바인딩하는 역할을 함

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: example-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: example-serviceaccount
  namespace: example-namespace
roleRef:
  kind: ClusterRole
  name: example-clusterrole
  apiGroup: rbac.authorization.k8s.io

이 예시에서 example-serviceaccount는 클러스터 전체에서 nodes와 pods 리소스에 대해 읽기 권한을 가짐

 

728x90
728x90

service ↔ external 네트워크

  • 외부 트래픽이 LoadBalancer, NodePort, Ingress 등을 통해 쿠버네티스 클러스터에 진입함
  • 각 노드(Node A, Node B)는 호스트 네트워크 네임스페이스를 가지며, 여기에는 호스트 네트워크 인터페이스 카드(NIC)인 eth0가 있음
  • kube-proxy는 iptables/IPVS를 이용하여 네트워크 트래픽을 관리함
  • cni0 브릿지를 통해 veth0, veth1 등의 가상 이더넷 인터페이스가 연결됨
  • 각 파드(Pod)는 자신만의 네트워크 네임스페이스를 가지며, pause 컨테이너를 통해 다른 컨테이너들과 연결됨

쿠버네티스 애플리케이션을 외부 네트워크에 노출하는 방법

Service

쿠버네티스의 서비스(Service)는 NodePort를 설정하거나, 여러 파드(Pod)에 트래픽을 분산하기 위해 여러 기술을 활용함

가장 중요한 기술은 kube-proxy를 중심으로 동작하며, iptables 또는 IPVS를 사용하여 트래픽을 적절히 분산시킴

  • NodePort : 클러스터의 각 노드에서 지정된 포트를 열어 외부 트래픽을 수신
  • LoadBalancer : 클라우드 제공업체의 로드 밸런서를 사용하여 외부 트래픽을 분산
  • ExternalName : 클러스터 외부의 서비스에 대해 DNS 이름을 매핑할 수 있음

Ingress

  • Ingress controller 설치
    • Ingress를 사용하려면 클러스터에 Ingress Controller가 필요함
    • Ingress Controller는 클러스터 내에서 Ingress 리소스를 처리하고, 외부 트래픽을 내부 서비스로 라우팅함
  • 서비스 배포
    • Ingress를 통해 접근할 서비스를 먼저 배포해야 함
    • apiVersion: v1 kind: Service metadata: name: example-service spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP
  • ingress 리소스 생성
    • Ingress 리소스를 생성하여 특정도메인 example.com으로 오는 외부 트래픽을 요청을 특정 서비스 example-service로 라우팅하는 Ingress 리소스를 생성
    • apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-service port: number: 80
  • dns 설정
    • 도메인 이름과 ingress controller의 외부IP 주소를 매핑해야 함
728x90
728x90

서비스의 필요성

pod는 수요에 따라 확장 또는 축소해야 할 수 있고, 애플리케이션 충돌이나 노드 장애가 발생할 경우 다시 생성되기 때문에 매우 동적임

이러한 이벤트로 인해 pod의 IP 주소가 변경되면 네트워킹이 어려워질 수 있음

쿠버네티스는 Service를 사용하여 이 문제를 해결함

  1. 서비스와 연관된 백엔드 Pod를 연결하기 위해 앞단에 정적 가상 IP 주소를 할당
  2. 서비스는 pod의 ip주소를 추적
  3. 서비스는 서비스IP로 전송된 모든 트래픽을 뒷단 pod 세트로 부하 분산
  4. Pod IP 주소가 변경되더라도 클라이언트는 서비스 자체의 정적인 가상 IP 주소로만 직접 연결하기 때문에 Pod에 연결하는 데 아무런 문제가 없음

서비스의 구성 요소

  • Service 객체
    • Service는 Kubernetes 리소스로, API 서버에 정의되어 있음
    • spec.selector 필드를 사용하여 어떤 Pod가 이 서비스에 포함될지를 정의함
    • 예를 들어, app: myapp 라벨을 가진 모든 Pod가 이 서비스의 엔드포인트가 됨
  • Endpoints 객체
    • Service와 연결된 Pod의 IP 주소와 포트 정보를 포함하는 객체
    • Kubernetes 컨트롤러가 자동으로 생성하며, Service의 selector와 일치하는 Pod를 추적함
  • kube-proxy
    • 각 Kubernetes 노드에서 실행되며, Service에 대한 네트워크 트래픽을 적절한 Pod로 라우팅함
    • iptables, IPVS, 또는 유저스페이스 프록시 모드를 사용하여 트래픽을 관리함
      • iptables
        • 이 모드에서 kube-proxy는 API 서버의 변경 사항을 감시함
        • 각 새 서비스에 대해 iptables 규칙을 설치하여 서비스의 clusterIP 및 포트로의 트래픽을 캡처한 다음, 서비스의 백엔드 Pod로 트래픽을 리디렉션
        • Pod는 무작위로 선택됩니다. 이 모드는 안정적이며 Linux Netfilter가 사용자 공간과 커널 공간 사이를 전환할 필요 없이 트래픽을 처리하기 때문에 시스템 오버헤드가 낮음
      • IPVS
        • IPVS는 Netfilter 위에 구축되었으며 전송 계층 부하 분산을 구현함
        • IPVS는 Netfilter 후크 함수를 사용하여 해시 테이블을 기본 데이터 구조로 사용하고 커널 공간에서 작동함
        • IPVS 모드의 kube-proxy는 iptables 모드의 kube-proxy보다 낮은 지연 시간, 높은 처리량 및 더 나은 성능으로 트래픽을 리디렉션함
  • DNS
    • 클러스터 내에서 실행 중인 CoreDNS 또는 kube-dns는 서비스 디스커버리를 위해 Service의 DNS 이름을 관리함
    • 예를 들어, my-service.default.svc.cluster.local 같은 DNS 이름을 사용하여 서비스에 접근할 수 있음

서비스 동작 원리

  1. Service 정의
    • 사용자가 Service 객체를 생성하면 API 서버에 저장됨
    • Service 정의 예시
    • apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: myapp ports: - protocol: TCP port: 80 targetPort: 9376
  2. Pod와 Endpoints 연계
    • selector 필드에 정의된 라벨을 기준으로, 컨트롤러가 해당 라벨을 가진 모든 Pod를 찾아 Endpoints 객체를 생성함
    • Endpoints 객체는 서비스와 관련된 Pod의 IP 주소와 포트를 포함함
  3. kube-proxy 설정
    • 각 노드에서 실행 중인 kube-proxy는 Service와 Endpoints 정보를 주기적으로 API 서버에서 가져와 로컬 iptables 또는 IPVS 규칙을 설정함
  4. 트래픽 라우팅
    • 클러스터 내의 다른 Pod나 외부 클라이언트가 서비스의 클러스터 IP 주소 또는 DNS 이름을 사용하여 접근할 때, 트래픽이 kube-proxy를 통해 라우팅됨
    • kube-proxy는 로드 밸런싱 알고리즘을 사용하여 트래픽을 Endpoints 리스트에 있는 Pod로 분배함
  5. DNS를 통한 서비스 디스커버리
    • CoreDNS 또는 kube-dns가 클러스터 내에서 서비스 이름을 IP 주소로 변환함
    • 예를 들어, my-service.default.svc.cluster.local로 DNS 요청을 하면 서비스의 클러스터 IP 주소를 반환함
728x90
728x90

네트워크 네임스페이스

  • Host Network Namespace:
    • eth0 (Host NIC): 호스트 시스템의 물리적 네트워크 인터페이스로, 외부 네트워크와 통신함
    • kube-proxy:
      • Kubernetes 컴포넌트로, 클러스터 내의 네트워크 프록시 역할을 수행함
      • iptables 또는 IPVS를 사용하여 클러스터 내의 서비스 트래픽을 적절한 Pod로 라우팅함
    • cni0 (bridge): 호스트 네트워크 네임스페이스에서 사용하는 가상 브리지로, 쿠버네티스 CNI (Container Network Interface) 플러그인에 의해 생성됨. 여러 포드 네트워크 네임스페이스를 연결하는 역할을 함
    • veth0 (veth): 호스트 네트워크 네임스페이스와 포드 네트워크 네임스페이스를 연결하는 가상 이더넷 인터페이스 페어의 한 쪽 끝으로, 호스트 네트워크 네임스페이스의 cni0 브리지와 연결됨
  • Pod Network Namespace
    • Pod A
      • eth0 (veth) : Pod의 네트워크 인터페이스
      • pause container : 네트워크 네임스페이스를 유지하는 용도로 사용됨
      • container1, container2 : Pod A 내부의 실제 애플리케이션 컨테이너
      • localhost : Pod 내부의 컨테이너 간 통신을 위해 사용됨
    • Pod B
      • eth0 : Pod의 네트워크 인터페이스
      • pause container : 네트워크 네임스페이스를 유지하는 용도로 사용됨
      • container1 : Pod B 내부의 실제 애플리케이션 컨테이너

Pod 간 통신하는 방법 : Pod IP 사용

컨테이너 간 네트워킹과 달리 Pod 간 통신은 Pod를 클러스터의 동일한 노드나 다른 노드에 배포하든 실제 IP를 사용하여 이루어짐

쿠버네티스를 사용하면 모든 노드에 Pod에 대한 지정된 CIDR IP 범위가 있음

이를 통해 모든 Pod가 클러스터의 다른 Pod가 볼 수 있는 고유한 IP 주소를 수신함

새 Pod가 생성되면 IP 주소가 겹치지 않음

네트워크 연결 과정

Pod A에서 Pod B로 데이터가 전송될 때의 이벤트 흐름은 다음과 같음

  1. Pod A 트래픽은 eth0를 통해 루트 네트워크 네임스페이스의 가상 인터페이스 veth0로 흐름
  2. 트래픽은 veth0를 거쳐 cni0 가상 브리지로 이동
  3. 트래픽은 cni0 가상 브리지를 통해 veth1로 이동
  4. 트래픽은 veth1을 통해 Pod 2의 eth0 인터페이스에 도달
728x90
728x90

pod는 동일한 호스트에 배치된 하나 이상의 컨테이너로 구성되며, 네트워크 스택 및 볼륨과 같은 리소스를 공유하도록 구성된다

“네트워크 스택 공유”는 pod의 모든 컨테이너가 localhost를 통해 서로 연결될 수 있음을 의미한다

네트워크 네임스페이스

  • Host Network Namespace:
    • eth0 (Host NIC): 호스트 시스템의 물리적 네트워크 인터페이스로, 외부 네트워크와 통신함
    • kube-proxy:
      • Kubernetes 컴포넌트로, 클러스터 내의 네트워크 프록시 역할을 수행함
      • iptables 또는 IPVS를 사용하여 클러스터 내의 서비스 트래픽을 적절한 Pod로 라우팅함
    • cni0 (bridge): 호스트 네트워크 네임스페이스에서 사용하는 가상 브리지로, 쿠버네티스 CNI (Container Network Interface) 플러그인에 의해 생성됨. 여러 포드 네트워크 네임스페이스를 연결하는 역할을 함
    • veth0 (veth): 호스트 네트워크 네임스페이스와 포드 네트워크 네임스페이스를 연결하는 가상 이더넷 인터페이스 페어의 한 쪽 끝으로, 호스트 네트워크 네임스페이스의 cni0 브리지와 연결됨
  • Pod Network Namespace
    • eth0 (veth) : 포드 내 모든 컨테이너는 동일한 네트워크 네임스페이스를 공유하며, 이 네트워크 네임스페이스 내에서 eth0 인터페이스를 사용하여 통신함
    • pause 컨테이너: 포드 네트워크 네임스페이스를 설정하고 유지하며, 이 네트워크 네임스페이스를 다른 컨테이너들과 공유함
    • container1, container2, container3: 사용자 컨테이너들이며, 모두 pause 컨테이너가 설정한 네트워크 네임스페이스를 공유함

네트워크 연결 과정

  1. pod가 생성되고 함께 PAUSE 컨테이너가 생성될 때, PAUSE 컨테이너에 네트워크 인터페이스(eth0)가 생성됨
  2. pod가 생성되는 Node의 host network namespace에도 가상의 인터페이스(veth0)가 하나 생성되며, PAUSE 컨테이너와 직접 연결됨
  3. 이후 PAUSE 컨테이너는 해당 인터페이스에 새로운 IP주소도 자동으로 할당받아 갖게 됨
  4. k8s는 PAUSE 컨테이너가 가진 네트워크 인터페이스를 pod 내 모든 컨테이너가 사용할 수 있도록 구성함
  5. pod 내 모든 컨테이너는 PAUSE 컨테이너를 통해 동일한 IP를 사용하게 되며, 포트를 통해 컨테이너를 구분하게 됨
728x90
728x90

일반 도커 컨테이너 네트워킹

이 구조는 Docker 컨테이너가 서로 독립적으로 실행되면서도 네트워크 통신이 가능하게 하여, 유연한 애플리케이션 배포와 스케일링을 지원함

네트워크 네임스페이스

  • 호스트 네트워크 네임스페이스
    • 호스트 네트워크 네임스페이스는 기본적으로 호스트 운영체제에서 사용하는 네트워크 스택을 의미
    • 모든 호스트의 네트워크 설정 및 트래픽은 이 네임스페이스를 통해 관리됨
    • 이 네임스페이스는 물리적 네트워크 인터페이스(eth0)와 가상 브리지 네트워크(docker0)를 포함
      • eth0 이란?
        • 호스트 머신이 외부 네트워크와 통신할 수 있게 해줌
        • 운영 체제는 여러 개의 NIC를 가질 수 있으며, 이를 구분하기 위해 각각의 인터페이스에 eth0, eth1 등의 이름을 부여함
        • eth0는 물리적인 첫 번째 네트워크 인터페이스 카드(NIC)와 연결되어 있음
        • 이 NIC는 네트워크 케이블을 통해 다른 네트워크 장치(예: 스위치, 라우터)와 물리적으로 연결됨
        • 운영 체제는 eth0를 통해 네트워크 설정을 관리하고, 네트워크를 통한 데이터 송수신을 제어함 (eth1도 마찬가지)
        • 네트워크 데이터를 주고받을 때, 운영 체제는 eth0 인터페이스를 통해 데이터를 NIC로 전달함
        • NIC는 데이터를 전기 신호로 변환하여 네트워크 케이블을 통해 전송하고, 반대로 수신된 전기 신호를 데이터로 변환하여 운영 체제에 전달함
      • docker0 이란?이는 호스트 네임스페이스에 존재하며, 여러 컨테이너를 연결하는 가상 네트워크 스위치 역할을 함또한 eth0 (Host NIC)와 연결되어 있어 컨테이너가 외부 네트워크와도 통신할 수 있게 해줌
      • 컨테이너는 이 브리지 네트워크를 통해 서로 통신할 수 있음
      • 도커는 기본적으로 docker0라는 브리지 네트워크를 생성함
  • 컨테이너 네트워크 네임스페이스
    • 컨테이너 네트워크 네임스페이스는 각 컨테이너가 독립된 네트워크 스택을 가지도록 하는 네임스페이스
    • 각 컨테이너는 자체 네트워크 인터페이스(eth0), 독립된 라우팅 테이블, 포트 등의 네트워크 리소스를 가짐

네트워크 연결 과정

  • 컨테이너 생성 시 네트워크 네임스페이스 할당
    • 도커는 새로운 컨테이너를 생성할 때, 컨테이너가 독립된 네트워크 환경을 가질 수 있도록 해당 컨테이너를 위한 별도의 네트워크 네임스페이스를 생성함
  • 가상 이더넷 페어 (veth pair) 생성
    • 도커는 호스트 네임스페이스와 컨테이너 네임스페이스를 연결하는 가상 이더넷 페어(veth pair)를 생성함
    • 이 페어는 두 개의 인터페이스로 구성되며, 하나는 호스트 네임스페이스에, 다른 하나는 컨테이너 네임스페이스에 위치함
    • 이 쌍은 서로 연결되어 있어, 컨테이너가 브리지 네트워크와 통신할 수 있게 함
  • 브리지 네트워크에 연결
    • 호스트 네임스페이스에 위치한 veth 인터페이스는 docker0 브리지 네트워크에 연결됨
    • 컨테이너 네임스페이스에 위치한 veth 인터페이스는 컨테이너 내부에서 eth0으로 나타남
  • IP 주소 할당
    • 도커는 각 컨테이너의 eth0 인터페이스에 IP 주소를 할당함. 이 IP 주소는 docker0 브리지 네트워크의 서브넷 내에서 유효함
728x90
728x90

CNI란?

CNI(Container Network Interface)는 컨테이너 네트워킹을 위한 표준 인터페이스를 정의하는 프로젝트

CNI는 컨테이너 네트워크 인터페이스를 쉽게 확장하고 맞춤화할 수 있게 해주며, 다양한 네트워킹 솔루션과 통합 가능함

CNI는 표준일 뿐, 특정 서비스에 적용하기 위해서는 인터페이스를 구체화하여 서비스에 맞춰 적용해야 함

이를 위해 컨테이너 관리 시스템에서 네트워킹 구성 및 관리를 위한 플러그인 기반의 다양한 프레임워크가 있음

kubernetes Network Plugin (CNI plugin)

네트워크 모델은 각 노드의 컨테이너 런타임에 의해 구현됨

가장 일반적인 컨테이너 런타임은 컨테이너 네트워크 인터페이스(CNI) 플러그인을 사용하여 네트워크 및 보안 기능을 관리함

Network Plugin을 사용하는 가장 큰 이유는 기본제공되는 kubenet 만으로는 서로 다른 노드에 있는 pod의 교차 네트워킹을 지원하지 않기 때문

CNI 플러그인을 설치하면, Kubenet은 사용되지 않음

Calico와 Kubenet 비교

  calico kubenet
네트워크 설정 • Calico는 네트워크 설정을 관리하며, 각 파드에 고유한 IP 주소를 할당함
• IP-in-IP, BGP(Border Gateway Protocol) 등을 사용하여 네트워크를 구성하고, 노드 간 트래픽을 라우팅함
◦ Kubenet은 기본적인 네트워크 설정을 제공하며, 각 파드에 고유한 IP 주소를 할당함
◦ 브리지 네트워크(cbr0)와 veth 페어를 사용하여 파드 간 통신을 설정함

네트워크 정책 • Calico는 강력한 네트워크 정책을 지원하여, 파드 간 및 파드와 외부 간의 트래픽을 세밀하게 제어할 수 있음
• 보안 그룹과 네트워크 정책을 통해 트래픽을 허용하거나 차단함
◦ Kubenet은 기본적인 네트워크 정책만 제공하며, 세밀한 트래픽 제어나 고급 보안 기능을 지원하지 않음
네트워크 기능 • Calico는 고급 네트워크 기능을 제공하며, 대규모 클러스터 환경에서도 높은 성능과 확장성을 보장함
• 네트워크 격리, 암호화, 모니터링 등의 기능을 제공함
◦ Kubenet은 간단한 네트워크 설정과 관리가 가능하지만, 대규모 클러스터 환경에서는 확장성과 성능 면에서 제한적임
728x90
728x90

멀티-컨테이너 팟(Multi-container pod)은 쿠버네티스(Kubernetes)에서 여러 컨테이너가 함께 배치되어 서로 긴밀하게 협력하며 실행되는 구조를 말함

이러한 팟은 단일 컨테이너로 구성된 팟과는 달리, 여러 컨테이너가 동일한 네트워크 공간을 공유하고 저장소 리소스에도 접근할 수 있음

멀티-컨테이너 팟을 사용하면 각 컨테이너는 자신의 역할에 집중할 수 있고, 유지보수가 쉬워지며, 시스템의 전체적인 안정성과 확장성을 향상할 수 있음

 

아래에는 멀티-컨테이너 팟을 구성하기 위한 대표적인 세 가지 패턴을 정리함

각 패턴은 특정 상황에 맞추어 설계되었으며, 쿠버네티스 환경에서 효율적인 컨테이너 관리와 운영을 가능하게 함

 

사이드카(Sidecar) 패턴

Sidecar 패턴은 주요 애플리케이션 컨테이너에 추가적인 기능을 제공하기 위해 별도의 사이드카 컨테이너를 추가하는 패턴

주요 애플리케이션은 자체적으로 동작하며, 사이드카 컨테이너는 이를 보조하거나 보완하는 역할을 수행함

예를 들어, 로그 수집, 파일 동기화, 구성 업데이트 등의 기능을 처리할 수 있음

이렇게 별도의 사이드카 컨테이너를 두어 메인 컨테이너의 기능을 분리하면, 각 컨테이너를 독립적으로 업데이트하고 재사용할 수 있음

 

앰배서더(Ambassader) 패턴

앰배서더 패턴은 외부 시스템과의 통신을 관리하기 위해 사용함

이 패턴에서 앰배서더 컨테이너는 프록시 서버처럼 작동하여 메인 컨테이너가 외부 서비스와 통신할 때 중계 역할을 함

예를 들어, 데이터베이스나 외부 API에 대한 접근을 캡슐화하여 메인 컨테이너의 코드 변경 없이도 외부 연결을 쉽게 수정하거나 업그레이드할 수 있음

 

어댑터(Adapter) 패턴

어댑터 패턴은 외부 라이브러리나 도구를 사용하기 쉽게 만들어주는 패턴

어댑터 패턴에서는 어댑터 컨테이너가 메인 컨테이너로부터 출력되는 데이터를 수정하거나 변환하는 역할을 함

예를 들어, 메인 컨테이너에서 생성된 로그 데이터를 특정 형식으로 변환하여 로그 관리 시스템에 전달할 수 있음

728x90
728x90

쿠버네티스(Kubernetes) 환경에서 작업을 효율적으로 관리하기 위해 여러 클러스터와 네임스페이스를 다뤄야 하는 경우가 있음

kubeconfig 파일이란?

kubeconfig 파일이란 쿠버네티스 클라이언트인 kubectl이 클러스터와 통신하기 위해 사용하는 설정 파일

이 파일에는 클러스터의 접속 정보, 사용자 인증 정보, 사용 중인 컨텍스트 등이 저장됨

여러 개의 클러스터와 사용자, 네임스페이스를 갖고 있는 경우 각각을 별도의 파일로 관리하는 대신 한 파일에 모두 통합할 수도 있음

kubeconfig파일 경로는 일반적으로 ~/.kube/config에 위치함

환경변수에 kubeconfig파일 경로 여러 개 등록하기

export KUBECONFIG=~/.kube/config:~/.kube/config-dev

환경변수에 파일 경로를 여러 개 등록해줄 수 있음

k9s에서 context 리소스를 검색해보면 환경변수로 등록한 컨텍스트들을 확인할 수 있음

파일 병합하기

환경변수에 파일 여러 개를 등록할 수 있지만, 파일 하나로 관리하고 싶으면 아래와 같이 파일을 병합할 수 있음

여러 kubeconfig 파일을 하나로 통합하는 가장 간단한 방법은 kubectl config view --flatten 명령어를 사용하는 것

이 명령어는 현재 KUBECONFIG 환경변수에 설정된 모든 파일을 병합하여 출력함

# 여러 config파일 병합하기
kubectl config view --flatten > merged-kubeconfig.yaml

# 병합한 파일 KUBECONFIG 환경변수로 등록
export KUBECONFIG=~/merged-kubeconfig.yaml

컨텍스트 선택하기

여러 컨텍스트 중 사용할 컨텍스트를 선택하려면 다음과 같이 하면 됨

kubectl config use-context my-context-name

 

728x90

'Kubernetes' 카테고리의 다른 글

쿠버네티스 네트워크 - 1. CNI  (0) 2024.07.07
Multi-container pod 패턴  (0) 2024.05.07
쿠버네티스의 마스터노드와 워커 노드  (0) 2024.04.28
CNI란?  (0) 2024.04.28
쿠버네티스 소개  (0) 2024.04.28

+ Recent posts