DevCastleOne

본 내용의 코드와 설명은 인프런 > 쿠버네티스 어나더 클래스를 기본으로 한다.

쿠버네티스의 Object에는 여러 종류가 있다.

같은 종류의 object끼리는 name이 중복되면 안된다.

 

lables 

  • 명세서이다.
  • part-of: 어플리케이션 전체이름
  • componet: 이 서비스를 구성하고 있는 각각의 분리된 기능들 (아키텍처 내 구성요소)
  • name: 어플리케이션 실제이름
  • instance: 애플리케이션의 인스턴스를 식별하는 고유한 이름
  • version: App 버전이 변경이 되면 변경해야함.
  • managed-by: Object 생성 주체 확인 용도 (쿠버네티스 권고사항)
  • selector와 매칭이 되어서 두 Object를 연결하는데 사용한다.
    • selector는 label의 instance 만으로도 유니크한 매핑 가능

 

 

Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: anotherclass-123
  labels:
    part-of: k8s-anotherclass
    managed-by: dashboard
  • 단일 클러스터 내에서의 리소스 그룹 격리 메커니즘이다.
  • 초기에 네 개의 네임스페이스를 갖는다.
    • default
    • kube-node-lease
    • kube-public
    • kube-system

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

 

  • 쿠버네티의 리소스(object)들은 대부분 namespace내에 소속되지만 , 일부는 namespace를 포함하는 cluster의 범위에 생성됨
  • Namespace와 PersistentVolume Cluster Level의 Object이다.
  • Deployment와 Service Namespace Level의 Object이다.

 

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    matchLabels:
      part-of: k8s-anotherclass
      component: backend-server
      name: api-tester
      instance: api-tester-1231
  replicas: 2
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        part-of: k8s-anotherclass
        component: backend-server
        name: api-tester
        instance: api-tester-1231
        version: 1.0.0
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          image: 1pro/api-tester:v1.0.0
          ports:
          - name: http
            containerPort: 8080
          envFrom:
            - configMapRef:
                name: api-tester-1231-properties
          startupProbe:
            httpGet:
              path: "/startup"
              port: 8080
            periodSeconds: 5
            failureThreshold: 24
          readinessProbe:
            httpGet:
              path: "/readiness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          livenessProbe:
            httpGet:
              path: "/liveness"
              port: 8080
            periodSeconds: 10
            failureThreshold: 3
          resources:
            requests:
              memory: "100Mi"
              cpu: "100m"
            limits:
              memory: "200Mi"
              cpu: "200m"
          volumeMounts:
            - name: files
              mountPath: /usr/src/myapp/files/dev
            - name: secret-datasource
              mountPath: /usr/src/myapp/datasource
      volumes:
        - name: files
          persistentVolumeClaim:
            claimName: api-tester-1231-files
        - name: secret-datasource
          secret:
            secretName: api-tester-1231-postgresql
  • Pod를 만들고 업그레이드 해주는 역할
  • template부터 이 내용대로 pod가 만들어진다.
  • readinessProbe는 앱에 트래픽을 연결시킬지를 판단하는애고
  • livenessProbe는 앱이 정상이 아니면 재시작을 시킬건지 판단하는 애
  • limit을 설정해주지 않으면 파드가 자원으 모든것을 써버린다.
  • volumeMounts
    • mountPath: 파드 내부에 만들어지는 디렉토리 
    • name은 volumes의 name이랑 같으면 persistentVolumeClaim이라는 object와 연결됨. 서로 name이 같아야함

 

  • application은 크게 App 초기화 단계, User 초기화 단계 , App 기동의 상태를 가진다.
    • 그런데 여기서 각각의 probe는 의미있는 역할을 한다.
    • startupProbe
      • 컨테이너 내의 애플리케이션이 시작되었는지를 나타냄.
      • 성공할 때 까지 다른 나머지의 probe는 활성화 되지 않음
      • 컨테이너에 startupProbe가 없을 경우  기본 상태는 Success이다.
    • livenessProbe
      • 앱이 정상인지 확인하는 역할을 한다.
        • livenessProbe의 기본 상태는 Success이다.
        • livenessProbe가 fail 한다면 kubelet은 컨테이너를 죽이고 해당 컨테이너는 재시작 정책의 대상이 된다.
      • 호출주기는 readnessProbe보다 길게 가져가는것이 좋다.
    • readnessProbe
      • 앱에 트래픽을 연결 시키는 역할을 한다.
        • 외부 API의 접근을 제어하기 위한 설정이다.
        • Pod의 labes와 Service의 Selector를 연결하는데
          • Service는 Pod의 트래픽 연결을 설정을 해주는 역할이다.
          • readnessProbe는 그 트래픽 연결을 제어하는 역할이다.
      • Pod의 labes와 Service의 Selector는 처음부터 바로 연결되지 않는다.
        • readnessProbe가 성공일때 연결이 된다.
        • readnessProbe를 설정하지 않으면 기본 상태는 Success이다.
      • 예제를 설명해보겠다.
        • 만약 트래픽이 많이 들어오고 앱은 죽은것은 아니고 요청을 처리할것이 많아서 계속해서 처리중일수 있다. 그래서 결과값이 안나올수 있다.
        • 그럴때 readnessProbe가 설정되어 있으면 잠시 외부 API 접근을 막고 앱에서 처리할수 있도록 시간을 벌어줄수 있다.
        • 그렇기 때문에 livenessProbe의 주기와 다르게 한다. livenessProbe의 주기는 좀 더 길게 가져가면 효율적이다.

Deployment strategy type은 ReCreate , RollingUpdate가 존재함

  • template의 내용중 바뀌는게 있으면 update가 된다.  
  • ReCreate는 서비스 중단 타이밍이 존재
  • RollingUpdate는 업데이트중 서비스 중단이 없음 
    • 업데이트 중에 자원 사용량이 150퍼 증가함
    • 업데이트 중에 두 버전이 동시에 호출됨
      • 이게 문제라면 Blue/Green 방식이 있다. 별도 배포 솔루션이 필요함
      • Blue/Green 방식은 자원 사용량 200% 증가됨
        • 운영 환경에서는 자원 사용량 200%라는게 쉬운것이 아니다. pod가 20개 등등 여러 App들을 동시에 update 시켜야할수도 있기 때문에 적절한 방법을 해야함
    • RollingUpdate에는 maxUnavailable , maxSurge 속성이 있다.
      • maxUnavailable은 업데이트 동안 최대 이용 불가능 파드수
      • maxSurge는 업데이트 동안 최대 새로 추가되는 파드 수

Service

apiVersion: v1
kind: Service
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
spec:
  selector:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
  ports:
    - port: 80
      targetPort: http
      nodePort: 31231
  type: NodePort
  • 서비스의 역할은 파트에 트래픽을 연결시켜주는것이다.
  • metadata
    • namespace는 antheorclass-123에 속한 obejct이다
    • targetPort는 컨테이너 포트를 가르키는 것이고 http는 컨테이너 포트의 name으로 지정한것을 연결시킨다.

 

서비스는 크게 Discovery , Publishing , Registry , Load Balancing 기능이 있다.

Service type을 NodePort로 지정하면 외부에서 접속할수 있게 된다. 이것이 서비스 퍼블리싱이다.

Service type을 ClusterIp로 설정하면 (default) 서비스 내부 DNS를 이용한 Service 이름으로 API  호출이 가능하다. 이것이 서비스 디스커버리이다.

 

Configmap

: pod의 환경변수 값을 제공하는 역할

: data가 환경변수로 들어갈 값

: Pod가 생성될때 환경변수는 값이 들어가기 때문에 ConfigMap을 바꿔도 변경되지 않는다.

 

Secret도 configmap과 비슷한데 pod에 좀더 중요한 값을 제공하는 역할

: Secret은 volume과 연결되기 때문에 Secret은 변경을 하면 변경된 사항이 바로 적용된다.

: 저장시 Base64로 인코딩 된다.

: Secret은 tpye이라는 속성이 있고 기본은 opaque라는 타입이고 Configmap을 써도 되는 모든 상황에 조금 중요한 데이터라는 생각이 되면 Secret으로 대체될수있다.

: 그러나 다른 타입을 사용할 경우 configmap과 전혀 달라진다. type에는 docker-registry , tls 등이 있다.

: 사용자 편의에 따라 커스텀하게 관리할 수 있는 요소를 제공해주는거다.

: Secret은 용어 때문에 보안에 용이 한것처럼 보이지만 사실상 암호화는 configmap이나 Secret이나 데이터 자체를 암호화 해야한다.

: Secret도 base64로 인코딩 되어서 저장되지만 누구나 base64로 인코딩 된 사실을 알수있다. secret != 암호화 이다.ㅎㅎ 

 

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-properties
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
data:
  spring_profiles_active: "dev"
  application_role: "ALL"
  postgresql_filepath: "/usr/src/myapp/datasource/postgresql-info.yaml"
---
apiVersion: v1
kind: Secret
metadata:
  namespace: anotherclass-123
  name: api-tester-1231-postgresql
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231
    version: 1.0.0
    managed-by: dashboard
stringData:
  postgresql-info.yaml: |
    driver-class-name: "org.postgresql.Driver"
    url: "jdbc:postgresql://postgresql:5431"
    username: "dev"
    password: "dev123"

PersistenVolumeClaim(PVC)

- pod에서 pv를 지정할때 사용함

 

PersistentVolume(PV)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: api-tester-1231-files
  labels:
    part-of: k8s-anotherclass
    component: backend-server
    name: api-tester
    instance: api-tester-1231-files
    version: 1.0.0
    managed-by: dashboard
spec:
  capacity:
    storage: 2G
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  local:
    path: "/root/k8s-local-volume/1231"
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - {key: kubernetes.io/hostname, operator: In, values: [k8s-master]}

:실제 볼륨을 지정하는 역할을 함

: namespace가 아닌 더 넓은 범위에 cluster Level이다.

: local이 중요함

  • Path를 volume으로 사용하겠다는 내용
  • local을 쓰면 필수로 nodeAffinity라는 속성을 꼭 사용하게 되어 있고 nodeAffinity라는 속성은 어느 Node에 Pod를 생성 할 건지를 정하는 속성이다.

 

PV와 PVC 대신에 hostPath와 nodeSelector를 쓰면 안되나.?

HostPath와 nodeSelector로 가능은 하지만 ReadOnly 기능으로 사용하려고 나온것이다.

테스트 환경에서 임시 저장용도로 사용은 가능하나. 운영에선 사용해서는 안댐

 

 

HPA

: 부하에 따라 pod를 늘려주고 줄여주는 scaling 역할을 함.

 

참고자료

https://medium.com/finda-tech/kubernetes-pod%EC%9D%98-%EC%A7%84%EB%8B%A8%EC%9D%84-%EB%8B%B4%EB%8B%B9%ED%95%98%EB%8A%94-%EC%84%9C%EB%B9%84%EC%8A%A4-probe-7872cec9e568

 

kubernetes Pod의 진단을 담당하는 서비스 : probe

프로브(Probe)는 컨테이너에서 kubelet에 의해 주기적으로 수행되는 진단(diagnostic)이다.

medium.com

https://www.inflearn.com/course/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-%EC%96%B4%EB%82%98%EB%8D%94-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A7%80%EC%83%81%ED%8E%B8-sprint1/dashboard

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band