반응형
  • cordon
    • 지정한 노드에 Pod 를 스케줄링 하지 않는다.
  • taint
    • 지정한 노드에 Pod를 스케줄링 하지 않지만 tolerations 설정을 통해 스케줄링이 가능하다.

 

728x90
반응형
반응형

static pod 에 대해서 알아보다가 몇가지 기억할 만한 것들을 적어본다.

- master node 의  /etc/kubernetes/manifests 하위에는 yaml 파일들이 있는데 이 yaml 파일들은 마스터 노드가 실행시에 자동으로 생성되는 static pod 들이다. 보통 etcd, api-server등이 있다.

- node에 생성된 static pod 를 지우기 위해서는 해당 노드에 가서 지워야 한다. 지우기 위해서는 노드 안에 있는 kubelet의 config 파일(/var/lib/kubelet/config.yaml) 에 있는 staticPodPath 값을 찾아서 path 위치에 있는 yaml 파일을 지워야 한다. kubectl delete pod 로 지우면 다시 생성된다.

- 조회는 가능하지만 edit 는 불가능 하다.

 

728x90
반응형
반응형

Lens 라는 툴을 사용해 보려고 host pc 에서 VM 에 있는 K8S 를 연결시켜보려고 시도를 해봤다.

2021/01/05 10:08:52 http: proxy error: x509: certificate is valid for 10.96.0.1, 10.0.1.7, not [ip]

그런데 위와 같은 에러 메세지가 나면서 연결이 되지 않았다. 위에 [ip] 는 host pc 의 ip 이다.

Google에서 찾아보니 인증서에 나의 로컬 ip 가 들어가 있지 않아서 라는 이야기가 나왔다.

그럼 현재 k8s 에 있는 apiserver 인증서 내용을 살펴보자.

openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text

위와 같이 입력하면 apiserver.crt 파일에 있는 내용을 출력해서 볼 수 있다. 출력되는 항목중에 Subject Alternative Name 이라는 항목이 있다.

 X509v3 Subject Alternative Name:
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:master01-virtualbox, IP Address:10.96.0.1, IP Address:10.0.1.7

여기 정보를 보면 10.96.0.1, 10.0.1.7 로 정의 되어 있다. 이곳에 내 로컬pc 의 ip 가 정의되어있어야 인증서 오류가 안나게 된다. 그럼 어떻게 해야 저부분을 수정을 할수 있나.

kube-system 네임스페이스에 있는 configmap 중에 kubeadm-config 라는 항목이 있다.

kubectl -n kube-system get configmap kubeadm-config -o yaml

apiVersion: v1
data:
  ClusterConfiguration: |
    apiServer:
      extraArgs:
        authorization-mode: Node,RBAC
      timeoutForControlPlane: 4m0s
    apiVersion: kubeadm.k8s.io/v1beta2
    certificatesDir: /etc/kubernetes/pki
    clusterName: kubernetes
    controllerManager: {}
    dns:
      type: CoreDNS
    etcd:
      local:
        dataDir: /var/lib/etcd
    imageRepository: k8s.gcr.io
    kind: ClusterConfiguration
    kubernetesVersion: v1.19.2
    networking:
      dnsDomain: cluster.local
      podSubnet: 10.244.0.0/16
      serviceSubnet: 10.96.0.0/12
    scheduler: {}
  ClusterStatus: |
    apiEndpoints:
      master01-virtualbox:
        advertiseAddress: 10.0.1.7
        bindPort: 6443
    apiVersion: kubeadm.k8s.io/v1beta2
    kind: ClusterStatus
kind: ConfigMap
metadata:
  creationTimestamp: "2020-10-12T10:21:12Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        .: {}
        f:ClusterConfiguration: {}
        f:ClusterStatus: {}
    manager: kubeadm
    operation: Update
    time: "2020-10-12T10:21:12Z"
  name: kubeadm-config
  namespace: kube-system
  resourceVersion: "168"
  selfLink: /api/v1/namespaces/kube-system/configmaps/kubeadm-config
  uid: 93b6e988-686e-449b-9bd1-a6f02b15d1ea

위처럼 정의 되어있다.

update 를 위해서는 다음과 같이 명령어로 수행해 볼 수 있다.

kubeadm init phase certs --apiserver-cert-extra-sans stringSlice
Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names.

(kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init-phase/#cmd-phase-certs)

kubeadmin init phase certs apiserver --apiserver-cert-extra-sans "추가할 IP"

그런데 먼저 하기전에 한가지 더 할 일이 있다.

/etc/kubernetes/pki 에 있는 apiserver.key, apiserver.crt 파일을 다른곳에 옮겨야 한다. 그렇지 않으면 인증서가 새로 생성되지 않는다. 다른 위치에 옮기고 나서 명령어를 실행한다.

sudo kubeadm init phase certs apiserver --apiserver-cert-extra-sans=X.X.X.X
I0105 11:06:44.899381    1295 version.go:252] remote version is much newer: v1.20.1; falling back to: stable-1.19
W0105 11:06:46.225883    1295 configset.go:348] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local master01-virtualbox] and IPs [10.96.0.1 10.0.1.7 X.X.X.X]

위와같이 실행 결과를 볼수 있다. 실제 인증서를 확인해 보면 다음과 같이 들어가 있다.

 X509v3 Subject Alternative Name:
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, DNS:master01-virtualbox, IP Address:10.96.0.1, IP Address:10.0.1.7, IP Address:X.X.X.X

그런데 다시 Lens 로 접속 해보니 에러 발생

2021/01/05 13:14:53 http: proxy error: x509: certificate signed by unknown authority

그래서 결국 configmap 도 수정해주고 재기동 한 결과 정상적으로 접속이 됐다.

apiVersion: v1
data:
  ClusterConfiguration: |
    apiServer:
      certSANs:
      - X.X.X.X

 

728x90
반응형
반응형

파드 스케줄링

파드를 만들때 어떤 노드에서 실행할지 다양한 옵션으로 선택할 수 있다.

NodeSelector(노드 셀렉터)

  • 설정
    spec:
      containers:
      nodeSelector:
        key: value

Node Affinity

  • 노드 레이블을 기반으로 파드를 스케줄링 한다.
  • 노드 셀렉터를 함께 설정할 경우 둘다 만족하는 노드에 스케줄링된다.
  • requiredDuringSchedulingIgnoredDuringExecution : 스케줄링 하는동안 꼭 필요한 조건
  • preferredDuringSchedulingIgnoredDuringExecution : 만족하면 좋은 조건. (필수아님)
  • 스케줄링 하는 동안 조건이 변경되더라도 무시한다.
  • 설정
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: beta.kubernetes.io/os
                operator: In
                values:
                - linux
                - window
              - key: disktype
                operator: Exists
          preferredDuringSchedulingIgnoredDuringExecution  
          - weight: 10
            preference:
              matchExpressions:
              - key: kubernetes.io/hostname
                operator: In
                values:
                - worker-node01
    • operators : In, NotIn, Exists, DoesNotExist, Gt(Greater than), Lt(Lower than)

Pod affinity, antiAffinity

  • affinity: 서로 연관성이 있는 Pod 를 같은 노드에 배치
  • antiAffinity: 자원을 많이 차지 하는 Pod 를 서로 다른 노드에 배치
  • 설정
    spec:
        affinity:
          podAntiAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - store
              topologyKey: "kubernetes.io/hostname"
    • app 필드 값이 store 인 노드는 피해서 스케줄링 한다.
    • topologyKey : affinity 를 만족하면 topologyKey 기준으로 같은 노드에 pod 를 실행하고 anitiAffinity를 만족하면 topologyKey 기준으로 다른 노드에 pod 를 실행한다.

taint, toleration

  • 테인트를 설정한 노드는 스케줄링 하지 않는다.
  • 테인트를 설정한 노드에 스케줄링 하려면 톨러레이션을 설정해야 한다.
  • kubectl taint nodes 노드명 key01=value01:NoSchedule (key=value:효과)
  • kubectl taint nodes 노드명 key01=value01:NoSchedule- (테인트 제거)
  • 톨러레이션
    spec:
      tolerations:
      - key: "key01"
        operator: "Equal"
        value: "value01"
        effect: "NoSchedule"
    • effect
      • NoSchedule : 톨러레이션 설정 없으면 스케줄링 안함.
      • PreferNoSchedule : 스케줄링 안하지만 자원 부족하면 할수도 있음
      • NoExecute : 스케줄링 안하며 기존 파드도 설정이 없는경우 종료시킴

cordon, drain

  • cordon
    • 지정한 노드에 추가로 파드를 스케줄링 하지 않는다.
    • kubectl cordon 노드명
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl cordon worker01-virtualbox
      node/worker01-virtualbox cordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS                     ROLES    AGE   VERSION
      master01-virtualbox   Ready                      master   79d   v1.19.2
      worker01-virtualbox   Ready,SchedulingDisabled   <none>   79d   v1.19.2
      worker02-virtualbox   NotReady                   <none>   79d   v1.19.2
      master01@master01-VirtualBox:~$ kubectl uncordon worker01-virtualbox
      node/worker01-virtualbox uncordoned
      master01@master01-VirtualBox:~$ kubectl get nodes
      NAME                  STATUS     ROLES    AGE   VERSION
      master01-virtualbox   Ready      master   79d   v1.19.2
      worker01-virtualbox   Ready      <none>   79d   v1.19.2
      worker02-virtualbox   NotReady   <none>   79d   v1.19.2
  • drain
    • 지정된 노드에 있는 파드를 다른 노드로 옮긴다.
    • 노드에 데몬셋이 존재할 경우 적용 불가능
    • 데몬셋 무시하고 적용할 경우 --ignore-daemonsets=true 옵션 추가
    • 컨트롤러를 이용하지 않은 파드들도 drain 불가능

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Secret

  • 비밀번호 같은 민감한 정보를 저장하는 용도로 사용

생성

  • 명령어
    • kubectl create generic secret명 --from-file~
    • 실제 값은 base64 로 인코딩한 값이 들어간다.
  • 템플릿
    apiVersion: v1
    kind: Secret
    metadata:
      name: user-pass-yaml
    type: Opaque
    data:
      username: 값
      password: 값
    • type
      • Opaque : 기본값
      • kubernetes.io/service-account-token : 쿠버네티스 인증토큰 저장
      • kubernetes.io/dockerconfigjson: 도커 저장소 인증정보 저장
      • kubernetes.io/tls: TLS 인증서 저장
    • data 값은 base64 로 인코딩 한 값을 넣어야 한다.
      • echo -n "username" | base64

사용

  • 환경변수로 사용

     

    spec:
      containers:
      - name:
        image:
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: user-pass-yaml
              key: username
  • volume 에 바인딩 하기
    spec:
      containers:
      - name:
        image:
        volumeMounts:
        - name: volume-secret
          mountPath: /etc/config
          readOnly: true
      volumes:
      - name: config-secret
        secret:
          secretName: user-pass-yaml 
  • 프라이빗 커네이너 이미지 pull
    • kubectl create secret docker-registry dockersecret --docker-username= --docker-password= --docker-email= --docker-service=https://~
    • 설정
      spec:
      containers:
      - name:
        image:
      imagePullSecrets:
      - name: dockersecret      
  • TLS 사용
    • kubectl create secret tls tlssecret --key tls.key --cert tls.crt

제한

  • secret 은 etcd 에 저장된다.
  • secret의 최대 용량은 1MB
  • 작은 용량의 secret 을 여러개 만들어도 문제가 생길수 있다.
  • etcd 는 접근 제한을 해야 한다.

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Label, Annotation

Label(레이블)

  • 키-값 쌍으로 구성
  • 파드 관리할때 구분하는 역할을 한다.
  • 규칙
    • 63글자 넘으면 안됨
    • 시작과 끝문자는 알파벳 대소문자 및 숫자
    • 중간에는 대시(-), 밑줄(_), 점(.), 숫자등이 올수 있음
  • 레이블 셀렉터
    • 등호기반(=, ==)
    • 집합기반(in, notin..)
    • 레이블을 모두 만족시켜야 하는경우 (And) 는 쉼표로 연결
    • 실제 서비스에서 정상적으로 셀렉트를 했는지 보려면 서비스의 endpoint를 확인해보면 된다.
  • pod 선택시 -l 옵션 사용
    • kubectl get pod -l 레이블~

Annotation

  • 쿠버네티스 시스템이 필요한 정보를 담는다.
  • 키는 쿠버네티스 시스템이 인식할 수 있는 값을 사용한다.

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

ConfigMap

  • 컨테이너에 필요한 환경 설정을 컨테이너와 분리해서 제공하는 기능

사용

  • 설정
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-dev
    data:
      DB_URL: localhost
      DB_USER: myuser
      DB_PASS: mypass
      DEBUG_INFO: debug  
  • 컨피그맵 일부만 사용
    spec:
      containers:
      - name:
        image:
        env:
        - name: DEBUG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: config-dev
              key : DEBUG_INFO
    • .env[].valueFrom 사용
    • .env[].valueFrom.configMapKeyRef 를 통해 이미 정의된 configmap 사용
  • 컨피그맵 전체를 불러오기
    spec:
      containers:
      - name:
        image:      
        envFrom:
        - configMapRef:
          name: config-dev      
  • volume 에 바인딩 하기
    spec:
      containers:
      - name:
        image:
        volumeMounts:
        - name: config-volume
          mountPath: /etc/config
      volumes:
      - name: config-volume
        configMap:
          name: config-dev    
    • 컨테이너 내부에 파일로 저장한다.
      root@nginx-deployment-67b8444cdf-sp7lx:/# ls /etc/config/
      DB_PASS  DB_URL  DB_USER  DEBUG_INFO

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Ingress

개념

  • 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙
  • 인그레스는 규칙들의 모음이며 실제로는 인그레스 컨트롤러가 동작시킨다.

설정

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foos1
        pathType: Prefix
        backend:
          service:
            name: s1
            port:
              number: 80
      - path: /bars2
        pathType: Prefix
        backend:
          service:
            name: s2
            port:
              number: 80
  - host: bar.foo.com      
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:      
          service:
            name: s2
            port:
              number: 80  
  • annotation 은 인그레스 컨트롤러마다 다르다. (https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/)

    ingress version 차이

  • 1.18

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: test-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: /testpath
            pathType: Prefix
            backend:
              serviceName: test
              servicePort: 80
  • 1.19

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: minimal-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: /testpath
            pathType: Prefix
            backend:
              service:
                name: test
                port:
                  number: 80

SSL 설정

  • tls 생성
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=kube-book.com"
    Can't load /root/.rnd into RNG
    140377540018624:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:88:Filename=/root/.rnd
    Generating a RSA private key
    ........................+++++
    ........+++++
    writing new private key to 'tls.key'  
  • tls secret 생성
    kubectl create secret tls kube-book-secret --key tls.key --cert tls.crt  
  • .spec.tls 설정
    spec:
    tls:
    - hosts:
      - kube-boo.com
      secretName: kube-book-secret

무중단 배포시 주의 할점

  • maxSurge 와 maxUnavailable 설정
    • maxSurge : 디플로이먼트에 기본 pod 개수에 여분의 파드를 몇개 추가 할수 있는지 설정
    • maxUnavailable : 디플로이먼트 업데이트시 사용할수 없는 파드 개수
  • readinessProbe 확인
    • 실제 서비스 요청 처리할 준비가 되었는지 진단
    • 설정 불가능할 경우 .spec.minReadySeconds 설정. 해당 설정 기간동은 트래픽을 받지 않지만 그 이후에는 받는다.
  • graceful 종료
    • 기존 받은 요청만 처리하고 새 요청은 받지 않는다
    • 설정 불가능 할 경우 hock 을 설정한다.

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형
반응형

Service

개념

  • 동적으로 변하는 Pod 들을 고정적으로 접근할 때 사용한다.
  • 서비스는 주로 L4영역에서 통신할 때 사용한다.

서비스 타입

  • ClusterIP
    • default, 클러스터 내부에서만 사용가능
  • NodePort 모
    • 모든 노드에 지정된 포트를 할당함.
    • 외부에서 접근 가능
  • LoadBalancer
    • EXTERNAL-IP 생성
    • 외부에서 Pod 접근 가능 할수 있게 해줌
  • ExternalName
    • 서비스를 .spec.externalName 필드에 설정한 값과 연결한다.
    • 클러스터 안에서 외부에 접근할 때 주로 사용한다.

서비스 사용

  • 설정

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      type: ClusterIP
      selector:
        app: MyApp
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    • .spec.clusterIP 값을 None 로 설정하면 IP 가 없는 서비스 생성 가능

kube-proxy

  • userspace 모드
    • Pod 연결 요청시 실패할 경우 다른 Pod에 연결을 재시도함.
  • iptables 모드
    • 클라이언트 요청을 iptables 를 거쳐 Pod 로 직접 전달
    • Pod 연결 요청시 실패할 경우 재시도 안함
  • IPVS 모드

출처 : 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리자 자동화 표준 (동양북스)

728x90
반응형

+ Recent posts