k8s 42

Pod Lifecycle

Pod Pod은 Kubernetes에서 scheduling 가능한 최소한의 배포 단위로, Pod은 전체 생애에서 단 한번만 schedule된다. 다시 말해서 Node에 할당된 pod은 종료될 때까지, 해당 node에서만 존재할 수 있다는 이야기다. Pod 자체는 Self-heal이 불가능하므로 Fail 발생시 그대로 제거되며, 다른 UUID값을 갖는 Pod으로 대체된다. Pod Phase 'kubectl get pod -o yaml' 등의 명령어로 Pod의 디테일한 정보를 확인해보면, 사용자가 정의한 spec 외에 status 라는 필드가 존재한다. 그리고 이 필드에는 phase 항목이 존재하는데, 이는 Pod의 lifecycle이 현재 어느 단계에 있는지를 알려준다. 우선 Pod의 전체 Lifecycl..

kustomize를 활용한 Manifest 관리

Manifest의 재사용성 이 글을 읽고 있는 대부분의 사람은 Kubernetes에서 App 배포를 위해 Manifest 파일을 작성한 경험이 있을 것이다. 예를 들어 Nginx로 구성한 Frontend의 Deployment, Service, Persistent Volume, PVC, ConfigMap 등을 정의하고 "kubectl apply -f" 명령어로 적용하는 것이다. 현재 App을 배포한 Namespace를 dev라고 하고 테스트를 완료한 상태에서 production에 배포하려고 한다. spec이 동일하지 않고 일부 필드를 추가해야 하거나 환경변수 값이 다른 경우도 있다고 가정하자. 가장 단순한 해결책으로 기존에 작성한 Manifest 파일을 복사해서 production 환경에 맞게 수정하는 작..

CI-CD 2021.02.24

CI를 위한 Jenkins, GitHub, Docker Hub 연계

본격적인 CI 구성을 위해 Jenkins와 GitHub 그리고 Docker Hub를 연계하는 방법에 대해 설명한다. k8s 위에 Jenkins를 배포하는 방법에 대해선 이전 포스트를 참고한다. 실습 환경에서 CI는 다음과 같은 일련의 순서로 이루어진다고 가정하자. 1. 개발자가 자신이 작업한 코드를 GitHub Repository에 반영 2. Jenkins는 해당 Repository를 Checkout하여 Docker Image로 빌드 3. 빌드 완료 후 Docker Hub로 Image를 Push 실제 CI 과정에선 코드 리뷰나 테스트 등의 과정이 포함되어야 하나 이번 실습에선 생략하도록 한다. 우선은 Jenkihns가 GitHub에서 Code를 가져올 수 있도록 Credential을 추가하자. GitHu..

CI-CD 2021.02.20

Kubernetes 위에 Jenkins 설치하기

이번엔 Kubernetes 위에 Jenkins를 설치해보자. 가장 먼저 아래와 같이 Manifest 파일을 작성한다. [jenkins-master.yaml] apiVersion: apps/v1 kind: StatefulSet metadata: name: jenkins spec: serviceName: jenkins replicas: 1 selector: matchLabels: app: jenkins template: metadata: labels: app: jenkins spec: serviceAccountName: jenkins containers: - name: jenkins image: jenkins/jenkins:lts ports: - name: http-port containerPort: 808..

CI-CD 2021.02.19

ArgoCD: Kubernetes에 GitOps 적용하기

What is GitOps? 개발자의 코드가 실제 서비스로 반영되기까지 많은 과정을 거쳐야 한다. Repository에 Push 후 CI를 통해 Docker Image로 빌드되고, Container Registry(ex: DockerHub)로 업로드하면 CI 과정은 끝나며 이후부턴 Kubernetes에 어떻게 배포할지 고민이 필요하다. 처음엔 Manifest 파일을 작성하고 이를 kubectl 명령어를 통해 서비스를 배포하다가, 서비스마다 일일이 Manifest 파일을 작성하기 번거롭기 때문에 Helm, kustomize 등을 활용하고, 이후 자동화를 위해 Jenkins나 Ansible 등의 툴이나 API 호출같은 방식을 택하게 된다. 문제는 사람마다 선호하는 배포 방식이 제각각이고 여러 소스(원천)로부..

CI-CD 2021.02.17

Linux Namespaces

Namespace는 프로그래밍 언어 외에 다양한 컴퓨팅 분야에 널리 사용되는 개념이다. 하나의 namespace 안에서 이름과 개체(또는 자원)은 1:1로 매칭된다. 일반적인 정의는 다음과 같다. In computing, a namespace is a set of signs(names) that are used to identify and refer to objects of various kinds. A namespace ensures that all of a given set of objects have unique names so that they can be easily identified. - Wikipedia 예를 들어, C++, Java와 같은 프로그래밍 언어에서는 동일한 Namespace 안..

Calico IPAM

Kubernetes는 직접 Pod에 IP 주소를 할당하고 관리하는 대신 IPAM 플러그인을 사용하도록 설계되었다. CNI 플러그인과 마찬가지로 다양한 IPAM 플러그인이 존재하지만, 보통은 CNI 플러그인과 같이 제공하는 경우가 많다. Calico 역시 자체 IPAM 플러그인 calico-ipam을 가지고 있으며 다음과 같은 기능을 가지고 있다. Calico IPAM Calico 설치시 따로 설정을 변경하지 않는 이상, Default로 사용되는 IPAM 플러그인이다. 기본적으로 K8s의 Pod CIDR과 매칭되는 하나의 IP Pool을 사용하지만, 필요한 경우 Pod CIDR을 쪼개서 여러개의 IP Pool을 구성하여 이를 node, namespace, pod annotation에 따라 선택할 수 있는 ..

Kubernetes 2021.01.31

Calico 설치 및 Mode 변경

Calico 설치 본 설치는 50개 이하 Node로 구성된 on-prem K8s 클러스터에 적합한 방식이며, 그외에는 Calico 공식 홈페이지를 참고하도록 하자. 테스트 환경은 Master 1개, Worker 2개로 이루어진 간단한 Cluster이며, 각 Node의 IP와 Pod CIDR은 다음과 같다. master: 172.30.1.42 worker-1: 172.30.1.45 worker-2: 172.30.1.29 Pod CIDR: 192.168.0.0/16 1. Manifest 다운로드 Manifest 파일은 아래 명령어를 통해 Download 하도록 하자. 해당 파일을 종종 수정해야 할 일이 생기므로, 매번 인터넷에서 가져오는 것보다 직접 갖고 있는 편이 좋다. curl https://docs.p..

Kubernetes 2021.01.29

StatefulSet

redis, mysql과 같이 상태를 유지해야하는(Stateful) 어플리케이션은 자신만의 Persistent Volume을 요구한다. 또한 자체적인 고가용성(High Availability)를 위해 Main&Backup 또는 Read Replicas로 구성하는 것이 일반적이다. Deployment의 경우 모든 Pod이 동등하며 랜덤하게 관리되므로, 특정 Pod을 Master 또는 Slave로 지칭하거나, 우선순위를 부여할 수 없다. 또한 Service를 통해 접근시 Load Balancing이 발생하기 때문에 어떤 Pod에 연결될지 알 수 없다. 무엇보다 한개의 Persistent Volume과 Claim을 여러 Pod에서 가지려고 하는 문제가 발생한다. 이런 Stateful Application 배포..

Kubernetes 2021.01.25

CNI - Spec

Container Runtime은 Pod 생성시, 다음과 같은 방법으로 CNI에게 Network 설정을 요청한다. CNI 플러그인이 지원해야하는 Operation CNI 플러그인은 실행가능한 파일로 구현하여, 각 Container Runtime Engine(Docker, rkt 등)에 의해 호출된다. 네트워크 인터페이스를 컨테이너의 Network Namespace에 추가하고, 호스트와 연결(veth pair)한다. 또한 IPAM 플러그인을 통해인터페이스에 IP를 할당하고, Routing Rule을 갱신할 수 있어야 한다. CNI Spec v0.4.0을 기준으로 다음과 같은 4개의 Operation을 지원해야 한다. ADD: 네트워크에 Container 추가 DEL: 네트워크에서 Container 제거 C..