디렉토리내의 json 파일 중 "system_user"와 find me라는 단어가 포함된 파일들을 찾아서 이동시키는 스크립트

#!/bin/bash

RESULT=(`find ./ -name "*.json" | xargs grep -l "\"system_user\"" | xargs grep -l "find me"`)
backup_dir="/var/log/backup"
for elem in "${RESULT[@]}"
do
	mv $elem "${backup_dir}"
done

 

 

'언어 > Sell Script' 카테고리의 다른 글

rsync, expect 를 활용한 data 백업  (0) 2022.12.09
Shell Script  (0) 2021.08.31
Shell ?  (0) 2021.08.26
#! /bin/bash

echo ===========================START============================
echo start time: `date`
USER="guest"
PW="pass" #보안확인 필요
IP="10.100.3.10"
echo "backup server IP: " $IP
conditionFile="/var/log/dataBackup_*.log"
ls $conditionFile
if [[ ! "$?" -eq 0 ]]; then
	echo "conditionFile not exists"
    echo end time: `date`
    exit 0
fi

echo "wating for 5 sec..."
sleep 5

expect << EOL

set time -1
spawn rsync -ahvz --include=*.log* --exclude=* /var/log/ ${USER}@${IP}:/var/log/
# /var/log/ 하위에 .log 포맷만 대상으로 처리
expect "password:"
send "${PW}\n"
expect "]#"

set time -1
spawn rsync -ahvz --exclude=exclusive_dir /var/log/file_data/ ${USER}@${IP}:/var/log/file_data/
# /var/log/file_data/ 하위에 exclusive_dir이라는 디렉토리는 제외하고 대상 처리
expect "password:"
send "${PW}\n"
expect "]#"

EOL

backup_dirs=(
"/var/log/backup" 
"/var/log/file_data_backup"
)

for elem in "${backup_dirs[@]}"
do
	if [ ! -d #elem ]; then
    	mkdir $elem
        echo mkdir $elem
    fi
done

mv /var/log/*.log "${backup_dirs[0]}"
sleep 1
mv /var/log/file_data/* "${backup_dirs[1]}"

echo end_time: `date`
echo ===========================END============================

백업 서버로 로그파일을 백업하는 스크립트 

테스트 내용: Application 실행 시 custom Annotation이 붙은 메소드만 호출하는 방법

springboot version : 2.3.12.RELEASE

spring-framework version: 5.2.15.RELEASE

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>security</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
</project>

 

 

@Component
public class First {

    private void invoker() {
        System.out.println("First class invoker method call");
    }
}

@Component
public class Second {
    @MyAnnotation
    private void invoker() {
        System.out.println("second class invoker method call");
    }
}

@Component
public class Third {
    @MyAnnotation
    private void invoker() {
        System.out.println("Third class invoker method call");
    }
}

//호출될 클래스 및 메소드

 

 

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//annotation 정의
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}

 

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.core.SpringVersion;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Component
public class AppRunner implements ApplicationRunner {

   // @Autowired
    //private AnnotationConfigApplicationContext context; //일반 application 인 경우

    @Autowired
    private AnnotationConfigServletWebServerApplicationContext context; //web application 인 경우

	//private final Logger logger = LoggerFactory.getLogger(this.getClass()); 

    public void run(ApplicationArguments args) {
        System.out.println(
                SpringVersion.getVersion());
        System.out.println(SpringBootVersion.getVersion());

        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = context.getBean(beanDefinitionName);
            Method[] declaredMethods = bean.getClass().getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                Annotation[] annotations = declaredMethod.getAnnotations();
                for (Annotation annotation : annotations) {
                    if (annotation instanceof MyAnnotation) {
                        System.out.println("beanName: " + beanDefinitionName);
                        declaredMethod.setAccessible(true);
                        try {
                            System.out.println(declaredMethod.getName());
                            System.out.println("class name: " + bean.getClass().getName());
                            declaredMethod.invoke(bean);
                        } catch (IllegalAccessException e) {
                            System.out.println("can not access method " + declaredMethod.getName());
                            System.out.println(e.getMessage());
                        } catch (InvocationTargetException e) {
                            System.out.println(e.getMessage());
                        }
                    }
                }
            }
        }
    }
}
//application 구동 후 run 메소드 실행

 

 

import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(App.class);
        app.setWebApplicationType(WebApplicationType.SERVLET);
        app.run(args);
    }
}

//메인 메소드

@MyAnnotation가 붙은 Second, Third Class의 invoker 메소드만 호출됨을 확인

Istio?

istio.io/

 

Istio

A service mesh for observability, security in depth, and management that speeds deployment cycles.

istio.io

ref:&nbsp;https://istio.io/latest/docs/concepts/what-is-istio/

 

  • 다수의 컨테이너가 동작하는 서비스 메시같은 환경에서 각각의 컨테이너의 트래픽을 관찰하고 정상 동작하는지를 모니터링하는 도구
    • Pod안에 Proxy를 배치하여 Container에서 구동하는 Application이 Proxy를 통해 통신

 

 istio 설치

istio.io/latest/docs/setup/getting-started/

 

Getting Started

Try Istio’s features quickly and easily.

istio.io

 

  • # curl -L https://istio.io/downloadIstio | sh -
  • # cd istio-1.8.2
  • # export PATH=$PWD/bin:$PATH

 

  • # istioctl profile list
  • # istioctl install --set profile=demo -y
      • demo 버전설치

 

기존에 istioctl로 컴포넌트를 addon하던 기능이 1.8버전에서는 deprecated되었다

 

grafana 설치(https://istio.io/latest/docs/ops/integrations/)

  • kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml
  • kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/kiali.yaml
  •  

 

샘플 테스트

출처:&nbsp;https://istio.io/latest/docs/examples/bookinfo/

  • # kubectl label namespace default istio-injection=enable
  • # kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

gateway 설치

  • # kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  • # kubectl get gateways
  • # kubectl get svc -n istio-system -l istio=ingressgateway

'클라우드 > K8s' 카테고리의 다른 글

K8s 모니터링시스템  (0) 2022.04.03
K8s 오토스케일링  (0) 2022.04.03
K8s DNS  (0) 2022.04.03
K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03

K8s 모니터링시스템

 

출처:&nbsp;https://github.com/kubernetes/community/blob/master/contributors/design-proposals/instrumentation/monitoring_architecture.md

 

Metrics-server

  • Metrics-server는 K8s의 가장 기본적인 리소스 메트릭 파이프라인을 구성하는 방법이다

설치URL

 

'클라우드 > K8s' 카테고리의 다른 글

Istio?  (0) 2022.04.03
K8s 오토스케일링  (0) 2022.04.03
K8s DNS  (0) 2022.04.03
K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03

Cluster level Scalability?

  • 지정된 특정 조건만족시 Cluster의 Node를 확장/축소를 수행하는 컴포넌트
  • 보통 GCP, AWS, Azure와 같은 클라우드 인프라에서 사용

 

 

 

Pods layer autoscale

VPA(Vertical Pods Autoscaler)?

  • Pod들의 상태를 모니터링하다가 지정된 조건에 의해 scale up/down을 수행하는 컴포넌트

 

HPA(Horizontal Pod Autoscaler)?

  • 디플로이먼트에 속한 Pod들의 상태를 모니터링하다가 지정된 조건에 의해 scale in/out을 수행하는 컴포넌트

HPA 동작 flow

 

 

HPA 테스트

https://kubernetes.io/ko/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

 

HorizontalPodAutoscaler 연습

HorizontalPodAutoscaler(약어: HPA)는 워크로드 리소스(예: 디플로이먼트 또는 스테이트풀셋)를 자동으로 업데이트하며, 워크로드의 크기를 수요에 맞게 자동으로 스케일링하는 것을 목표로 한다. 수평

kubernetes.io

 

 

'클라우드 > K8s' 카테고리의 다른 글

Istio?  (0) 2022.04.03
K8s 모니터링시스템  (0) 2022.04.03
K8s DNS  (0) 2022.04.03
K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03

coreDNS?

  • 클러스터 내부에서만 사용하는 DNS 서버
  • Service나 Pod에 도메인서비스를 지원
  • 클러스터 안에서 Pod사이에 통신을 할때 IP가 아닌 도메인으로 통신하도록 하는 deployment
  • DNS를 통한 Service와 Pod Access
    • service_name.namespace.svc.cluster.local
    • Pod-IP-Address.namespace.pod.cluster.local

'클라우드 > K8s' 카테고리의 다른 글

K8s 모니터링시스템  (0) 2022.04.03
K8s 오토스케일링  (0) 2022.04.03
K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03
Pod 스케줄링  (0) 2022.04.03

볼륨(Volume)

 

Volumes

On-disk files in a container are ephemeral, which presents some problems for non-trivial applications when running in containers. One problem is the loss of files when a container crashes. The kubelet restarts the container but with a clean state. A second

kubernetes.io

  • 컨테이너는 Pod에 바인딩 되는 볼륨을 마운트하고 마치 로컬 파일시스템에 있는 것처럼 스토리지에 접근한다.
  임시 볼륨 로컬불륨 네트워크볼륨 네트워크볼륨
(클라우드 종속적)
목적 컨테이너와 데이터공유 목적 Node기반의 데이터공유 목적
클러스터 외부에 있는 자원과의 데이터공유 목적  
종류 emptyDir

hostpath
local
iSCSI
NFS
cephFS
glusterFS
...
gcePersistentDisk
awsEBS
azureFile
...

 

 

 

emptyDir

  • 하나의 포드안에서 두개이상의 컨테이너가 데이터를 공유
  • Pod와 생명주기를 같이한다.

단일 pod안에서 데이터공유

kubernetes.io/docs/concepts/storage/volumes/#emptydir

 

Volumes

On-disk files in a container are ephemeral, which presents some problems for non-trivial applications when running in containers. One problem is the loss of files when a container crashes. The kubelet restarts the container but with a clean state. A second

kubernetes.io

 

 

emptyDir 테스트

apiVersion: v1
kind: Pod
metadata:
  name: web-empty
spec:
  containers:
  - image: nginx
    name: web
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  - image: redis
    name: redis
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/
  volumes:
  - name: html
    emptyDir: {}
  • container web(/usr/share/nginx/html) container redis(/usr/share/)가 mount 된다.

 

 

hostPath

단일 노드에서 pod간 데이터공유

 

 

hostPath 테스트

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: web
  name: web
spec:
  volumes:
  - name: html
    hostPath:
      path: /webdata
  containers:
  - image: nginx
    name: web
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  • Node의 /webdata 패스와 pod의 /usr/share/nginx/html mount

 

 

 

NFS

apiVersion: v1
kind: Pod
metadata:
  name: web-nfs
spec:
  containers:
  - image: nginx
    name: web
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    nfs:
      name: 10.2.3.22
      path: /shared/nfs

 

 

 

GCE 영구 디스크를 동일한 리전에 생성

  • # gcloud compute disks create --size=10GiB --zone=asia-northeast1-c mongodb

 

 

 

PV(PersistentVolume) & PVC(PersistentVolumeClaim)

  • 스토리지 관리자가 storage Pool(PV)를 등록하고 애플리케이선 운영자가 PVC를 통해서 스토리지를 요청하는 구조
  • 애플리케이션 운영자가 애플리케이션의 구동에 필요한 스토리지 스펙을 PVC를 가지고 K8s에 요청
  • 애플리케이션 운영자와 스토리지 관리자의 역할을 분리시킬 수 있는 이점이 있다.

 

PV(PersistentVolume)

 

퍼시스턴트 볼륨

이 페이지에서는 쿠버네티스의 퍼시스턴트 볼륨 에 대해 설명한다. 볼륨에 대해 익숙해지는 것을 추천한다. 소개 스토리지 관리는 컴퓨트 인스턴스 관리와는 별개의 문제다. 퍼시스턴트볼륨 서

kubernetes.io

 

 

PV & PVC yaml

---
# PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  nfs:
    path: /tmp
    server: 172.17.0.2
    
---
# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}
      
      
---
# POD
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

 

PVC(PersistentVolumeClaim)

  • 퍼시스턴트볼륨클레임 (PVC)은 사용자의 스토리지에 대한 요청이다

 

 

 

GCE PV & PVC 테스트

apiVersion: v1 
kind: Pod 
metadata: 
  name: mongodb 
spec: 
  containers: 
  - image: mongo 
    name: mongodb 
    volumeMounts: 
    - mountPath: /data/db 
      name: mongodb 
  volumes: 
  - name: mongodb 
    persistentVolumeClaim: 
      claimName: mongo-pvc 
--- 
apiVersion: v1 
kind: PersistentVolumeClaim 
metadata: 
  name: mongo-pvc 
spec: 
  accessModes: 
    - ReadWriteOnce 
  resources: 
    requests: 
      storage: 10Gi 
  storageClassName: "" 
--- 
apiVersion: v1 
kind: PersistentVolume 
metadata: 
  name: mongo-pv 
spec: 
  capacity: 
    storage: 10Gi 
  volumeMode: Filesystem 
  accessModes: 
    - ReadWriteOnce 
    - ReadOnlyMany 
  persistentVolumeReclaimPolicy: Retain 
  gcePersistentDisk: 
    pdName: mongodb 
    fsType: ext4 
---

 

Storage classes

kubernetes.io/docs/concepts/storage/storage-classes/#gce-pd

 

Storage Classes

This document describes the concept of a StorageClass in Kubernetes. Familiarity with volumes and persistent volumes is suggested. Introduction A StorageClass provides a way for administrators to describe the "classes" of storage they offer. Different clas

kubernetes.io

  • PV를 직접 만드는 대신 사용자가 원하는 PV 유형을 선택하도록 오브젝트 정의
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: storage
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
  fstype: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: storage
---
apiVersion: v1
kind: Pod
metadata:
  name: mongodb
spec:
  containers:
  - image: mongo
    name: mongodb
    volumeMounts:
    - mountPath: /data/db
      name: mongodb
  volumes:
  - name: mongodb
    persistentVolumeClaim:
      claimName: mongo-pvc
---

  • # kubectl get sc

  • # kubectl get pv
  • #kubectl edit pv pvc-4a87cccb-70b6-46c2-a6be-4497c3c3ffd0
    • 정책변경가능

'클라우드 > K8s' 카테고리의 다른 글

K8s 오토스케일링  (0) 2022.04.03
K8s DNS  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03
Pod 스케줄링  (0) 2022.04.03
K8s Secret  (0) 2022.03.31
  • API 인증요청
    • 일반 사용자(Human User) 또는 그룹(Group)
      • 클러스터 외부에서 K8s를 조작하는 사용자로, 다양한 방법으로 인증을 거친다.
    • Kubernetes-admin
      • K8s의 모든 권한을 소유한 유저 
    • serviceAccount
      • K8s 내부적으로 관리되며 Pod가 K8s API를 다룰 떄 사용하는 계정
      • Pod가 실행될 때 ServiceAccount를 설정하지 않으면 같은 namespace에 default라는 serviceAccount가 할당됨
  • Authentication(인증)
    • user 또는 application이 API에 접근을 허가 받는 과정
    • 인증방식: 클라이언트 인증서, bearer token, HTTP 기본인증 지원
  • Authorization(인가)
    • RBAC 모델기반
    • 요청 ID에 적절한 role이 있는지 확인
  • Adminssion Control
    • 요청이 올바른 형식인지 판별
    • 요청이 처리되기 전에 수정사항을 잠재적으로 적용

 

 

~/.kube/config 파일분석

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTi #..생략
    server: https://192.168.1.10:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDR #..생략
    client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJV #..생략
  • cluster.server : 외부에서 쿠버네티스 API에 접근할 주소 설정
  • name : cluster 이름
  • context.cluster : 접근할 클러스터 설정
  • context.user : 접근할 사용자 그룹이 누구인지 설정
  • user.client-certificate-data : 클라이언트 인증에 필요한 해시값을 설정
  • user.client-key-data :  클라이언트 key 해시값을 설정

 

 

User 생성 테스트

https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user

 

Certificate Signing Requests

FEATURE STATE: Kubernetes v1.19 [stable] The Certificates API enables automation of X.509 credential provisioning by providing a programmatic interface for clients of the Kubernetes API to request and obtain X.509 certificates from a Certificate Authority

kubernetes.io

Private key 생성

openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuse"

유저등록

  • # cat myuser.csr | base64 | tr -d "\n"

csr파일을 base64로 인코딩한 문자열을 아래 yaml파일의 request에 추가합니다.

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFV  #..생락
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth

  • # kubectl apply -f ./myuser.yaml
    • 유저 생성
  • # kubectl certificate approve myuser
    • 유저 승인
  • # kubectl get csr myuser -o yaml
    • myuser의 인증서 정보 표시

 

Service Account 생성

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx
    name: webserver
  serviceAccount: get-pod

  • # kubectl create serviceaccount get-pod
    • serviceaccount 생성
  • 위에서 생성한 serviceaccount를 Pod에 적용

 

 

 

권한관리

  • Role
    • 어떤 API를 사용할 수 있는지 권한정의, 지정된 네임스페이스에서만 유효
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"]
  • apiGroups
    • role이 사용할 API group
    • Pod는 코드 API이기 때문에 apiGroups를 따로 지정하지 않는다, 만약 리소스가 job이라면 "batch"를 지정
  • resources
    • pods, deployments, services 등 사용할 API resource들을 명시
  • verbs
    • 나열된 API 리소스에 허용할 기능 나열

 

  • RoleBinding
    • Role과 유저를 연결

 

  • # kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
    • role 생성
  • # kubectl create rolebinding developer-binding-my-user --role=developer --user=myuser
    • role binding
  • # kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
    • user를 config에 등록
  • # kubectl config set-context myuser --cluster=kubernetes --user=myuser
    • user의 context 등록
  • # kubectl config use-context myuser
    • 현재 작업 context를 myuser로 변경

 

 

 

  • ClusterRole & ClusterRoleBinding
    • ClusterRole
      • 특정 네임스페이스 사용 권한이 아닌 클러스터 전체 사용 권한을 관리
kubectl create clusterrole developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
kubectl create clusterrolebinding developer-binding-myuser --clusterrole=developer --user=myuser

 

'클라우드 > K8s' 카테고리의 다른 글

K8s DNS  (0) 2022.04.03
K8s volume  (0) 2022.04.03
Pod 스케줄링  (0) 2022.04.03
K8s Secret  (0) 2022.03.31
K8s Configmap  (0) 2022.03.31

K8s는 Pod를 어떤 노드에서 실행할지에 대한 다양한 옵션이 있고 아래 4가지 방식을 지원합니다.

  • Node Selector
  • Node Affinity & pod Affinity pod antiAffinity
  • node taint & pod toleration
  • cordon & drain

 

 

 

Node Selector?

  • Pod가 클러스터 안 어떤 노드에서 실행될지를 Label을 이용하여 지정하는 방식

 

 

Node Selector 테스트

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx
    name: webserver
    ports:
    - containerPort: 80
  nodeSelector:
    cpu: "2core_over"

  • # kubectl label node w{1,2}-k8s cpu=2core_over
    • node 1, 2에 label 추가

  • cpu label이 지정된 노드에서만 pod가 실행됨을 확인 할 수 있다.

 

 

Node Affinity & antiAffinity?

  • Node Node Affinity
    • 특정 노드에서만 Pod가 실행되도록 하는 기능
    • Node Selector와 유사하지만 아래의 두가지 요구조건이 만족하는 Pod에만 스케줄링 하도록 지정 할 수 있습니다
      • requiredDuringSchedulingIgnoredDuringExecution
        • 스케줄링하는 동안 꼭 필요한 조건
      • preferedDuringSchedulingIgnoredDuringExecution
        • 스케줄링하는 동안 만족하면 좋은 조건
  • Pod Affinity
    • Pod들을 더 가깝게 배치하는 방법
  • Pod AntiAffinity
    • Pod들을 분산 배치하는 방법

 

 

Node Affinity 테스트

apiVersion: v1
kind: Pod
metadata:
  name: nginx-gpu-ssd
spec:
  containers:
  - name: webserver
    image: nginx:1.15
    ports:
    - containerPort: 8888
      protocol: TCP
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - {key: disktype, operator: Exists}
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 10
        preference:
          matchExpressions:
          - {key: gpu, operator: In, values: ["true"]}
          - {key: disktype, operator: In, values: ["ssd"]}

  • w1-k8s 노드에 gpu=true cpu=2core disktype=ssd 레이블 추가

  • requiredDuringSchedulingIgnoredDuringExecution 설정에 의해서 disktype label이 존재하는 레이블 중에서 gpu가 true disktype이 ssd인 w1-k8s node가 스케줄링 되는것을 확인 할 수 있다
    • w1-k8s 가중치: 20
    • w2-k8s disktype 레이블이 없으므로 해당사항없음
    • w3-k8s 가중치: 10

 

 

Pod Affinity 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "100000"

  • backend pod가 실행중인 w3-k8s node에서 frontend pod가 실행됨을 확인 할 수 있다

 

 

Pod AntiAffinity 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: backend
            topologyKey: kubernetes.io/hostname
      containers:
      - name: main
        image: busybox
        args:
        - sleep
        - "100000"
  • topologyKey
    • 노드 label을 이용해 pod의 affinity와 antiaffinity를 설정할 수 있는 또 하나의 기준
    • K8s는 Pod를 스케줄링 할 때 먼저 Pod의 label을 기준으로 대상 노드를 찾고, topology 필드를 확인하여 해당 노드가 원하는 노드인지 확인한다.

  • backend pod가 실행중인 w1-k8s node에서 frontend pod가 실행되지 않음을 확인 할 수 있다

 

 

 

node taint & pod toleration

  • node taint
    • 특정 Node에 taint를 설정하여 설정한 Node에는 Pod를 스케줄링 하지 않도록 할 수 있음.
      • master node인 m-k8s에는 taint NoSchedule가 설정돼 있어 해당 Node는 스케줄링을 받지 않도록 설정되어 있다
    • toleration
      • taint를 설정한 Node에 Pod를 스케줄링하려면 toleration을 설정해아 함
      • toleration이 있는 Pod는 동일한 taint가 있는 node를 포함하여 tain가 설정돼있지 않은 모든 node에 배치된다

 

 

node taint & pod toleration 테스트

1. taint 설정되지 않는 node에만 pod 배치여부확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • # kubectl taint nodes w3-k8s key01=value01:NoSchedule
    • w3-k8s Node에 taint 설정
    • 형식: kebectl taint nodes 노드이름 키=값:효과
  • taint가 설정된 m-k8s ,w3-k8s Node에는 pod가 할당되지 않음을 확인 할 수 있다

 

2. Pod에 toleration 설정하여(taint가 동일한 Node는 없음) Node에 Pod 배치여부 확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • Taint가 설정돼있지 않은 w1-k8s, w2-k8s에만 pod가 스케줄링됨을 알 수 있다

 

3. Pod에 toleration 설정하여(taint가 동일한 Node는 있음) Node에 Pod 배치여부 확인

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • # kubectl taint node w1-k8s role=web:NoSchedule
    • w1-k8s Node에 taint 설정
  • taint와 tolerations이 일치하는 w1-k8s Node에 Pod가 스케줄링 됨을 확인 할 수 있다.
  • 또한 taint가 설정되지 않은 w2-k8s에 Pod에도 스케줄링 된다

 

4. Node에 전부 taint가 설정되어 있고 pod tolerations 설정이 맞지 않는다면?

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx
      tolerations:
      - key: "role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"

  • 모든 Node에 taint가 설정되어 있고 Pod tolerations 설정이 맞지 않는 경우 pod는 pending 상태가 된다. 

 

 

 

cordon & drain?

  • 특정 Node에 있는 Pod들을 모두 다른 노드로 옮기거나 특정 Node에 Pod들을 스케줄링하지 않도록 제한하는 기능
  • cordon
    • 특정 노드에 Pod 스케줄링 금지
  • uncordon
    • 특정 노드에 Pod 스케줄링 해제
  • drain
    • 특정 노드에서 동작중인 모든 Pod를 제거
      • kubectl drain Node [option]
        • option
          • --ignore-deamonsets
            • DaemonSet이 관리하는 Pod들은 ignore
          • --force
            • RC, RS, Job, DaemonSet 또는 StatefulSet에서 관리하지 않는 Pod 제거

 

 

cordon & uncordon 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • # kubectl cordon w1-k8s
    • w1-k8s Node를 cordon 설정
  • w1-k8s Node에 pod가 할당되지 않음을 확인 할 수 있다
  • # kubectl uncordon w1-k8s
    • cordon 해제

 

 

drain 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  name: weserver
spec:
  replicas: 4
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
    spec:
      containers:
      - name: nginx-container
        image: nginx

  • w3-k8s Node에서 Controller에 의해서 관리되지 않는 db pod와 deployment에 의해서 관리되는 webserver pod가 실행중이다.
  • # kubectl drain w3-k8s --ignore-daemonsets --force
    • Controller에 의해서 관리되지 않는 db pod는 삭제되고 deployment의 관리를 받는 webserver pod는 다른 Node에서 실행됨을 확인 할 수 있다.
  • w3-k8s Node는 cordon을 했을때와 동일하게 상태가 SchedulingDisabled인것을 확인 할 수 있다.
  • static Pod는 삭제되지 않습니다.

'클라우드 > K8s' 카테고리의 다른 글

K8s volume  (0) 2022.04.03
K8s 인증과 권한관리  (0) 2022.04.03
K8s Secret  (0) 2022.03.31
K8s Configmap  (0) 2022.03.31
K8s 버전 업그레이드  (0) 2022.03.18

K8s Secret?

  • 시크릿은 비밀번호, OAuth 토큰, SSH 키 같은 민감한 정보들을 저장하는 용도로 사용
  • 구성정보를 base64로 인코딩해서 한곳에서 관리
    • 인코딩된 정보가 pod로 전달되면 해당 정보는 디코딩 된 형태로 보임
  • secret의 최대 크기는 1MB
  • Secret는 etcd에 암호화 하지 않은 텍스트 형태로 저장됨
kubectl create secret <Available Commands> name
                        docker-registry
                        generic
                        tls
                        
 ex)
 kubectl create secret tls my-secret --cert=path/to/certi/file --key=path/to/key/file
 
 kubectl creaate secret docker-registry reg-secret --docker-username=xxx \
   --docker-password=pass --docker-email=xxx@gmail.com
   
kubectl creaate secret genetic generic-secret \
--from-literal=INTERVAL=2 --from-file=/config/

 

 

K8s Secret 생성 테스트

apiVersion: v1
kind: Pod
metadata:
  name: genid-env-secret
spec:
  containers:
  - image: ubuntu
    command: ["bash"]
    args:
    - "-c"
    - sleep 100000
    env:
    - name: INTERVAL
      valueFrom:
        secretKeyRef:
          name: test-secret
          key: INTERVAL
    name: generator
    volumeMounts:
    - name: html
      mountPath: /webdata
  - image: nginx:1.14
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
  volumes:
  - name: html
    emptyDir: {}

  • # kubectl create secret generic test-secret --from-literal=INTERVAL=2 --from-file=./genid-web-config/

 

 

K8s Secret 볼륨마운트 테스트

apiVersion: v1
kind: Pod
metadata:
  name: genid-env-secret
spec:
  containers:
  - image: ubuntu
    command: ["bash"]
    args:
    - "-c"
    - sleep 100000
    env:
    - name: INTERVAL
      valueFrom:
        secretKeyRef:
          name: test-secret
          key: INTERVAL
    name: generator
    volumeMounts:
    - name: html
      mountPath: /webdata
    - name: config
      mountPath: /etc/nginx/conf.d
  - image: nginx:1.14
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    secret:
      secretName: test-secret
      items:
      - key: nginx-config.conf
        path: nginx-config

 

'클라우드 > K8s' 카테고리의 다른 글

K8s 인증과 권한관리  (0) 2022.04.03
Pod 스케줄링  (0) 2022.04.03
K8s Configmap  (0) 2022.03.31
K8s 버전 업그레이드  (0) 2022.03.18
K8s 애플리케이션 변수관리  (0) 2022.03.17

K8s Configmap란?

  • 컨테이너에 필요한 환경 설정을 컨테이너와 분리해서 제공하는 기능
  • 컨테이 구성 정보를 한곳에 모아서 관리
  • Configmap을 단일진입점으로 Pod가 생성/재시작 할때마다 해당 Configmap을 참조하도록 하는게 가능
//형식
kubectl create configmap CONFIG_NAME --from-literal=id=jaon --from-literal=age=30
                                                   key value             key value 
kubectl create configmap CONFIG_NAME -- from-file=text.file
                                                    key  내용: value 
kubectl create configmap CONFIG_NAME --from-file=mydate=text.file
                                                   key     value
kubectl create configmap CONFIG_NAME --from-file=/config_dir/
                                              directory file전부

 

 

Configmap 생성 테스트

  • # kubectl create configmap test-config --from-literal=INTEVAL=2 --from-literal=OPTION=boy --from-file=config.dir/
    • configmap 생성
  • # kubectl describe configmaps test-config
  • # kubectl edit configmap test-config
    • configmap 수정

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: config-test
  namespace: default
data:
  URL: localhost
  USER: myuser
  PASS: mypass
  DEBUG_MODE: info

  • yaml 형식으로 configmap 생성

 

 

Configmap Pod에 일부 configmap 적용 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: configmap-test
  name: configmap-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: configmap-test
  template:
    metadata:
      labels:
        app: configmap-test
    spec:
      containers:
      - image: nginx
        name: nginx
        env:
        - name: DEBUG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: config-test
              key: DEBUG_MODE
        - name: URL
          valueFrom:
            configMapKeyRef:
              name: config-test
              key: URL

  • configmap에서 pod에 일부 적용된 환경변수 조회

 

 

Configmap Pod에 전체 configmap 적용 테스트

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: configmap-test
  name: configmap-test
spec:
  replicas: 3
  selector:
    matchLabels:
      app: configmap-test
  template:
    metadata:
      labels:
        app: configmap-test
    spec:
      containers:
      - image: nginx
        name: nginx
        envFrom:
        - configMapRef:
            name: config-test

  • configmap의 전체 내용을 pod에 적용

 

 

Configmap 볼륨 적용 테스트

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume-test
spec:
  containers:
  - image: ubuntu
    name: id-generator
    command:
    - sleep
    - "100000"
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: test-config
          key: INTERVAL
    volumeMounts:
    - name: html
      mountPath: /webdata
  - image: nginx
    name: web-server
    ports:
    - containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
  volumes:
  - name: html
    emptyDir: {} #pod의 container간 volume mount (/webdata와 /usr/share/nginx/html path연결)
  - name: config
    configMap:
      name: test-config
      items:
      - key: nginx-config.conf #configmap test-conf의 key
        path: nginx-config.confs #생성할 파일이름
      - key: INTERVAL #configmap test-conf의 key
        path: IS_IS_INTERVAL

'클라우드 > K8s' 카테고리의 다른 글

Pod 스케줄링  (0) 2022.04.03
K8s Secret  (0) 2022.03.31
K8s 버전 업그레이드  (0) 2022.03.18
K8s 애플리케이션 변수관리  (0) 2022.03.17
K8s Self-healing  (0) 2022.03.17

K8s 버전 업그레이드

 

업그레이드 계획 수립(v1.20.2를  v1.20.8로 업그레이드)

  • # kubadm upgrade plan

 

kubeadm을 1.20.8 버전으로 업그레이드(kubeadm 자체도 업그레이드가 필요)

  • # yum upgrade -y kubeadm-1.20.8

 

kubeadm을 이용하여 업그레이드 시도

  • # kubeadm upgrade apply 1.20.8

 

kubelet 업그레이드

  • # yum upgrade kubelet-1.20.8 -y

kubelet restart 및 daemon-reload

  • # systemctl restart kubelet
  • # systemctl daemon-reload
    • master node의 버전만 upgrade되었으므로 각각의 work node도 업그레이드를 해야함

work node kubelet 업그레이드

  • yum upgrade kubelet-1.20.8 -y
  • systemctl restart kubelet
  • systemctl daemon-reload

 

버전확인

  • work node 3은 다른 버전으로 kubelet을 업그레이드 진행

'클라우드 > K8s' 카테고리의 다른 글

K8s Secret  (0) 2022.03.31
K8s Configmap  (0) 2022.03.31
K8s 애플리케이션 변수관리  (0) 2022.03.17
K8s Self-healing  (0) 2022.03.17
K8s label  (0) 2022.03.17

애플리케이션에서 환경변수를 설정하는 방법은 3가지가 있다.

 

1. 환경변수를 pod에 저장하는 방법(kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/)

 

apiVersion: v1
kind: Pod
metadata:
  name: envar-demo
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      value: "Hello from the environment"
    - name: DEMO_FAREWELL
      value: "Such a sweet sorrow"

envars.yaml

 

 

 

2. Configmap환경변수를 ConfigMap 에 저장하는 방법

 

configmap 생성 및 조회

  • # kubectl create configmap map-name --from-file=test
  • # kubectl get configmaps -o yaml

 

apiVersion: v1
kind: Pod
metadata:
  name: envar-configmap
  labels:
    purpose: demonstrate-envars
spec:
  containers:
  - name: envar-demo-container
    image: gcr.io/google-samples/node-hello:1.0
    env:
    - name: DEMO_GREETING
      valueFrom:
        configMapKeyRef:
          name: map-name
          key: test

envars-configmap.yaml

 

configmap을 통한 환경번수 설정

 

전체 keylist를 환경변수에 설정

 

configmap을 활용한 디렉토리 마운트

/etc/config에 파일형태로 환경변수 저장

  • configmap에 3개의 key-value pairs를 추가할 경우 pod내에서도 이 설정이 1분마다 refresh되어 반영됨을 확인 할 수 있다.
    • key-value pairs의 삭제 또한 반영된다.
  • 마운트형태가 아닌 일반 configmap방식은 pod가 restart되어야 configmap의 변경사항이 반영된다.

 

3. 환경변수를 Secret에 저장하는 방법

  • bese64 인코딩된 형태로 데이터를 저장한다.
    • 비밀번호, OAuth 토큰 및 ssh 키등

secret 생성

  • # echo -n admin > username
  • # echo -n 242q3afsa2 > password
  • # kubectl create secret generic db-user-pass --from-file=u sername --from-file=password
  • # kubectl get secrets db-user-pass -o yaml
  • 디코딩
    • # echo YWRtaW4= | base64 --decode

secret를 환경변수로 pod생성

 

 

  • kubectl create secret generic db-secret --from-literal=' DB_Password=Passw0rd!0' --dry-run=client  -o yaml > secret-mysql.yaml
  • kubectl get secret db-secret -o yaml

'클라우드 > K8s' 카테고리의 다른 글

K8s Configmap  (0) 2022.03.31
K8s 버전 업그레이드  (0) 2022.03.18
K8s Self-healing  (0) 2022.03.17
K8s label  (0) 2022.03.17
K8s Network  (0) 2022.03.17

livenessProbe

  • 컨테이너의 실행 여부를 진단하여 실패시 컨테이너를 종료시키고 재시작 정책에 따라 컨테이너 재시작
    • (Pod을 재시작하는 것이 아니라 Container을 재시작하는 한다.)
  • 컨테이너가 재시작되더라도 Pod의 IP address는 바뀌지 않는다.

 

 

 

livenessProbe 매커니즘

  • httpGet
    • 지정한 IP주소, port, path에 HTTP GET 요청을 보내, 해당 컨테이너의 응답을 확인
    • 반환코드가 200이 아닌 값이 나오면 컨테이너 재시작
  • tcpSocket
    • 지정된 포트에 TCP연결을 시도하여 연결되지 않으면 컨테이너 재시작
  • exec
    • exec 명령을 전달하고 명령 종료코드가 0이 아닌값이면 컨테이너 재시작
livenessProbe 필드 설명
initialDelaySeconds ( default: 0초 ) pod 실행 후 delay할 시간
periodSeconds (default: 10초) health check 검사 주기
timeoutSeconds (default: 1초)  health check 요청에 대한 응답대기시간
successThreshold (default: 1번) 성공 횟수
failureThreshold (default: 3번) 연속 실패횟수

 

 

 

livenessProbe 테스트

  • redis pod의 livenessProbe를 설정하여 container 정상성 확인

 

 

redis liveness probe 실패

  • liveness probe가 연속 3회(default) 실패하면 컨테이너 재시작
    • 컨테이너의 httpGet 요청이 실패

 

 

 

livenessProbe 멀티컨테이너 테스트

livenessProbe 멀티컨테이너

  • redis와 nginx 멀티컨테이너 생성(성공)

 

 

멀티 컨테이너 생성실패

  • 단일 pod 멀티컨테이너는 서로 리소스를 공유하므로 redis가 사용하는 6379 port를 각각 binding 할 수 없다.

 

 

 

readinessProbe

  • 컨테이너 실행된 후 실제로 서비스에 대한 응답을 할 수 있는지 진단
  • 해당 진단이 실패하는 경우 엔드포인트 컨트롤러는 해당 파드에 연결된 모든 서비스를 대상으로 엔드포인트 정보를 제거 
  • 해당 pod가 readinessProbe를 지원하지 않는 경우 기본 상태값은 succeed

'클라우드 > K8s' 카테고리의 다른 글

K8s 버전 업그레이드  (0) 2022.03.18
K8s 애플리케이션 변수관리  (0) 2022.03.17
K8s label  (0) 2022.03.17
K8s Network  (0) 2022.03.17
K8s Controller  (0) 2022.03.17

K8s label란?

  • key value 형태로 구성하며 클러스터 안에 오브젝트를 만들 때 메타데이터로 설정할 수 있다.
  • key는 컨트롤러들이 Pod를 관리 할 때 자신이 관리해야 할 Pod를 구분하는 역할을 함
metadata:
  labels:
    rel: product
    name: mainui

https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/

 

레이블과 셀렉터

레이블 은 파드와 같은 오브젝트에 첨부된 키와 값의 쌍이다. 레이블은 오브젝트의 특성을 식별하는 데 사용되어 사용자에게 중요하지만, 코어 시스템에 직접적인 의미는 없다. 레이블로 오브

kubernetes.io

 

 

label 테스트

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

레이블 조회 및 key확인

  • # kubectl get pods --show-labels
  • # kubectl get pod -L app

 

레이블 추가 및 삭제

  • # kubectl label pod label-demo test=foo
    • test1=test1 test2=test2 test3=test3 형식으로 다수의 key-value 지정가능
  • # kubectl label pod label-demo test-
  • # kubectl label pod label-demo app=httpd --overwrite
    • 덮어쓰기

 

조건검색

  • # kubectl get pod -l 'env=prod,creation_method=manual'
    • -l 또는 --selector 사용가능
  • # kubectl delete pods --selector 'env=prod'

 

 

 

Node label

  • Worker Node의 특성을 Label로 설정
  • Worker Node의 특성을 고려하여 Pod를 선택적으로 배치 할 수 있다

 

 

Node label 테스트

  • # kubectl label nodes w1-k8s gpu=true disk=ssd
    • w1-k8s node에 gpu disk label 설정
  • #kubectl label nodes w2-k8s gpu=true
    • w2-k8s node에 gpu label 설정
  • #kubectl label nodes w3-k8s disk=ssd
    • w3-k8s node에 disk label 설정

 

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: node-selector-test
  name: node-selector-test
spec:
  containers:
  - image: nginx
    name: webserver
    ports:
    - containerPort: 80
  nodeSelector:
    gpu: "true"
    disk: ssd

  • nodeSelector에 의해서 설정 된 label이 있는 node가 선택된다

 

 

 

Annotation이란?

  • label과 동일하게 key-value 쌍으로 사용자가 설정 할 수 있다
  • k8s에게 특정 정보를 전달할 용도로 사용
  • 관리를 위해 필요한 정보를 기록할 용도로 사용
    • 릴리즈, 로깅, 모니터링에 필요한 정보들을 기록
annotations:
  builder: "jaon"
  buildDate: "20220331"
  imageRepository: https://xxx.com/"

 

 

Annocation 테스트

apiVersion: v1
kind: Pod
metadata:
  name: annotation-test
  annotations:
    image-registry: "https://hub.docker.com/"
spec:
  containers:
  - image: nginx
    name: annotation-test
    ports:
    - containerPort: 80

 

 

 

Canary Deployment

  • 블루 그린 업데이트
    • 기존에 실행된 Pod의 개수와 같은 개수의 신규 Pod를 모두 실행한 후 신규 Pod가 정상적으로 실행됐는지 확인한 이후 트래픽을 한꺼번에 신규 파드 쪽으로 옮김
    • downtime이 발생함.
  • 롤링 업데이트
    • 배포된 전체 Pod를 한꺼번에 교체하지 않고 일정 개수씩 교체하면서 배포
    • 서비스 중단없이 업데이트하는 방식
  • 카나리 업데이트
    • 기존 버전을 유지한 채로 일부 버전만 신규 Pod로 교체하고 버그나 이상이 없는지 확인

 

 

Canary 배포 테스트

apiVersion: v1
kind: Service
metadata:
  name: mainui-svc
spec:
  selector:
    app: mainui
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mainui-stable
spec:
  replicas: 2
  selector:
    matchLabels:
      app: mainui
      version: stable
  template:
    metadata:
      labels:
        app: mainui
        version: stable
    spec:
      containers:
      - name: mainui
        image: nginx:1.14
        ports:
        - containerPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mainui-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mainui
      version: canary
  template:
    metadata:
      labels:
        app: mainui
        version: canary
    spec:
      containers:
      - name: mainui
        image: nginx:1.15
        ports:
        - containerPort: 80
  • label을 통해서 기존에 구동중인 service에 canary버전을 단일진입점으로 포함시켜서 canary버전을 검증한다
    • canary버전에 문제가 없다면 기존 stable버전의 deployment를 삭제하여 canary버전으로 서비스를 할 수 있다
      • 기존 서비스에 영향을 끼치지 않고 서비스가 가능하다

'클라우드 > K8s' 카테고리의 다른 글

K8s 애플리케이션 변수관리  (0) 2022.03.17
K8s Self-healing  (0) 2022.03.17
K8s Network  (0) 2022.03.17
K8s Controller  (0) 2022.03.17
K8s namespaces  (0) 2022.03.17

 K8s Service란?

  • 쿠버네티스의 네트워크를 의미
  • Pod들을 묶어주는 virtual IP
  • 동적으로 변하는 pod들에 고정적으로 접근 할 때 사용하는 방법을 제공
    • 포드의 IP가 변동되었을때 재설정을 하지 않아야 할 필요성이 있음
      • 포드가 지속적으로 생성/삭제시 IP의 지속적인 변동으로 로드밸런싱을 관리해줄 개체가 필요
  • Service Type
    • ClusterIP
    • NodePort
    • LoadBalancer
    • ExternalName

 

 

 

Cluster IP

  • ClusterIP
    • Pod 그룹의 단일 진입점(Virtual IP) 생성 
    • default 서비스 타입 클러스터 안에서만 사용할 수 있다
    • 클러스터안의 Node나 Pod에서 Cluster IP를 통해서 서비스에 연결된 Pod에 접근 할 수 있다
    • 단 클러스터 외부에서는 접근 할 수 없다

 

 

Cluster IP 테스트

apiVersion: v1
kind: Service
metadata:
  name: culster-ip-service
spec:
  type: ClusterIP
  clusterIP: 10.100.0.254
  selector:
    app: webserver
#  sessionAffinity: ClientIP  #client session을 1개의 pod에 고정
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  annotations:
    kubernetes.io/change-cause: version 1.20
spec:
  progressDeadlineSeconds: 2
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
        test: test_branch
    spec:
      containers:
      - name: webserver
        image: nginx:1.20
        ports:
        - containerPort: 80

service 생성

  • yaml에서 정의한 cluster ip 10.100.0.254를 vip로 가지는 service가 생성되었다

sercice Endpoints ip확인

  • service Endpoints가 pod의 IP와 연결됨을 확인 할 수 있다
  • # curl 10.100.0.254:80
    • service에 묶여있는 3개의 pod에 랜덤하게 요청한다(round-robin방식 X)

scale out

  • pod를 5개로 scale out시 service에도 2개의 EndPoint IP가 추가됨을 확인 할 수 았다.

 

 

sessionAffinity 설정

  • sessionAffinity를 설정하여 클라이언트의 세션을 하나의 pod로 고정시킨다

1 session에서 요청수행

  • busybox를 생성하여 ClusterIP로 wget 요청을 해보자
    • # kubectl run -it --rm --image=busybox bash
    • # wget -O- -q 10.4.5.5
      • 동일 클라이언트(동일세션) 요청을 동일 pod가 응답함을 확인할 수 있다

session에 따른 응답

 

 

 

NodePort

  • 서비스 하나에 모든 Node의 지정된 포트를 할당
  • NodePort를 사용하면 클러스터 내부/외부에서 접근 할 수 있다
  • Default NodePort 범위: 30000 - 32767

 

 

NodePort 테스트

apiVersion: v1
kind: Service
metadata:
  name: cluster-ip-service
spec:
  type: NodePort
  clusterIP: 10.100.100.254
  selector:
    app: webserver-test
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30001

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-test
  annotations:
    kubernetes.io/change-cause: version 1.20
spec:
  progressDeadlineSeconds: 2
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webserver-test
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver-test
    spec:
      containers:
      - name: webserver-test
        image: nginx:1.15
        ports:
        - containerPort: 80

 

 

노드포트 생성

  • # kubectl create -f ./nodePortTest.yaml

 

노드포트를 이용한 pod접근

  • GKE에서 방화벽 해제가 필요
    • # gcloud compute firewall-rules create test-go-svc-rules --allow=tcp:30001
      • 30001번포트의 방화벽을 allow한다.
  • # kubectl get nodes -o wide
  • # curl 34.85.11.146:30001
  • # curl 104.198.123.19:30001
  • # curl 35.200.69.28:30001

 

gcloud firewall rule 삭제

  • # gcloud compute firewall-rules list
  • # gcloud compute firewall-rules delete test-go-svc-rule

 

 

 

LoadBalancer

  • AWS/GCP/Azure등과 같은 클라우드에서 제공하는 LoadBalancer와 pod를 연결한 후 해당 LoadBalancer IP를 이용하여 클러스터 외부에서 pod에 접근 할 수 있다
apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-test
spec:
  type: LoadBalancer
  selector:
    app: test-go
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

 

로드밸런서 생성

  • # kubectl create -f ./loadbalceTest.yaml

 

 

 

NodePort vs LoadBalancer

  • NodePort는 Node의 IP를 알아야 접근이 가능하여 외부에 Node의 IP가 노출될 우려가 있다.
  • LoadBalancer는 대표 IP(EXTERNAL-IP)를 통해서 pod들에 접근하여 Node의 IP가 외부에 노출되지 않는다.
  • LoadBalancer는 경로를 최적화하여 구현할 수 있다.

 

 

 

ExternalName

  • 클러스터 내부에서 외부에 접속 시 사용할 도메인을 등록해서 사용
  • 클러스터 도메인이 실제 외부 도메인으로 치환되어 동작한다

 

 

ExternalName 테스트

apiVersion: v1
kind: Service
metadata:
  name: externalname-svc
spec:
  type: ExternalName
  externalName: google.com

  • Pod 내부에서 ExternalName으로 google.com로 curl실행
    • # curl externalname-svc.default.svc.cluster.local
  • 특정 서비스에 접근하는 도메인
    • 서비스이름.네임스페이스.svc.cluster.local
  • 특정 Pod 접근하는 도메인
    • IP주소.네임스페이스.pod.cluster.local

 

 

 

Headless 서비스란?

  • Loadbalancing이 필요 없거나 단일 서비스 IP가 필요 없는 경우 사용
  • Pod의 endpoint에 DNS resolving Service 지원
  • Pod의 DNS 주소: pod-ip-addr.namesapce.pod.cluster.local

 

 

Headless 테스트

apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  type: ClusterIP
  clusterIP: None
  selector:
    app: webserver-test
#  sessionAffinity: ClientIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-test
  annotations:
    kubernetes.io/change-cause: version 1.20
spec:
  progressDeadlineSeconds: 2
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webserver-test
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver-test
    spec:
      containers:
      - name: webserver-test
        image: nginx:1.15
        ports:
        - containerPort: 80

headless 생성

  • # curl 172-16-221-172.default.pod.cluster.local
    • Pod ip를 domain으로 가지는게 의미가 있나?
    • service discovery 관련 공부가 필요할 듯 하다.

 

 

 

Kube-proxy

  • K8s service의 backend 구현
  • endPoint 연결을 위한 iptable rule 구성
  • Cluster IP나 Node port로 접근할 수 있게 만들어 실제 조작을 하는 컴포넌트
  • mode
    • userspace
      • 클라이언트의 서비스 요청을 iptables를 거쳐 kube-proxy가 받아서 연결
    • iptables
      • service API 요청시 iptables rule 생성
      • 클라이언트에서 오는 모든 요청은 iptables을 거쳐서 pod로 직접 전달
    • IPVS
      • L4 로드밸런싱 기술을 이용
      • 별도의 ipvs 지원 모듈을 설정한 후 적용 가능

 

 

 

인그레스란?

  • 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙의 모음
  • 서비스들에 대한 단일 진입점을 구성 
    • 서비스에 대한 외부 URL 제공
    • 트래픽 로드밸런싱
    • SSL 인증 처리
    • 도메인 기반 가상 호스팅 제공

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-go-ingress
spec:
  rules:
  - host: fastwon1.com
  - http:
      paths:
      - path: /
        backend:
          serviceName: test-go-svc
          servicePort: 80

 

인그레스 조회

  • # kubectl get ingress

 

 

 

 

 

 

'클라우드 > K8s' 카테고리의 다른 글

K8s Self-healing  (0) 2022.03.17
K8s label  (0) 2022.03.17
K8s Controller  (0) 2022.03.17
K8s namespaces  (0) 2022.03.17
K8s Pod 구성패턴  (0) 2022.03.17

Controller이란?

  • 특정 application을 운영하는데 있어서 pod의 개수를 보장하는 역할을 하는 컴포넌트

 

https://devops.com.vn/using-replica-set-and-daemon-set-deploying-managing-pod-in-k8s/



1. ReplicationController란?

  • k8s 프로젝트 초장기부터 있었던 가장 기본적인 컨트롤러
  • 지정한 숫자만큼의 Pod의 개수를 보장하며 파드 집합의 실행을 안정적으로 보장하기 위한 컴포넌트
    • 현재 구동중인 Pod 개수가 요구된 pod 개수보다 부족한경우 template를 이용하여 pod를 생성 
    • 요구된 pod의 수 보다 현재 구동중인 pod가 많다면 최근에 생성된 pod를 삭제
    • 기본구성
      • selector
        • Controller는 오직 selector만을 기준으로만 동작한다
      • replicas
        • Pod의 개수를 보장
      • template
        • RC는 pod 생성/삭제에 대해서 해당 template를 참조한다
  • 현재는 비슷한 역할을 수행하는 ReplicaSet을 사용하는 추세

 

ReplicationController Test

apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx-pod
      labels:  #해당 labels는 반드시 상단의 selector의 값들을 전부 포함해야한다.
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

  • # kubectl apply -f ./replicationController.yaml
  • # kubectl describe rc rc-nginx
  • 현재 Replicas의 current와 disired가 같다면 pod를 추가 할 수 없다

scale in

  • # kubectl scale rc rc-nginx --replicas=2

 

scale out

  • # kubectl scale rc http-go --replicas=5
  • pod의 label 확인
    • # kubectl get pods --show-labels



2. ReplicaSet이란?

  • ReplicationController와 같은 역할을 수행하는 컨트롤러
  • selector를 통해서 ReplicationController보다 다양한 표현이 가능하다
  • ReplicationController와 동일하게 selector만을 기준으로 pod를 관리한다
ReplicationController.yaml ReplicaSet.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: rc-nginx
spec:
replicas: 3
selector:
app: nginx
note: "12"
abc: "2"
template:
metadata:
name: nginx-pod
labels:
app: nginx
note: "12"
abc: "2"
test: test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
note: "12"
abc: "2"
template:
metadata:
name: nginx-pod
labels:
app: nginx
note: "12"
abc: "2"
test: test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
matchExpressions 연산자 설명
In key와 values를 지정하여 동일한 key, value가 일치하는 Pod 매칭
NotIn Key는 일치하고 value는 일치하지 않는 Pod 매칭
Exists key에 맞는 label의 Pod 매칭
DoesNotExist Key와 다른 label의 Pod 매칭
matchExpressions In Exists
표현 spec:
replicas: 3
selector:
  matchExpressions:
- {key: version, operator: In, values: ["1.14",1.15]}
spec:
replicas: 3
selector:
  matchExpressions:
- {key: version, operator: Exists}
설명 key가 version이면서 해당값이 1.14이거나 1.15인 경우에만 Pod 매칭 key가 version이 존재하는 pod 매칭
matchExpressions NotIn DoesNotExist
표현 spec:
replicas: 3
selector:
  matchExpressions:
- {key: version, operator: NotIn, values: ["1.14",1.15]}
spec:
replicas: 3
selector:
  matchExpressions:
- {key: version, operator: Exists}
설명 key가 version이면서 해당값이 1.14이거나 1.15인 아닌 경우에만 Pod 매칭 key가 version이 존재하는 않는 pod 매칭

 

ReplicaSet Test

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
      test: test
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

 

  • # kubectl apply -f ./rs-nginx.yaml
  • # kubectl scale rs rs-nginx --replicas=2
    • scale in
  • # kubectl delete rs rs-nginx --cascade=orphan
    • 현재 구동중인 pod는 삭제하지 않고 rs만 삭제



3. Deployment란?

  • stateless 앱을 배포하기 위해서 사용하는 가장 기본적인 컨트롤러
  • ReplicaSet을 관리하여 앱 배포를 세밀하게 관리한다
  • 단순 실행시켜야하는 pod를 유지하는것 뿐만 아니라 롤링 업데이트(Rolling Update) & Rolling Back 지원
  • Rolling Update
    • pod 인스턴스를 점진적으로 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어 질 수 있도록 한다
ReplicaSet.yaml Deployment.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: nginx-pod
labels:
app: nginx
test: test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
name: nginx-pod
labels:
app: nginx
test: test
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

 

Deployment Test

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

  • delpoyment -> rsplicaSet -> pod 생성
  • # kubectl apply -f ./deployment-nginx.yaml
  • # kubectl get deployments.apps,rs,pod

 

Rolling Update

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
        test: test_branch
    spec:
      containers:
      - name: webserver
        image: nginx:1.14
        ports:
        - containerPort: 80

deployment로 생성한 pod의 nginx 버전변경

  • # kubectl apply -f ./deployment-nginx.yaml --record
  • # kubectl set image deployment deployment-nginx webserver=nginx:1.15 --record

구동중인 pod container의 버전확인

  • pod 버전 update 확인

rollout 실행

  • # kubectl rollout status deployment deployment-nginx
    • rolling update 동작확인
  • # kubectl rollout pause deployment deployment-nginx
    • rolling update 중단
  • # kubectl rollout status deployment deployment-nginx
    • rolling update 다시시작

  • # kubectl rollout history deployment deployment-nginx
    • rolling update history 확인
      • default값은 최대 10개

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-nginx
  kubernetes.io/change-cause: version 1.14
spec:
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 50%
      maxUnavailable: 25%
    type: RollingUpdatae
  replicas: 3
  selector:
    matchLabels:
      app: webserver
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webserver
        test: test_branch
    spec:
      containers:
      - name: webserver
        image: nginx:1.14
        ports:
        - containerPort: 80

 

Rolling update 전략 의미
progressDeadlineSeconds deployment 진행 중 실패했을경우, 실패했을때까지의 대기시간(default: 600초)
revisionHistoryLimit rolling update command history 저장 개수(default :10개)
maxSurge 업데이트 진행 중 최대로 생성할 수 있는 pod 수(default: 25%)

예시: maxSurge: 50%
- 현재 replicas 3개 기준(1.5(50%) = 2) 3+2(반올림)--> 업데이트 중 최대 pod 5개까지 생성 가능
maxUnavailable 업데이트 진행 중 사용 할 수 없는 최대 pod 수(default: 25%)
- 75% pod는 항상 가용중임을 의미
annotations:




annotations:
kubernetes.io/change-cause: version 1.15
...
spec:
containers:
- name: webserver
image: nginx:1.15
annotations:
kubernetes.io/change-cause: version 1.16
...
spec:
containers:
- name: webserver
image: nginx:1.16
annotations:
kubernetes.io/change-cause: version 1.17
...
spec:
containers:
- name: webserver
image: nginx:1.17


- annotations를 추가하여 rollout history에 Change-cause 정보를 변경 할 수 있다

- Rolling update는 container의 이미지변경시에 적용된다

 

Rollback

1.19로 update한 nginx container를 nginx 1.14로 rollback

  • # kubectl rollout undo deployment deployment-nginx --to-revision=1
    • --to-revision 생략시 바로 전단계로 rollback

  • rollback 이후 rollout history의 1번이 삭제되고 3번으로 변경



4. DaemonSet이란?

  • 전체 노드에서 Pod가 한 개씩 실행하도록 보장하는 컴포넌트
  • 클러스터 전체 노드에 특정 Pod를 실행할 때 사용
  • 클러스터에 노드가 추가되면 DaemonSet이 해당 노드에 Pod 실행
  • 노드가 클러스터에서 빠지면 해당 노드의 Pod는 사라짐
  • 사용 케이스
    • 로그수집기
    • 모니터링 에이전트

 

DaemonSet Test

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 80

 

daemonSet 생성

  • 현재 Ready 중인 w1-k8s node와 w2-k8s node에 각각 1개의 pod가 생성된다

node 삭제 후 해당 node의 daemonSet pod 삭제 확인

  • # kubectl delete nodes w2-k8s
    • w2-k8s node 삭제
  • 일정시간 경과 후 w2-k8s에서 구동중이던 daemonSet pod가 삭제됨을 확인

 

node추가 시 daemonSet pod 자동 생성 확인

  • 현재 w2-k8s node가 없는 상황 -> daemonSet pod는 w1-k8s에만 구동중이다
  • w2-k8s node를 join하여 w2-k8s node에 daemonSet pod가 자동 생성됨을 확인해보자
    • 준비사항
      • api server ip/port
        • # kubectl config view | grep server
      • token
        • # kubeadmon token list로 확인
          • 만약 token 값이 없으면 생성한다.
            • # kubeadm token create --tth 시간
      • Hash값
        • # openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

node join

  • kubeadm join <Kubernetes API Server:PORT> --token <2. Token 값> --discovery-token-ca-cert-hash sha256: Hash 값
    • # kubeadm join 192.168.1.10:6443 --token 123456.1234567890123456  --discovery-token-ca-cert-hash sha256:ca382767cc3a2d5fba351381f454b3afaa9dad53d8271a602ea95abe8b2268d6

 

DaemonSet Rolling-Update

daemonSet의 이미지 버전변경

  • # kubectl edit daemonsets.apps daemonset-nginx
    • edit를 통해서 container의 이미지 버전변경
  • 기존에 구동중인 daemonSet Pod가 terminate -> Running됨을 확인
  • Rollback
    • # kubectl rollout undo daemonset daemonset-nginx



StatefulSet이란?

  • Pod의 상태를 유지해주는 역할을 하는 컴포넌트
    • 특정 데이터를 볼륨에 저장한 후 Pod를 재시작하였을때 해당 데이터를 유지할 수 있게 한다
  • Pod 재시작 시 pod의 이름을 유지시킬 수 있다
  • 여러 Pod 사이의 순서를 지정하여 실행되게 할 수 있다



StatefulSet test

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-nginx
spec:
  replicas: 3
  serviceName: statefulset-nginx-service
#  podManagementPolicy: OrderedReady  순차적으로 pod 생성
#  podManagementPolicy: Parallel 병렬적으로 pod 생성
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx-pod
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-container
        image: nginx
        ports:
        - containerPort: 80

 

  •  scale out 수행 시
    • # kubectl scale statefulset statefulset-nginx --replicas=5
      • statefulset-nginx-3, statefulset-nginx-4가 생성
  • scale in 수행 시
    • # kubectl scale statefulset statefulset-nginx --replicas=2
      • statefulset-nginx-2, statefulset-nginx-3, statefulset-nginx-4가 삭제

 

Rolling-Update

  • # kubectl edit statefulsets.apps statefulset-nginx
    • rolling-update는 pod이름의 역순으로 Terminating -> Running 수행한다

 

rollback

 

  • # kubectl rollout undo statefulset statefulset-nginx
    • rollback은 pod이름의 역순으로 Terminating -> Running 수행한다



Job이란?

  • 실행된 후 종료해야하는 성격의 작업을 실행시킬 때 사용하는 컴포넌트
    • Batch 성 작업에 용이
      • 비정상 종료 -> 다시실행
      • 정상 종료 -> 완료



Job Test

apiVersion: batch/v1
kind: Job
metadata:
  name: job-test
spec:
#  completions: 5  //정상적으로 실행 종료되어야하는 pod 개수 지정
#  parallelism: 2  //동시에 수행되는 pod 개수 지정
#  activeDeadlineSeconds: 5  //정상적으로 종료되는 시간 지정
  template:
    spec:
      containers:
      - name: ubuntu-container
        image: ubuntu
        command: ["bash"]
        args:
        - "-c"
        - echo "job test"; sleep 50; echo "'end'"
      restartPolicy: Never # //비정상 종료시 pod를 재시작
 #     restartPolicy: OnFailure  //비정상 종료시 container를 재시작 
 #  backoffLimit: 3  //restartPolicy가 OnFailure인 경우 3번까지 container를 재시작

  • completed된 pod는 재시작되지 않고 Pod가 정상적으로 실행돼 종료됐음을 의미하는 Completed 상태가 된다



CronJob이란?

  • Job을 시간을 기준으로 관리하는 컴포넌트
  • CronJob Schedule

매월 1일 1시 15분에 수행
주중: 요일 = 1-5
주말: 요일 = 0,6

*/10 * * * * = 10분마다 한번씩 수행
* * 1,3,5,6 * * = 매월 1, 3, 5, 6일에 한번 수행

CronJob Test

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-test
spec:
  schedule: "14 * * * *"
  startingDeadlineSeconds: 500 //지정된 시간에 job이 실행되지 못한경우 설정한 시간까지 지나면 cronjob을 실행하지 않도록 지정
  # concurrencyPoilcy: Allow  //job 여러개를 동시에 실행(default)
  # concurrencyPoilcy: Forbid // job을 동시에 실행하지 않고 기다림(처음 실행된 작업이 끝난 후 실행)
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: ubuntu-container
            image: ubuntu
            command: ["bashs"]
            args:
            - "-c"
            - echo "job test"; sleep 3; echo "'end'"
          restartPolicy: Never
#    backoffLimit: 3

'클라우드 > K8s' 카테고리의 다른 글

K8s label  (0) 2022.03.17
K8s Network  (0) 2022.03.17
K8s namespaces  (0) 2022.03.17
K8s Pod 구성패턴  (0) 2022.03.17
POD  (0) 2022.03.17

K8s namespaces

 

namespace

  • 쿠버네티스 클러스터 하나를 여러 개 논리적인 단위로 나눠서 사용
  • 용도에 따라 실행해야 하는 앱을 구분할 때 사용

 

 

 

namespace 조회

  • # kubectl get ns
  • # kubectl get pod -n kube-system
    • kube-system namespace내의 pod 조회

 

 

 

namespace 생성

namespace 생성

  • # kubectl get ns
  • # kubectl create namespace namespace-test

 

namespace yaml파일 생성

  • # kubectl create namespace test-ns --dry-run=client -o yaml > test-ns.yaml

 

 

 

생성한 네임스페이스에 pod 생성

  • # kubectl create -f ./nginx.yaml -n test-ns

 

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: test-ns
spec:
  containers:
  - image: nginx:1.14
    name: nginx
    ports:
     - containerPort: 80
     - containerPort: 443

yaml 파일에 namespace 등록

 

 

 

 

생성한 네임스페이스에 deployment 생성

namespace에 nginx컨테이너 생성

  • # kubectl create deployment nginx --image nginx -n office
  • # kubectl get pod --namespace office
    • office네임스페이스의 pod 조회

 

 

 

네임스페이스 조회

네임스페이스 조회

  • # kubectl get all --all-namespaces
  • # kubectl get pods --all-namespaces

 

 

 

디폴트네임스페이스 변경

1) .kube/config 파일에서 default namespace변경

~/.kube/config파일
파일변경 후 변경사항 확인

  • ~/.kube/config 파일에 namespace 추가

 

2) config context 변경

  • # kubectl config set-context test-ns@kubernetes --cluster=kubernetes --user=kubernetes-admin --namespace=test-ns
    • test-ns로 context 생성
  • # kubectl config view
    • context 확인
  • # kubectl config current-context
    • 현재 context 확인
  • # kubectl config use-context test-ns@kubernetes
    • 현재 context switch

 

 

 

네임스페이스 삭제

  • # kubectl delete ns office
    • 네임스페이스 하위의 리소스들도 전부 삭제된다.

'클라우드 > K8s' 카테고리의 다른 글

K8s Network  (0) 2022.03.17
K8s Controller  (0) 2022.03.17
K8s Pod 구성패턴  (0) 2022.03.17
POD  (0) 2022.03.17
K8s 동작원리  (0) 2022.03.17

사이트카 패턴

  • 원래 사용려던 기본 컨테이너 기능 확장 또는 강화하는 용도의 컨테이너 추가
  • 멀티컨테이너 형태로 구성
    • 웹서버 컨테이너
      • 로그를 파일로 남김
    • 로그 수집 컨테이너
      • 파일시스템에 쌓이는 로그를 수집하여 외부 로그수집기로 전송

 

 

 

앰배서더 패턴

  • pod안에서 프록시 역할을 하는 컨테이너를 추가하는 패턴
  • 멀티컨테이너 형태로 구성
    • 앱 컨테이너
      • 외부에 접근하는 경우 앰배서더 컨테이너를 통해서 연결되도록 설정
    • 앰베서더 컨테이너
      • 프록시 또는 로드밸런서 역할 수행

 

 

어댑터 패턴

  • pod 외부로 노출되는 정보를 표준화하는 어댑터 컨테이너를 사용
  • 멀티컨테이너 형태로 구성
    • 앱 컨테이너
      • Adapter 컨테이너가 전달한 정보를 가공하여 노출
    • 어댑터 컨테이너
      • 외부 모니터링 정보를 Adapter 컨테이너가가 받아서 앱 컨테이너에 전달
  • 프로메테우스에서 사용하는 패턴

 

 

 

 

 

 

https://matthewpalmer.net/kubernetes-app-developer/articles/multi-container-pod-design-patterns.html

 

Multi-Container Pod Design Patterns - CKAD Course

Multi-Container Pod Design Patterns in Kubernetes Multi-container pods are extremely useful for specific purposes in Kubernetes. While it’s not always necessary to combine multiple containers into a single pod, knowing the right patterns to adopt creates

matthewpalmer.net

 

 

 

'클라우드 > K8s' 카테고리의 다른 글

K8s Controller  (0) 2022.03.17
K8s namespaces  (0) 2022.03.17
POD  (0) 2022.03.17
K8s 동작원리  (0) 2022.03.17
Single Master K8s 설치 및 기본 명령어  (0) 2022.03.17

+ Recent posts