2023 01 18
2023-01-18¶
배포 전략 & 쿠버네티스¶
- 참고: https://www.redhat.com/ko/topics/containers/what-is-a-kubernetes-cluster
- 좋은 배포 요건
- 자동화
- 사용자 영향 최소화
- 빠른 배포 & 빠른 롤백
- 배포에 대한 기록이 될 것
- 배포 전략
- Rolling Update
- 점진적으로 교체하는 방식
- 배포/롤백 둘 다 조금 느림
- Blue/Green
- 기존 Blue, 신규 Green
- 로드밸런서가 포인팅 하는 것 싹 옮겨줌
- 즉각적인 배포
- 2배의 리소스를 투입할 수 있는 여건이 필요
- Canary
- 일부 서버에서 단계적으로 트래픽 전환
- 실시간으로 새로운 버전 테스트 가능
- 트래픽 전환으로 빠른 롤백 가능
- Rolling Update
- CI/CD
- 어플리케이션을 짧은 주기로 사용자에게 전달하는 것
- CI: Continuous Integration
- CD: Continuous Delivery / Deployment
- 배포 파이프라인 예시
- start -> build image -> deliver image to image registry -> update tag -> argocd -> sync -> merge branch
- Docker
- 컨테이너 기반의 오픈소스 가상화 플랫폼
- 환경에 상관없이 어플리케이션 구축/테스트/배포
- Docker Container
- 격리된 공간에서 프로세스가 동작함
- 여러 Container가 동일한 머신에서 실행 가능하며, 커널을 공유함
- Container 실행에 필요한 파일 및 설정값을 포함함
- Container는 이미지로 구동
- Docker image 만드는 법
- Dockerfile: 자체 DSL 언어를 사용하기
- jib: Java 어플리케이션을 간단하게 이미지화 할 수 있음
- Gradle 플러그인으로 사용해보자
- docker build를 통해 Docker daemon이 레지스트리로 부터 이미지를 가져오고, 이미지를 만듦
- 만들어진 이미지를 통해 Docker run으로 컨테이너로 띄움
- 쿠버 개요
- 쿠버네티스
- 2014년 구글에서 만든 오픈소스 컨테이너 오케스트레이션
- Cluster (상위 개념)
- 어플리케이션 컨테이너를 실행하기 위한 일련의 노드 머신
- 컨트롤 플레인 및 하나 이상의 노드를 포함하고 있음
- YAML 파일로 원하는 상태를 지정해주세요
- 컨트롤 플레인 (Master Node)
- 어느 어플리케이션을 실행하고 어플리케이션이 어느 컨테이너 이미지를 사용할지 원하는 상태로 유지 관리
- 컨트롤 플레인은 etcd, controller manager, scheduler, kube apiserver로 이루어짐
- etcd <-> kube apiserver
- scheduler <-> kube apiserver
- controller manager <-> kube apiserver
- scheduler: 어느 Pod를 어느 Node에 배치할지
- etcd: 설정값들의 저장소
- controller manager: 리소스 매니저, Pod 관리자
- kube apiserver: Node와 소통하는 역할
- 노드 (Worker Node)
- 어플리케이션과 워크로드를 실제로 실행
- 컨테이너는 반드시 Pod안에서 구동됨
- Node안에 보통 하나의 Pod를 담아 구동시킴
- 노드는 pod, kubelet으로 구성됨
- pod: 컨테이너를 구동시킴
- kubelet: 마스터 노드, 다른 워커 노드와 통신하는 역할 수행
- 쿠버네티스
- 쿠버 구성 요소
- Object: 템플릿을 통해 리소스의 바라는 상태를 정의해두면 이를 바탕으로 오브젝트 생성/삭제
- Namespace: 클러스터 내부를 논리적인 단위로 구분해 사용
- Pod: 쿠버네티스에서 컨테이너가 실행되는 최소 단위
- Service
- Controller: Pod 관리하는 역할
- ReplicaSet: Self-Healing, 가용성 보장
- Deployment: 무상태 어플리케이션 배포시 사용
- DaemonSet: 모든 노드에 동일한 파트 실행시 사용
- StatefulSet: 상태 있는 파드 관리
- Job: 일회성 작업
- Cronjob: 주기적 작업
- Service: Pod가 생성/삭제 되면서 IP 변경될 수 있는데, 이를 고정된 주소로 박아버리는 것을 도와줌
- ClusterIP: 클러스터 내부에서 접근 가능한 IP 제공
- NodePort: 노드에 노출되어 외부에서 접근 가능한 서비스
- LoadBalancer: 외부 로드밸런서 pod에 연결
- Ingress: 클러스터 내부로 접근하는 요청 어찌 처리할지 정의해둔 규칙
- Object: 템플릿을 통해 리소스의 바라는 상태를 정의해두면 이를 바탕으로 오브젝트 생성/삭제
Scala 타입¶
- 참고: https://docs.scala-lang.org/tour/unified-types.html
- Scala 타입 계층
- Any: 모든 타입의 슈퍼 클래스 (equals, hashCode, toString 등 정의되어있음)
- AnyVal: Value 타입을 나타냄
- Double
- Float
- Long
- Int
- Short
- Byte
- Unit: 아무런 의미없는 단일 타입
()로 나타냄, 무조건 리턴타입 있어야해서 도입함 - Boolean
- Char
- AnyRef: Ref 타입을 나타냄. Value가 아닌 친구는 모두 AnyRef의 서브타입. (java.lang.Object와 동일)
- AnyVal: Value 타입을 나타냄
-
Scala 타입 캐스팅
- Byte -> Short -> Int -> Long -> Float -> Double
- Char -> Int
- 정상적인 타입 변환 방향
- 비정상적인 타입 변환 방향
- **Nothing & Null
- Nothing
- 모든 타입의 subtype (bottom type)
- 예외 발생, 프로그램 종료, 무한루프 돌 때 Nothing을 씁니다
- 평가되지 않는 식을 표현할 때(?) 쓰는 듯 합니다.
- 아직 잘 모르겠음
- Null
- AnyRef 밑에 있는 subtype
- Scala 코드에선 딱히 쓰실 필요 없고,
- 다른 JVM 언어의 호환을 위해 Null 타입을 만들어두긴 했어요
- Null 대신 쓸 수 있는거 마련되어 있어요
- Nothing
Scala 클래스¶
- 참고: https://docs.scala-lang.org/tour/classes.html
-
class 정의하기
- class 키워드로 만들어주세요
- class 이름은 대문자로 시작해주세요
- Point 클래스 만들어보기
- 생성자
- 생성자에 기본값을 줄 수 있어
-
Private Member와 게터/세터
- default public
- 세터 문법이 독특함
_=: getter로 쓴 친구의 이름과 동일한 이름으로 지정해야해class Point { private var _x = 0 private var _y = 0 private val bound = 100 def x = _x def x_= (newValue : Int) : Unit = { if (newValue < bound) { _x = newValue } else { printWarning } } def y = _y def y_= (newValue : Int) : Unit = { if (newValue < bound) { _y = newValue } else { printWarning } } private def printWarning = println("WARNING: OUT OF BOUNDS") }
- 기본 생성자의 인자는 val/var로 지정해서 생성할 수 있어. 다만 val/var 써주면 public이 기본이긴 해
- 하지만 val이 불변이니, 세터로 주입할 생각 X
- 그냥 아무것도 안쓰면, val + private이 기본이야!
Scala 파라미터¶
- 참고: https://docs.scala-lang.org/tour/default-parameter-values.html
- 참고: https://docs.scala-lang.org/tour/named-arguments.html
- Default Parameter 개요
- 기본저긍로 스칼라는 메서드, 클래스 생성자 등에서 default parameter를 가질 수 있음
- 그에 따라 디폴트 파라미터에 대해서는 굳이 지정해주지 않아도 호출이 가능함
- Default Parameter 주의할 점
- 메서드에 디폴트 파라미터를 가진다면 애매한 상황이 발생할 수 있어
- 따라서 스칼라는 (같은 이름 + 디폴트 파라미터) 에 대응되는 메서드를 만들 수 없어
- 아래 상황에서
A.func()어떤거 호출할지 모르겠지?
- Argument Parameter에 이름 지정해주기
- 메서드 호출시, 이름이 지정된 파라미터는 순서와 상관없이 있음
- 그러나,,, 어떤건 이름이 정해져있고, 어떤건 이름이 없다면...
- 이름 없는 아규먼트가 무조건 먼저와야 하며, 해당 이름없는 친구는 메서드 시그니처 순서대로 투입됨
Scala Trait¶
- 참고: https://docs.scala-lang.org/tour/traits.html
- Trait 개요
- 클래스들 사이에 인터페이스와 필드를 공유할 때 쓰임
- Java8의 인터페이스와 비슷
-
Trait 사용법
trait예약어- generic, abstract method를 통해서 확장성을 노려보세요
extend,override를 통해 구현해주세요- 제네릭이 있다면 확정지어주세요
trait Iterator[A] { def hasNext: Boolean def next(): A } class IntIterator(to: Int) extends Iterator[Int] { private var current = 0 override def hasNext: Boolean = current < to override def next(): Int = { if (hasNext) { val t = current current += 1 t } else 0 } } val iterator = new IntIterator(10) iterator.next() iterator.next()
- Subtyping
- trait이 요구되는 곳에 trait 서브타입을 대입하여 사용할 수 있다
import scala.collection.mutable.ArrayBuffer trait Pet { val name: String } class Cat(val name: String) extends Pet class Dog(val name: String) extends Pet val dog = new Dog("Harry") val cat = new Cat("Sally") val animals = ArrayBuffer.empty[Pet] animals.append(dog) animals.append(cat) animals.forEach(pet => println(pet))
- trait이 요구되는 곳에 trait 서브타입을 대입하여 사용할 수 있다
Scala Tuple¶
- Tuple 개요
- 튜플은 불변이다!
- 메서드에서 여러개를 리턴할 때 유용함
- Tuple Element 접근
Scala Mixin¶
- Mixin으로 클래스를 합성하기
- Mixin은 클래스를 합성할 때 사용할 수 있는 trait이다
- 아래 예시에서 D는 B라는 부모클래스를 상속받았으며, C 믹스인을 가진다
- 클래스는 하나만 상속받을 수 있지만, 믹스인은 여러개 받을 수 있음
- Mixin 예시
abstract class AbsIterator { type T def hasNext: Boolean def next(): T } class StringIterator(s: String) extends AbsIterator { type T = Char private var i = 0 def hasNext = i < s.length def next() = { val ch = s charAt i i += 1 ch } } trait RichIterator extends AbsIterator { def foreach(f: T => Unit): Unit = while (hasNext) f(next()) } class RichStringIter extends StringIterator("Scala") with RichIterator val richStringIter = new RichStringIter richStringIter.foreach(println)
Mixin?¶
- 참고: https://ko.wikipedia.org/wiki/%EB%AF%B9%EC%8A%A4%EC%9D%B8
- 설명
- 다른 클래스의 부모클래스가 되지 않으면서, 다른 클래스에서 사용할 수 있는 메서드를 포함하는 클래스
- 코드 재사용성을 높이고, 다이아몬드 문제 제거
- 메서드가 포함된 인터페이스로 볼 수 있음
30분 스칼라¶
- 참고: https://school.programmers.co.kr/learn/courses/12/12-30%EB%B6%84-scala
- 변수와 계산하기
- 스칼라는 싹 다 객체야
- 1 + 2 는 곧 (1).+(2) 라고 생각하면 됩니다
- 익명함수
- 세상에 함수를 이렇게 정의할 수 있어
- 중첩 for문
- 아니 뭔 for 문을 이따구로;;
- 클래스
- 자바 스타일과 스칼라 스타일의 차이를 한 번 보자보자 어디보자
class JPerson() { var _name: String = null def this(_name: String) = { this() this._name = _name } // 스칼라 스타일 Setter def name_=(_name:String) = this._name = _name // 자바 스타일 Setter def setName(_name:String) = this._name = _name // 스칼라 스타일 Getter def name = this._name // 자바 스타일 Getter def getName() = name }
- 자바 스타일과 스칼라 스타일의 차이를 한 번 보자보자 어디보자