글 작성자: 근삼이

아키텍쳐

쿠버네티스 클러스터는 크게 Control Plane 컴포넌트와 Node 컴포넌트 그룹으로 구분지을 수 있습니다. Control Plane을 포함한 모든 클러스터의 구성 요소들은 컨테이너 기반으로 동작하도록 설치가 되고, 기본적으로 간단화하기 위해, 또 보안을 위해 Control Plane 컴포넌트들은 특정 노드에만 올라가고, 일반 사용자 그룹의 컨테이너는 배포가 되지 않도록 설정됩니다. 일반적인 쿠버네티스 클러스터의 아키텍쳐에서는 이렇게 Control Plane 컴포넌트로 구성된 Control Plane 노드와 사용자 컨테이너 배포를 위한 Worker 노드로 구분되어 구성됩니다.

설치 방법별 구성요소 관리 팁

  • kubeadm 사용 배포시

    Control Plane 노드의 /etc/kubernetes/manifests 폴더에 Control Plane 컴포넌트들 배포에 관한 yaml 파일이 모여있다.

  • kubeadm 없이 배포시

    Control Plane 노드의 /etc/systemd/system/~ 폴더에 Control Plane 컴포넌트들 실행을 위한 옵션들이 정의되어 있다.

YAML 이용한 배포

템플릿 쉽게 획득하기

  • pod
    kubectl run nginx --image=nginx --dry-run -o yaml
  • 나머지(deployment, job, configmap, namespace, service, ....)
    kubectl create deployment --image=nginx nginx -o yaml

기본 형식

다양한 형태의 서비스들에 대해서 아래 양식은 항상 공통되게 적용됩니다.

apiVersion:     #kubernetes api 버전 명식
kind:           #생성할 객체의 종류 (ex. Pod, Deployment, Service ...)
metadata:       #생성할 객체의 metadata 정의
	name:           #객체 이름
	labels:         #객체 라벨
		key: value      #라벨은 key, value쌍으로 여러개 만들 수 있음
spec:           #객체마다 다르니까 알아서 하셈
  • Pod 템플릿
    apiVersion: v1
    kind: Pod
    metadata:
      name: testpod
      labels:
        app: testpod
    spec:
      containers:
      - name: testpod
        image: nginx
  • ReplicationController 템플릿
    💡
    ReplicationController 는 RelicaSet의 기능에 포함되며, 이후 삭제될 오브젝트이니 참고 하자.
    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
  • ReplicaSet 템플릿
    apiVersion: apps/v1
    kind: ReplicaSet
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
      selector:
        matchLabels:
          type: front-end
  • Deployment 템플릿
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      replicas: 3
      selector:
        app: nginx
      template:
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
      selector:
        matchLabels:
          type: front-end

간단한 작업용 명령 배포 팁

  • pod 생성
    kubectl run --image=nginx nginx
  • deployment 생성
    kubectl create deployment --image=nginx nginx
  • 서비스 노출
    kubectl expose deployment nginx --port 80
  • 서비스 수정
    kubectl edit deployment nginx
  • 스케일 조정
    kubectl scale deployment nginx --replicas=4
  • 이미지 변경
    kubectl set image deployment nginx nginx=nginx:1.18
  • ClusterIP
    kubectl create service clusterip nginx --tcp=80:80 --dry-run=client -o yaml
  • NodePort
    kubectl create service nodeport nginx --tcp=80:30080 --dry-run=client -o yaml

DNS

<서비스 이름>.<네임 스페이스>.svc.cluster.local

스케줄링시 노드 선택 방식

Taints 및 Tolerations

이 방식은 기본적으로 노드 관점에서 스케줄링을 제한하기 위한 방식이다. Taints가 적용된 노드에는 해당 된 Taints 룰에 위배되지 않는 적당한 Toleration 이 적용된 POD만 스케줄링 될 수 있다.

  • Taints

    Taints는 아래와 같은 형태로 노드에 적용 할 수 있다.

    kubectl taint nodes node1 key1=value1:NoSchedule
    kubectl taint nodes node1 key1=value1:NoExecute
    kubectl taint nodes node1 key2=value2:PreferNoSchedule

    뒤에 오는 effect 는 보기와 같이 총 3가지가 있다.

    • NoSchedule : pod을 해당 노드에 스케줄링 하지 않는다.
    • PreferNoSchedule : pod을 해당 노드에 스케줄링 하지 않으려 하지만, 불가피 한 경우에는 스케줄링 한다.
    • NoExecute : pod을 해다 온드에 스케줄링 하지 않고, 이미 스케줄링 되어 있으면 내쫒는다.
  • Tolerations

    Tolerations는 pod의 spec 섹션에 다음과 같은 형태로 정의 한다. 아래 예시는 example-key를 사용하는 NoSchedule 효과의 taints가 적용된 노드에 대해서 스케줄링 할 수 있도록 Toleration을 설정한 내용이다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        env: test
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
      tolerations:
      - key: "example-key"
        operator: "Exists"
        effect: "NoSchedule"

    operator 항목으로는 ExistsEqual 을 사용할 수 있다.

nodeSelector

nodeSelector는 pod 관점에서 가장 간단하게 pod의 배치를 지정할 수 있는 방법이다. 노드에 설정되어 있는 label을 기준으로 해당된 label이 설정된 노드에만 스케줄링 된다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

affinity 와 anti-affinity

nodeSelector와 마찬가지로 pod 관점에서 설정하는 label을 활용한 노드 선택 정책이며, 보다 복잡한 룰 설정이 가능하도록 해준다.

  • affinity
    apiVersion: v1
    kind: Pod
    metadata:
      name: with-node-affinity
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/e2e-az-name
                operator: In
                values:
                - e2e-az1
                - e2e-az2
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: another-node-label-key
                operator: In
                values:
                - another-node-label-value
      containers:
      - name: with-node-affinity
        image: k8s.gcr.io/pause:2.0

    affinity에는 현재 requiredDuringSchedulingIgnoredDuringExecutionpreferredDuringSchedulingIgnoredDuringExecution 의 두가지 종류의 affinity가 존재한다. 네이밍 규칙에서 볼 수 있듯이 추후에 이미 스케줄링 된 pod에 대해서 재배치 여부를 결정할 수 있는 옵션도 추가될 예정이라고 한다.

    • requiredDuringSchedulingIgnoredDuringExecution : affinity룰에 충족하는 노드에만 스케줄링 된다.
    • preferredDuringSchedulingIgnoredDuringExecution : affinity룰에 충족하는 노드에 우선 스케줄링 된다.

Static Pod

controlplane에 해당하는 서비스는 스케줄러가 아닌 staticpod의 형태로 배포가 된다. 이러한 서비스들은 기본적으로 kubelet이 관리하며, staticpod 전용 디렉토레로 선언된 폴더에 yaml 파일을 배치함으로써 pod을 배포할 수 있다. static pod 디렉토리는 kubelet 실행시 옵션으로 지정되거나, config 파일에 정의되어 있다.

master $ ps -ef | grep /usr/bin/kubelet
root      2699     1  3 17:21 ?        00:00:03 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --cgroup-driver=systemd --network-plugin=cni --pod-infra-container-image=k8s.gcr.io/pause:3.2 --resolv-conf=/run/systemd/resolve/resolv.conf
root      4564  3664  0 17:22 pts/0    00:00:00 grep --color=auto /usr/bin/kubelet
master $ cat  /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  anonymous:
    enabled: false
  webhook:
    cacheTTL: 0s
    enabled: true
--- 중략 ---
nodeStatusUpdateFrequency: 0s
rotateCertificates: true
runtimeRequestTimeout: 0s
staticPodPath: /etc/kubernetes/manifests
streamingConnectionIdleTimeout: 0s
syncFrequency: 0s
volumeStatsAggPeriod: 0s

클러스터 관리 및 업그레이드

노드 정지

  • kubectl drain <nodename> : 해당 노드에 배포된 요소들 다른 노드로 이동 및 제거 + 새로운 스케줄링 정지
  • kubectl cordon <nodename> : 해당 노드에 새로운 스케줄링 정지
  • kubectl uncordon <nodename> : drain 혹은 cordon 명령을 통해 스케줄링이 정지 된 것을 해제

UPGRADE

  • kubernetes는 1번 업그레이드 시에 1개의 마이너 버전 업그레이드를 지원한다. (ex. 1.12.4 → 1.13.4)
  • 업그레이드는 Master 노드 → Worker 노드 순서로 진행한다.

    업그레이드 과정(kubeadm 기준)

    1. kubeadm upgrade plan 명령으로 업그레이드 가능 버전 확인

    2. kubectl drain <nodename> 명령으로 노드 중지

    3. 패키지 매니저를 통해 kubeadm 버전 업그레이드 (ex. apt install kubeadm=1.19.0-00)

    4. [master노드]kubeadm upgrade apply <버전이름> [worker노드]kubeadm upgrade node

    5. 패키지 매니저를 통해 kubelet 버전 업그레이드 (ex. apt install kubelet=1.19.0-00)

클러스터 백업, ETCD

클러스터를 백업하는 방법은 크게 두가지로 나눌 수 있다. etcd의 기능을 활용하는 법, kube-apiserver의 기능을 활용하는 법.

  • kube-apiserver

    kube-apiserver를 활용하는 경우, kubectl이나 직접 api 호출하는 형태를 통해서 yaml 파일로 저장할 수도 있다.

    kubectl get all -A -o yaml > backup.yaml

    하지만, 모든 범위를 커버하는 것은 어렵기 때문에 velero와 같은 백업 솔루션을 사용하는 것이 바람직하다.

  • etcd

    etcd는 쿠버네티스 클러스터의 모든 상태를 저장하는데 사용되는 key-value 기반의 데이터베이스이다. etcd에는 snapshot 기능이 있는데, 해당 기능을 활용해서 특정 시점의 상태를 하나의 dbfile로 저장하여 관리하고 복원할 수 있다.

    먼저 etcdctl 명령어를 사용하려면, 몇가지 기본 옵션을 채워주어야 한다. 채워줄 대상 값은 현재 실행 중인 etcd서비스 혹은 pod에 실행 인자로 들어간 값과 동일하게 하면 되니, 참고하면 된다.

    kubectl get pod -n kube-system etcd-master -o yaml
    alias etcdctl="ETCDCTL_API=3 etcdctl --cacert=/etc/kubernetes/pki/etcd/ca.crt \
    --cert=/etc/kubernetes/pki/etcd/server.crt \
    --endpoints=https://127.0.0.1:2379 \
    --key=/etc/kubernetes/pki/etcd/server.key \
    snapshot save /tmp/snapshot-pre-boot.db"

    스냅샷은 대상 디렉토리만 지정해주면 매우 간단하게 생성할 수 있다.

    etcdctl snapshot save /tmp/snapshot-pre-boot.db

    restore를 수행할때는 기존 data디렉토리 및 cluster-token 과 다른 값을 이용해 새로운 클러스터를 생성하는 형태로 수행해야한다. 이는 기존에 동작중인 etcd클러스터와 의도치 않게 섞이게 되는 불상사를 막기 위한 방법이다.

    etcdctl snapshot restore \
    --data-dir="/etc/etcd-restore" \
    --initial-cluster-token="etcd-cluster-1" \
    --initial-advertise-peer-urls="https://127.0.0.1:2380" \
    --initial-cluster="master=https://127.0.0.1:2380" \
    --name="master" \
    /tmp/snapshot-pre-boot.db

    restore가 정상적으로 되면 /etc/kubernetes/manifest 디렉토리에 위치한 etcd.yaml 파일의 내용도 적절하게 수정해 주어야 한다. 수정해 주어야 하는 내용은 etcd 실행 옵션과 볼륨 마운트 부분이다.

보안

kube-apiserver 인증

  • static password auth (id, pw)

    kube-apiserver를 실행할때 --basic-auth-file=<filename> 옵션을 함께 주어서 적용할 수 있다. 파일은 username, password, uid 가 포함된 csv파일이다. (선택항목으로 group 정보를 네번째 항목으로 줄 수 있다.)

    user01, password1, u0001, "group01"
    user02, password2, u0002, "group02"
    user03, password3, u0003, "group02, group03"

    curl을 통해 호출시에는 다음과 같은 형태로 호출할 수 있다.

    curl -v -k https://masterip:6443/api/v1/pods -u "user01:password1"
  • static token auth (token)

    kube-apiserver를 실행할때 --token-auth-file=<filename> 옵션을 함께 주어서 적용할 수 있다. 파일은 token, password, uid 가 포함된 csv파일이다. (선택항목으로 group 정보를 네번째 항목으로 줄 수 있다.)

    31ada4fd-adec-460c-809a-9e56ceb75269, user01, u0001, "group01"
    31ada4fd-adec-460c-809a-9e56ceb75268, user02, u0002, "group02"
    31ada4fd-adec-460c-809a-9e56ceb75267, user03, u0003, "group02, group03"

    curl을 통해 호출시에는 다음과 같은 형태로 호출할 수 있다.

    curl -v -k https://masterip:6443/api/v1/pods --header "Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269"
  • 인증서를 이용한 인증
    curl -v k https://masterip:6443/api/v1/pods --key admin.key --cert admin.crt --cacert ca.crt

kubernetes 인증서

kubernetes에서 동작하는 모든 controlplane은 각각의 인증서를 가지고 동작하도록 설계되어 있다. 일반적인 웹서비스와 다르게, kubernetes에서는 클라이언트도 CA로부터 인증받은 사용자만 클러스터에 접근할 수 있다. 이는, 일반적으로 kubernetes 클라이언트 자체에 접근하는 동작은 클러스터 관리자만이 수행하는 동작이기 때문이다.(일반 사용자들은 쿠버네티스가 호스팅 하는 다른 서비스들에 접근하지, 쿠버네티스 클러스터에는 접근할 일이 없다.)

때문에, 쿠버네티스 클러스터에 접근하기 위해서는 클러스터의 컨트롤 플레인들의 인증서를 인증하는 CA인증서를 활용해서, 사용자가 클러스터에 접근할 때 사용할 인증서에도 싸인을 해주어야 한다. 다행히도 쿠버네티스에서는 이러한 작업을 간편하게 할 수 있도록 api를 제공하며, 우리는 간단하게 csr을 생성하고, CertificateSigningRequest 오브젝트를 yaml를 이용해 생성하여 간편하게 CA인증 및 인증서 획득 작업을 진행할 수 있다.

apiVersion: certificates.k8s.io/v1  #어떤 이유에서인지 katacoda 실습에서는 apiVersion을 certificates.k8s.io/v1beta1 으로 해야 성공하였다.(구버전이어서 그런듯)
kind: CertificateSigningRequest
metadata:
  name: john
spec:
  groups:
  - system:authenticated
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

참고로 위에서 설명한 사용자(관리자)가 접근하는 kubernetes 클러스터는 편의상 '쿠버네티스 클러스터' 라는 이름으로 지칭하였지만 정확하게는, kube-api server를 의미한다. 우리가 kubernetes rest api를 사용하든, kubectl 명령어를 사용하든, 결국 통신하게 되는 서비스는 kube-api server 서비스이기 때문이다.

  • 인증서 세부정보 확인 방법

    인증서 파일경로는 각 컴포넌트들의 실행 옵션에 포함되어 있으니 참고하자.

    openssl x509 -in <crt-file-path> --text -noout
  • kubectl 명령 사용시 인증 관련 config

    ~/.kube/config 파일은 kubectl 명령어 사용시 기본적으로 적용시킬 config 파일이다. 해당 파일의 내용은 직접 확인 및 편집 할 수도 있고, 다음 명령을 통해 확인 및 조작이 가능하다.

    kubectl config view
    kubectl config set ~~

    파일 내용은 cluster, context, users 세파트로 이루어져있고, 아래는 예시이다.

    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority: fake-ca-file
        server: https://1.2.3.4
      name: development
    - cluster:
        insecure-skip-tls-verify: true
        server: https://5.6.7.8
      name: scratch
    contexts:
    - context:
        cluster: development
        namespace: frontend
        user: developer
      name: dev-frontend
    - context:
        cluster: development
        namespace: storage
        user: developer
      name: dev-storage
    current-context: dev-frontend
    kind: Config
    preferences: {}
    users:
    - name: developer
      user:
        client-certificate: fake-cert-file
        client-key: fake-key-file
    - name: experimenter
      user:
        password: some-password
        username: exp

API 그룹 및 사용자 그룹 권한 할당

kube-apiserver를 통해 api를 호출하면 다음과 같은 api group들을 시작으로 하여 하위의 여러 api들을 호출할 수 있다.

api, apis, healthz, livez, logs, metrics, openapi, readyz, version

그 중에서도 /api/apis 로 시작하는 그룹은 각각의 방식으로 쿠버네티스의 자원을 표현하고 컨트롤 할 수 있는 api를 제공한다. 이들은 특별히 각각 core, named 로 별칭하여 부르기도 한다.

  • RBAC

    쿠버네티스는 Role을 생성하여 각각의 Role에 권한을 세부적으로 명시하고, RoleBinding을 통해 특정 Role을 사용자에게 종속시키는 방식으로 사용자에게 권한을 할당한다. 특정 namespace에 한정된 권한 할당은 일반 role과 rolebinding을 사용하고, 클러스터 레벨의(namespace에 종속되지 않는)자원에 대한 권한 할당은 clusterrole과 clusterrolebinding을 사용한다.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""] # "" indicates the core API group
      resources: ["pods"]
      verbs: ["get", "watch", "list"]
    apiVersion: rbac.authorization.k8s.io/v1
    # This role binding allows "jane" to read pods in the "default" namespace.
    # You need to already have a Role named "pod-reader" in that namespace.
    kind: RoleBinding
    metadata:
      name: read-pods
      namespace: default
    subjects:
    # You can specify more than one "subject"
    - kind: User
      name: jane # "name" is case sensitive
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      # "roleRef" specifies the binding to a Role / ClusterRole
      kind: Role #this must be Role or ClusterRole
      name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
      apiGroup: rbac.authorization.k8s.io

    명령어로 간편하게 할 수도 있다.

    kubectl create clusterrole michelle-node --resource=nodes --verb=*
    kubectl create clusterrolebinding michelle-node --clusterrole=michelle-node --user=michelle

    할당할 수 있는 자원들을 보고 싶다면 다음 명령을 통해서도 쉽게 확인할 수 있다.

    kubectl api-resources

컨테이너 이미지 저장소 보안

쿠버네티스에서는 도커 credencial을 secret에 저장하여 관리할 수 있도록 기능을 제공한다.

kubectl create secret docker-registry \
--docker-username=dock_user \
--docker-password=dock_password \
--docker-server=myprivateregistry.com:5000 \
--docker-email=dock_user@myprivateregistry.com \
private-reg-cred
apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey

컨테이너 네트워크 보안정책

지원되는 cni에 한해서 쿠버네티스는 네트워크 보안 정책을 하나의 오브젝트형태로 관리할 수 있는 기능을 지원한다. 현재까지 지원되는 cni는 다음과 같다.

  • kube-router
  • calico
  • romana
  • weave-net
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

네트워크

CNI

컨테이너 런타임에는 여러 종류가 있고, 각각의 런타임들은 모두 비슷한 방식을 통해서 컨테이너라는 자원격리를 구현해 낸다. 컨테이너 런타임들의 대표적인 예로는, docker, rkt, ucr 등이 있다.

자원 격리를 위한 세부적인 구현 방식들은 조금씩 다르지만, 모두 비슷한 아키텍쳐를 통해 비슷한 기능을 구현하기 때문에 여러가지 컨테이너 런타임들을 효율적으로 활용하기 위해서 여러가지 표준이 생기게 되었고, 그중 네트워크 네임스페이스와 관련된 부분의 표준은 CNI(CONTAINER NETWORK INTERFACE)로 불리게 되었다.

이러한 CNI를 따르고 CNI를 위한 기능을 제공하는 어플리케이션들은 CNI 플러그인 이라고 부르며, CNCF에서는 이러한 CNI를 제안하며 이미 몇가지 지원되는 플러그인들을 제공했다.

BRIDGE, VLAN, IPVLAN, MACVLAN, WINDOWS 와 같은 인터페이스 플러그인과, host-local, dhcp, static 과 같은 IPAM 플러그인들이 그 예이다.

그 이외에도 다양한 벤더사들에서 만든 서드파티 플러그인들이 있는데, 그것들이 바로 weave, flannel, cilium, Vmware NSX, Calico 와 같은 것들이다.

그러나, 아이러니하게도 CNI를 따르지 않고 자체적인 모델을 사용하는 런타임이 있다. 다른 것이 아니라 바로 docker 이다. docker는 CNM(Container Network Model)이라는 다른 표준을 따르고 있기 때문에, CNI를 사용하는 다른 컨테이너 런타임들과 통합되지 못하고 있다.

그렇다면, 쿠버네티스는 어떻게 docker를 런타임으로 하여 컨테이너 오케스트레이션을 수행할 수 있는걸까?

그것은 바로 docker가 CNI표준을 따르지 않기는 하지만, 직접 설정하는 방식을 통해서 docker도 CNI와 함께 사용할 수 있기 때문이다.

예를들어서, docker 컨테이너의 네트워크 타입을 none으로 설정하고, 직접 bridge 플러그인을 사용하여 네트워크 설정을 할 수 있다.

docker run --network=none nginx
bridge add 2e98dcf12 /var/run/netns/2e34dcf34

시험규칙

Linux 서버 터미널

Linux 서버 터미널 (오른쪽)은 Linux 서버의 터미널을 표시합니다. 이 터미널 지침은 명령 줄에 "man lf_exam"을 입력하여 시험 중에 가져올 수도 있습니다.

  1. 루트 권한은 'sudo -i'를 실행하여 얻을 수 있습니다.
  1. 지원 인프라가 시작되고 안정화되는 데 약 15 분이 소요되므로 node-1을 재부팅하지 않아야합니다. 언제든지 node-1 이외의 노드를 재부팅 할 수 있습니다.
  1. 시험 세션이 종료되므로 node-1에서 certerminal 또는 sshd 구성 및 프로세스를 중지하거나 변경하지 마십시오.
  1. 들어오는 포트 8080 / tcp, 4505 / tcp 및 4506 / tcp를 차단하지 마십시오. 여기에는 배포의 기본 방화벽 구성 파일과 대화 형 방화벽 명령에있는 방화벽 규칙이 포함됩니다.
  1. Ctrl + W 대신 Ctrl + Alt + W를 사용합니다.
    • Ctrl + W는 Chrome에서 현재 탭을 닫는 단축키입니다.
  1. Ctrl + C 및 Ctrl + V는 시험 터미널에서 지원되지 않습니다. 복사하여 붙여 넣으려면 다음을 사용하십시오.
    • Linux의 경우 : 복사 할 텍스트를 선택하고 붙여 넣을 중간 버튼을 선택합니다 (또는 중간 버튼이없는 경우 왼쪽과 오른쪽을 동시에).
    • Mac의 경우 : ⌘ + C를 사용하여 복사하고 ⌘ + V를 사용하여 붙여 넣습니다.
    • Windows의 경우 : 복사하려면 Ctrl + Insert, 붙여 넣으려면 Shift + Insert
  1. 이 시험에 포함 된 서비스 및 응용 프로그램의 설치를 성공적으로 완료하려면 시스템 보안 정책을 수정해야 할 수 있습니다.
  1. 시험 중에는 하나의 터미널 콘솔 만 사용할 수 있습니다. GNU Screen 및 tmux와 같은 터미널 멀티플렉서를 사용하여 가상 콘솔을 만들 수 있습니다.
  1. 터미널에서 글꼴 크기를 변경하려면 기본 Chrome 키 (Ctrl 및 '+'또는 Ctrl 및 '-')를 사용하십시오.
  1. 시험 중에 시스템의 로케일을 변경하지 않아야합니다.
  1. node-1의 방화벽을 조작하거나 실행중인 lxd 또는 dnsmasq 프로세스를 조작해서는 안됩니다.

시험 중 후보자 행동 규칙

  • 응시자는 시험 중 감독관 이외의 다른 사람과 의사 소통 할 수 없습니다.
  • 응시자는 시험 중에 문제를 소리내어 스스로 읽을 수 없습니다.
  • 감독관이 특정 허가를받은 경우를 제외하고 응시자는 책상을 떠나거나 웹캠을 볼 수 없습니다.
  • 응시자는 음식을 먹거나 마시거나 (아래 규칙에 따라 투명한 액체 제외) 껌을 씹을 수 없습니다.
  • 응시자는 라벨이없는 투명한 병 또는 투명한 유리에 담긴 투명한 액체를 마실 수 있습니다.
  • 응시자는 의학적으로 필요한 경우를 제외하고 귀, 얼굴 또는 몸에 전자 장치를 착용 할 수 없습니다.
  • 응시자는 과도하거나 반복적 인 소음을 내서는 안됩니다.
  • 응시자는 입 및 / 또는 얼굴을 가리지 않아야합니다.
  • 응시자는 시험 콘솔 화면 외부의 어떤 것 (종이, 전자 장치 등)에 글을 쓰거나 입력 할 수 없습니다.
  • 응시자는 감독관의 모든 요청을 준수해야합니다. 응시자가 준수하지 않을 경우 시험이 종료됩니다.

반응형